*
*/
/*
- 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++;
}
/*
*/
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)
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;
}
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);
}
}
+ 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);
}