/* * Copyright (c) 2002, 2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: t-queue.c,v 1.6 2005/06/16 20:37:09 ca Exp $") #include "sm/assert.h" #include "sm/magic.h" #include "sm/rpool.h" #include "sm/test.h" #include "sm/queue.h" #include struct entry { int item; TAILQ_ENTRY(entry) entries; } *n1, *n2, *np, *nn; struct queue { sm_rpool_P hd_rpool; TAILQ_HEAD(fh, entry) fh; #if 0 struct fh { struct entry *tqh_first; /* first element */ struct entry **tqh_last; /* addr of last next element */ } fh; #endif /* 0 */ }; #if 0 #define TAILQ_HEAD(name, type) \ struct name { \ struct type *tqh_first; /* first element */ \ struct type **tqh_last; /* addr of last next element */ \ #define TAILQ_ENTRY(type) \ struct { \ struct type *tqe_next; /* next element */ \ struct type **tqe_prev; /* address of previous next element */ \ } #define TAILQ_INIT(head) do { \ (head)->tqh_first = NULL; \ (head)->tqh_last = &(head)->tqh_first; \ } while (0) #define TAILQ_INSERT_TAIL(head, elm, field) do { \ (elm)->field.tqe_next = NULL; \ (elm)->field.tqe_prev = (head)->tqh_last; \ *(head)->tqh_last = (elm); \ (head)->tqh_last = &(elm)->field.tqe_next; \ } while (0) #endif /* 0 */ static void test_lists(sm_rpool_P rp) { int old, count; struct queue head; TAILQ_INIT(&(head.fh)); SM_TEST(TAILQ_EMPTY(&(head.fh))); head.hd_rpool = rp; n1 = malloc(sizeof(*n1)); SM_TEST(n1 != NULL); n1->item = 1; TAILQ_INSERT_HEAD(&(head.fh), n1, entries); SM_TEST(!TAILQ_EMPTY(&(head.fh))); SM_TEST(TAILQ_LAST(&(head.fh), fh) == n1); n1 = malloc(sizeof(*n1)); SM_TEST(n1 != NULL); n1->item = 128; TAILQ_INSERT_TAIL(&(head.fh), n1, entries); SM_TEST(TAILQ_LAST(&(head.fh), fh) == n1); #if 0 (*(((struct fh *)((&(head.fh)->tqh_last))->tqh_last)) #endif /* 0 */ n2 = malloc(sizeof(*n2)); SM_TEST(n2 != NULL); n2->item = 196; TAILQ_INSERT_AFTER(&(head.fh), n1, n2, entries); SM_TEST(TAILQ_LAST(&(head.fh), fh) == n2); n2 = malloc(sizeof(*n2)); SM_TEST(n2 != NULL); n2->item = 64; TAILQ_INSERT_BEFORE(n1, n2, entries); SM_TEST(TAILQ_LAST(&(head.fh), fh) != n2); old = -1; count = 0; TAILQ_FOREACH(np, &(head.fh), entries) { if (SmTestVerbose) { printf("Element\t%d: %4d\n", count, np->item); } SM_TEST(old < np->item); old = np->item; ++count; } SM_TEST(count == 4); for (np = TAILQ_FIRST(&(head.fh)); np != TAILQ_END(&(head.fh)); np = nn) { nn = TAILQ_NEXT(np, entries); free(np); } } int main(int argc, char *argv[]) { sm_rpool_P rp; sm_test_begin(argc, argv, "test lists"); test_lists(NULL); rp = sm_rpool_new(NULL); SM_TEST(rp != NULL); if (rp != NULL) { test_lists(rp); sm_rpool_delete(rp); } return sm_test_end(); }