-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
So that we can filter by dso. Symbols in other dsos won't be accounted for. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1246399282-20934-2-git-send-email-acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
- Loading branch information
Arnaldo Carvalho de Melo
authored and
Ingo Molnar
committed
Jun 30, 2009
1 parent
f5812a7
commit 2590340
Showing
5 changed files
with
238 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
/* | ||
* (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com> | ||
* | ||
* Licensed under the GPLv2. | ||
*/ | ||
|
||
#include "strlist.h" | ||
#include <errno.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
static struct str_node *str_node__new(const char *s, bool dupstr) | ||
{ | ||
struct str_node *self = malloc(sizeof(*self)); | ||
|
||
if (self != NULL) { | ||
if (dupstr) { | ||
s = strdup(s); | ||
if (s == NULL) | ||
goto out_delete; | ||
} | ||
self->s = s; | ||
} | ||
|
||
return self; | ||
|
||
out_delete: | ||
free(self); | ||
return NULL; | ||
} | ||
|
||
static void str_node__delete(struct str_node *self, bool dupstr) | ||
{ | ||
if (dupstr) | ||
free((void *)self->s); | ||
free(self); | ||
} | ||
|
||
int strlist__add(struct strlist *self, const char *new_entry) | ||
{ | ||
struct rb_node **p = &self->entries.rb_node; | ||
struct rb_node *parent = NULL; | ||
struct str_node *sn; | ||
|
||
while (*p != NULL) { | ||
int rc; | ||
|
||
parent = *p; | ||
sn = rb_entry(parent, struct str_node, rb_node); | ||
rc = strcmp(sn->s, new_entry); | ||
|
||
if (rc > 0) | ||
p = &(*p)->rb_left; | ||
else if (rc < 0) | ||
p = &(*p)->rb_right; | ||
else | ||
return -EEXIST; | ||
} | ||
|
||
sn = str_node__new(new_entry, self->dupstr); | ||
if (sn == NULL) | ||
return -ENOMEM; | ||
|
||
rb_link_node(&sn->rb_node, parent, p); | ||
rb_insert_color(&sn->rb_node, &self->entries); | ||
|
||
return 0; | ||
} | ||
|
||
int strlist__load(struct strlist *self, const char *filename) | ||
{ | ||
char entry[1024]; | ||
int err; | ||
FILE *fp = fopen(filename, "r"); | ||
|
||
if (fp == NULL) | ||
return errno; | ||
|
||
while (fgets(entry, sizeof(entry), fp) != NULL) { | ||
const size_t len = strlen(entry); | ||
|
||
if (len == 0) | ||
continue; | ||
entry[len - 1] = '\0'; | ||
|
||
err = strlist__add(self, entry); | ||
if (err != 0) | ||
goto out; | ||
} | ||
|
||
err = 0; | ||
out: | ||
fclose(fp); | ||
return err; | ||
} | ||
|
||
void strlist__remove(struct strlist *self, struct str_node *sn) | ||
{ | ||
rb_erase(&sn->rb_node, &self->entries); | ||
str_node__delete(sn, self->dupstr); | ||
} | ||
|
||
bool strlist__has_entry(struct strlist *self, const char *entry) | ||
{ | ||
struct rb_node **p = &self->entries.rb_node; | ||
struct rb_node *parent = NULL; | ||
|
||
while (*p != NULL) { | ||
struct str_node *sn; | ||
int rc; | ||
|
||
parent = *p; | ||
sn = rb_entry(parent, struct str_node, rb_node); | ||
rc = strcmp(sn->s, entry); | ||
|
||
if (rc > 0) | ||
p = &(*p)->rb_left; | ||
else if (rc < 0) | ||
p = &(*p)->rb_right; | ||
else | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
static int strlist__parse_list_entry(struct strlist *self, const char *s) | ||
{ | ||
if (strncmp(s, "file://", 7) == 0) | ||
return strlist__load(self, s + 7); | ||
|
||
return strlist__add(self, s); | ||
} | ||
|
||
int strlist__parse_list(struct strlist *self, const char *s) | ||
{ | ||
char *sep; | ||
int err; | ||
|
||
while ((sep = strchr(s, ',')) != NULL) { | ||
*sep = '\0'; | ||
err = strlist__parse_list_entry(self, s); | ||
*sep = ','; | ||
if (err != 0) | ||
return err; | ||
s = sep + 1; | ||
} | ||
|
||
return *s ? strlist__parse_list_entry(self, s) : 0; | ||
} | ||
|
||
struct strlist *strlist__new(bool dupstr, const char *slist) | ||
{ | ||
struct strlist *self = malloc(sizeof(*self)); | ||
|
||
if (self != NULL) { | ||
self->entries = RB_ROOT; | ||
self->dupstr = dupstr; | ||
if (slist && strlist__parse_list(self, slist) != 0) | ||
goto out_error; | ||
} | ||
|
||
return self; | ||
out_error: | ||
free(self); | ||
return NULL; | ||
} | ||
|
||
void strlist__delete(struct strlist *self) | ||
{ | ||
if (self != NULL) { | ||
struct str_node *pos; | ||
struct rb_node *next = rb_first(&self->entries); | ||
|
||
while (next) { | ||
pos = rb_entry(next, struct str_node, rb_node); | ||
next = rb_next(&pos->rb_node); | ||
strlist__remove(self, pos); | ||
} | ||
self->entries = RB_ROOT; | ||
free(self); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#ifndef STRLIST_H_ | ||
#define STRLIST_H_ | ||
|
||
#include "rbtree.h" | ||
#include <stdbool.h> | ||
|
||
struct str_node { | ||
struct rb_node rb_node; | ||
const char *s; | ||
}; | ||
|
||
struct strlist { | ||
struct rb_root entries; | ||
bool dupstr; | ||
}; | ||
|
||
struct strlist *strlist__new(bool dupstr, const char *slist); | ||
void strlist__delete(struct strlist *self); | ||
|
||
void strlist__remove(struct strlist *self, struct str_node *sn); | ||
int strlist__load(struct strlist *self, const char *filename); | ||
int strlist__add(struct strlist *self, const char *str); | ||
|
||
bool strlist__has_entry(struct strlist *self, const char *entry); | ||
|
||
static inline bool strlist__empty(const struct strlist *self) | ||
{ | ||
return rb_first(&self->entries) == NULL; | ||
} | ||
|
||
int strlist__parse_list(struct strlist *self, const char *s); | ||
#endif /* STRLIST_H_ */ |