Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

q.c

00001 #include <sys/types.h>
00002 #include <sys/time.h>
00003 
00004 #include <assert.h>
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include <unistd.h>
00009 
00010 #include "queue.h"
00011 #include "shqueue.h"
00012 
00013 typedef enum {
00014         FORWARD_WALK_FAILED = 1,
00015         FOREACH_WALK_FAILED,
00016         LIST_END_NOT_MARKED_FAILURE,
00017         PREV_WALK_FAILED,
00018         REVERSE_FOREACH_WALK_FAILED,
00019         EXPECTED_HEAD_FAILED
00020 } FAILURE_REASON;
00021 
00022 const char *failure_reason_names[] = {
00023         "",
00024         "walking the list using the _NEXT forward failed",
00025         "walking the list using the _FOREACH macro failed",
00026         "what was expected to be the last element wasn't marked as such",
00027         "walking the list using the _PREV macro failed",
00028         "walking the list using the _REVERSE_FOREACH macro failed",
00029         "expected to be at the head of the list"
00030 };
00031 
00032 SH_LIST_HEAD(sh_lq);
00033 struct sh_le {
00034         char content;
00035         SH_LIST_ENTRY sh_les;
00036 };
00037 
00038 /* create a string from the content of a list queue */
00039 char *
00040 sh_l_as_string(l)
00041         struct sh_lq *l;
00042 {
00043         static char buf[1024];
00044         struct sh_le *ele = SH_LIST_FIRST(l, sh_le);
00045         int i = 1;
00046 
00047         buf[0] = '"';
00048         while (ele != NULL) {
00049                 buf[i] = ele->content;
00050                 ele = SH_LIST_NEXT(ele, sh_les, sh_le);
00051                 if (ele != NULL)
00052                         buf[++i] = ' ';
00053                 i++;
00054         }
00055         buf[i++] = '"';
00056         buf[i] = '\0';
00057         return buf;
00058 }
00059 
00060 /* init a list queue */
00061 struct sh_lq *
00062 sh_l_init(items)
00063         const char *items;
00064 {
00065         const char *c = items;
00066         struct sh_le *ele = NULL, *last_ele = (struct sh_le*)-1;
00067         struct sh_lq *l = calloc(1, sizeof(struct sh_lq));
00068 
00069         SH_LIST_INIT(l);
00070 
00071         while (*c != '\0') {
00072                 if (c[0] != ' ') {
00073                         last_ele = ele;
00074                         ele = calloc(1, sizeof(struct sh_le));
00075                         ele->content = c[0];
00076                         if (SH_LIST_EMPTY(l))
00077                                 SH_LIST_INSERT_HEAD(l, ele, sh_les, sh_le);
00078                         else
00079                                 SH_LIST_INSERT_AFTER(
00080                                     last_ele, ele, sh_les, sh_le);
00081                 }
00082                 c++;
00083         }
00084         return (l);
00085 }
00086 
00087 struct sh_lq *
00088 sh_l_remove_head(l)
00089         struct sh_lq *l;
00090 {
00091         struct sh_le *ele = SH_LIST_FIRST(l, sh_le);
00092 
00093         SH_LIST_REMOVE_HEAD(l, sh_les, sh_le);
00094         if (ele != NULL)
00095                 free(ele);
00096 
00097         return (l);
00098 }
00099 
00100 struct sh_lq *
00101 sh_l_remove_tail(l)
00102         struct sh_lq *l;
00103 {
00104         struct sh_le *ele = SH_LIST_FIRST(l, sh_le);
00105 
00106         if (SH_LIST_EMPTY(l))
00107                 return (l);
00108 
00109         while (SH_LIST_NEXT(ele, sh_les, sh_le) != NULL)
00110                 ele = SH_LIST_NEXT(ele, sh_les, sh_le);
00111 
00112         if (ele) {
00113                 SH_LIST_REMOVE(ele, sh_les, sh_le);
00114                 free(ele);
00115         }
00116         return (l);
00117 }
00118 
00119 struct sh_lq *
00120 sh_l_remove_item(l, item)
00121         struct sh_lq *l;
00122         const char *item;
00123 {
00124         struct sh_le *ele = SH_LIST_FIRST(l, sh_le);
00125 
00126         while (ele != NULL) {
00127                 if (ele->content == item[0])
00128                         break;
00129                 ele = SH_LIST_NEXT(ele, sh_les, sh_le);
00130         }
00131         if (ele)
00132                 SH_LIST_REMOVE(ele, sh_les, sh_le);
00133         return (l);
00134 }
00135 
00136 struct sh_lq *
00137 sh_l_insert_head(l, item)
00138         struct sh_lq *l;
00139         const char *item;
00140 {
00141         struct sh_le *ele = calloc(1, sizeof(struct sh_le));
00142 
00143         ele->content = item[0];
00144         SH_LIST_INSERT_HEAD(l, ele, sh_les, sh_le);
00145 
00146         return (l);
00147 }
00148 
00149 struct sh_lq *
00150 sh_l_insert_tail(l, item)
00151         struct sh_lq *l;
00152         const char *item;
00153 {
00154         struct sh_le *ele = NULL;
00155         struct sh_le *last_ele = SH_LIST_FIRST(l, sh_le);
00156 
00157         if (last_ele != NULL)
00158                 while (SH_LIST_NEXT(last_ele, sh_les, sh_le) != NULL)
00159                         last_ele = SH_LIST_NEXT(last_ele, sh_les, sh_le);
00160 
00161         if (last_ele == NULL) {
00162                 ele = calloc(1, sizeof(struct sh_le));
00163                 ele->content = item[0];
00164                 SH_LIST_INSERT_HEAD(l, ele, sh_les, sh_le);
00165         } else {
00166                 ele = calloc(1, sizeof(struct sh_le));
00167                 ele->content = item[0];
00168                 SH_LIST_INSERT_AFTER(last_ele, ele, sh_les, sh_le);
00169         }
00170 
00171         return (l);
00172 }
00173 
00174 struct sh_lq *
00175 sh_l_insert_before(l, item, before_item)
00176         struct sh_lq *l;
00177         const char *item;
00178         const char *before_item;
00179 {
00180         struct sh_le *ele = NULL;
00181         struct sh_le *before_ele = SH_LIST_FIRST(l, sh_le);
00182 
00183         while (before_ele != NULL) {
00184                 if (before_ele->content == before_item[0])
00185                         break;
00186                 before_ele = SH_LIST_NEXT(before_ele, sh_les, sh_le);
00187         }
00188         if (before_ele != NULL) {
00189                 ele = calloc(1, sizeof(struct sh_le));
00190                 ele->content = item[0];
00191                 SH_LIST_INSERT_BEFORE(l, before_ele, ele, sh_les, sh_le);
00192         }
00193         return (l);
00194 }
00195 
00196 struct sh_lq *
00197 sh_l_insert_after(l, item, after_item)
00198         struct sh_lq *l;
00199         const char *item;
00200         const char *after_item;
00201 {
00202         struct sh_le *ele = NULL;
00203         struct sh_le *after_ele = SH_LIST_FIRST(l, sh_le);
00204 
00205         while (after_ele != NULL) {
00206                 if (after_ele->content == after_item[0])
00207                         break;
00208                 after_ele = SH_LIST_NEXT(after_ele, sh_les, sh_le);
00209         }
00210         if (after_ele != NULL) {
00211                 ele = calloc(1, sizeof(struct sh_le));
00212                 ele->content = item[0];
00213                 SH_LIST_INSERT_AFTER(after_ele, ele, sh_les, sh_le);
00214         }
00215         return (l);
00216 }
00217 
00218 void
00219 sh_l_discard(l)
00220         struct sh_lq *l;
00221 {
00222         struct sh_le *ele = NULL;
00223 
00224         while ((ele = SH_LIST_FIRST(l, sh_le)) != NULL) {
00225                 SH_LIST_REMOVE(ele, sh_les, sh_le);
00226                 free(ele);
00227         }
00228 
00229         free(l);
00230 }
00231 
00232 int
00233 sh_l_verify(l, items)
00234         struct sh_lq *l;
00235         const char *items;
00236 {
00237         const char *c = items;
00238         struct sh_le *ele = NULL, *lele = NULL;
00239         int i = 0, nele = 0;
00240 
00241         while (*c != '\0') {
00242                 if (c[0] != ' ')
00243                         nele++;
00244                 c++;
00245         }
00246 
00247         /* use the FOREACH macro to walk the list */
00248         c = items;
00249         i = 0;
00250         SH_LIST_FOREACH(ele, l, sh_les, sh_le) {
00251                 if (ele->content != c[0])
00252                         return (FOREACH_WALK_FAILED);
00253                 i++;
00254                 c +=2;
00255         }
00256         if (i != nele)
00257                 return (FOREACH_WALK_FAILED);
00258         i = 0;
00259         if (items[0] != '\0') {
00260                 /* walk the list forward */
00261                 c = items;
00262                 ele = SH_LIST_FIRST(l, sh_le);
00263                 while (*c != '\0') {
00264                         lele = ele;
00265                         if (c[0] != ' ') {
00266                                 if (ele->content != c[0])
00267                                           return (FORWARD_WALK_FAILED);
00268                                 i++;
00269                                 ele = SH_LIST_NEXT(ele, sh_les, sh_le);
00270                         }
00271                         c++;
00272                 }
00273                 ele = lele;
00274 
00275                 if (i != nele)
00276                         return (FOREACH_WALK_FAILED);
00277 
00278                 /* ele should be the last element in the list... */
00279                 /* ... so sle_next should be -1 */
00280                 if (ele->sh_les.sle_next != -1)
00281                         return (LIST_END_NOT_MARKED_FAILURE);
00282 
00283                 /* and NEXT needs to be NULL */
00284                 if (SH_LIST_NEXT(ele, sh_les, sh_le) != NULL)
00285                         return (LIST_END_NOT_MARKED_FAILURE);
00286 
00287                 /*
00288                  * walk the list backwards using PREV macro, first move c
00289                  * back a bit
00290                  */
00291                 c--;
00292                 i = 0;
00293                 while (c >= items) {
00294                         if (c[0] != ' ') {
00295                                 lele = ele;
00296                                 if (ele->content != c[0])
00297                                         return (PREV_WALK_FAILED);
00298                                 ele = SH_LIST_PREV(ele, sh_les, sh_le);
00299                                 i++;
00300                         }
00301                         c--;
00302                 }
00303                 ele = lele;
00304 
00305                 if (i != nele)
00306                         return (PREV_WALK_FAILED);
00307 
00308                 if (ele != SH_LIST_FIRST(l, sh_le))
00309                         return (EXPECTED_HEAD_FAILED);
00310         }
00311         return (0);
00312 }
00313 
00314 SH_TAILQ_HEAD(sh_tq);
00315 struct sh_te {
00316         char content;
00317         SH_TAILQ_ENTRY sh_tes;
00318 };
00319 
00320 /* create a string from the content of a list queue */
00321 char *
00322 sh_t_as_string(l)
00323         struct sh_tq *l;
00324 {
00325         static char buf[1024];
00326         struct sh_te *ele = SH_TAILQ_FIRST(l, sh_te);
00327         int i = 1;
00328 
00329         buf[0] = '"';
00330         while (ele != NULL) {
00331                 buf[i] = ele->content;
00332                 ele = SH_TAILQ_NEXT(ele, sh_tes, sh_te);
00333                 if (ele != NULL)
00334                         buf[++i] = ' ';
00335                 i++;
00336         }
00337         buf[i++] = '"';
00338         buf[i] = '\0';
00339         return (buf);
00340 }
00341 
00342 /* init a tail queue */
00343 struct sh_tq *
00344 sh_t_init(items)
00345         const char *items;
00346 {
00347         const char *c = items;
00348         struct sh_te *ele = NULL, *last_ele = (struct sh_te*)-1;
00349         struct sh_tq *l = calloc(1, sizeof(struct sh_tq));
00350 
00351         SH_TAILQ_INIT(l);
00352 
00353         while (*c != '\0') {
00354                 if (c[0] != ' ') {
00355                         ele = calloc(1, sizeof(struct sh_te));
00356                         ele->content = c[0];
00357 
00358                         if (SH_TAILQ_EMPTY(l))
00359                                 SH_TAILQ_INSERT_HEAD(l, ele, sh_tes, sh_te);
00360                         else
00361                                 SH_TAILQ_INSERT_AFTER(
00362                                     l, last_ele, ele, sh_tes, sh_te);
00363                         last_ele = ele;
00364                 }
00365                 c++;
00366         }
00367         return (l);
00368 }
00369 
00370 struct sh_tq *
00371 sh_t_remove_head(l)
00372         struct sh_tq *l;
00373 {
00374         struct sh_te *ele = SH_TAILQ_FIRST(l, sh_te);
00375 
00376         if (ele != NULL)
00377                 SH_TAILQ_REMOVE(l, ele, sh_tes, sh_te);
00378 
00379         free(ele);
00380 
00381         return (l);
00382 }
00383 
00384 struct sh_tq *
00385 sh_t_remove_tail(l)
00386         struct sh_tq *l;
00387 {
00388         struct sh_te *ele = SH_TAILQ_FIRST(l, sh_te);
00389 
00390         if (SH_TAILQ_EMPTY(l))
00391                 return(l);
00392 
00393         while (SH_TAILQ_NEXT(ele, sh_tes, sh_te) != NULL)
00394                 ele = SH_TAILQ_NEXT(ele, sh_tes, sh_te);
00395 
00396         if (ele != NULL) {
00397                 SH_TAILQ_REMOVE(l, ele, sh_tes, sh_te);
00398                 free(ele);
00399         }
00400 
00401         return (l);
00402 }
00403 
00404 struct sh_tq *
00405 sh_t_remove_item(l, item)
00406         struct sh_tq *l;
00407         const char *item;
00408 {
00409         struct sh_te *ele = SH_TAILQ_FIRST(l, sh_te);
00410 
00411         while (ele != NULL) {
00412                 if (ele->content == item[0])
00413                         break;
00414                 ele = SH_TAILQ_NEXT(ele, sh_tes, sh_te);
00415         }
00416         if (ele != NULL)
00417                 SH_TAILQ_REMOVE(l, ele, sh_tes, sh_te);
00418 
00419         return (l);
00420 }
00421 
00422 struct sh_tq *
00423 sh_t_insert_head(l, item)
00424         struct sh_tq *l;
00425         const char *item;
00426 {
00427         struct sh_te *ele = calloc(1, sizeof(struct sh_te));
00428 
00429         ele->content = item[0];
00430         SH_TAILQ_INSERT_HEAD(l, ele, sh_tes, sh_te);
00431 
00432         return (l);
00433 }
00434 
00435 struct sh_tq *
00436 sh_t_insert_tail(l, item)
00437         struct sh_tq *l;
00438         const char *item;
00439 {
00440         struct sh_te *ele = 0;
00441         ele = calloc(1, sizeof(struct sh_te));
00442         ele->content = item[0];
00443         SH_TAILQ_INSERT_TAIL(l, ele, sh_tes);
00444         return l;
00445 }
00446 
00447 struct sh_tq *
00448 sh_t_insert_before(l, item, before_item)
00449         struct sh_tq *l;
00450         const char *item;
00451         const char *before_item;
00452 {
00453         struct sh_te *ele = NULL;
00454         struct sh_te *before_ele = SH_TAILQ_FIRST(l, sh_te);
00455 
00456         while (before_ele != NULL) {
00457                 if (before_ele->content == before_item[0])
00458                         break;
00459                 before_ele = SH_TAILQ_NEXT(before_ele, sh_tes, sh_te);
00460         }
00461 
00462         if (before_ele != NULL) {
00463                 ele = calloc(1, sizeof(struct sh_te));
00464                 ele->content = item[0];
00465                 SH_TAILQ_INSERT_BEFORE(l, before_ele, ele, sh_tes, sh_te);
00466         }
00467 
00468         return (l);
00469 }
00470 
00471 struct sh_tq *
00472 sh_t_insert_after(l, item, after_item)
00473         struct sh_tq *l;
00474         const char *item;
00475         const char *after_item;
00476 {
00477         struct sh_te *ele = NULL;
00478         struct sh_te *after_ele = SH_TAILQ_FIRST(l, sh_te);
00479 
00480         while (after_ele != NULL) {
00481                 if (after_ele->content == after_item[0])
00482                         break;
00483                 after_ele = SH_TAILQ_NEXT(after_ele, sh_tes, sh_te);
00484         }
00485 
00486         if (after_ele != NULL) {
00487                 ele = calloc(1, sizeof(struct sh_te));
00488                 ele->content = item[0];
00489                 SH_TAILQ_INSERT_AFTER(l, after_ele, ele, sh_tes, sh_te);
00490         }
00491 
00492         return (l);
00493 }
00494 
00495 void
00496 sh_t_discard(l)
00497         struct sh_tq *l;
00498 {
00499         struct sh_te *ele = NULL;
00500 
00501         while ((ele = SH_TAILQ_FIRST(l, sh_te)) != NULL) {
00502                 SH_TAILQ_REMOVE(l, ele, sh_tes, sh_te);
00503                 free(ele);
00504         }
00505         free(l);
00506 }
00507 
00508 int
00509 sh_t_verify(l, items)
00510         struct sh_tq *l;
00511         const char *items;
00512 {
00513         const char *c = items, *b = NULL;
00514         struct sh_te *ele = NULL, *lele = NULL;
00515         int i = 0, nele = 0;
00516 
00517         while (*c != '\0') {
00518                 if (c[0] != ' ')
00519                         nele++;
00520                 c++;
00521         }
00522 
00523         /* use the FOREACH macro to walk the list */
00524         c = items;
00525         i = 0;
00526         SH_TAILQ_FOREACH(ele, l, sh_tes, sh_te) {
00527                 if (ele->content != c[0])
00528                         return (FOREACH_WALK_FAILED);
00529                 i++;
00530                 c +=2;
00531         }
00532         if (i != nele)
00533                 return (FOREACH_WALK_FAILED);
00534         i = 0;
00535         if (items[0] != '\0') {
00536                 /* walk the list forward */
00537                 c = items;
00538                 ele = SH_TAILQ_FIRST(l, sh_te);
00539                 while (*c != '\0') {
00540                         lele = ele;
00541                         if (c[0] != ' ') {
00542                                 if (ele->content != c[0])
00543                                         return (FORWARD_WALK_FAILED);
00544                                 i++;
00545                                 ele = SH_TAILQ_NEXT(ele, sh_tes, sh_te);
00546                         }
00547                         c++;
00548                 }
00549 
00550                 if (i != nele)
00551                         return (FOREACH_WALK_FAILED);
00552 
00553                 if (lele != SH_TAILQ_LAST(l, sh_tes, sh_te))
00554                         return (LIST_END_NOT_MARKED_FAILURE);
00555                 ele = lele;
00556 
00557                 /* ele should be the last element in the list... */
00558                 /* ... so sle_next should be -1 */
00559                 if (ele->sh_tes.stqe_next != -1)
00560                         return (LIST_END_NOT_MARKED_FAILURE);
00561 
00562                 /* and NEXT needs to be NULL */
00563                 if (SH_TAILQ_NEXT(ele, sh_tes, sh_te) != NULL)
00564                         return (LIST_END_NOT_MARKED_FAILURE);
00565 
00566                 /* walk the list backwards using SH_LIST_PREV macro */
00567                 c--;
00568                 b = c;
00569                 i = 0;
00570                 while (c >= items) {
00571                         if (c[0] != ' ') {
00572                                 lele = ele;
00573                                 if (ele->content != c[0])
00574                                         return (PREV_WALK_FAILED);
00575                                 ele = SH_TAILQ_PREV(l, ele, sh_tes, sh_te);
00576                                 i++;
00577                         }
00578                         c--;
00579                 }
00580                 ele = lele;
00581 
00582                 if (i != nele)
00583                         return (PREV_WALK_FAILED);
00584 
00585                 if (ele != SH_TAILQ_FIRST(l, sh_te))
00586                         return (-1);
00587 
00588                 /* c should be the last character in the array, walk backwards
00589                 from here using FOREACH_REVERSE and check the values again */
00590                 c = b;
00591                 i = 0;
00592                 ele = SH_TAILQ_LAST(l, sh_tes, sh_te);
00593                 SH_TAILQ_FOREACH_REVERSE(ele, l, sh_tes, sh_te) {
00594                         if (ele->content != c[0])
00595                                 return (REVERSE_FOREACH_WALK_FAILED);
00596                         i++;
00597                         c -=2;
00598                 }
00599                 if (i != nele)
00600                         return (REVERSE_FOREACH_WALK_FAILED);
00601         }
00602         return (0);
00603 }
00604 
00605 int
00606 sh_t_verify_TAILQ_LAST(l, items)
00607         struct sh_tq *l;
00608         const char *items;
00609 {
00610         const char *c = items;
00611         struct sh_te *ele = NULL;
00612 
00613         c = items;
00614         while (*c != '\0') {
00615                 c++;
00616         }
00617         if (c == items) {
00618           /* items is empty, so last should be NULL */
00619           if (SH_TAILQ_LAST(l, sh_tes, sh_te) != NULL)
00620                 return (-1);
00621         } else {
00622                 c--;
00623                 ele = SH_TAILQ_LAST(l, sh_tes, sh_te);
00624                 if (ele->content != c[0])
00625                         return (-1);
00626         }
00627         return (0);
00628 }
00629 
00630 typedef void *qds_t;
00631 struct {
00632         const char *name;
00633         qds_t *(*f_init)(const char *);
00634         qds_t *(*f_remove_head)(qds_t *);
00635         qds_t *(*f_remove_tail)(qds_t *);
00636         qds_t *(*f_remove_item)(qds_t *, const char *);
00637         qds_t *(*f_insert_head)(qds_t *, const char *);
00638         qds_t *(*f_insert_tail)(qds_t *, const char *);
00639         qds_t *(*f_insert_before)(qds_t *, const char *, const char *);
00640         qds_t *(*f_insert_after)(qds_t *, const char *, const char *);
00641         qds_t *(*f_discard)(qds_t *);
00642         char *(*f_as_string)(qds_t *);
00643         int (*f_verify)(qds_t *, const char *);
00644 } qfns[]= {
00645 {       "sh_list",
00646         (qds_t*(*)(const char *))sh_l_init,
00647         (qds_t*(*)(qds_t *))sh_l_remove_head,
00648         (qds_t*(*)(qds_t *))sh_l_remove_tail,
00649         (qds_t*(*)(qds_t *, const char *))sh_l_remove_item,
00650         (qds_t*(*)(qds_t *, const char *))sh_l_insert_head,
00651         (qds_t*(*)(qds_t *, const char *))sh_l_insert_tail,
00652         (qds_t*(*)(qds_t *, const char *, const char *))sh_l_insert_before,
00653         (qds_t*(*)(qds_t *, const char *, const char *))sh_l_insert_after,
00654         (qds_t*(*)(qds_t *))sh_l_discard,
00655         (char *(*)(qds_t *))sh_l_as_string,
00656         (int(*)(qds_t *, const char *))sh_l_verify },
00657 {       "sh_tailq",
00658         (qds_t*(*)(const char *))sh_t_init,
00659         (qds_t*(*)(qds_t *))sh_t_remove_head,
00660         (qds_t*(*)(qds_t *))sh_t_remove_tail,
00661         (qds_t*(*)(qds_t *, const char *))sh_t_remove_item,
00662         (qds_t*(*)(qds_t *, const char *))sh_t_insert_head,
00663         (qds_t*(*)(qds_t *, const char *))sh_t_insert_tail,
00664         (qds_t*(*)(qds_t *, const char *, const char *))sh_t_insert_before,
00665         (qds_t*(*)(qds_t *, const char *, const char *))sh_t_insert_after,
00666         (qds_t*(*)(qds_t *))sh_t_discard,
00667         (char *(*)(qds_t *))sh_t_as_string,
00668         (int(*)(qds_t *, const char *))sh_t_verify }
00669 };
00670 
00671 typedef enum {
00672         INSERT_BEFORE,
00673         INSERT_AFTER,
00674         INSERT_HEAD,
00675         INSERT_TAIL,
00676         REMOVE_HEAD,
00677         REMOVE_ITEM,
00678         REMOVE_TAIL,
00679 } OP;
00680 
00681 const char *op_names[] = {
00682         "INSERT_BEFORE",
00683         "INSERT_AFTER",
00684         "INSERT_HEAD",
00685         "INSERT_TAIL",
00686         "REMOVE_HEAD",
00687         "REMOVE_ITEM",
00688         "REMOVE_TAIL" };
00689 
00690 struct {
00691         char *init;             /* initial state. */
00692         char *final;            /* final state. */
00693         char *elem;             /* element to operate on */
00694         char *insert;           /* element to insert */
00695         OP      op;             /* operation. */
00696 } ops[] = {
00697 
00698         /* most operations on a empty list */
00699         { "", "", NULL, NULL, REMOVE_HEAD },
00700         { "", "", NULL, NULL, REMOVE_TAIL },
00701         { "", "A", NULL, "A", INSERT_HEAD },
00702         { "", "A", NULL, "A", INSERT_TAIL },
00703 
00704         /* all operations on a one element list */
00705         { "A", "", NULL, NULL, REMOVE_HEAD },
00706         { "A", "", NULL, NULL, REMOVE_TAIL },
00707         { "A", "", "A", NULL, REMOVE_ITEM },
00708         { "B", "A B", NULL, "A", INSERT_HEAD },
00709         { "A", "A B", NULL, "B", INSERT_TAIL },
00710         { "B", "A B", "B", "A", INSERT_BEFORE },
00711         { "A", "A B", "A", "B", INSERT_AFTER },
00712 
00713         /* all operations on a two element list */
00714         { "A B", "B", NULL, NULL, REMOVE_HEAD },
00715         { "A B", "A", NULL, NULL, REMOVE_TAIL },
00716         { "A B", "A", "B", NULL, REMOVE_ITEM },
00717         { "A B", "B", "A", NULL, REMOVE_ITEM },
00718         { "B C", "A B C", NULL, "A", INSERT_HEAD },
00719         { "A B", "A B C", NULL, "C", INSERT_TAIL },
00720         { "B C", "A B C", "B", "A", INSERT_BEFORE },
00721         { "A C", "A B C", "C", "B", INSERT_BEFORE },
00722         { "A C", "A B C", "A", "B", INSERT_AFTER },
00723         { "A C", "A C B", "C", "B", INSERT_AFTER },
00724 
00725         /* all operations on a three element list */
00726 
00727         { "A B C", "B C", NULL, NULL, REMOVE_HEAD },
00728         { "A B C", "A B", NULL, NULL, REMOVE_TAIL },
00729         { "A B C", "A B", "C", NULL, REMOVE_ITEM },
00730         { "A B C", "A C", "B", NULL, REMOVE_ITEM },
00731         { "A B C", "B C", "A", NULL, REMOVE_ITEM },
00732         { "B C D", "A B C D", NULL, "A", INSERT_HEAD },
00733         { "A B C", "A B C D", NULL, "D", INSERT_TAIL },
00734         { "A B C", "X A B C", "A", "X", INSERT_BEFORE },
00735         { "A B C", "A X B C", "B", "X", INSERT_BEFORE },
00736         { "A B C", "A B X C", "C", "X", INSERT_BEFORE },
00737         { "A B C", "A X B C", "A", "X", INSERT_AFTER },
00738         { "A B C", "A B X C", "B", "X", INSERT_AFTER },
00739         { "A B C", "A B C X", "C", "X", INSERT_AFTER },
00740 };
00741 
00742 int
00743 main(argc, argv)
00744         int argc;
00745         char *argv[];
00746 {
00747         void *list;
00748         int fc, tc;             /* tc is total count, fc is failed count */
00749         int eval, i, t, result;
00750 
00751         eval = 0;
00752         for (t = 0; t < sizeof(qfns) / sizeof(qfns[0]); ++t) {
00753                 fc = tc = 0;
00754                 printf("TESTING: %s\n", qfns[t].name);
00755 
00756                 for (i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
00757                         list = qfns[t].f_init(ops[i].init);
00758                         result = qfns[t].f_verify(list, ops[i].init);
00759                         if (result == 0) {
00760                                 fc++;
00761                                 putchar('.');
00762                         } else {
00763                                 putchar('+'); /* + means failed before op */
00764                                 printf("\nVerify failed: %s\n",
00765                                     failure_reason_names[result]);
00766                                 eval = 1;
00767                         }
00768                         if (!strcmp("sh_tailq", qfns[t].name)) {
00769                                 result =
00770                                     sh_t_verify_TAILQ_LAST(list, ops[i].init);
00771                         }
00772 #ifdef VERBOSE
00773                         printf("\ncase %d %s in %s init: \"%s\" desired: \"%s\" elem: \"%s\" insert: \"%s\"\n",
00774                             i, op_names[ops[i].op], qfns[t].name,
00775                             ops[i].init, ops[i].final,
00776                             ops[i].elem, ops[i].insert);
00777                         fflush(stdout);
00778 #endif
00779                         tc++;
00780                         switch (ops[i].op) {
00781                         case REMOVE_HEAD:
00782                                 qfns[t].f_remove_head(list);
00783                                 break;
00784                         case REMOVE_TAIL:
00785                                 qfns[t].f_remove_tail(list);
00786                                 break;
00787                         case REMOVE_ITEM:
00788                                 qfns[t].f_remove_item(list, ops[i].elem);
00789                                 break;
00790                         case INSERT_HEAD:
00791                                 qfns[t].f_insert_head(list, ops[i].insert);
00792                                 break;
00793                         case INSERT_TAIL:
00794                                 qfns[t].f_insert_tail(list, ops[i].insert);
00795                                 break;
00796                         case INSERT_BEFORE:
00797                                 qfns[t].f_insert_before(
00798                                     list, ops[i].insert, ops[i].elem);
00799                                 break;
00800                         case INSERT_AFTER:
00801                                 qfns[t].f_insert_after(
00802                                     list, ops[i].insert, ops[i].elem);
00803                                 break;
00804                         }
00805                         if (!strcmp("sh_tailq", op_names[ops[i].op])) {
00806                                 result = sh_t_verify_TAILQ_LAST(list,
00807                                     ops[i].final);
00808                         }
00809                         if (result == 0)
00810                                 result = qfns[t].f_verify(list, ops[i].final);
00811                         if (result == 0) {
00812                                 fc++;
00813                                 putchar('.');
00814                         } else {
00815                                 putchar('*'); /* * means failed after op */
00816                                 printf("\ncase %d %s in %s init: \"%s\" desired: \"%s\" elem: \"%s\" insert: \"%s\" got: %s - %s\n",
00817                                     i, op_names[ops[i].op], qfns[t].name,
00818                                     ops[i].init, ops[i].final,
00819                                     ops[i].elem, ops[i].insert,
00820                                     qfns[t].f_as_string(list),
00821                                     failure_reason_names[result]);
00822                                 fflush(stdout);
00823                                 eval = 1;
00824                         }
00825 
00826                         tc++;
00827                         qfns[t].f_discard(list);
00828                 }
00829 
00830                 printf("\t%0.2f%% passed (%d/%d).\n",
00831                     (((double)fc/tc) * 100), fc, tc);
00832         }
00833         return (eval);
00834 }

Generated on Sun Dec 25 12:14:52 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2