1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CRAZY_LINKER_UTIL_H
6 #define CRAZY_LINKER_UTIL_H
15 // Helper macro to loop around EINTR errors in syscalls.
16 #define HANDLE_EINTR(expr) TEMP_FAILURE_RETRY(expr)
18 // Helper macro to tag unused variables. Use in the declaration, between
19 // the type and name, as in:
20 // int CRAZY_UNUSED my_var = 0;
21 #define CRAZY_UNUSED __attribute__((unused))
23 // Helper scoped pointer class.
27 ScopedPtr() : ptr_(NULL) {}
28 explicit ScopedPtr(T* ptr) : ptr_(ptr) {}
29 ~ScopedPtr() { Reset(NULL); }
43 T* Get() { return ptr_; }
44 T& operator*() { return *ptr_; }
45 T* operator->() { return ptr_; }
51 // Return the base name from a file path. Important: this is a pointer
52 // into the original string.
53 const char* GetBaseNamePtr(const char* path);
55 // Helper class used to implement a string. Similar to std::string
56 // without all the crazy iterator / iostream stuff.
58 // Required because crazy linker should only link against the system
59 // libstdc++ that only provides new/delete.
64 String(const char* str, size_t len);
65 String(const String& other);
66 explicit String(const char* str);
67 explicit String(char ch);
71 const char* c_str() const { return ptr_; }
72 char* ptr() { return ptr_; }
73 size_t size() const { return size_; }
74 size_t capacity() const { return capacity_; }
76 bool IsEmpty() const { return size_ == 0; }
78 char& operator[](size_t index) { return ptr_[index]; }
80 String& operator=(const String& other) {
81 Assign(other.ptr_, other.size_);
85 String& operator=(const char* str) {
86 Assign(str, strlen(str));
90 String& operator=(char ch) {
95 String& operator+=(const String& other) {
100 String& operator+=(const char* str) {
101 Append(str, strlen(str));
105 String& operator+=(char ch) {
110 void Resize(size_t new_size);
112 void Reserve(size_t new_capacity);
114 void Assign(const char* str, size_t len);
116 void Assign(const String& other) { Assign(other.ptr_, other.size_); }
118 void Assign(const char* str) { Assign(str, strlen(str)); }
120 void Append(const char* str, size_t len);
122 void Append(const String& other) { Append(other.ptr_, other.size_); }
124 void Append(const char* str) { Append(str, strlen(str)); }
128 ptr_ = const_cast<char*>(kEmpty);
133 static const char kEmpty[];
140 // Helper template used to implement a simple vector or POD-struct items.
141 // I.e. this uses memmove() to move items during insertion / removal.
143 // Required because crazy linker should only link against the system
144 // libstdc++ which only provides new/delete.
149 Vector() : items_(0), count_(0), capacity_(0) {}
150 ~Vector() { free(items_); }
152 T& operator[](size_t index) { return items_[index]; }
154 bool IsEmpty() const { return count_ == 0; }
156 void PushBack(T item) { InsertAt(static_cast<int>(count_), item); }
159 T result = items_[0];
165 T result = items_[count_ - 1];
170 void Remove(T item) {
171 int index = IndexOf(item);
176 void InsertAt(int index, T item);
178 void RemoveAt(int index);
180 int IndexOf(T item) const;
182 bool Has(T item) const { return IndexOf(item) >= 0; }
184 size_t GetCount() const { return count_; }
186 void Reserve(size_t new_capacity);
188 void Resize(size_t new_count);
197 int Vector<T>::IndexOf(T item) const {
198 for (size_t n = 0; n < count_; ++n) {
199 if (items_[n] == item)
200 return static_cast<int>(n);
206 void Vector<T>::InsertAt(int index, T item) {
207 if (count_ >= capacity_)
208 Reserve(capacity_ + (capacity_ >> 1) + 4);
212 size_t n = static_cast<size_t>(index);
216 memmove(items_ + n + 1, items_ + n, (count_ - n) * sizeof(T));
223 void Vector<T>::RemoveAt(int index) {
227 size_t n = static_cast<size_t>(index);
231 memmove(items_ + n, items_ + n + 1, (count_ - n - 1) * sizeof(T));
236 void Vector<T>::Reserve(size_t new_capacity) {
237 items_ = reinterpret_cast<T*>(realloc(items_, new_capacity * sizeof(T)));
238 capacity_ = new_capacity;
239 if (count_ > capacity_)
244 void Vector<T>::Resize(size_t new_size) {
245 if (new_size > capacity_)
248 if (new_size > count_)
249 memset(items_ + count_, 0, (new_size - count_) * sizeof(T));
254 // Helper template class to implement a set.
255 // Given that the crazy linker doesn't expect to deal with hundreds
256 // of libraries at the same time, implement it with a vector.
263 // Returns the number of items in the set.
264 size_t GetCount() const { return items_.GetCount(); }
266 bool IsEmpty() const { return items_.IsEmpty(); }
268 // Returns true iff the set contains a given item.
269 bool Has(T item) const { return items_.Has(item); }
271 // Add an item to the set. Returns false iff the item was already in it.
274 // Delete an item from the set. Returns false iff the item was not in it.
282 bool Set<T>::Add(T item) {
283 int idx = items_.IndexOf(item);
287 items_.PushBack(item);
292 bool Set<T>::Del(T item) {
293 int idx = items_.IndexOf(item);
296 items_.RemoveAt(idx);
302 #endif // CRAZY_LINKER_UTIL_H