sllLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* sllLib.c - singly linked list subroutine library */
  2. /* Copyright 1984-1998 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01m,11nov01,dee  add ColdFire support
  8. 01l,04sep98,cdp  make ARM CPUs with ARM_THUMB==TRUE use portable routines.
  9. 01l,03mar00,zl   merged SH support from T1
  10. 01k,22apr97,jpd  added optimised ARM code.
  11. 01j,19mar95,dvs  removed tron references.
  12. 01i,09jun93,hdn  added a support for I80X86
  13. 01h,17jul92,jmm  fixed sllEach to cope with having its current node deleted
  14. 01g,26may92,rrr  the tree shuffle
  15. 01f,19nov91,rrr  shut up some ansi warnings.
  16. 01e,04oct91,rrr  passed through the ansification filter
  17.                   -changed functions to ansi style
  18.   -fixed #else and #endif
  19.   -changed VOID to void
  20.   -changed copyright notice
  21. 01d,23jul91,hdn  added conditional macro for optimized TRON codes.
  22. 01c,29sep90,jcf  documentation.
  23. 01b,10may90,jcf  fixed PORTABLE definition.
  24. 01a,03jun89,jcf  written.
  25. */
  26. /*
  27. DESCRIPTION
  28. This subroutine library supports the creation and maintenance of a
  29. singly linked list.  The user supplies a list head (type SL_LIST)
  30. that will contain pointers to the first and last nodes in the list.
  31. The nodes in the list can be any user-defined structure, but they must reserve
  32. space for a pointer as their first element.  The forward chain is terminated
  33. with a NULL pointer.
  34. .ne 16
  35. NON-EMPTY LIST:
  36. .CS
  37.    ---------             --------          --------
  38.    | head--------------->| next----------->| next---------
  39.    |       |             |      |          |      |      |
  40.    |       |             |      |          |      |      |
  41.    | tail------          | ...  |    ----->| ...  |      |
  42.    |-------|  |                      |                   v
  43.               |                      |                 -----
  44.               |                      |                  ---
  45.               |                      |                   -
  46.               ------------------------
  47. .CE
  48. .ne 12
  49. EMPTY LIST:
  50. .CS
  51. -----------
  52.         |  head------------------
  53.         |         |             |
  54.         |  tail----------       |
  55.         |         |     v       v
  56.         |         |   -----   -----
  57.         -----------    ---     ---
  58.                         - -
  59. .CE
  60. INCLUDE FILE: sllLib.h
  61. */
  62. /* LINTLIBRARY */
  63. #include "vxWorks.h"
  64. #include "stdlib.h"
  65. #include "sllLib.h"
  66. /* optimized version available for 680X0, I80X86, SH, and ARM */
  67. #if (defined(PORTABLE) || 
  68.      ((CPU_FAMILY != MC680X0) && 
  69.       (CPU_FAMILY != I80X86) && 
  70.       (CPU_FAMILY != SH) && 
  71.       (CPU_FAMILY != COLDFIRE) && 
  72.       (CPU_FAMILY != ARM)) || 
  73.      ((CPU_FAMILY == ARM) && ARM_THUMB))
  74. #define sllLib_PORTABLE
  75. #endif
  76. /*******************************************************************************
  77. *
  78. * sllCreate - create a singly linked list head
  79. *
  80. * Create, initialize and return a pointer to a singly linked list head.
  81. *
  82. * RETURNS: Pointer to singly linked list head, or NULL if creation failed.
  83. */
  84. SL_LIST *sllCreate (void)
  85.     {
  86.     SL_LIST *pList = (SL_LIST *) malloc ((unsigned) sizeof (SL_LIST));
  87.     sllInit (pList); /* initialize list */
  88.     return (pList);
  89.     }
  90. /*******************************************************************************
  91. *
  92. * sllInit - initialize singly linked list head
  93. *
  94. * Initialize the specified list to an empty list.
  95. *
  96. * RETURNS: OK, or ERROR if intialization failed.
  97. */
  98. STATUS sllInit
  99.     (
  100.     SL_LIST *pList     /* pointer to list head to be initialized */
  101.     )
  102.     {
  103.     pList->head  = NULL; /* initialize list */
  104.     pList->tail  = NULL;
  105.     return (OK);
  106.     }
  107. /*******************************************************************************
  108. *
  109. * sllDelete - terminate singly linked list head free associated memory
  110. *
  111. * Terminate the specified list.
  112. *
  113. * RETURNS: OK, or ERROR if singly linked list head could not be deallocated.
  114. *
  115. * ARGSUSED
  116. */
  117. STATUS sllDelete
  118.     (
  119.     SL_LIST *pList     /* pointer to list head to be initialized */
  120.     )
  121.     {
  122.     free ((char *) pList); /* free list */
  123.     return OK;
  124.     }
  125. /*******************************************************************************
  126. *
  127. * sllTerminate - terminate singly linked list head
  128. *
  129. * Terminate the specified list.
  130. *
  131. * RETURNS: OK, or ERROR if singly linked list could not be terminated.
  132. *
  133. * ARGSUSED
  134. */
  135. STATUS sllTerminate
  136.     (
  137.     SL_LIST *pList     /* pointer to list head to be initialized */
  138.     )
  139.     {
  140.     return (OK);
  141.     }
  142. #ifdef sllLib_PORTABLE
  143. /*******************************************************************************
  144. *
  145. * sllPutAtHead - add node to beginning of list
  146. *
  147. * This routine adds the specified node to the end of the specified list.
  148. *
  149. * SEE ALSO: sllPutAtTail()
  150. */
  151. void sllPutAtHead
  152.     (
  153.     SL_LIST *pList,     /* pointer to list descriptor */
  154.     SL_NODE *pNode      /* pointer to node to be added */
  155.     )
  156.     {
  157.     if ((pNode->next = pList->head) == NULL)
  158. pList->head = pList->tail = pNode;
  159.     else
  160. pList->head = pNode;
  161.     }
  162. /*******************************************************************************
  163. *
  164. * sllPutAtTail - add node to end of list
  165. *
  166. * This routine adds the specified node to the end of the specified singly
  167. * linked list.
  168. *
  169. * SEE ALSO: sllPutAtHead()
  170. */
  171. void sllPutAtTail
  172.     (
  173.     SL_LIST *pList,     /* pointer to list descriptor */
  174.     SL_NODE *pNode      /* pointer to node to be added */
  175.     )
  176.     {
  177.     pNode->next = NULL;
  178.     if (pList->head == NULL)
  179. pList->tail = pList->head = pNode;
  180.     else
  181. pList->tail->next = pNode;
  182. pList->tail = pNode;
  183.     }
  184. /*******************************************************************************
  185. *
  186. * sllGet - get (delete and return) first node from list
  187. *
  188. * This routine gets the first node from the specified singly linked list,
  189. * deletes the node from the list, and returns a pointer to the node gotten.
  190. *
  191. * RETURNS: Pointer to the node gotten, or NULL if the list is empty.
  192. */
  193. SL_NODE *sllGet
  194.     (
  195.     FAST SL_LIST *pList         /* pointer to list from which to get node */
  196.     )
  197.     {
  198.     FAST SL_NODE *pNode;
  199.     if ((pNode = pList->head) != NULL)
  200. pList->head = pNode->next;
  201.     return (pNode);
  202.     }
  203. #endif /* sllLib_PORTABLE */
  204. /*******************************************************************************
  205. *
  206. * sllRemove - remove specified node in list
  207. *
  208. * Remove the specified node in a singly linked list.
  209. */
  210. void sllRemove
  211.     (
  212.     SL_LIST *pList,             /* pointer to list head */
  213.     SL_NODE *pDeleteNode,       /* pointer to node to be deleted */
  214.     SL_NODE *pPrevNode          /* pointer to previous node or NULL if head */
  215.     )
  216.     {
  217.     if (pPrevNode == NULL)
  218. {
  219. pList->head = pDeleteNode->next;
  220. if (pList->tail == pDeleteNode)
  221.     pList->tail = NULL;
  222. }
  223.     else
  224. {
  225. pPrevNode->next = pDeleteNode->next;
  226. if (pList->tail == pDeleteNode)
  227.     pList->tail = pPrevNode;
  228. }
  229.     }
  230. /*******************************************************************************
  231. *
  232. * sllPrevious - find and return previous node in list
  233. *
  234. * Find and return the previous node in a singly linked list.
  235. */
  236. SL_NODE *sllPrevious
  237.     (
  238.     SL_LIST *pList,             /* pointer to list head */
  239.     SL_NODE *pNode              /* pointer to node to find previous node for */
  240.     )
  241.     {
  242.     SL_NODE *pTmpNode = pList->head;
  243.     if ((pTmpNode == NULL) || (pTmpNode == pNode))
  244. return (NULL); /* no previous node */
  245.     while (pTmpNode->next != NULL)
  246. {
  247. if (pTmpNode->next == pNode)
  248.     return (pTmpNode);
  249. pTmpNode = pTmpNode->next;
  250. }
  251.     return (NULL); /* node not found */
  252.     }
  253. /*******************************************************************************
  254. *
  255. * sllCount - report number of nodes in list
  256. *
  257. * This routine returns the number of nodes in the given list.
  258. *
  259. * CAVEAT
  260. * This routine must actually traverse the list to count the nodes.
  261. * If counting is a time critical fuction, consider using lstLib which
  262. * maintains a count field.
  263. *
  264. * RETURNS: Number of nodes in specified list.
  265. *
  266. * SEE ALSO: lstLib.
  267. */
  268. int sllCount
  269.     (
  270.     SL_LIST *pList      /* pointer to list head */
  271.     )
  272.     {
  273.     FAST SL_NODE *pNode = SLL_FIRST (pList);
  274.     FAST int count = 0;
  275.     while (pNode != NULL)
  276. {
  277. count ++;
  278. pNode = SLL_NEXT (pNode);
  279. }
  280.     return (count);
  281.     }
  282. /*******************************************************************************
  283. *
  284. * sllEach - call a routine for each node in a linked list
  285. *
  286. * This routine calls a user-supplied routine once for each node in the
  287. * linked list.  The routine should be declared as follows:
  288. * .CS
  289. *  BOOL routine (pNode, arg)
  290. *      DL_NODE *pNode; /@ pointer to a linked list node    @/
  291. *      int arg; /@ arbitrary user-supplied argument @/
  292. * .CE
  293. * The user-supplied routine should return TRUE if sllEach() is to
  294. * continue calling it with the remaining nodes, or FALSE if it is done and
  295. * sllEach() can exit.
  296. *
  297. * RETURNS: NULL if traversed whole linked list, or pointer to DL_NODE that
  298. *          sllEach ended with.
  299. */
  300. SL_NODE *sllEach
  301.     (
  302.     SL_LIST     *pList,         /* linked list of nodes to call routine for */
  303.     FUNCPTR     routine,        /* the routine to call for each list node */
  304.     int         routineArg      /* arbitrary user-supplied argument */
  305.     )
  306.     {
  307.     FAST SL_NODE *pNode = SLL_FIRST (pList);
  308.     FAST SL_NODE *pNext;
  309.     while (pNode != NULL)
  310. {
  311. pNext = SLL_NEXT (pNode);
  312. if ((* routine) (pNode, routineArg) == FALSE)
  313.     break;
  314. pNode = pNext;
  315. }
  316.     return (pNode); /* return node we ended with */
  317.     }