| Index: third_party/crazy_linker/crazy_linker/src/crazy_linker_util.h
|
| diff --git a/third_party/crazy_linker/crazy_linker/src/crazy_linker_util.h b/third_party/crazy_linker/crazy_linker/src/crazy_linker_util.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c020571f7aa930c7ede109d16d4a5f0faa6aff24
|
| --- /dev/null
|
| +++ b/third_party/crazy_linker/crazy_linker/src/crazy_linker_util.h
|
| @@ -0,0 +1,325 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef CRAZY_LINKER_UTIL_H
|
| +#define CRAZY_LINKER_UTIL_H
|
| +
|
| +#include <fcntl.h>
|
| +#include <stdarg.h>
|
| +#include <stdio.h>
|
| +#include <unistd.h>
|
| +
|
| +namespace crazy {
|
| +
|
| +// Helper macro to loop around EINTR errors in syscalls.
|
| +#define HANDLE_EINTR(expr) TEMP_FAILURE_RETRY(expr)
|
| +
|
| +// Helper macro to tag unused variables. Use in the declaration, between
|
| +// the type and name, as in:
|
| +// int CRAZY_UNUSED my_var = 0;
|
| +#define CRAZY_UNUSED __attribute__((unused))
|
| +
|
| +// Helper scoped pointer class.
|
| +template <class T>
|
| +class ScopedPtr {
|
| +public:
|
| + ScopedPtr() : ptr_(NULL) {}
|
| + explicit ScopedPtr(T* ptr) : ptr_(ptr) {}
|
| + ~ScopedPtr() {
|
| + Reset(NULL);
|
| + }
|
| +
|
| + T* Release() {
|
| + T* ret = ptr_;
|
| + ptr_ = NULL;
|
| + return ret;
|
| + }
|
| +
|
| + void Reset(T* ptr) {
|
| + if (ptr_)
|
| + delete ptr_;
|
| + ptr_ = ptr;
|
| + }
|
| +
|
| + T* Get() { return ptr_; }
|
| + T& operator*() { return *ptr_; }
|
| + T* operator->() { return ptr_; }
|
| +private:
|
| + T* ptr_;
|
| +};
|
| +
|
| +// Return the base name from a file path. Important: this is a pointer
|
| +// into the original string.
|
| +const char* GetBaseNamePtr(const char* path);
|
| +
|
| +// Helper class used to implement a string. Similar to std::string
|
| +// without all the crazy iterator / iostream stuff.
|
| +//
|
| +// Required because crazy linker should only link against the system
|
| +// libstdc++ that only provides new/delete.
|
| +//
|
| +class String {
|
| +public:
|
| + String();
|
| + String(const char* str, size_t len);
|
| + String(const String& other);
|
| + explicit String(const char* str);
|
| + explicit String(char ch);
|
| +
|
| + ~String();
|
| +
|
| + const char* c_str() const { return ptr_; }
|
| + size_t size() const { return size_; }
|
| + size_t capacity() const { return capacity_; }
|
| +
|
| + bool IsEmpty() const { return size_ == 0; }
|
| +
|
| + char& operator[](size_t index) {
|
| + return ptr_[index];
|
| + }
|
| +
|
| + String& operator =(const String& other) {
|
| + Assign(other.ptr_, other.size_);
|
| + return *this;
|
| + }
|
| +
|
| + String& operator=(const char* str) {
|
| + Assign(str, strlen(str));
|
| + return *this;
|
| + }
|
| +
|
| + String& operator=(char ch) {
|
| + Assign(&ch, 1);
|
| + return *this;
|
| + }
|
| +
|
| + String& operator +=(const String& other) {
|
| + Append(other);
|
| + return *this;
|
| + }
|
| +
|
| + String& operator +=(const char* str) {
|
| + Append(str, strlen(str));
|
| + return *this;
|
| + }
|
| +
|
| + String& operator +=(char ch) {
|
| + Append(&ch, 1);
|
| + return *this;
|
| + }
|
| +
|
| + void Resize(size_t new_size);
|
| +
|
| + void Reserve(size_t new_capacity);
|
| +
|
| + void Assign(const char* str, size_t len);
|
| +
|
| + void Assign(const String& other) {
|
| + Assign(other.ptr_, other.size_);
|
| + }
|
| +
|
| + void Assign(const char* str) {
|
| + Assign(str, strlen(str));
|
| + }
|
| +
|
| + void Append(const char* str, size_t len);
|
| +
|
| + void Append(const String& other) {
|
| + Append(other.ptr_, other.size_);
|
| + }
|
| +
|
| + void Append(const char* str) {
|
| + Append(str, strlen(str));
|
| + }
|
| +
|
| +private:
|
| +
|
| + void Init(void) {
|
| + ptr_ = const_cast<char*>(kEmpty);
|
| + size_ = 0;
|
| + capacity_ = 0;
|
| + }
|
| +
|
| + static const char kEmpty[];
|
| +
|
| + char* ptr_;
|
| + size_t size_;
|
| + size_t capacity_;
|
| +};
|
| +
|
| +// Helper template used to implement a simple vector or POD-struct items.
|
| +// I.e. this uses memmove() to move items during insertion / removal.
|
| +//
|
| +// Required because crazy linker should only link against the system
|
| +// libstdc++ which only provides new/delete.
|
| +//
|
| +template <class T>
|
| +class Vector {
|
| +public:
|
| + Vector() : items_(0), count_(0), capacity_(0) {}
|
| + ~Vector() {
|
| + free(items_);
|
| + }
|
| +
|
| + T& operator[](size_t index) {
|
| + return items_[index];
|
| + }
|
| +
|
| + bool IsEmpty() const {
|
| + return count_ == 0;
|
| + }
|
| +
|
| + void PushBack(T item) {
|
| + InsertAt(static_cast<int>(count_), item);
|
| + }
|
| +
|
| + T PopFirst() {
|
| + T result = items_[0];
|
| + RemoveAt(0);
|
| + return result;
|
| + }
|
| +
|
| + T PopLast() {
|
| + T result = items_[count_ - 1];
|
| + Resize(count_ - 1);
|
| + return result;
|
| + }
|
| +
|
| + void Remove(T item) {
|
| + int index = IndexOf(item);
|
| + if (index >= 0)
|
| + RemoveAt(index);
|
| + }
|
| +
|
| + void InsertAt(int index, T item);
|
| +
|
| + void RemoveAt(int index);
|
| +
|
| + int IndexOf(T item) const;
|
| +
|
| + bool Has(T item) const {
|
| + return IndexOf(item) >= 0;
|
| + }
|
| +
|
| + size_t GetCount() const { return count_; }
|
| +
|
| + void Reserve(size_t new_capacity);
|
| +
|
| + void Resize(size_t new_count);
|
| +
|
| +private:
|
| + T* items_;
|
| + size_t count_;
|
| + size_t capacity_;
|
| +};
|
| +
|
| +template <class T>
|
| +int Vector<T>::IndexOf(T item) const {
|
| + for (size_t n = 0; n < count_; ++n) {
|
| + if (items_[n] == item)
|
| + return static_cast<int>(n);
|
| + }
|
| + return -1;
|
| +}
|
| +
|
| +template <class T>
|
| +void Vector<T>::InsertAt(int index, T item) {
|
| + if (count_ >= capacity_)
|
| + Reserve(capacity_ + (capacity_ >> 1) + 4);
|
| +
|
| + if (index < 0)
|
| + index = 0;
|
| + size_t n = static_cast<size_t>(index);
|
| + if (n > count_)
|
| + n = count_;
|
| + else
|
| + memmove(items_ + n + 1, items_ + n, (count_ - n) * sizeof(T));
|
| +
|
| + items_[n] = item;
|
| + count_++;
|
| +}
|
| +
|
| +template <class T>
|
| +void Vector<T>::RemoveAt(int index) {
|
| + if (index < 0)
|
| + return;
|
| +
|
| + size_t n = static_cast<size_t>(index);
|
| + if (n >= count_)
|
| + return;
|
| +
|
| + memmove(items_ + n, items_ + n + 1, (count_ - n - 1) * sizeof(T));
|
| + count_--;
|
| +}
|
| +
|
| +template <class T>
|
| +void Vector<T>::Reserve(size_t new_capacity) {
|
| + items_ = reinterpret_cast<T*>(realloc(items_, new_capacity * sizeof(T)));
|
| + capacity_ = new_capacity;
|
| + if (count_ > capacity_)
|
| + count_ = capacity_;
|
| +}
|
| +
|
| +template <class T>
|
| +void Vector<T>::Resize(size_t new_size) {
|
| + if (new_size > capacity_)
|
| + Reserve(new_size);
|
| +
|
| + if (new_size > count_)
|
| + memset(items_ + count_, 0, (new_size - count_) * sizeof(T));
|
| +
|
| + count_ = new_size;
|
| +}
|
| +
|
| +// Helper template class to implement a set.
|
| +// Given that the crazy linker doesn't expect to deal with hundreds
|
| +// of libraries at the same time, implement it with a vector.
|
| +template <class T>
|
| +class Set {
|
| +public:
|
| + Set() : items_() {}
|
| + ~Set() {}
|
| +
|
| + // Returns the number of items in the set.
|
| + size_t GetCount() const { return items_.GetCount(); }
|
| +
|
| + bool IsEmpty() const { return items_.IsEmpty(); }
|
| +
|
| + // Returns true iff the set contains a given item.
|
| + bool Has(T item) const {
|
| + return items_.Has(item);
|
| + }
|
| +
|
| + // Add an item to the set. Returns false iff the item was already in it.
|
| + bool Add(T item);
|
| +
|
| + // Delete an item from the set. Returns false iff the item was not in it.
|
| + bool Del(T item);
|
| +
|
| +private:
|
| + Vector<T> items_;
|
| +};
|
| +
|
| +template <class T>
|
| +bool Set<T>::Add(T item) {
|
| + int idx = items_.IndexOf(item);
|
| + if (idx >= 0)
|
| + return false;
|
| +
|
| + items_.PushBack(item);
|
| + return true;
|
| +}
|
| +
|
| +template <class T>
|
| +bool Set<T>::Del(T item) {
|
| + int idx = items_.IndexOf(item);
|
| + if (idx < 0)
|
| + return false;
|
| + items_.RemoveAt(idx);
|
| + return true;
|
| +}
|
| +
|
| +} // namespace crazy
|
| +
|
| +#endif // CRAZY_LINKER_UTIL_H
|
|
|