Symlist improvements.

Thu, 24 Feb 2005 09:12:21 +0100

author
Tuomo Valkonen <tuomov@iki.fi>
date
Thu, 24 Feb 2005 09:12:21 +0100
changeset 88
308dfa54da3e
parent 87
95553f8ea540
child 89
17a16ed84bbf

Symlist improvements.

dlist.h file | annotate | diff | comparison | revisions
symlist.c file | annotate | diff | comparison | revisions
symlist.h file | annotate | diff | comparison | revisions
--- 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) \
--- 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;
+}
+
--- 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 */

mercurial