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
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
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
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
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
00279
00280 if (ele->sh_les.sle_next != -1)
00281 return (LIST_END_NOT_MARKED_FAILURE);
00282
00283
00284 if (SH_LIST_NEXT(ele, sh_les, sh_le) != NULL)
00285 return (LIST_END_NOT_MARKED_FAILURE);
00286
00287
00288
00289
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
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
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
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
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
00558
00559 if (ele->sh_tes.stqe_next != -1)
00560 return (LIST_END_NOT_MARKED_FAILURE);
00561
00562
00563 if (SH_TAILQ_NEXT(ele, sh_tes, sh_te) != NULL)
00564 return (LIST_END_NOT_MARKED_FAILURE);
00565
00566
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
00589
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
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;
00692 char *final;
00693 char *elem;
00694 char *insert;
00695 OP op;
00696 } ops[] = {
00697
00698
00699 { "", "", NULL, NULL, REMOVE_HEAD },
00700 { "", "", NULL, NULL, REMOVE_TAIL },
00701 { "", "A", NULL, "A", INSERT_HEAD },
00702 { "", "A", NULL, "A", INSERT_TAIL },
00703
00704
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
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
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;
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('+');
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('*');
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 }