diff --git a/src/uthash.h b/src/uthash.h index ba57acee..9e81ab3a 100644 --- a/src/uthash.h +++ b/src/uthash.h @@ -307,12 +307,12 @@ do { } \ _count += _bkt_count; \ if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ - HASH_OOPS("invalid bucket count %d, actual %d\n", \ + HASH_OOPS("invalid bucket count %u, actual %u\n", \ (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ } \ } \ if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("invalid hh item count %d, actual %d\n", \ + HASH_OOPS("invalid hh item count %u, actual %u\n", \ (head)->hh.tbl->num_items, _count ); \ } \ /* traverse hh in app order; check next/prev integrity, count */ \ @@ -330,7 +330,7 @@ do { (head)->hh.tbl->hho) : NULL ); \ } \ if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("invalid app item count %d, actual %d\n", \ + HASH_OOPS("invalid app item count %u, actual %u\n", \ (head)->hh.tbl->num_items, _count ); \ } \ } \ diff --git a/src/utlist.h b/src/utlist.h index b5f3f04c..b0754578 100644 --- a/src/utlist.h +++ b/src/utlist.h @@ -551,6 +551,26 @@ do { } \ } while (0) +#define DL_POP_LAST(head,out) \ + DL_POP_LAST2(head,out,prev,next) + +#define DL_POP_LAST2(head,out,prev,next) \ +do { \ + if (head) { \ + (out) = (head)->prev; \ + if ((out) == (head)) { \ + (head) = NULL; \ + } else { \ + (head)->prev = (out)->prev; \ + (head)->prev->next = NULL; \ + } \ + (out)->prev = NULL; \ + (out)->next = NULL; \ + } else { \ + (out) = NULL; \ + } \ +} while (0) + #define DL_DELETE(head,del) \ DL_DELETE2(head,del,prev,next) @@ -662,6 +682,62 @@ do { (head)=(add); \ } while (0) +#define CDL_APPEND(head,add) \ + CDL_APPEND2(head,add,prev,next) + +#define CDL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev->next = (add); \ + (head)->prev = (add); \ + (add)->next = head; \ + } else { \ + (head)=(add); \ + (head)->prev = (head); \ + (head)->next = head; \ + } \ +} while (0) + +#define CDL_CONCAT(head1,head2) \ + CDL_CONCAT2(head1,head2,prev,next) + +#define CDL_CONCAT2(head1,head2,prev,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head2) { \ + if (head1) { \ + _tmp = (head2)->prev; \ + (head2)->prev = (head1)->prev; \ + (head1)->prev->next = (head2); \ + (head1)->prev = _tmp; \ + _tmp->next = (head1); \ + } else { \ + (head1)=(head2); \ + } \ + } \ +} while (0) + +#define CDL_POP_LAST(head,out) \ + CDL_POP_LAST2(head,out,prev,next) + +#define CDL_POP_LAST2(head,out,prev,next) \ +do { \ + if (head) { \ + (out) = (head)->prev; \ + if ((out) == (head)) { \ + (head) = NULL; \ + } else { \ + (head)->prev = (out)->prev; \ + (head)->prev->next = (head); \ + } \ + (out)->prev = (out); \ + (out)->next = (out); \ + } else { \ + (out) = NULL; \ + } \ +} while (0) + #define CDL_DELETE(head,del) \ CDL_DELETE2(head,del,prev,next) diff --git a/tests/Makefile b/tests/Makefile index 977f858c..d5eecae7 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -13,7 +13,7 @@ PROGS = test1 test2 test3 test4 test5 test6 test7 test8 test9 \ test58 test59 test60 test61 test62 test63 test64 test65 \ test66 test67 test68 test69 test70 test71 test72 test73 \ test74 test75 test76 test77 test78 test79 test80 test81 \ - test82 test83 test84 + test82 test83 test84 test85 test86 test87 CFLAGS = -I$(HASHDIR) #CFLAGS += -DHASH_BLOOM=16 #CFLAGS += -O2 diff --git a/tests/README b/tests/README index 3ef4f66c..adac740c 100644 --- a/tests/README +++ b/tests/README @@ -86,6 +86,9 @@ test81: test utarray_insert past end of array test82: test utarray_inserta past end of array test83: test HASH_REPLACE_STR with char[] key test84: test HASH_REPLACE_STR with char* key +test85: CDL_APPEND +test86: CDL_CONCAT +test87: CDL_POP_LAST DL_POP_LAST Other Make targets diff --git a/tests/test85.c b/tests/test85.c new file mode 100644 index 00000000..a188941b --- /dev/null +++ b/tests/test85.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include "utlist.h" + +#define BUFLEN 20 + +typedef struct el { + char bname[BUFLEN]; + struct el *next, *prev; +} el; + +int namecmp(void *_a, void *_b) { + el *a = (el*)_a; + el *b = (el*)_b; + return strcmp(a->bname,b->bname); +} + +el *head = NULL; + +int main(int argc, char *argv[]) { + el *name, *tmp; + + char linebuf[BUFLEN]; + FILE *file; + + if ( (file = fopen( "test11.dat", "r" )) == NULL ) { + perror("can't open: "); + exit(-1); + } + + while (fgets(linebuf,BUFLEN,file) != NULL) { + if ( (name = (el*)malloc(sizeof(el))) == NULL) exit(-1); + strncpy(name->bname,linebuf,BUFLEN); + CDL_APPEND(head, name); + } + printf("-----> INSERTED\n"); + CDL_FOREACH(head,tmp) printf("%s", tmp->bname); + + fclose(file); + + return 0; +} \ No newline at end of file diff --git a/tests/test86.c b/tests/test86.c new file mode 100644 index 00000000..8d4260c9 --- /dev/null +++ b/tests/test86.c @@ -0,0 +1,57 @@ +#include +#include "utlist.h" + +typedef struct el { + int id; + struct el *next, *prev; +} el; + +el *headA = NULL, *headB = NULL; + +int main(int argc, char *argv[]) { + int i; + el els[10], *e; + for(i=0;i<10;i++) els[i].id='a'+i; + + /* test DL macros */ + printf("DL macros\n"); + CDL_APPEND(headA,&els[0]); + CDL_APPEND(headA,&els[1]); + CDL_APPEND(headA,&els[2]); + CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); + + CDL_APPEND(headB,&els[3]); + CDL_APPEND(headB,&els[4]); + CDL_APPEND(headB,&els[5]); + CDL_FOREACH(headB,e) printf("%c ", e->id); printf("\n"); + + CDL_CONCAT(headA,headB); + CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); + + /* other variations */ + headA = NULL; + headB = NULL; + CDL_APPEND(headB,&els[3]); + CDL_APPEND(headB,&els[4]); + CDL_APPEND(headB,&els[5]); + + CDL_CONCAT(headA,headB); + CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); + + headA = NULL; + headB = NULL; + CDL_APPEND(headA,&els[0]); + CDL_APPEND(headA,&els[1]); + CDL_APPEND(headA,&els[2]); + CDL_CONCAT(headA,headB); + CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); + + headA=NULL; + headB=NULL; + CDL_APPEND(headA,&els[0]); + CDL_APPEND(headB,&els[1]); + CDL_CONCAT(headA,headB); + CDL_FOREACH(headA,e) printf("%c ", e->id); printf("\n"); + + return 0; +} \ No newline at end of file diff --git a/tests/test87.c b/tests/test87.c new file mode 100644 index 00000000..6d933a5e --- /dev/null +++ b/tests/test87.c @@ -0,0 +1,57 @@ +#include +#include "utlist.h" + +typedef struct el { + int id; + struct el *next, *prev; +} el; + +el *head = NULL; + +int main(int argc, char *argv[]) { + int i; + int count; + el els[10], *e; + el *out; + + for(i=0;i<10;i++) els[i].id='a'+i; + + /* test CDL macros */ + printf("CDL macros\n"); + CDL_PREPEND(head,&els[0]); + CDL_PREPEND(head,&els[1]); + CDL_PREPEND(head,&els[2]); + CDL_FOREACH(head,e) + printf("%c ", e->id); + printf("\n"); + CDL_POP_LAST(head, out); + CDL_FOREACH(head,e) + printf("%c ", e->id); + printf("\n"); + CDL_FOREACH(out,e) + printf("%c ", e->id); + + printf("\n"); + + // reset + head = NULL; + + /* test DL macros */ + printf("DL macros\n"); + DL_PREPEND(head,&els[0]); + DL_PREPEND(head,&els[1]); + DL_PREPEND(head,&els[2]); + DL_FOREACH(head,e) + printf("%c ", e->id); + printf("\n"); + DL_POP_LAST(head, out); + DL_FOREACH(head,e) + printf("%c ", e->id); + printf("\n"); + DL_FOREACH(out,e) + printf("%c ", e->id); + + printf("\n"); + + return 0; +} \ No newline at end of file