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

VxWorks

开发平台:

C/C++

  1. /* lstLib.c - doubly linked list subroutine library */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02a,19sep01,pcm  added lstLibInit () to bring module into image (SPR 20698)
  8. 01z,05oct98,jmp  doc: cleanup.
  9. 01y,14oct95,jdi  doc: fixed typo in lstNth().
  10. 01x,13feb95,jdi  doc format change.
  11. 01w,20jan93,jdi  documentation cleanup for 5.1.
  12. 01v,09jul92,hdn  put an optimized lstGet()
  13. 01u,26may92,rrr  the tree shuffle
  14. 01t,25nov91,rrr  cleanup of some ansi warnings.
  15. 01s,04oct91,rrr  passed through the ansification filter
  16.                   -changed functions to ansi style
  17.   -changed VOID to void
  18.   -changed copyright notice
  19. 01r,30apr91,jdi  documentation tweaks.
  20. 01q,05apr91,jdi  documentation -- removed header parens and x-ref numbers;
  21.  doc review by dnw.
  22. 01p,11feb91,jaa  documentation cleanup.
  23. 01o,05nov87,jlf  documentation
  24. 01n,02apr87,ecs  hushed lint in lstFree.
  25. 01m,25mar87,jlf  documentation
  26. 01l,21dec86,dnw  changed to not get include files from default directories.
  27. 01k,01jul86,jlf  documentation.
  28. 01j,21may86,llk  added lstFree and lstNStep.
  29. 01i,09apr86,rdc  added lstFind.
  30. 01h,20jul85,jlf  documentation.
  31. 01g,19sep84,jlf  fixed spacing in comments by adding .ne's.
  32. 01f,08sep84,jlf  added comments and copyright notice.
  33. 01e,29jun84,dnw  added lstConcat and lstExtract.
  34. 01d,03jun84,dnw  added lstFirst, lstLast.
  35.  changed list.{head,tail} to list.node.{next,previous}.
  36.  cleaned up comments, etc.
  37. 01c,07may84,ecs  added lstNext, lstPrevious, and lstCount.
  38. 01b,09jun83,ecs  modified the documentation
  39. 01a,06aug82,dnw  created from old singly-linked-list lib which is now "slllb".
  40. */
  41. /*
  42. DESCRIPTION
  43. This subroutine library supports the creation and maintenance of a
  44. doubly linked list.  The user supplies a list descriptor (type LIST)
  45. that will contain pointers to the first and last nodes in the list,
  46. and a count of the number of nodes in the list.  The nodes in the
  47. list can be any user-defined structure, but they must reserve space
  48. for two pointers as their first elements.  Both the forward and
  49. backward chains are terminated with a NULL pointer.
  50. The linked-list library simply manipulates the linked-list data structures;
  51. no kernel functions are invoked.  In particular, linked lists by themselves
  52. provide no task synchronization or mutual exclusion.  If multiple tasks will
  53. access a single linked list, that list must be guarded with some
  54. mutual-exclusion mechanism (e.g., a mutual-exclusion semaphore).
  55. NON-EMPTY LIST:
  56. .CS
  57.    ---------             --------          --------
  58.    | head--------------->| next----------->| next---------
  59.    |       |             |      |          |      |      |
  60.    |       |       ------- prev |<---------- prev |      |
  61.    |       |       |     |      |          |      |      |
  62.    | tail------    |     | ...  |    ----->| ...  |      |
  63.    |       |  |    v                 |                   v
  64.    |count=2|  |  -----               |                 -----
  65.    ---------  |   ---                |                  ---
  66.               |    -                 |                   -
  67.               |                      |
  68.               ------------------------
  69. .CE
  70. EMPTY LIST:
  71. .CS
  72. -----------
  73.         |  head------------------
  74.         |         |             |
  75.         |  tail----------       |
  76.         |         |     |       v
  77.         | count=0 |   -----   -----
  78.         -----------    ---     ---
  79.                         - -
  80. .CE
  81. INCLUDE FILES: lstLib.h
  82. */
  83. /* LINTLIBRARY */
  84. #include "vxWorks.h"
  85. #include "lstLib.h"
  86. #include "stdlib.h"
  87. #define HEAD node.next /* first node in list */
  88. #define TAIL node.previous /* last node in list */
  89. /*********************************************************************
  90. *
  91. * lstLibInit - initializes lstLib module
  92. *
  93. * This routine pulls lstLib into the vxWorks image.
  94. *
  95. * RETURNS: N/A
  96. */
  97. void lstLibInit (void)
  98.     {
  99.     return;
  100.     }
  101. /*********************************************************************
  102. *
  103. * lstInit - initialize a list descriptor
  104. *
  105. * This routine initializes a specified list to an empty list.
  106. *
  107. * RETURNS: N/A
  108. */
  109. void lstInit
  110.     (
  111.     FAST LIST *pList     /* ptr to list descriptor to be initialized */
  112.     )
  113.     {
  114.     pList->HEAD  = NULL;
  115.     pList->TAIL  = NULL;
  116.     pList->count = 0;
  117.     }
  118. /*************************************************************************
  119. *
  120. * lstAdd - add a node to the end of a list
  121. *
  122. * This routine adds a specified node to the end of a specified list.
  123. *
  124. * RETURNS: N/A
  125. */
  126. void lstAdd
  127.     (
  128.     LIST *pList,        /* pointer to list descriptor */
  129.     NODE *pNode         /* pointer to node to be added */
  130.     )
  131.     {
  132.     lstInsert (pList, pList->TAIL, pNode);
  133.     }
  134. /**************************************************************************
  135. *
  136. * lstConcat - concatenate two lists
  137. *
  138. * This routine concatenates the second list to the end of the first list.
  139. * The second list is left empty.  Either list (or both) can be
  140. * empty at the beginning of the operation.
  141. *
  142. * RETURNS: N/A
  143. */
  144. void lstConcat
  145.     (
  146.     FAST LIST *pDstList,        /* destination list */
  147.     FAST LIST *pAddList         /* list to be added to dstList */
  148.     )
  149.     {
  150.     if (pAddList->count == 0) /* nothing to do if AddList is empty */
  151. return;
  152.     if (pDstList->count == 0)
  153. *pDstList = *pAddList;
  154.     else
  155. {
  156. /* both lists non-empty; update DstList pointers */
  157. pDstList->TAIL->next     = pAddList->HEAD;
  158. pAddList->HEAD->previous = pDstList->TAIL;
  159. pDstList->TAIL           = pAddList->TAIL;
  160. pDstList->count += pAddList->count;
  161. }
  162.     /* make AddList empty */
  163.     lstInit (pAddList);
  164.     }
  165. /**************************************************************************
  166. *
  167. * lstCount - report the number of nodes in a list
  168. *
  169. * This routine returns the number of nodes in a specified list.
  170. *
  171. * RETURNS:
  172. * The number of nodes in the list.
  173. */
  174. int lstCount
  175.     (
  176.     LIST *pList         /* pointer to list descriptor */
  177.     )
  178.     {
  179.     return (pList->count);
  180.     }
  181. /**************************************************************************
  182. *
  183. * lstDelete - delete a specified node from a list
  184. *
  185. * This routine deletes a specified node from a specified list.
  186. *
  187. * RETURNS: N/A
  188. */
  189. void lstDelete
  190.     (
  191.     FAST LIST *pList,   /* pointer to list descriptor */
  192.     FAST NODE *pNode    /* pointer to node to be deleted */
  193.     )
  194.     {
  195.     if (pNode->previous == NULL)
  196. pList->HEAD = pNode->next;
  197.     else
  198. pNode->previous->next = pNode->next;
  199.     if (pNode->next == NULL)
  200. pList->TAIL = pNode->previous;
  201.     else
  202. pNode->next->previous = pNode->previous;
  203.     /* update node count */
  204.     pList->count--;
  205.     }
  206. /************************************************************************
  207. *
  208. * lstExtract - extract a sublist from a list
  209. *
  210. * This routine extracts the sublist that starts with <pStartNode> and ends
  211. * with <pEndNode> from a source list.  It places the extracted list in
  212. * <pDstList>.
  213. *
  214. * RETURNS: N/A
  215. */
  216. void lstExtract
  217.     (
  218.     FAST LIST *pSrcList,      /* pointer to source list */
  219.     FAST NODE *pStartNode,    /* first node in sublist to be extracted */
  220.     FAST NODE *pEndNode,      /* last node in sublist to be extracted */
  221.     FAST LIST *pDstList       /* ptr to list where to put extracted list */
  222.     )
  223.     {
  224.     FAST int i;
  225.     FAST NODE *pNode;
  226.     /* fix pointers in original list */
  227.     if (pStartNode->previous == NULL)
  228. pSrcList->HEAD = pEndNode->next;
  229.     else
  230. pStartNode->previous->next = pEndNode->next;
  231.     if (pEndNode->next == NULL)
  232. pSrcList->TAIL = pStartNode->previous;
  233.     else
  234. pEndNode->next->previous = pStartNode->previous;
  235.     /* fix pointers in extracted list */
  236.     pDstList->HEAD = pStartNode;
  237.     pDstList->TAIL = pEndNode;
  238.     pStartNode->previous = NULL;
  239.     pEndNode->next       = NULL;
  240.     /* count number of nodes in extracted list and update counts in lists */
  241.     i = 0;
  242.     for (pNode = pStartNode; pNode != NULL; pNode = pNode->next)
  243. i++;
  244.     pSrcList->count -= i;
  245.     pDstList->count = i;
  246.     }
  247. /************************************************************************
  248. *
  249. * lstFirst - find first node in list
  250. *
  251. * This routine finds the first node in a linked list.
  252. *
  253. * RETURNS
  254. * A pointer to the first node in a list, or
  255. * NULL if the list is empty.
  256. */
  257. NODE *lstFirst
  258.     (
  259.     LIST *pList         /* pointer to list descriptor */
  260.     )
  261.     {
  262.     return (pList->HEAD);
  263.     }
  264. /************************************************************************
  265. *
  266. * lstGet - delete and return the first node from a list
  267. *
  268. * This routine gets the first node from a specified list, deletes the node
  269. * from the list, and returns a pointer to the node gotten.
  270. *
  271. * RETURNS
  272. * A pointer to the node gotten, or
  273. * NULL if the list is empty.
  274. */
  275. NODE *lstGet
  276.     (
  277.     FAST LIST *pList    /* ptr to list from which to get node */
  278.     )
  279.     {
  280.     FAST NODE *pNode = pList->HEAD;
  281.     if (pNode != NULL)                      /* is list empty? */
  282. {
  283. pList->HEAD = pNode->next;          /* make next node be 1st */
  284. if (pNode->next == NULL)            /* is there any next node? */
  285.     pList->TAIL = NULL;             /*   no - list is empty */
  286. else
  287.     pNode->next->previous = NULL;   /*   yes - make it 1st node */
  288. pList->count--;                     /* update node count */
  289. }
  290.     return (pNode);
  291.     }
  292. /************************************************************************
  293. *
  294. * lstInsert - insert a node in a list after a specified node
  295. *
  296. * This routine inserts a specified node in a specified list.
  297. * The new node is placed following the list node <pPrev>.
  298. * If <pPrev> is NULL, the node is inserted at the head of the list.
  299. *
  300. * RETURNS: N/A
  301. */
  302. void lstInsert
  303.     (
  304.     FAST LIST *pList,   /* pointer to list descriptor */
  305.     FAST NODE *pPrev,   /* pointer to node after which to insert */
  306.     FAST NODE *pNode    /* pointer to node to be inserted */
  307.     )
  308.     {
  309.     FAST NODE *pNext;
  310.     if (pPrev == NULL)
  311. { /* new node is to be first in list */
  312. pNext = pList->HEAD;
  313. pList->HEAD = pNode;
  314. }
  315.     else
  316. { /* make prev node point fwd to new */
  317. pNext = pPrev->next;
  318. pPrev->next = pNode;
  319. }
  320.     if (pNext == NULL)
  321. pList->TAIL = pNode; /* new node is to be last in list */
  322.     else
  323. pNext->previous = pNode; /* make next node point back to new */
  324.     /* set pointers in new node, and update node count */
  325.     pNode->next = pNext;
  326.     pNode->previous = pPrev;
  327.     pList->count++;
  328.     }
  329. /************************************************************************
  330. *
  331. * lstLast - find the last node in a list
  332. *
  333. * This routine finds the last node in a list.
  334. *
  335. * RETURNS
  336. * A pointer to the last node in the list, or
  337. * NULL if the list is empty.
  338. */
  339. NODE *lstLast
  340.     (
  341.     LIST *pList         /* pointer to list descriptor */
  342.     )
  343.     {
  344.     return (pList->TAIL);
  345.     }
  346. /************************************************************************
  347. *
  348. * lstNext - find the next node in a list
  349. *
  350. * This routine locates the node immediately following a specified node.
  351. *
  352. * RETURNS:
  353. * A pointer to the next node in the list, or
  354. * NULL if there is no next node.
  355. */
  356. NODE *lstNext
  357.     (
  358.     NODE *pNode         /* ptr to node whose successor is to be found */
  359.     )
  360.     {
  361.     return (pNode->next);
  362.     }
  363. /************************************************************************
  364. *
  365. * lstNth - find the Nth node in a list
  366. *
  367. * This routine returns a pointer to the node specified by a number <nodenum>
  368. * where the first node in the list is numbered 1.
  369. * Note that the search is optimized by searching forward from the beginning
  370. * if the node is closer to the head, and searching back from the end
  371. * if it is closer to the tail.
  372. *
  373. * RETURNS:
  374. * A pointer to the Nth node, or
  375. * NULL if there is no Nth node.
  376. */
  377. NODE *lstNth
  378.     (
  379.     FAST LIST *pList,           /* pointer to list descriptor */
  380.     FAST int nodenum            /* number of node to be found */
  381.     )
  382.     {
  383.     FAST NODE *pNode;
  384.     /* verify node number is in list */
  385.     if ((nodenum < 1) || (nodenum > pList->count))
  386. return (NULL);
  387.     /* if nodenum is less than half way, look forward from beginning;
  388. otherwise look back from end */
  389.     if (nodenum < (pList->count >> 1))
  390. {
  391. pNode = pList->HEAD;
  392. while (--nodenum > 0)
  393.     pNode = pNode->next;
  394. }
  395.     else
  396. {
  397. nodenum -= pList->count;
  398. pNode = pList->TAIL;
  399. while (nodenum++ < 0)
  400.     pNode = pNode->previous;
  401. }
  402.     return (pNode);
  403.     }
  404. /************************************************************************
  405. *
  406. * lstPrevious - find the previous node in a list
  407. *
  408. * This routine locates the node immediately preceding the node pointed to 
  409. * by <pNode>.
  410. *
  411. * RETURNS:
  412. * A pointer to the previous node in the list, or
  413. * NULL if there is no previous node.
  414. */
  415. NODE *lstPrevious
  416.     (
  417.     NODE *pNode         /* ptr to node whose predecessor is to be found */
  418.     )
  419.     {
  420.     return (pNode->previous);
  421.     }
  422. /************************************************************************
  423. *
  424. * lstNStep - find a list node <nStep> steps away from a specified node
  425. *
  426. * This routine locates the node <nStep> steps away in either direction from 
  427. * a specified node.  If <nStep> is positive, it steps toward the tail.  If
  428. * <nStep> is negative, it steps toward the head.  If the number of steps is
  429. * out of range, NULL is returned.
  430. *
  431. * RETURNS:
  432. * A pointer to the node <nStep> steps away, or
  433. * NULL if the node is out of range.
  434. */
  435. NODE *lstNStep
  436.     (
  437.     FAST NODE *pNode,           /* the known node */
  438.     int nStep                   /* number of steps away to find */
  439.     )
  440.     {
  441.     int i;
  442.     for (i = 0; i < abs (nStep); i++)
  443. {
  444. if (nStep < 0)
  445.     pNode = pNode->previous;
  446. else if (nStep > 0)
  447.     pNode = pNode->next;
  448. if (pNode == NULL)
  449.     break;
  450. }
  451.     return (pNode);
  452.     }
  453. /************************************************************************
  454. *
  455. * lstFind - find a node in a list
  456. *
  457. * This routine returns the node number of a specified node (the 
  458. * first node is 1).
  459. *
  460. * RETURNS:
  461. * The node number, or
  462. * ERROR if the node is not found.
  463. */
  464. int lstFind
  465.     (
  466.     LIST *pList,                /* list in which to search */
  467.     FAST NODE *pNode            /* pointer to node to search for */
  468.     )
  469.     {
  470.     FAST NODE *pNextNode;
  471.     FAST int index = 1;
  472.     pNextNode = lstFirst (pList);
  473.     while ((pNextNode != NULL) && (pNextNode != pNode))
  474. {
  475. index++;
  476. pNextNode = lstNext (pNextNode);
  477. }
  478.     if (pNextNode == NULL)
  479. return (ERROR);
  480.     else
  481. return (index);
  482.     }
  483. /************************************************************************
  484. *
  485. * lstFree - free up a list
  486. *
  487. * This routine turns any list into an empty list.
  488. * It also frees up memory used for nodes.
  489. *
  490. * RETURNS: N/A
  491. *
  492. * SEE ALSO: free()
  493. */
  494. void lstFree
  495.     (
  496.     LIST *pList         /* list for which to free all nodes */
  497.     )
  498.     {
  499.     NODE *p1, *p2;
  500.     if (pList->count > 0)
  501. {
  502. p1 = pList->HEAD;
  503. while (p1 != NULL)
  504.     {
  505.     p2 = p1->next;
  506.     free ((char *)p1);
  507.     p1 = p2;
  508.     }
  509. pList->count = 0;
  510. pList->HEAD = pList->TAIL = NULL;
  511. }
  512.     }