# HG changeset patch # User Tuomo Valkonen # Date 1109232741 -3600 # Node ID 308dfa54da3edb3fb61b651f92309bc1ab2f8692 # Parent 95553f8ea54062ada372c015f48b35bd50478caf Symlist improvements. diff -r 95553f8ea540 -r 308dfa54da3e dlist.h --- a/dlist.h Wed Feb 23 19:05:01 2005 +0100 +++ b/dlist.h Thu Feb 24 09:12:21 2005 +0100 @@ -37,7 +37,7 @@ (LIST)=(ITEM); -#define LINK_ITEM_LIST LINK_ITEM +#define LINK_ITEM_LAST LINK_ITEM #define LINK_ITEM_BEFORE(LIST, BEFORE, ITEM, NEXT, PREV) \ diff -r 95553f8ea540 -r 308dfa54da3e symlist.c --- a/symlist.c Wed Feb 23 19:05:01 2005 +0100 +++ b/symlist.c Thu Feb 24 09:12:21 2005 +0100 @@ -21,12 +21,12 @@ } -bool symlist_insert(Symlist **symlist, void *symbol) +static Symlist *mknode(void *symbol) { Symlist *node; if(symbol==NULL) - return FALSE; + return NULL; node=ALLOC(Symlist); @@ -35,6 +35,72 @@ node->symbol=symbol; + return node; +} + + +static Symlist *symlist_find_node(Symlist *symlist, void *symbol) +{ + Symlist *node=symlist; + + while(node!=NULL){ + if(node->symbol==symbol) + break; + node=node->next; + } + + return node; +} + + +bool symlist_insert_last(Symlist **symlist, void *symbol) +{ + Symlist *node=mknode(symbol); + + if(node==NULL) + return FALSE; + + LINK_ITEM_LAST(*symlist, node, next, prev); + + return TRUE; +} + + +bool symlist_insert_first(Symlist **symlist, void *symbol) +{ + Symlist *node=mknode(symbol); + + if(node==NULL) + return FALSE; + + LINK_ITEM_FIRST(*symlist, node, next, prev); + + return TRUE; +} + + +bool symlist_reinsert_last(Symlist **symlist, void *symbol) +{ + Symlist *node=symlist_find_node(*symlist, symbol); + + if(node==NULL) + return FALSE; + + UNLINK_ITEM(*symlist, node, next, prev); + LINK_ITEM_LAST(*symlist, node, next, prev); + + return TRUE; +} + + +bool symlist_reinsert_first(Symlist **symlist, void *symbol) +{ + Symlist *node=symlist_find_node(*symlist, symbol); + + if(node==NULL) + return FALSE; + + UNLINK_ITEM(*symlist, node, next, prev); LINK_ITEM_FIRST(*symlist, node, next, prev); return TRUE; @@ -43,15 +109,10 @@ void symlist_remove(Symlist **symlist, void *symbol) { - Symlist *node=*symlist; + Symlist *node=symlist_find_node(*symlist, symbol); - while(node!=NULL){ - if(node->symbol==symbol){ - free_node(symlist, node); - return; - } - node=node->next; - } + if(node!=NULL) + free_node(symlist, node); } @@ -62,34 +123,45 @@ } -/* Warning: not thread-safe */ - - -static Symlist *iter_next=NULL; +SymlistIterTmp symlist_iter_tmp=NULL; -void *symlist_init_iter(Symlist *symlist) +void symlist_iter_init(SymlistIterTmp *state, Symlist *symlist) { - if(symlist==NULL){ - iter_next=NULL; - return NULL; - } - - iter_next=symlist->next; - return symlist->symbol; + *state=symlist; } -void *symlist_iter() +void *symlist_iter(SymlistIterTmp *state) { - Symlist *ret; + void *symbol=NULL; - if(iter_next==NULL) - return NULL; + if(*state!=NULL){ + symbol=(*state)->symbol; + (*state)=(*state)->next; + } - ret=iter_next; - iter_next=iter_next->next; - - return ret->symbol; + return symbol; } + +void symlist_iter_rev_init(SymlistIterTmp *state, Symlist *symlist) +{ + *state=(symlist==NULL ? NULL : symlist->prev); +} + + +void *symlist_iter_rev(SymlistIterTmp *state) +{ + void *symbol=NULL; + + if(*state!=NULL){ + symbol=(*state)->symbol; + *state=(*state)->prev; + if((*state)->next==NULL) + *state=NULL; + } + + return symbol; +} + diff -r 95553f8ea540 -r 308dfa54da3e symlist.h --- a/symlist.h Wed Feb 23 19:05:01 2005 +0100 +++ b/symlist.h Thu Feb 24 09:12:21 2005 +0100 @@ -23,16 +23,39 @@ }; -#define ITERATE_SYMLIST(TYPE, VAR, LIST) \ - for((VAR)=(TYPE)symlist_init_iter(LIST); \ - (VAR)!=NULL; \ - (VAR)=(TYPE)symlist_iter()) +typedef Symlist* SymlistIterTmp; + +#define SYMLIST_FIRST(TYPE, LL) ((LL)==NULL ? NULL : (TYPE)(LL)->symbol) +#define SYMLIST_LAST(TYPE, LL) ((LL)==NULL ? NULL : (TYPE)(LL)->prev->symbol) +#define FOR_ALL_ON_SYMLIST(TYPE, VAR, LL, TMP) \ + for(symlist_iter_init(&(TMP), LL), \ + VAR=(TYPE)symlist_iter(&(TMP)); \ + VAR!=NULL; \ + VAR=(TYPE)symlist_iter(&(TMP))) + +#define FOR_ALL_ON_SYMLIST_REV(TYPE, VAR, LL, TMP) \ + for(symlist_iter_rev_init(&(TMP), LL), \ + VAR=(TYPE)symlist_iter_rev(&(TMP)); \ + VAR!=NULL; \ + VAR=(TYPE)symlist_iter_rev(&(TMP))) -bool symlist_insert(Symlist **symlist, void *symbol); -void symlist_remove(Symlist **symlist, void *symbol); -void symlist_clear(Symlist **symlist); -void *symlist_init_iter(Symlist *symlist); -void *symlist_iter(); +#define FOR_ALL_ON_SYMLIST_UNSAFE(TYPE, VAR, LL) \ + FOR_ALL_ON_SYMLIST(TYPE, VAR, LL, symlist_iter_tmp) + +extern SymlistIterTmp symlist_iter_tmp; + +#define SYMLIST_EMPTY(LIST) ((LIST)==NULL) + +extern bool symlist_insert_last(Symlist **symlist, void *symbol); +extern bool symlist_insert_first(Symlist **symlist, void *symbol); +extern bool symlist_reinsert_last(Symlist **symlist, void *symbol); +extern bool symlist_reinsert_first(Symlist **symlist, void *symbol); +extern void symlist_remove(Symlist **symlist, void *symbol); +extern void symlist_clear(Symlist **symlist); +extern void symlist_iter_init(SymlistIterTmp *state, Symlist *symlist); +extern void *symlist_iter(SymlistIterTmp *state); +extern void symlist_iter_rev_init(SymlistIterTmp *state, Symlist *symlist); +extern void *symlist_iter_rev(SymlistIterTmp *state); #endif /* LIBTU_SYMLIST_H */