From f3d07ad12f8ef0979404b1dfbfa3ed43b624b753 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 9 Apr 2009 16:51:05 +0000 Subject: [PATCH] ellLib changes: ANSIfication patch; moved test code out of ellLib.c into its own unit test program in libCom/test; changed ellFree() to take a function pointer for the free() routine, so it can be used on Windows; modified epicsExit and dbBkpt to use it and pass in the free routine. --- src/db/dbBkpt.c | 17 +- src/libCom/ellLib/ellLib.c | 404 +------------------------- src/libCom/ellLib/ellLib.h | 71 ++--- src/libCom/misc/epicsExit.c | 2 +- src/libCom/test/Makefile | 5 + src/libCom/test/epicsEllTest.c | 197 +++++++++++++ src/libCom/test/epicsRunLibComTests.c | 2 + 7 files changed, 243 insertions(+), 455 deletions(-) create mode 100644 src/libCom/test/epicsEllTest.c diff --git a/src/db/dbBkpt.c b/src/db/dbBkpt.c index 902dd9950..e8a6a2899 100644 --- a/src/db/dbBkpt.c +++ b/src/db/dbBkpt.c @@ -613,21 +613,8 @@ static void dbBkptCont(dbCommon *precord) ellDelete(&lset_stack, (ELLNODE *)pnode); --lset_stack_count; - { - /* - * free entrypoint queue - * - * avoid use of ellFree because problems on windows occur if the - * free is in a different DLL than the malloc - */ - ELLNODE * nnode = pnode->ep_queue.node.next; - while ( nnode ) - { - ELLNODE * pnode = nnode; - nnode = nnode->next; - free ( pnode ); - } - } + /* free entrypoint queue */ + ellFree(&pnode->ep_queue, free); /* remove execution semaphore */ epicsEventDestroy(pnode->ex_sem); diff --git a/src/libCom/ellLib/ellLib.c b/src/libCom/ellLib/ellLib.c index edcb1fb10..40d9c6de7 100644 --- a/src/libCom/ellLib/ellLib.c +++ b/src/libCom/ellLib/ellLib.c @@ -1,10 +1,9 @@ /*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found +* EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* $Id$ @@ -13,8 +12,6 @@ * Date: 07-02-92 */ -/* #define DEBUG_DRIVER */ - #include #define epicsExportSharedSymbols @@ -31,12 +28,7 @@ * *****************************************************************************/ #ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ void epicsShareAPI ellInit (ELLLIST *pList) -#else -void epicsShareAPI ellInit (plist) -ELLLIST *plist; -#endif { plist->node.next = NULL; plist->node.previous = NULL; @@ -49,13 +41,7 @@ ELLLIST *plist; * This function adds a node to the end of a linked list. * *****************************************************************************/ -#ifdef __STDC__ void epicsShareAPI ellAdd (ELLLIST *pList, ELLNODE *pNode) -#else -void epicsShareAPI ellAdd (pList, pNode) -ELLLIST *pList; -ELLNODE *pNode; -#endif { pNode->next = NULL; pNode->previous = pList->node.previous; @@ -77,13 +63,7 @@ ELLNODE *pNode; * be empty at the begining of the operation. * *****************************************************************************/ -#ifdef __STDC__ void epicsShareAPI ellConcat (ELLLIST *pDstList, ELLLIST *pAddList) -#else -void epicsShareAPI ellConcat (pDstList, pAddList) -ELLLIST *pDstList; -ELLLIST *pAddList; -#endif { if (pAddList->count == 0) return; /* Add list is empty, nothing to add. */ @@ -114,12 +94,7 @@ ELLLIST *pAddList; * *****************************************************************************/ #ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ int epicsShareAPI ellCount (ELLLIST *pList) -#else -int epicsShareAPI ellCount (pList) -ELLLIST *pList; -#endif { return(pList->count); } @@ -129,13 +104,7 @@ ELLLIST *pList; * This function deletes a specific node from a specified list; * *****************************************************************************/ -#ifdef __STDC__ void epicsShareAPI ellDelete (ELLLIST *pList, ELLNODE *pNode) -#else -void epicsShareAPI ellDelete (pList, pNode) -ELLLIST *pList; -ELLNODE *pNode; -#endif { if (pList->node.previous == pNode) pList->node.previous = pNode->previous; @@ -161,15 +130,7 @@ ELLNODE *pNode; * when it is non-empty. * *****************************************************************************/ -#ifdef __STDC__ void epicsShareAPI ellExtract (ELLLIST *pSrcList, ELLNODE *pStartNode, ELLNODE *pEndNode, ELLLIST *pDstList) -#else -void epicsShareAPI ellExtract (pSrcList, pStartNode, pEndNode, pDstList) -ELLLIST *pSrcList; -ELLNODE *pStartNode; -ELLNODE *pEndNode; -ELLLIST *pDstList; -#endif { ELLNODE *pnode; int count; @@ -217,12 +178,7 @@ ELLLIST *pDstList; * *****************************************************************************/ #ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ ELLNODE * epicsShareAPI ellFirst (ELLLIST *pList) -#else -ELLNODE * epicsShareAPI ellFirst (pList) -ELLLIST *pList; -#endif { return(pList->node.next); } @@ -233,12 +189,7 @@ ELLLIST *pList; * removed from the list. If the list is empty, NULL will be returned. * *****************************************************************************/ -#ifdef __STDC__ ELLNODE * epicsShareAPI ellGet (ELLLIST *pList) -#else -ELLNODE * epicsShareAPI ellGet (pList) -ELLLIST *pList; -#endif { ELLNODE *pnode = pList->node.next; @@ -254,14 +205,7 @@ ELLLIST *pList; * list. * *****************************************************************************/ -#ifdef __STDC__ void epicsShareAPI ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode) -#else -void epicsShareAPI ellInsert (plist, pPrev, pNode) -ELLLIST *plist; -ELLNODE *pPrev; -ELLNODE *pNode; -#endif { if (pPrev != NULL) { @@ -291,12 +235,7 @@ ELLNODE *pNode; * *****************************************************************************/ #ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ ELLNODE * epicsShareAPI ellLast (ELLLIST *pList) -#else -ELLNODE * epicsShareAPI ellLast (pList) -ELLLIST *pList; -#endif { return(pList->node.previous); } @@ -308,12 +247,7 @@ ELLLIST *pList; * *****************************************************************************/ #ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ ELLNODE * epicsShareAPI ellNext (ELLNODE *pNode) -#else -ELLNODE * epicsShareAPI ellNext (pNode) -ELLNODE *pNode; -#endif { return(pNode->next); } @@ -324,13 +258,7 @@ ELLNODE *pNode; * nodeNum'th node in the list, NULL will be returned. * *****************************************************************************/ -#ifdef __STDC__ ELLNODE * epicsShareAPI ellNth (ELLLIST *pList, int nodeNum) -#else -ELLNODE * epicsShareAPI ellNth (pList, nodeNum) -ELLLIST *pList; -int nodeNum; -#endif { ELLNODE *pnode; @@ -365,12 +293,7 @@ int nodeNum; * *****************************************************************************/ #ifndef DLLLIB_USE_MACROS -#ifdef __STDC__ ELLNODE * epicsShareAPI ellPrevious (ELLNODE *pNode) -#else -ELLNODE * epicsShareAPI ellPrevious (pNode) -ELLNODE *pNode; -#endif { return(pNode->previous); } @@ -381,13 +304,7 @@ ELLNODE *pNode; * no node that many steps from pNode, NULL will be returned. * *****************************************************************************/ -#ifdef __STDC__ ELLNODE * epicsShareAPI ellNStep (ELLNODE *pNode, int nStep) -#else -ELLNODE * epicsShareAPI ellNStep (pNode, nStep) -ELLNODE *pNode; -int nStep; -#endif { if (nStep > 0) { @@ -413,13 +330,7 @@ int nStep; * not in pList, -1 is returned. Note that the first node is 1. * *****************************************************************************/ -#ifdef __STDC__ int epicsShareAPI ellFind (ELLLIST *pList, ELLNODE *pNode) -#else -int epicsShareAPI ellFind (pList, pNode) -ELLLIST *pList; -ELLNODE *pNode; -#endif { ELLNODE *got = pList->node.next; int count = 1; @@ -445,12 +356,7 @@ ELLNODE *pNode; * In other words, this is a pretty worthless function. * *****************************************************************************/ -#ifdef __STDC__ -void epicsShareAPI ellFree (ELLLIST *pList) -#else -void epicsShareAPI ellFree (pList) -ELLLIST *pList; -#endif +void epicsShareAPI ellFree (ELLLIST *pList, FREEFUNC freeFunc) { ELLNODE *nnode = pList->node.next; ELLNODE *pnode; @@ -459,7 +365,7 @@ ELLLIST *pList; { pnode = nnode; nnode = nnode->next; - free(pnode); + freeFunc(pnode); } pList->node.next = NULL; pList->node.previous = NULL; @@ -504,305 +410,3 @@ void epicsShareAPI ellVerify (ELLLIST *pList) assert (count==ellCount(pList)); } -#ifdef DEBUG_DRIVER - /**************************************************************************** - * - * This is a bunch of code that can be used to test the ellLib code. It is - * provided here so that you may use it if and when you decide to alter - * something in this file, you need not re-create it for testing purposes. - * - * In general, I believe that you will end up with a core dump if the tests - * fail. If all tests complete properly, there will be a: - * printf("All tests completed successful\n") - * to assure you of it. - * - *****************************************************************************/ - -#include -#undef NULL -#include - -struct myNode { - ELLNODE ellNode; - int list; - int num; -}; -main() -{ - ELLLIST list1; - ELLLIST list2; - int i1, i2, i3; - struct myNode *pmyNode, *pfirst, *pn1; - - printf("\nellInit() check... "); - list1.count = 27; - list1.node.next = (ELLNODE *) 0x01010101; - list1.node.previous = (ELLNODE *) 0x10101010; - - ellInit(&list1); - ellInit(&list2); - - if ((list1.count != 0)||(list1.node.next != NULL)||(list1.node.previous != NULL)) - { - printf("FAILED!!!"); - printf("list1.count %d, list1.node.next %08.8X, list1.node.previous %08.8X\n", list1.count, list1.node.next, list1.node.previous); - exit(1); - } - printf("ok"); - - - /* First build a couple lists and fill them with nodes. */ - printf("\nellAdd() check... "); - i1 = 2; - pmyNode = (struct myNode *) malloc(sizeof(struct myNode)); - pmyNode->ellNode.next = (ELLNODE *) 0x10101010; - pmyNode->ellNode.previous = (ELLNODE *) 0x10101010; - - ellAdd(&list1, pmyNode); - pmyNode->list = 1; - pmyNode->num = 1; - - if ((list1.count != 1)||(list1.node.next != (ELLNODE *)pmyNode)|| - (list1.node.previous != (ELLNODE *)pmyNode)||(pmyNode->ellNode.next != NULL)|| - (pmyNode->ellNode.previous != NULL)) - { - printf("FAILED!!!!!\n"); - exit(2); - } - pfirst = pmyNode; - while(i1 <= 21) /* put 21 nodes into LIST1 */ - { - pmyNode = (struct myNode *) malloc(sizeof(struct myNode)); - ellAdd(&list1, pmyNode); - pmyNode->list = 1; - pmyNode->num = i1; - i1++; - } - if ((list1.count != 21)||(list1.node.next != (ELLNODE *)pfirst)|| - (list1.node.previous != (ELLNODE *)pmyNode)||(pmyNode->ellNode.next != NULL)) - { - printf("FAILED!!!\n"); - exit(3); - } - printf("ok\nellFirst() check... "); - - if (ellFirst(&list1) != (ELLNODE *)pfirst) - { - printf("FAILED!!!\n"); - exit(5); - } - printf("ok\nellLast() check... "); - if (ellLast(&list1) != (ELLNODE *)pmyNode) - { - printf("FAILED!!!\n"); - exit(6); - } - printf("ok\nellNext() check... "); - if ((ellNext(pmyNode) != NULL)||(ellNext(pfirst) != (ELLNODE *)(pfirst->ellNode.next))) - { - printf("FAILED!!!\n"); - exit(7); - } - printf("ok\nellNth() check... "); - if ((ellNth(&list1, 0) != NULL)|| - ((pn1 = (struct myNode *)ellNth(&list1, 21)) != pmyNode)|| - (ellNth(&list1, 22) != NULL)|| - (ellNth(&list1, 1) != (ELLNODE *)(pfirst))|| - (ellNth(&list1, 2) != (ELLNODE *)(pfirst->ellNode.next))|| - (ellNth(&list1, 20) != (ELLNODE *)(pmyNode->ellNode.previous))) - { - printf("FAILED!!!\n"); - exit(8); - } - printf("ok\nellPrevious() check... "); - - if ((ellPrevious(pmyNode) != (ELLNODE *)(pmyNode->ellNode.previous))|| - (ellPrevious(pfirst) != NULL)|| - (ellPrevious(pfirst->ellNode.next) != (ELLNODE *)pfirst)) - { - printf("FAILED!!!\n"); - exit(9); - } - printf("ok\nellGet() check... "); - if (((pn1 = (struct myNode *)ellGet(&list1)) != pfirst)|| - (list1.node.next != pfirst->ellNode.next)) - { - printf("FAILED!!!\n"); - exit(10); - } - ellAdd(&list2, pn1); - if (((pn1 = (struct myNode *)ellGet(&list2)) != pfirst)|| - (list2.node.next != NULL)||(list2.node.previous != NULL)) - { - printf("FAILED!!!\n"); - exit(11); - } - printf("ok\nellCount() check... "); - if ((ellCount(&list1) != 20)||(ellCount(&list2) != 0)) - { - printf("FAILED!!!\n"); - exit(4); - } - printf("ok\nellConcat() check... "); - ellConcat(&list1, &list2); - if ((ellCount(&list1) != 20)||(ellCount(&list2) != 0)|| - (list1.node.previous != (ELLNODE *)pmyNode)) - { - printf("FAILED!!! (12)\n"); - exit(12); - } - ellAdd(&list2, pn1); - ellConcat(&list1, &list2); - if ((ellCount(&list1) != 21)||(ellCount(&list2) != 0)|| - (list1.node.previous != (ELLNODE *)pn1)|| - (list2.node.next != NULL)||(list2.node.previous!=NULL)) - { - printf("FAILED!!! (13)\n"); - printf("list1.count = %d list2.count = %d\n", ellCount(&list1), ellCount(&list2)); - exit(13); - } - printf("ok\nellDelete() check... "); - ellDelete(&list1, pn1); - if (ellCount(&list1) != 20) - { - printf("FAILED!!! (14)\n"); - exit(14); - } - printf("ok\nellFind() check... "); - ellAdd(&list2, pn1); - ellConcat(&list2, &list1); - i1 = -23; - if (ellFind(&list1, pn1) != -1) /* empty list */ - { - printf("FAILED!!! (15)\n"); - exit(15); - } - if ((i1 = ellFind(&list2, pn1)) != pn1->num) /* first node */ - { - printf("FAILED!!! (16)\n"); - exit(16); - } - pn1 = (struct myNode *)ellNth(&list2, 18); - if ((i1 = ellFind(&list2, pn1)) != 18) /* 18th node */ - { - printf("FAILED!!! (17)\n"); - exit(17); - } - printf("ok\nellInsert() check... "); - ellDelete(&list2, pn1); - ellInsert(&list2, NULL, pn1); /* move node 18 to top */ - if ((ellCount(&list2) != 21)||(((struct myNode *)(list2.node.next))->num != 18)) - { - printf("FAILED!!! (18)\n"); - exit (18); - } - if (ellFind(&list2, ellNth(&list2, 21)) != 21) - { /* Run thru all pointers to check integrity */ - printf("FAILED!!! (19)\n"); - exit(19); - } - pn1 = (struct myNode *)ellGet(&list2); - pmyNode = (struct myNode *)ellNth(&list2, 17); - ellInsert(&list2, pmyNode, pn1); - if (ellFind(&list2, ellNth(&list2, 21)) != 21) - { /* Run thru all pointers to check integrity */ - printf("FAILED!!! (20)\n"); - exit(20); - } - if ((((struct myNode *)(ellFirst(&list2)))->num != 1)|| - (((struct myNode *)(ellNth(&list2,17)))->num != 17)|| - (((struct myNode *)(ellNth(&list2,18)))->num != 18)) - { - printf("FAILED!!! (21)\n"); - exit(21); - } - pn1 = (struct myNode *)ellLast(&list2); - pmyNode = (struct myNode *) malloc(sizeof(struct myNode)); - ellInsert(&list2, pn1, pmyNode); - if ((ellCount(&list2) != 22)||(ellFind(&list2, ellNth(&list2, 22)) != 22)) - { - printf("FAILED!!! (33)\n"); - exit(33); - } - ellDelete(&list2, pmyNode); - free(pmyNode); - - printf("ok\nellExtract() check... "); - ellExtract(&list2, ellNth(&list2,9), ellNth(&list2, 19), &list1); - if ((ellCount(&list2) != 10)||(ellCount(&list1) != 11)) - { - printf("FAILED!!! (22)\n"); - exit(22); - } - if ((ellFind(&list2, ellNth(&list2, 10)) != 10)|| - (ellFind(&list1, ellNth(&list1, 11)) != 11)) - { - printf("FAILED!!! (23)\n"); - exit(23); - } - printf("ok\nellFree() check... "); - ellFree(&list2); - if (ellCount(&list2) != 0) - { - printf("FAILED!!! (24)\n"); - exit(24); - } - printf("ok\nellNStep() check... "); - pn1 = (struct myNode *)ellFirst(&list1); - i1 = 1; - while(pn1 != NULL) - { - pn1->num = i1++; - pn1 = (struct myNode *)ellNext(pn1); - } - pn1 = (struct myNode *)ellFirst(&list1); - if (pn1 == NULL) - { - printf("FAILED!!! (30)\n"); - exit(30); - } - pmyNode = (struct myNode *)ellNStep(pn1, 3); - if (pmyNode == NULL) - { - printf("FAILED!!! (27)\n"); - exit(27); - } - if (pmyNode->num != 4) - { - printf("FAILED!!! (25)\n"); - printf("got number %d\n", pmyNode->num); - exit(25); - - } - pmyNode = (struct myNode *)ellNStep(pn1, 30); - if (pmyNode != NULL) - { - printf("FAILED!!! (26)\n"); - exit(26); - } - pmyNode = (struct myNode *)ellNStep(pn1, 10); - if (pmyNode == NULL) - { - printf("FAILED!!! (28)\n"); - exit(28); - } - if (pmyNode->num != 11) - { - printf("FAILED!!! (29)\n"); - exit(29); - } - pmyNode = (struct myNode *)ellNStep(pmyNode, 0); - if (pmyNode->num != 11) - { - printf("FAILED!!! (31)\n"); - exit(31); - } - pmyNode = (struct myNode *)ellNStep(pmyNode, -4); - if (pmyNode->num != 7) - { - printf("FAILED!!! (32)\n"); - exit(32); - } - printf("ok\n\nAll tests completed successful\n"); -} -#endif diff --git a/src/libCom/ellLib/ellLib.h b/src/libCom/ellLib/ellLib.h index 06f87be05..4d33e5049 100644 --- a/src/libCom/ellLib/ellLib.h +++ b/src/libCom/ellLib/ellLib.h @@ -1,10 +1,9 @@ /*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found +* EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* ellLib.h $Id$ @@ -12,8 +11,8 @@ * Author: John Winans (ANL) * Date: 07-02-92 */ -#ifndef INCellLibh -#define INCellLibh +#ifndef INC_ellLib_H +#define INC_ellLib_H #include "shareLib.h" @@ -24,41 +23,35 @@ extern "C" { #define DLLLIB_USE_MACROS typedef struct ELLNODE { - struct ELLNODE *next; - struct ELLNODE *previous; -}ELLNODE; + struct ELLNODE *next; + struct ELLNODE *previous; +} ELLNODE; typedef struct ELLLIST { - ELLNODE node; - int count; -}ELLLIST; + ELLNODE node; + int count; +} ELLLIST; + +typedef void (*FREEFUNC)(void *); #ifdef DLLLIB_USE_MACROS - -#define ellInit(PLIST) { (PLIST)->node.next = NULL;\ - (PLIST)->node.previous = NULL;\ - (PLIST)->count = 0; } - -#define ellCount(PLIST) ((PLIST)->count) - -#define ellFirst(PLIST) ((PLIST)->node.next) - -#define ellLast(PLIST) ((PLIST)->node.previous) - -#define ellNext(PNODE) ((PNODE)->next) - -#define ellPrevious(PNODE) ((PNODE)->previous) - -#else /*DLLLIB_USE_MACROS*/ - -epicsShareFunc void epicsShareAPI ellInit (ELLLIST *pList); -epicsShareFunc int epicsShareAPI ellCount (ELLLIST *pList); -epicsShareFunc ELLNODE * epicsShareAPI ellFirst (ELLLIST *pList); -epicsShareFunc ELLNODE * epicsShareAPI ellLast (ELLLIST *pList); -epicsShareFunc ELLNODE * epicsShareAPI ellNext (ELLNODE *pNode); -epicsShareFunc ELLNODE * epicsShareAPI ellPrevious (ELLNODE *pNode); - -#endif /*DLLLIB_USE_MACROS*/ + #define ellInit(PLIST) {\ + (PLIST)->node.next = (PLIST)->node.previous = NULL;\ + (PLIST)->count = 0;\ + } + #define ellCount(PLIST) ((PLIST)->count) + #define ellFirst(PLIST) ((PLIST)->node.next) + #define ellLast(PLIST) ((PLIST)->node.previous) + #define ellNext(PNODE) ((PNODE)->next) + #define ellPrevious(PNODE) ((PNODE)->previous) +#else + epicsShareFunc void epicsShareAPI ellInit (ELLLIST *pList); + epicsShareFunc int epicsShareAPI ellCount (ELLLIST *pList); + epicsShareFunc ELLNODE * epicsShareAPI ellFirst (ELLLIST *pList); + epicsShareFunc ELLNODE * epicsShareAPI ellLast (ELLLIST *pList); + epicsShareFunc ELLNODE * epicsShareAPI ellNext (ELLNODE *pNode); + epicsShareFunc ELLNODE * epicsShareAPI ellPrevious (ELLNODE *pNode); +#endif /* DLLLIB_USE_MACROS */ epicsShareFunc void epicsShareAPI ellAdd (ELLLIST *pList, ELLNODE *pNode); epicsShareFunc void epicsShareAPI ellConcat (ELLLIST *pDstList, ELLLIST *pAddList); @@ -69,12 +62,12 @@ epicsShareFunc void epicsShareAPI ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELL epicsShareFunc ELLNODE * epicsShareAPI ellNth (ELLLIST *pList, int nodeNum); epicsShareFunc ELLNODE * epicsShareAPI ellNStep (ELLNODE *pNode, int nStep); epicsShareFunc int epicsShareAPI ellFind (ELLLIST *pList, ELLNODE *pNode); -/* use of ellFree on windows causes problems because the malloc and free are not in the same DLL */ -epicsShareFunc void epicsShareAPI ellFree (ELLLIST *pList); +/* ellFree has to take a free function to work properly on Windows */ +epicsShareFunc void epicsShareAPI ellFree (ELLLIST *pList, FREEFUNC freeFunc); epicsShareFunc void epicsShareAPI ellVerify (ELLLIST *pList); #ifdef __cplusplus } #endif -#endif /*INCellLibh*/ +#endif /* INC_ellLib_H */ diff --git a/src/libCom/misc/epicsExit.c b/src/libCom/misc/epicsExit.c index 0280000a2..3d46ff281 100644 --- a/src/libCom/misc/epicsExit.c +++ b/src/libCom/misc/epicsExit.c @@ -52,7 +52,7 @@ static epicsThreadPrivateId exitPvtPerThread = 0; static void destroyExitPvt ( exitPvt * pep ) { - ellFree ( &pep->list ); + ellFree ( &pep->list, free ); free ( pep ); } diff --git a/src/libCom/test/Makefile b/src/libCom/test/Makefile index 4a99bd98e..638be1667 100644 --- a/src/libCom/test/Makefile +++ b/src/libCom/test/Makefile @@ -32,6 +32,11 @@ epicsMathTest_SRCS += epicsMathTest.c testHarness_SRCS += epicsMathTest.c TESTS += epicsMathTest +TESTPROD_HOST += epicsEllTest +epicsEllTest_SRCS += epicsEllTest.c +testHarness_SRCS += epicsEllTest.c +TESTS += epicsEllTest + TESTPROD_HOST += epicsStdioTest epicsStdioTest_SRCS += epicsStdioTest.c testHarness_SRCS += epicsStdioTest.c diff --git a/src/libCom/test/epicsEllTest.c b/src/libCom/test/epicsEllTest.c new file mode 100644 index 000000000..6570ca587 --- /dev/null +++ b/src/libCom/test/epicsEllTest.c @@ -0,0 +1,197 @@ +/*************************************************************************\ +* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +#include +#include + +#include "ellLib.h" +#include "epicsUnitTest.h" +#include "testMain.h" + +struct myItem { + ELLNODE node; + int list; + int num; +}; + +MAIN(epicsEllTest) +{ + ELLLIST list1; + ELLLIST list2; + int i1; + struct myItem *pitem, *pfirst, *pick; + + testPlan(67); + + list1.count = 27; + list1.node.next = (ELLNODE *) 0x01010101; + list1.node.previous = (ELLNODE *) 0x10101010; + + ellInit(&list1); + ellInit(&list2); + + testOk1(list1.count == 0); + testOk1(list1.node.next == NULL); + testOk1(list1.node.previous == NULL); + + /* First build a couple lists and fill them with nodes. */ + i1 = 2; + pitem = (struct myItem *) malloc(sizeof(struct myItem)); + pitem->node.next = (ELLNODE *) 0x10101010; + pitem->node.previous = (ELLNODE *) 0x10101010; + + ellAdd(&list1, &pitem->node); + pitem->list = 1; + pitem->num = 1; + + testOk1(list1.count == 1); + testOk1(list1.node.next == &pitem->node); + testOk1(list1.node.previous == &pitem->node); + testOk1(pitem->node.next == NULL); + testOk1(pitem->node.previous == NULL); + + pfirst = pitem; + while (i1 <= 21) { /* put 21 nodes into LIST1 */ + pitem = (struct myItem *) malloc(sizeof(struct myItem)); + ellAdd(&list1, &pitem->node); + pitem->list = 1; + pitem->num = i1; + i1++; + } + + testOk1(list1.count == 21); + testOk1(list1.node.next == &pfirst->node); + testOk1(list1.node.previous == &pitem->node); + testOk1(pitem->node.next == NULL); + + testOk1(ellFirst(&list1) == &pfirst->node); + testOk1(ellLast(&list1) == &pitem->node); + testOk1(ellNext(&pitem->node) == NULL); + testOk1(ellNext(&pfirst->node) == pfirst->node.next); + + testOk1(ellNth(&list1, 0) == NULL); + + pick = (struct myItem *)ellNth(&list1, 21); + testOk1(pick == pitem); + + testOk1(ellNth(&list1, 22) == NULL); + testOk1(ellNth(&list1, 1) == &pfirst->node); + testOk1(ellNth(&list1, 2) == pfirst->node.next); + testOk1(ellNth(&list1, 20) == pitem->node.previous); + + testOk1(ellPrevious(&pitem->node) == pitem->node.previous); + testOk1(ellPrevious(&pfirst->node) == NULL); + testOk1(ellPrevious(pfirst->node.next) == &pfirst->node); + + pick = (struct myItem *)ellGet(&list1); + testOk1(pick == pfirst); + testOk1(list1.node.next == pfirst->node.next); + + ellAdd(&list2, &pick->node); + + pick = (struct myItem *)ellGet(&list2); + testOk1(pick == pfirst); + testOk1(list2.node.next == NULL); + testOk1(list2.node.previous == NULL); + + testOk1(ellCount(&list1) == 20); + testOk1(ellCount(&list2) == 0); + + ellConcat(&list1, &list2); + + testOk1(ellCount(&list1) == 20); + testOk1(ellCount(&list2) == 0); + testOk1(list1.node.previous == &pitem->node); + + ellAdd(&list2, &pick->node); + ellConcat(&list1, &list2); + + testOk1(ellCount(&list1) == 21); + testOk1(ellCount(&list2) == 0); + testOk1(list1.node.previous == &pick->node); + testOk1(list2.node.next == NULL); + testOk1(list2.node.previous == NULL); + + ellDelete(&list1, &pick->node); + testOk1(ellCount(&list1) == 20); + + ellAdd(&list2, &pick->node); + ellConcat(&list2, &list1); + testOk1(ellFind(&list1, &pick->node) == -1); /* empty list */ + testOk1(ellFind(&list2, &pick->node) == pick->num); /* first node */ + + pick = (struct myItem *)ellNth(&list2, 18); + testOk1(ellFind(&list2, &pick->node) == 18); /* 18th node */ + + ellDelete(&list2, &pick->node); + ellInsert(&list2, NULL, &pick->node); /* move #18 to top */ + testOk1(ellCount(&list2) == 21); + testOk1(((struct myItem *)list2.node.next)->num == 18); + + testOk1(ellFind(&list2, ellNth(&list2, 21)) == 21); + + pick = (struct myItem *)ellGet(&list2); + pitem = (struct myItem *)ellNth(&list2, 17); + ellInsert(&list2, &pitem->node, &pick->node); + testOk1(ellFind(&list2, ellNth(&list2, 21)) == 21); + + testOk1(((struct myItem *)ellFirst(&list2))->num == 1); + testOk1(((struct myItem *)ellNth(&list2,17))->num == 17); + testOk1(((struct myItem *)ellNth(&list2,18))->num == 18); + + pick = (struct myItem *)ellLast(&list2); + pitem = (struct myItem *) malloc(sizeof(struct myItem)); + ellInsert(&list2, &pick->node, &pitem->node); + testOk1(ellCount(&list2) == 22); + testOk1(ellFind(&list2, ellNth(&list2, 22)) == 22); + + ellDelete(&list2, &pitem->node); + free(pitem); + + ellExtract(&list2, ellNth(&list2,9), ellNth(&list2, 19), &list1); + testOk1(ellCount(&list2) == 10); + testOk1(ellCount(&list1) == 11); + + testOk1(ellFind(&list2, ellNth(&list2, 10)) == 10); + testOk1(ellFind(&list1, ellNth(&list1, 11)) == 11); + + ellFree(&list2, free); + testOk1(ellCount(&list2) == 0); + + pick = (struct myItem *)ellFirst(&list1); + i1 = 1; + while(pick != NULL) { + pick->num = i1++; + pick = (struct myItem *)ellNext(&pick->node); + } + pick = (struct myItem *)ellFirst(&list1); + testOk1(pick != NULL); + + pitem = (struct myItem *)ellNStep(&pick->node, 3); + testOk1(pitem != NULL); + testOk1(pitem->num == 4); + + pitem = (struct myItem *)ellNStep(&pick->node, 30); + testOk1(pitem == NULL); + + pitem = (struct myItem *)ellNStep(&pick->node, 10); + testOk1(pitem != NULL); + testOk1(pitem->num == 11); + + pitem = (struct myItem *)ellNStep(&pitem->node, 0); + testOk1(pitem->num == 11); + + pitem = (struct myItem *)ellNStep(&pitem->node, -4); + testOk1(pitem->num == 7); + + ellFree(&list1, free); + testOk1(ellCount(&list1) == 0); + + return testDone(); +} diff --git a/src/libCom/test/epicsRunLibComTests.c b/src/libCom/test/epicsRunLibComTests.c index 5d9559eab..5bd8562ab 100644 --- a/src/libCom/test/epicsRunLibComTests.c +++ b/src/libCom/test/epicsRunLibComTests.c @@ -53,6 +53,8 @@ void epicsRunLibComTests(void) runTest(epicsAlgorithm); + runTest(epicsEllTest); + runTest(epicsCalcTest); runTest(epicsEventTest);