]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/dlist.c
Update configure to set x on logrotate
[bacula/bacula] / bacula / src / lib / dlist.c
index cd905e6d195afd42f47c179976c291b078ea5dd7..9dd304e2f24d8a2e8f76fcc81bb3a0e5dc37d6c9 100644 (file)
@@ -10,7 +10,7 @@
  *
  */
 /*
-   Copyright (C) 2000-2003 Kern Sibbald and John Walker
+   Copyright (C) 2000-2004 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
  */
 void dlist::append(void *item) 
 {
-   ((dlink *)((char *)item+loffset))->next = NULL;
-   ((dlink *)((char *)item+loffset))->prev = tail;
+   ((dlink *)(((char *)item)+loffset))->next = NULL;
+   ((dlink *)(((char *)item)+loffset))->prev = tail;
    if (tail) {
-      ((dlink *)((char *)tail+loffset))->next = item;
+      ((dlink *)(((char *)tail)+loffset))->next = item;
    }
    tail = item;
    if (head == NULL) {               /* if empty list, */
       head = item;                   /* item is head as well */
    }
+   num_items++;
 }
 
 /*
@@ -55,34 +56,77 @@ void dlist::append(void *item)
  */
 void dlist::prepend(void *item) 
 {
-   ((dlink *)((char *)item+loffset))->next = head;
-   ((dlink *)((char *)item+loffset))->prev = NULL;
+   ((dlink *)(((char *)item)+loffset))->next = head;
+   ((dlink *)(((char *)item)+loffset))->prev = NULL;
    if (head) {
-      ((dlink *)((char *)head+loffset))->prev = item;
+      ((dlink *)(((char *)head)+loffset))->prev = item;
    }
    head = item;
    if (tail == NULL) {               /* if empty list, */                    
       tail = item;                   /* item is tail too */
    }
+   num_items++;
 }
 
+void dlist::insert_before(void *item, void *where)      
+{
+   dlink *where_link = (dlink *)((char *)where+loffset);     
+
+   ((dlink *)(((char *)item)+loffset))->next = where;
+   ((dlink *)(((char *)item)+loffset))->prev = where_link->prev;
+
+   if (where_link->prev) {
+      ((dlink *)(((char *)(where_link->prev))+loffset))->next = item;
+   }
+   where_link->prev = item;
+   if (head == where) {
+      head = item;
+   }
+   num_items++;
+}
+
+void dlist::insert_after(void *item, void *where)      
+{
+   dlink *where_link = (dlink *)((char *)where+loffset);     
+
+   ((dlink *)(((char *)item)+loffset))->next = where_link->next;
+   ((dlink *)(((char *)item)+loffset))->prev = where;
+
+   if (where_link->next) {
+      ((dlink *)(((char *)(where_link->next))+loffset))->prev = item;
+   }
+   where_link->next = item;
+   if (tail == where) {
+      tail = item;
+   }
+   num_items++;
+}
+
+
 void dlist::remove(void *item)
 {
    void *xitem;
-   dlink *ilink = (dlink *)((char *)item+loffset);   /* item's link */
+   dlink *ilink = (dlink *)(((char *)item)+loffset);   /* item's link */
    if (item == head) {
       head = ilink->next;
-      ((dlink *)((char *)head+loffset))->prev = NULL;
+      if (head) {
+        ((dlink *)(((char *)head)+loffset))->prev = NULL;
+      }
+      if (item == tail) {
+        tail = ilink->prev;
+      }
    } else if (item == tail) {
       tail = ilink->prev;
-      ((dlink *)((char *)tail+loffset))->next = NULL;
+      if (tail) {
+        ((dlink *)(((char *)tail)+loffset))->next = NULL;
+      }
    } else {
       xitem = ilink->next;
-      ((dlink *)((char *)xitem+loffset))->prev = ilink->prev;
+      ((dlink *)(((char *)xitem)+loffset))->prev = ilink->prev;
       xitem = ilink->prev;
-      ((dlink *)((char *)xitem+loffset))->next = ilink->next;
+      ((dlink *)(((char *)xitem)+loffset))->next = ilink->next;
    }
-   free(item);
+   num_items--;
 }
 
 void * dlist::next(void *item)
@@ -90,17 +134,27 @@ void * dlist::next(void *item)
    if (item == NULL) {
       return head;
    }
-   return ((dlink *)((char *)item+loffset))->next;
+   return ((dlink *)(((char *)item)+loffset))->next;
+}
+
+void * dlist::prev(void *item)
+{
+   if (item == NULL) {
+      return tail;
+   }
+   return ((dlink *)(((char *)item)+loffset))->prev;
 }
 
-/* Destroy the list and its contents */
+
+/* Destroy the list contents */
 void dlist::destroy()
 {
    for (void *n=head; n; ) {
-      void *ni = ((dlink *)((char *)n+loffset))->next;
+      void *ni = ((dlink *)(((char *)n)+loffset))->next;
       free(n);
       n = ni;
    }
+   num_items = 0;
 }
 
 
@@ -109,21 +163,22 @@ void dlist::destroy()
 
 struct MYJCR {
    char *buf;
-   dlist link;
+   dlink link;
 };
 
 int main()
 {
    char buf[30];
    dlist *jcr_chain;
+   MYJCR *jcr = NULL;
    MYJCR *save_jcr = NULL;
+   MYJCR *next_jcr;
 
    jcr_chain = (dlist *)malloc(sizeof(dlist));
-   jcr_chain->init((int)&MYJCR::link);
+   jcr_chain->init(jcr, &jcr->link);
     
    printf("Prepend 20 items 0-19\n");
    for (int i=0; i<20; i++) {
-      MYJCR *jcr;
       sprintf(buf, "This is dlist item %d", i);
       jcr = (MYJCR *)malloc(sizeof(MYJCR));
       jcr->buf = bstrdup(buf);
@@ -133,18 +188,52 @@ int main()
       }
    }
 
+   next_jcr = (MYJCR *)jcr_chain->next(save_jcr);
+   printf("11th item=%s\n", next_jcr->buf);
+   jcr = (MYJCR *)malloc(sizeof(MYJCR));
+   jcr->buf = save_jcr->buf;
    printf("Remove 10th item\n");
-   free(save_jcr->buf);
    jcr_chain->remove(save_jcr);
+   printf("Re-insert 10th item\n");
+   jcr_chain->insert_before(jcr, next_jcr);
    
    printf("Print remaining list.\n");
-   for (MYJCR *jcr=NULL; (jcr=(MYJCR *)jcr_chain->next(jcr)); ) {
+   foreach_dlist (jcr, jcr_chain) {
       printf("Dlist item = %s\n", jcr->buf);
       free(jcr->buf);
    }
    jcr_chain->destroy();
    free(jcr_chain);
 
+   jcr_chain = new dlist(jcr, &jcr->link);
+   printf("append 20 items 0-19\n");
+   for (int i=0; i<20; i++) {
+      sprintf(buf, "This is dlist item %d", i);
+      jcr = (MYJCR *)malloc(sizeof(MYJCR));
+      jcr->buf = bstrdup(buf);
+      jcr_chain->append(jcr);
+      if (i == 10) {
+        save_jcr = jcr;
+      }
+   }
+
+   next_jcr = (MYJCR *)jcr_chain->next(save_jcr);
+   printf("11th item=%s\n", next_jcr->buf);
+   jcr = (MYJCR *)malloc(sizeof(MYJCR));
+   jcr->buf = save_jcr->buf;
+   printf("Remove 10th item\n");
+   jcr_chain->remove(save_jcr);
+   printf("Re-insert 10th item\n");
+   jcr_chain->insert_before(jcr, next_jcr);
+   
+   printf("Print remaining list.\n");
+   foreach_dlist (jcr, jcr_chain) {
+      printf("Dlist item = %s\n", jcr->buf);
+      free(jcr->buf);
+   }
+
+   delete jcr_chain;
+
    sm_dump(False);
 
 }