[libsanitizer] Implement IntrusiveList<T>::Iterator, use IntrusiveList in sanitizer_flags.cc

llvm-svn: 204342
This commit is contained in:
Alexander Potapenko 2014-03-20 13:49:21 +00:00
parent 4fea4f917d
commit d23359c3e3
2 changed files with 31 additions and 20 deletions

View File

@ -15,18 +15,19 @@
#include "sanitizer_common.h"
#include "sanitizer_libc.h"
#include "sanitizer_list.h"
namespace __sanitizer {
CommonFlags common_flags_dont_use;
struct FlagDescriptionList {
struct FlagDescription {
const char *name;
const char *description;
FlagDescriptionList *next;
FlagDescription *next;
};
FlagDescriptionList *flag_descriptions = 0, *last_flag_description = 0;
IntrusiveList<FlagDescription> flag_descriptions;
void SetCommonFlagsDefaults(CommonFlags *f) {
f->symbolize = true;
@ -138,37 +139,30 @@ static LowLevelAllocator allocator_for_flags;
// The linear scan is suboptimal, but the number of flags is relatively small.
bool FlagInDescriptionList(const char *name) {
FlagDescriptionList *descr = flag_descriptions;
while (descr) {
if (!internal_strcmp(descr->name, name)) return true;
descr = descr->next;
IntrusiveList<FlagDescription>::Iterator it(&flag_descriptions);
while (it.hasNext()) {
if (!internal_strcmp(it.next()->name, name)) return true;
}
return false;
}
void AddFlagDescription(const char *name, const char *description) {
if (FlagInDescriptionList(name)) return;
FlagDescriptionList *new_description =
(FlagDescriptionList*)allocator_for_flags.Allocate(
sizeof(FlagDescriptionList));
if (!last_flag_description) {
flag_descriptions = new_description;
} else {
last_flag_description->next = new_description;
}
FlagDescription *new_description =
(FlagDescription*)allocator_for_flags.Allocate(
sizeof(FlagDescription));
new_description->name = name;
new_description->description = description;
new_description->next = 0;
last_flag_description = new_description;
flag_descriptions.push_back(new_description);
}
// TODO(glider): put the descriptions inside CommonFlags.
void PrintFlagDescriptions() {
FlagDescriptionList *descr = flag_descriptions;
IntrusiveList<FlagDescription>::Iterator it(&flag_descriptions);
Printf("Available flags for %s:\n", SanitizerToolName);
while (descr) {
while (it.hasNext()) {
FlagDescription *descr = it.next();
Printf("\t%s - %s\n", descr->name, descr->description);
descr = descr->next;
}
}

View File

@ -26,6 +26,8 @@ namespace __sanitizer {
// non-zero-initialized objects before using.
template<class Item>
struct IntrusiveList {
friend class Iterator;
void clear() {
first_ = last_ = 0;
size_ = 0;
@ -113,6 +115,21 @@ struct IntrusiveList {
}
}
class Iterator {
public:
explicit Iterator(IntrusiveList<Item> *list)
: list_(list), current_(list->first_) { }
Item *next() {
Item *ret = current_;
if (current_) current_ = current_->next;
return ret;
}
bool hasNext() const { return current_ != 0; }
private:
IntrusiveList<Item> *list_;
Item *current_;
};
// private, don't use directly.
uptr size_;
Item *first_;