home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / C_ALGORI.ZIP / C-SOURC@.EXE / MEMLIB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-12  |  46.4 KB  |  2,313 lines

  1. /******************************************************************************
  2. *+
  3. ** Module Name:   MEMLIB.C
  4. ** 
  5. ** Description:   Standard library routines for memory management using
  6. **                algorithms.
  7. **
  8. ** Libraries:  MEMLIB.LIB
  9. **
  10. ** Written by:  John Tal
  11. **
  12. **
  13. **
  14. ** Modification History:
  15. **
  16. ** Date          Programmer      Mod#     Modification
  17. ** ---------------------------------------------------------------------------
  18. ** 12-FEB-1991   J. Tal          V1.0-000 New
  19. **
  20. *-
  21. */
  22.  
  23.  
  24. #if C_ANSI
  25. #include <malloc.h>
  26. #include <memory.h>
  27. #include <stdlib.h>
  28. #endif
  29.  
  30. #include  <memlib.h>
  31.  
  32.  
  33.  
  34. /******************************************************************************
  35. *+
  36. ** Function Name:   MemHepDeque
  37. ** 
  38. ** Description:   Removes an entry from the heap
  39. **
  40. ** Return Codes:
  41. **               C_OK
  42. **
  43. ** Written by:  John Tal
  44. **
  45. **
  46. ** Modification History:
  47. **
  48. ** Date          Programmer      Mod#     Modification
  49. ** ---------------------------------------------------------------------------
  50. ** 12-FEB-1991   J. Tal          V1.0-000 New
  51. **
  52. *-
  53. */
  54.  
  55. #if C_ANSI
  56.  
  57. SHORT APIENTRY
  58. MemHepDeque(HEAP_P psHeap,PSHORT psPriority,PVOID * ppvData)
  59.  
  60. #else
  61.  
  62. SHORT APIENTRY
  63. MemHepDeque(psHeap,psPriority,ppvData)
  64. HEAP_P psHeap;
  65. PSHORT psPriority;
  66. PVOID * ppvData;
  67.  
  68. #endif
  69. {
  70.    if(psHeap -> sHeapBottom == C_HEAP_EMPTY)
  71.      return(C_NOTOK);
  72.  
  73.  
  74.    /*
  75.    **  Copy data in the top element structure to the passed pointers
  76.    */
  77.  
  78.    (*psPriority) = psHeap -> psHeapData[C_HEAP_TOP].sPriority;
  79.    (*ppvData)    = psHeap -> psHeapData[C_HEAP_TOP].pvData;  
  80.  
  81.  
  82.    /*
  83.    **  Move the bottom heap entry to the top
  84.    */
  85.  
  86.    memcpy(&psHeap -> psHeapData[C_HEAP_TOP],
  87.           &psHeap -> psHeapData[psHeap -> sHeapBottom],
  88.           sizeof(HEAP_DATA_T));
  89.  
  90.    /*
  91.    **  Zap/Erase old entry, may not be necessary
  92.    **
  93.    **  Check MemHepVacateHeap()
  94.    */
  95.  
  96.         memset(&psHeap -> psHeapData[psHeap -> sHeapBottom],
  97.                C_NOTHING,
  98.           sizeof(HEAP_DATA_T));
  99.  
  100.  
  101.    /*
  102.    **  Decrement the end of the heap
  103.    */
  104.         
  105.    psHeap -> sHeapBottom--;
  106.  
  107.  
  108.    /*
  109.    **  Adjust the heap by (potentially) moving this item down
  110.    */
  111.  
  112.    MemHepDown(psHeap, C_HEAP_TOP);
  113.  
  114.    return(C_OK);
  115.  
  116. }
  117.  
  118.  
  119. /******************************************************************************
  120. *+
  121. ** Function Name:   MemHepDown
  122. ** 
  123. ** Description:   Adjusts the heap after a deque
  124. **
  125. ** Return Codes:
  126. **               C_OK
  127. **
  128. ** Written by:  John Tal
  129. **
  130. **
  131. ** Modification History:
  132. **
  133. ** Date          Programmer      Mod#     Modification
  134. ** ---------------------------------------------------------------------------
  135. ** 12-FEB-1991   J. Tal          V1.0-000 New
  136. **
  137. *-
  138. */
  139.  
  140. #if C_ANSI
  141.  
  142. SHORT APIENTRY
  143. MemHepDown(HEAP_P psHeap, SHORT sRoot)
  144.  
  145. #else
  146.  
  147. SHORT APIENTRY
  148. MemHepDown(psHeap, sRoot)
  149. HEAP_P psHeap;
  150. SHORT sRoot;
  151.  
  152. #endif
  153. {
  154.  
  155.     BOOL   fHeapOk = C_FALSE;
  156.     SHORT  sRoot2;
  157.     SHORT  sMaxChild;
  158.  
  159.     sRoot2 = sRoot << 1;
  160.  
  161.     /*
  162.     **  Process until the root value is in its correct place
  163.     */
  164.  
  165.     while(
  166.           (sRoot2 <= psHeap -> sHeapBottom) && 
  167.           (!fHeapOk)
  168.          )
  169.     {
  170.  
  171.         /*
  172.         **  Calculate index of the child with the larger value
  173.         */
  174.  
  175.         if(sRoot2 == psHeap -> sHeapBottom)
  176.            sMaxChild = sRoot2;  /* only one child */
  177.         else
  178.         {
  179.           
  180.            /*
  181.            **  Select the greater of the 2 children
  182.            */
  183.  
  184.            if(psHeap -> psHeapData[sRoot2].sPriority >   /* left child */
  185.               psHeap -> psHeapData[sRoot2 + 1].sPriority)  /* right child */
  186.               sMaxChild = sRoot2;
  187.            else
  188.               sMaxChild = (sRoot2) + 1;
  189.  
  190.         }
  191.  
  192.  
  193.         /*
  194.         **  If heap property violated, swap values
  195.         */
  196.  
  197.         if(psHeap -> psHeapData[sRoot].sPriority <
  198.            psHeap -> psHeapData[sMaxChild].sPriority)
  199.         {
  200.            MemHepSwap(&psHeap -> psHeapData[sRoot],
  201.                       &psHeap -> psHeapData[sMaxChild]);
  202.  
  203.            sRoot = sMaxChild;
  204.            sRoot2 = sRoot << 1;
  205.  
  206.         }
  207.         else
  208.            fHeapOk = C_TRUE;
  209.     }
  210.  
  211.     return(C_OK);
  212.  
  213. }
  214.  
  215.  
  216. /******************************************************************************
  217. *+
  218. ** Function Name:   MemHepEnque
  219. ** 
  220. ** Description:   Queues an item to the heap (priority queue)
  221. **
  222. ** Return Codes:
  223. **               C_OK
  224. **               C_NOTOK         = Heap is full
  225. **
  226. ** Written by:  John Tal
  227. **
  228. **
  229. ** Modification History:
  230. **
  231. ** Date          Programmer      Mod#     Modification
  232. ** ---------------------------------------------------------------------------
  233. ** 06/12/90      J. Tal          V1.0-000 New
  234. **
  235. *-
  236. */
  237.  
  238. #if C_ANSI
  239.  
  240. SHORT APIENTRY
  241. MemHepEnque(HEAP_P psHeap,SHORT sPriority,PVOID pvData)
  242.  
  243. #else
  244.  
  245. SHORT APIENTRY
  246. MemHepEnque(psHeap,sPriority,pvData)
  247. HEAP_P psHeap;
  248. SHORT  sPriority;
  249. PVOID  pvData;
  250.  
  251. #endif
  252.  
  253. {
  254.    if(psHeap -> sHeapBottom > psHeap -> sMaxHeapElms)
  255.       return(C_NOTOK);
  256.  
  257.    /*
  258.    **  Take the next available slot in the end of the heap
  259.    */ 
  260.  
  261.    psHeap -> sHeapBottom++;     
  262.  
  263.  
  264.    /*
  265.    **  Move in the data to the heap member
  266.    */
  267.  
  268.    psHeap -> psHeapData[psHeap -> sHeapBottom].sPriority = sPriority;
  269.    psHeap -> psHeapData[psHeap -> sHeapBottom].pvData = pvData;
  270.  
  271.    /*
  272.    **  Adjust the heap by (potentially) moving this item up
  273.    */
  274.  
  275.    MemHepUp(psHeap);
  276.  
  277.    return(C_OK);
  278. }
  279.  
  280.  
  281. /******************************************************************************
  282. *+
  283. ** Function Name:   MemHepInit    
  284. ** 
  285. ** Description:   Creates a HEAP_T and initializes it
  286. **
  287. ** Return Codes:
  288. **               C_OK
  289. **
  290. ** Written by:  John Tal
  291. **
  292. ** Modification History:
  293. **
  294. ** Date          Programmer      Mod#     Modification
  295. ** ---------------------------------------------------------------------------
  296. ** 12-FEB-1991   J. Tal          V1.0-000 New
  297. **
  298. *-
  299. */
  300.  
  301. #if C_ANSI
  302.  
  303. SHORT APIENTRY
  304. MemHepInit(HEAP_PP ppsHeap, SHORT sNumElms)
  305.  
  306. #else
  307.  
  308. SHORT APIENTRY
  309. MemHepInit(ppsHeap, sNumElms)
  310. HEAP_PP  ppsHeap;
  311. SHORT    sNumElms;
  312.  
  313. #endif
  314.  
  315. {
  316.     /*
  317.     **  We are sent in the address of a pointer to HEAP_P type
  318.     **  calloc the heap structure
  319.     */
  320.  
  321.     (*ppsHeap) = (HEAP_P) calloc(1,sizeof(HEAP_T));
  322.  
  323.     /*
  324.     **  If got the memory, set the heap parms and alloc an array
  325.     **  of structures of type HEAP_DATA_T
  326.     */
  327.  
  328.     if((*ppsHeap) != NULL)
  329.     {
  330.        (*ppsHeap) -> sMaxHeapElms = sNumElms;
  331.        (*ppsHeap) -> sHeapBottom = C_HEAP_EMPTY;
  332.        (*ppsHeap) -> psHeapData = (HEAP_DATA_P) calloc(sNumElms,sizeof(HEAP_DATA_T));
  333.     }
  334.  
  335.          return(C_OK);
  336. }
  337.  
  338.  
  339. /******************************************************************************
  340. *+
  341. ** Function Name:   MemHepSearch
  342. ** 
  343. ** Description:   Searches a heap for an entry
  344. **
  345. ** Return Codes:
  346. **               C_OK
  347. **
  348. ** Written by:  John Tal
  349. **
  350. **
  351. ** Modification History:
  352. **
  353. ** Date          Programmer      Mod#     Modification
  354. ** ---------------------------------------------------------------------------
  355. ** 13-FEB-1991   J. Tal          V1.0-000 New
  356. **
  357. *-
  358. */
  359.  
  360. #if C_ANSI
  361.  
  362. SHORT APIENTRY
  363. MemHepSearch(HEAP_P psHeap,
  364.              PVOID pvData,
  365.              SHORT (*compare_func)(PVOID,PVOID), 
  366.              HEAP_DATA_PP ppsHeapData)
  367.  
  368. #else
  369.  
  370. SHORT APIENTRY
  371. MemHepSearch(psHeap,pvData,compare_func,ppsHeapData)
  372. HEAP_P  psHeap;
  373. PVOID   pvData;
  374. SHORT    (*compare_func)();
  375. HEAP_DATA_PP  ppsHeapData;
  376.  
  377. #endif
  378. {
  379.    SHORT  sCnt;
  380.    
  381.    (*ppsHeapData) = NULL;
  382.  
  383.    if(psHeap != NULL)
  384.    {
  385.       for(sCnt = C_HEAP_EMPTY + 1; sCnt <= psHeap -> sHeapBottom; sCnt++)
  386.       {
  387.          if(psHeap -> psHeapData[sCnt].pvData != NULL)
  388.          {
  389.              if( ((*compare_func)(psHeap -> psHeapData[sCnt].pvData,pvData)) == 0)
  390.                  (*ppsHeapData) = &psHeap -> psHeapData[sCnt];
  391.          }
  392.       }
  393.    }
  394.  
  395.    return(C_OK);
  396.  
  397. }
  398.  
  399.  
  400. /******************************************************************************
  401. *+
  402. ** Function Name:   MemHepSwap    
  403. ** 
  404. ** Description:   Swaps two HEAP_DATA_T elements
  405. **
  406. ** Return Codes:
  407. **               C_OK
  408. **
  409. ** Written by:  John Tal
  410. **
  411. **
  412. ** Modification History:
  413. **
  414. ** Date          Programmer      Mod#     Modification
  415. ** ---------------------------------------------------------------------------
  416. ** 12-feb-1991   J. Tal          V1.0-000 New
  417. **
  418. *-
  419. */
  420.  
  421.  
  422. #if C_ANSI
  423.  
  424. SHORT APIENTRY
  425. MemHepSwap(HEAP_DATA_P psHeap1,HEAP_DATA_P psHeap2)
  426.  
  427. #else
  428.  
  429. SHORT APIENTRY
  430. MemHepSwap(psHeap1,psHeap2)
  431. HEAP_DATA_P  psHeap1;
  432. HEAP_DATA_P  psHeap2;
  433.  
  434. #endif
  435.  
  436. {
  437.   HEAP_T  psHeapTemp;
  438.  
  439.   memcpy(&psHeapTemp,psHeap1,sizeof(HEAP_DATA_T));
  440.   memcpy(psHeap1,psHeap2,sizeof(HEAP_DATA_T));
  441.   memcpy(psHeap2,&psHeapTemp,sizeof(HEAP_DATA_T));
  442.  
  443.   return(C_OK);
  444.  
  445. }
  446.  
  447.  
  448. /******************************************************************************
  449. *+
  450. ** Function Name:   MemHepUp      
  451. ** 
  452. ** Description:   Adjusts a heap after an enque
  453. **
  454. ** Return Codes:
  455. **               C_OK
  456. **
  457. ** Written by:  John Tal
  458. **
  459. **
  460. ** Modification History:
  461. **
  462. ** Date          Programmer      Mod#     Modification
  463. ** ---------------------------------------------------------------------------
  464. ** 12-FEB-1991   J. Tal          V1.0-000 New
  465. **
  466. *-
  467. */
  468.  
  469.  
  470. #if C_ANSI
  471.  
  472. SHORT APIENTRY
  473. MemHepUp(HEAP_P psHeap)
  474.  
  475. #else
  476.  
  477. SHORT APIENTRY
  478. MemHepUp(psHeap)
  479. HEAP_P  psHeap;
  480.  
  481. #endif
  482.  
  483. {
  484.    SHORT  sCur;
  485.    SHORT  sParent;
  486.    SHORT  sHeapOk;
  487.  
  488.    sHeapOk = C_FALSE;
  489.    sCur = psHeap -> sHeapBottom;
  490.    sParent = sCur >> 1;
  491.  
  492.    
  493.    /*
  494.    **  move last element up in heap till in correct place
  495.    */
  496.  
  497.    while((sCur > (C_HEAP_EMPTY + 1)) && !sHeapOk)
  498.    {
  499.  
  500.       /*
  501.       **  compare current and parent
  502.       */
  503.  
  504.       if(psHeap -> psHeapData[sParent].sPriority >=
  505.          psHeap -> psHeapData[sCur].sPriority)
  506.       {
  507.          sHeapOk = C_TRUE;
  508.       }
  509.       else
  510.       {
  511.          MemHepSwap(&psHeap -> psHeapData[sParent],
  512.                     &psHeap -> psHeapData[sCur]);
  513.          sCur = sParent;
  514.          sParent = sParent >> 1;
  515.       }
  516.     }
  517.  
  518.     return(C_OK);
  519.  
  520. }
  521.  
  522.  
  523. /******************************************************************************
  524. *+
  525. ** Function Name:   MemHepVacateHeap
  526. ** 
  527. ** Description:   Vacates all data in a heap    
  528. **
  529. ** Return Codes:
  530. **               C_OK
  531. **
  532. ** Written by:  John Tal
  533. **
  534. **
  535. ** Modification History:
  536. **
  537. ** Date          Programmer      Mod#     Modification
  538. ** ---------------------------------------------------------------------------
  539. ** 12-FEB-1991   J. Tal          V1.0-000 New
  540. **
  541. *-
  542. */
  543.  
  544. #include  <memincs.h>
  545.  
  546.  
  547.  
  548. #if C_ANSI
  549.  
  550. SHORT APIENTRY
  551. MemHepVacateHeap(HEAP_PP ppsHeap,BOOL fFreeData)
  552.  
  553. #else
  554.  
  555. SHORT APIENTRY
  556. MemHepVacateHeap(ppsHeap,fFreeData)
  557. HEAP_PP  ppsHeap;
  558. BOOL     fFreeData;
  559.  
  560. #endif
  561.  
  562. {
  563.    HEAP_P  psHeap;
  564.    SHORT   sCnt;
  565.     
  566.    psHeap = (*ppsHeap);
  567.  
  568.    if(psHeap != NULL)
  569.    {
  570.       /*
  571.       **  If freeing data, check every [].pvData ptr and free()
  572.       */
  573.  
  574.       if(fFreeData)
  575.       {
  576.          for(sCnt = C_HEAP_EMPTY + 1; sCnt <= psHeap -> sHeapBottom; sCnt++)
  577.          {
  578.             if(psHeap -> psHeapData[sCnt].pvData != NULL)
  579.             {
  580.                free(psHeap -> psHeapData[sCnt].pvData);
  581.                psHeap -> psHeapData[sCnt].pvData = NULL;
  582.             }
  583.          }
  584.       }
  585.  
  586.  
  587.       /*
  588.       **  Free up the data for the array of heapdata structures  
  589.       */
  590.     
  591.       if(psHeap -> psHeapData != NULL)
  592.         free(psHeap -> psHeapData);
  593.       
  594.       free(psHeap);
  595.  
  596.       (*ppsHeap) = NULL;
  597.    }
  598.  
  599.    return(C_OK);
  600.  
  601.  
  602.  
  603. /******************************************************************************
  604. *+
  605. ** Function Name:   MemLstAddAfterMember
  606. ** 
  607. ** Description:   Adds a member after another given member in a list
  608. **
  609. ** Return Codes:
  610. **               C_OK
  611. **
  612. ** Written by:  John Tal
  613. **
  614. **
  615. ** Modification History:
  616. **
  617. ** Date          Programmer      Mod#     Modification
  618. ** ---------------------------------------------------------------------------
  619. ** 06/12/90      J. Tal          V1.0-000 New
  620. **
  621. *-
  622. */
  623.  
  624.  
  625. #if C_ANSI
  626.  
  627. SHORT APIENTRY
  628. MemLstAddAfterMember(LLIST_P psPrev,LLIST_P psNewMember)
  629.  
  630. #else
  631.  
  632. SHORT APIENTRY
  633. MemLstAddAfterMember(psPrev, psNewMember)
  634. LLIST_P  psPrev;
  635. LLIST_P  psNewMember;
  636.  
  637. #endif
  638.  
  639.  
  640. {
  641.      LLIST_P psTemp;
  642.  
  643.      psNewMember -> psNext = psPrev -> psNext;
  644.      psNewMember -> psPrev = psPrev;
  645.      psTemp = psPrev -> psNext;
  646.      psPrev -> psNext = psNewMember;
  647.      if(psTemp != NULL)
  648.         psTemp -> psPrev = psNewMember;
  649.  
  650.      return(C_OK);
  651. }
  652.  
  653.  
  654. /******************************************************************************
  655. *+
  656. ** Function Name:   MemLstAddBeforeMember
  657. ** 
  658. ** Description:   Adds a member before another given member in a list.
  659. **
  660. ** Return Codes:
  661. **               C_OK
  662. **
  663. ** Written by:  John Tal
  664. **
  665. **
  666. ** Modification History:
  667. **
  668. ** Date          Programmer      Mod#     Modification
  669. ** ---------------------------------------------------------------------------
  670. ** 06/12/90      J. Tal          V1.0-000 New
  671. **
  672. *-
  673. */
  674.  
  675. #if C_ANSI
  676.  
  677. SHORT APIENTRY
  678. MemLstAddBeforeMember(LLIST_P psListRoot,LLIST_P psPrev,LLIST_P psNewMember,LLIST_PP ppsRetMember)
  679.  
  680. #else
  681.  
  682. SHORT APIENTRY
  683. MemLstAddBeforeMember(psListRoot,psPrev,psNewMember,ppsRetMember)
  684. LLIST_P psListRoot;
  685. LLIST_P psPrev;
  686. LLIST_P psNewMember;
  687. LLIST_PP ppsRetMember;
  688.  
  689. #endif
  690.  
  691. {
  692.      LLIST_P psTemp;
  693.                                                                                  
  694.      if(psPrev == psListRoot)
  695.      {
  696.          psListRoot = psNewMember;
  697.          psPrev -> psPrev = psNewMember;
  698.          psNewMember -> psNext = psPrev;
  699.      } 
  700.      else
  701.      {
  702.         psTemp = psPrev -> psPrev;
  703.         psTemp -> psNext = psNewMember;
  704.         psPrev -> psPrev = psNewMember;
  705.         psNewMember -> psNext = psPrev;
  706.      }
  707.  
  708.      *ppsRetMember = psListRoot;
  709.  
  710.      return(C_OK);
  711. }
  712.  
  713.  
  714. /******************************************************************************
  715. *+
  716. ** Function Name:   MemLstAllocMember
  717. ** 
  718. ** Description:   Allocates memory for a new member.
  719. **                Initializes new member pointers.
  720. **
  721. ** Return Codes:
  722. **               C_OK
  723. **
  724. ** Written by:  John Tal
  725. **
  726. **
  727. ** Modification History:
  728. **
  729. ** Date          Programmer      Mod#     Modification
  730. ** ---------------------------------------------------------------------------
  731. ** 06/12/90      J. Tal          V1.0-000 New
  732. **
  733. *-
  734. */
  735.                                        
  736.  
  737. #if C_ANSI
  738.  
  739. SHORT APIENTRY
  740. MemLstAllocMember(LLIST_PP ppsRetMember)
  741.  
  742. #else
  743.  
  744. SHORT APIENTRY
  745. MemLstAllocMember(ppsRetMember)
  746. LLIST_PP ppsRetMember;
  747.  
  748. #endif
  749.  
  750.  
  751. {                                 
  752.    LLIST_P psItem;                      
  753.  
  754.    psItem = (LLIST_P) calloc(sizeof(LLIST_T),sizeof(BYTE));
  755.  
  756.    (*ppsRetMember) = psItem;
  757.  
  758.    if(psItem != NULL)
  759.       return(C_OK);
  760.    else
  761.       return(C_NOTOK);
  762.  
  763. }               
  764.  
  765.  
  766.  
  767. /******************************************************************************
  768. *+
  769. ** Function Name:   MemLstDeleteMember
  770. ** 
  771. ** Description:   Deletes a member from a list.  No search involved.
  772. **
  773. ** Return Codes:
  774. **               C_OK
  775. **
  776. ** Written by:  John Tal
  777. **
  778. **
  779. ** Modification History:
  780. **
  781. ** Date          Programmer      Mod#     Modification
  782. ** ---------------------------------------------------------------------------
  783. ** 06/12/90      J. Tal          V1.0-000 New
  784. **
  785. *-
  786. */
  787.  
  788.  
  789. #if C_ANSI
  790.  
  791. SHORT APIENTRY
  792. MemLstDeleteMember(LLIST_P psListRoot, LLIST_P psMember,LLIST_PP ppsRetMember)
  793.  
  794. #else
  795.  
  796. SHORT APIENTRY
  797. MemLstDeleteMember(psListRoot,psMember,ppsRetMember)
  798. LLIST_P psListRoot;    /* Root/head of list */
  799. LLIST_P psMember;      /* address of member to delete */
  800. LLIST_PP ppsRetMember; /* root/head on return */
  801.  
  802. #endif
  803.  
  804.  
  805.  
  806. {
  807.      LLIST_P psTemp;
  808.  
  809.      if(psMember == psListRoot)
  810.      {
  811.         psListRoot = psMember -> psNext;
  812.         if(psListRoot != NULL)
  813.            psListRoot -> psPrev = NULL;
  814.      }
  815.      else
  816.      {
  817.         psTemp = psMember -> psNext;
  818.         if(psTemp != NULL)
  819.            psTemp -> psPrev = psMember -> psPrev;
  820.         psTemp = psMember -> psPrev;
  821.         psTemp -> psNext = psMember -> psNext;
  822.      }
  823.  
  824.      free(psMember);
  825.  
  826.      (*ppsRetMember) = psListRoot;
  827.  
  828.      return(C_OK);
  829. }
  830.  
  831.  
  832. /******************************************************************************
  833. *+
  834. ** Function Name:   MemLstFindMember
  835. ** 
  836. ** Description:   Searches for a member in a list
  837. **
  838. ** Return Codes:
  839. **               C_OK
  840. **               (Check parameter on return, IF NULL = not in tree.
  841. **                Otherwise set to point to member)
  842. **
  843. ** Written by:  John Tal
  844. **
  845. **
  846. ** Modification History:
  847. **
  848. ** Date          Programmer      Mod#     Modification
  849. ** ---------------------------------------------------------------------------
  850. ** 06/12/90      J. Tal          V1.0-000 New
  851. **
  852. *-
  853. */
  854.  
  855.  
  856. #if C_ANSI
  857.  
  858. SHORT APIENTRY
  859. MemLstFindMember(LLIST_P psListRoot, 
  860.                   PVOID  pvData,
  861.                   SHORT (*compare_func)(PVOID,PVOID), 
  862.                   LLIST_PP ppsRetMember)
  863.  
  864. #else
  865.  
  866. SHORT APIENTRY
  867. MemLstFindMember(psListRoot,pvData,compare_func,ppsRetMember)
  868. LLIST_P psListRoot;     /*  root/head of list */
  869. PVOID   pvData;            /*  value you are searching for (could be PVOID) */  
  870. SHORT   (*compare_func)();  /* compare function you provide */
  871. LLIST_PP  ppsRetMember;  /*  root/head on return */
  872.  
  873. #endif
  874.  
  875. {
  876.     LLIST_P psList = NULL;
  877.     SHORT  sTemp;
  878.  
  879.     if(psListRoot != NULL)
  880.     {
  881.        psList = psListRoot;
  882.  
  883.        while ( (sTemp=((*compare_func)(pvData,psList -> pvData)) ) != 0)
  884.        {
  885.            psList = psList -> psNext;
  886.  
  887.            if(psList == NULL)
  888.                break;  
  889.        }
  890.  
  891.        if(psList != NULL)
  892.          if( ((*compare_func)(pvData,psList -> pvData)) != 0)
  893.               psList = NULL;
  894.  
  895.     }
  896.  
  897.     *ppsRetMember = psList;
  898.  
  899.     return(C_OK);
  900. }
  901.  
  902.  
  903.  
  904. /******************************************************************************
  905. *+
  906. ** Function Name:   MemLstFindTailMember
  907. ** 
  908. ** Description:   Finds the last member in a list.
  909. **
  910. ** Return Codes:
  911. **               C_OK
  912. **
  913. ** Written by:  John Tal
  914. **
  915. **
  916. ** Modification History:
  917. **
  918. ** Date          Programmer      Mod#     Modification
  919. ** ---------------------------------------------------------------------------
  920. ** 06/12/90      J. Tal          V1.0-000 New
  921. **
  922. *-
  923. */
  924.  
  925. #if C_ANSI
  926.  
  927. SHORT APIENTRY
  928. MemLstFindTailMember(LLIST_P psListRoot,LLIST_PP psRetMember)
  929.  
  930. #else
  931.  
  932. SHORT APIENTRY
  933. MemLstFindTailMember(psListRoot, psRetMember)
  934. LLIST_P  psListRoot;
  935. LLIST_PP psRetMember;
  936.  
  937. #endif
  938.  
  939.  
  940. {
  941.     LLIST_P psList = NULL;
  942.     LLIST_P psPrev = NULL;
  943.  
  944.     psList = psListRoot;
  945.  
  946.     while(psList != NULL)
  947.     {
  948.        psPrev = psList;
  949.        psList = psList -> psNext;
  950.     }
  951.  
  952.     psList = psPrev;
  953.  
  954.     *psRetMember = psList;
  955.  
  956.     return(C_OK);
  957. }
  958.  
  959.  
  960. /******************************************************************************
  961. *+
  962. ** Function Name:   MemLstInsertMember
  963. ** 
  964. ** Description:   Inserts a newly allocated member into a list.
  965. **                Uses the supplied compare function to determine
  966. **                where to place the entry in the list.
  967. **
  968. ** Return Codes:
  969. **               C_OK
  970. **
  971. ** Written by:  John Tal
  972. **
  973. **
  974. ** Modification History:
  975. **
  976. ** Date          Programmer      Mod#     Modification
  977. ** ---------------------------------------------------------------------------
  978. ** 06/12/90      J. Tal          V1.0-000 New
  979. **
  980. *-
  981. */
  982.  
  983. #if C_ANSI
  984.  
  985. SHORT APIENTRY
  986. MemLstInsertMember(LLIST_P psListRoot, LLIST_P psMember,SHORT (*compare_func)(PVOID,PVOID),LLIST_PP ppsRetMember)
  987.  
  988. #else
  989.  
  990. SHORT APIENTRY
  991. MemLstInsertMember(psListRoot,psMember,compare_func,ppsRetMember)
  992. LLIST_P  psListRoot;
  993. LLIST_P  psMember;
  994. SHORT    (*compare_func)();
  995. LLIST_PP ppsRetMember;
  996.  
  997. #endif
  998.  
  999. {
  1000.    LLIST_P psPrev = NULL;
  1001.    LLIST_P psList;
  1002.  
  1003.    if(psListRoot == NULL)
  1004.    {
  1005.       psListRoot = psMember;
  1006.       *ppsRetMember = psListRoot;
  1007.       return(C_OK);
  1008.    }
  1009.    else
  1010.    {
  1011.       psList = psListRoot;
  1012.  
  1013.       while( ((*compare_func)(psList -> pvData, psMember -> pvData)) < 0)
  1014.       {
  1015.            psPrev = psList;
  1016.          psList = psList -> psNext;
  1017.          if(psList == NULL)
  1018.             break;
  1019.       }
  1020.  
  1021.       if(psPrev == NULL)
  1022.          MemLstAddBeforeMember(psListRoot,psList,psMember,&psListRoot);
  1023.       else
  1024.          MemLstAddAfterMember(psPrev,psMember);  /* big change from binary, uses
  1025.                                          prev ptr found here */
  1026.  
  1027.       *ppsRetMember = psListRoot;
  1028.  
  1029.       return(C_OK);
  1030.  
  1031.    } /* if list != NULL */
  1032.  
  1033. }
  1034.  
  1035.  
  1036.  
  1037. /******************************************************************************
  1038. *+
  1039. ** Function Name:   MemLstUnlinkMember
  1040. ** 
  1041. ** Description:   Searches for a member in a list and unlinks 
  1042. **                that member from the list, does not free() pointer.
  1043. **
  1044. ** Return Codes:
  1045. **               C_OK
  1046. **
  1047. ** Written by:  John Tal
  1048. **
  1049. **
  1050. ** Modification History:
  1051. **
  1052. ** Date          Programmer      Mod#     Modification
  1053. ** ---------------------------------------------------------------------------
  1054. ** 06/12/90      J. Tal          V1.0-000 New
  1055. **
  1056. *-
  1057. */
  1058.  
  1059. #if C_ANSI
  1060.  
  1061. SHORT APIENTRY
  1062. MemLstUnlinkMember(LLIST_P psListRoot, LLIST_P psMember,LLIST_PP ppsRetMember)
  1063.  
  1064. #else
  1065.  
  1066. SHORT APIENTRY
  1067. MemLstUnlinkMember(psListRoot,psMember,ppsRetMember)
  1068. LLIST_P  psListRoot;
  1069. LLIST_P  psMember;
  1070. LLIST_PP ppsRetMember;
  1071.  
  1072. #endif
  1073.  
  1074.  
  1075. {
  1076.      LLIST_P psTemp;
  1077.  
  1078.      if(psMember == psListRoot)
  1079.      {
  1080.         psListRoot = psMember -> psNext;
  1081.         if(psListRoot != NULL)
  1082.            psListRoot -> psPrev = NULL;
  1083.      }
  1084.      else
  1085.      {
  1086.         psTemp = psMember -> psNext;
  1087.         if(psTemp != NULL)
  1088.            psTemp -> psPrev = psMember -> psPrev;
  1089.         psTemp = psMember -> psPrev;
  1090.         psTemp -> psNext = psMember -> psNext;
  1091.      }
  1092.  
  1093.      *ppsRetMember = psListRoot;
  1094.  
  1095.      return(C_OK);
  1096. }
  1097.  
  1098.  
  1099. /******************************************************************************
  1100. *+
  1101. ** Function Name:   MemLstVacateList
  1102. ** 
  1103. ** Description:   Removes all members from a list
  1104. **
  1105. ** Return Codes:
  1106. **               C_OK
  1107. **
  1108. ** Written by:  John Tal
  1109. **
  1110. **
  1111. ** Modification History:
  1112. **
  1113. ** Date          Programmer      Mod#     Modification
  1114. ** ---------------------------------------------------------------------------
  1115. ** 10-FEB-1991    J. Tal          V1.0-000 New
  1116. **
  1117. *-
  1118. */
  1119.  
  1120. #if C_ANSI
  1121.  
  1122. SHORT APIENTRY
  1123. MemLstVacateList(LLIST_PP ppsListRoot, BOOL fFreeData)
  1124.  
  1125. #else
  1126.  
  1127. SHORT APIENTRY
  1128. MemLstVacateList(ppsListRoot,fFreeData)
  1129. LLIST_PP ppsListRoot;
  1130. BOOL  fFreeData;
  1131.  
  1132. #endif
  1133. {
  1134.      LLIST_P psTemp;   /*  working pointer */
  1135.  
  1136.  
  1137.      psTemp = (*ppsListRoot);
  1138.  
  1139.      /*
  1140.      **  Spin through list from head to end
  1141.      */
  1142.  
  1143.      while(psTemp != NULL)
  1144.      {
  1145.         /*
  1146.         **  If free the data and data to free then free
  1147.         */
  1148.  
  1149.         if(fFreeData)
  1150.           if(psTemp -> pvData != NULL)
  1151.               free(psTemp -> pvData);
  1152.  
  1153.  
  1154.         /*
  1155.         **  Delete the member itself
  1156.         */
  1157.  
  1158.         MemLstDeleteMember(psTemp,psTemp,&psTemp);
  1159.      }
  1160.  
  1161.      /*
  1162.      **  Reset the pointer sent in, should be NULL now
  1163.      */
  1164.  
  1165.      (*ppsListRoot) = psTemp;
  1166.  
  1167.      return(C_OK);
  1168. }
  1169.  
  1170.  
  1171.  
  1172.  
  1173. /******************************************************************************
  1174. *+
  1175. ** Function Name:   MemQueDeqMember
  1176. ** 
  1177. ** Description:   Returns the pvData of the head member from the (FIFO) queue
  1178. **
  1179. ** Return Codes:
  1180. **               C_OK
  1181. **
  1182. ** Written by:  John Tal
  1183. **
  1184. **
  1185. ** Modification History:
  1186. **
  1187. ** Date          Programmer      Mod#     Modification
  1188. ** ---------------------------------------------------------------------------
  1189. ** 09-FEB-1991   J. Tal          V1.0-000 New
  1190. **
  1191. *-
  1192. */
  1193.  
  1194. #if C_ANSI
  1195.  
  1196. SHORT APIENTRY
  1197. MemQueDeqMember(LLIST_PP ppsListHead, LLIST_PP ppsListTail, PVOID * ppvData)
  1198.  
  1199. #else
  1200.  
  1201. SHORT APIENTRY
  1202. MemQueDeqMember(ppsListHead,ppsListTail, ppvData)
  1203. LLIST_PP ppsListHead;
  1204. LLIST_PP ppsListTail;
  1205. PVOID * ppvData;
  1206.  
  1207. #endif
  1208. {
  1209.      LLIST_P  psTempHead;
  1210.      LLIST_P  psTempTail;
  1211.  
  1212.  
  1213.      psTempHead = (*ppsListHead);
  1214.      psTempTail = (*ppsListTail);
  1215.  
  1216.      /*
  1217.      **  FIFO remove is simple, always take the head
  1218.      */
  1219.  
  1220.      if(psTempHead != NULL)
  1221.         (*ppvData) = psTempHead -> pvData;
  1222.  
  1223.      MemLstDeleteMember(psTempHead, psTempHead, ppsListHead);
  1224.  
  1225.      /*
  1226.      **  Check if deleted only member (head and tail)
  1227.      */
  1228.  
  1229.      if(psTempHead == psTempTail)
  1230.         (*ppsListTail) = NULL;
  1231.  
  1232.      return(C_OK);
  1233. }
  1234.  
  1235.  
  1236. /******************************************************************************
  1237. *+
  1238. ** Function Name:   MemQueEnqMember
  1239. ** 
  1240. ** Description:   Adds pvData to a member to the end of the (FIFO) queue
  1241. **                MemQue*** functions provide a generic FIFO queue
  1242. **                service.   
  1243. **
  1244. **                You send in the head and tail and the data.
  1245. **
  1246. **                A head, tail for a queue are implemented
  1247. **                via the MemLst*** functions and are compatible with
  1248. **                them should you want to use the MemLst*** functions
  1249. **                directly on the queue (use MemLstFindMember to
  1250. **                search the queue).
  1251. **
  1252. **                These Que functions were added by suggestion of
  1253. **                John Tomlinson and Pat Smith of Plant Automation Division.
  1254. **
  1255. **
  1256. ** Return Codes:
  1257. **               C_OK
  1258. **
  1259. ** Written by:  John Tal
  1260. **
  1261. **
  1262. ** Modification History:
  1263. **
  1264. ** Date          Programmer      Mod#     Modification
  1265. ** ---------------------------------------------------------------------------
  1266. ** 09-FEB-1991    J. Tal          V1.0-000 New
  1267. **
  1268. *-
  1269. */
  1270.  
  1271. #if C_ANSI
  1272.  
  1273. SHORT APIENTRY
  1274. MemQueEnqMember(LLIST_PP ppsListHead, LLIST_PP ppsListTail, PVOID pvData)
  1275.  
  1276. #else
  1277.  
  1278. SHORT APIENTRY
  1279. MemQueEnqMember(ppsListHead, ppsListTail, pvData)
  1280. LLIST_PP  ppsListHead;
  1281. LLIST_PP  ppsListTail;
  1282. PVOID     pvData;
  1283.  
  1284. #endif
  1285. {
  1286.      LLIST_P psTemp;
  1287.  
  1288.   
  1289.      /*
  1290.      **  Alloc a new member, caller is abstracted from this process
  1291.      **  of creating new queue internal members (LLIST_P)
  1292.      **
  1293.      **  NOTE:  psTemp is allocated off the stack but is not a 
  1294.      **         dangling pointer (cf C_ C Coding Guidelines)
  1295.      */
  1296.  
  1297.      MemLstAllocMember(&psTemp);
  1298.  
  1299.      if(psTemp == NULL)
  1300.         return(C_NOTOK);
  1301.  
  1302.      /*
  1303.      **  Point to the data we were sent
  1304.      */
  1305.  
  1306.      psTemp -> pvData = pvData;
  1307.  
  1308.      /*
  1309.      **  Connect to existing queue entries.
  1310.      **  If no entries, this is head and tail.
  1311.      **  If entries,  put after current tail and reset tail (head unaffected)
  1312.      */
  1313.  
  1314.      if((*ppsListHead) == NULL)
  1315.      {
  1316.         (*ppsListHead) = psTemp;
  1317.         (*ppsListTail) = psTemp;
  1318.      }
  1319.      else
  1320.      {
  1321.         MemLstAddAfterMember((*ppsListTail),psTemp);
  1322.         (*ppsListTail) = psTemp;
  1323.      }
  1324.           
  1325.      return(C_OK);
  1326. }
  1327.  
  1328.  
  1329.  
  1330. /******************************************************************************
  1331. *+
  1332. ** Function Name:   MemStkClearStack
  1333. ** 
  1334. ** Description:   LOGICALLY clears a stack.  See MemStkVacateStack.
  1335. **
  1336. **                Stacks are implemented here in link list using the 
  1337. **                MemLst routines.
  1338. **
  1339. **                Stacks are also known as LIFO (Last In First Out) Queues
  1340. **
  1341. **                Push a stack and that member is placed on top
  1342. **                Pop a stack and top member is returned and removed 
  1343. **
  1344. **
  1345. **  Top of Stack      StackMember  ->   Pointer to data to hold/remember
  1346. **                       |
  1347. **                       v
  1348. **                    StackMember  ->   Pointer to data to hold/remember
  1349. **                       |
  1350. **                       v
  1351. **  Bot of Stack      StackMember  ->   Pointer to data to hold/remember
  1352. **
  1353. **
  1354. **
  1355. **
  1356. ** Return Codes:
  1357. **               C_OK
  1358. **
  1359. ** Written by:  John Tal
  1360. **
  1361. **
  1362. ** Modification History:
  1363. **
  1364. ** Date          Programmer      Mod#     Modification
  1365. ** ---------------------------------------------------------------------------
  1366. ** 06/12/90      J. Tal          V1.0-000 New
  1367. **
  1368. *-
  1369. */
  1370.  
  1371. #if C_ANSI
  1372.  
  1373. SHORT APIENTRY
  1374. MemStkClearStack(LLIST_PP ppsLlistStack)
  1375.  
  1376. #else
  1377.  
  1378. SHORT APIENTRY
  1379. MemStkClearStack(ppsLlistStack)
  1380. LLIST_PP  ppsLlistStack;
  1381.  
  1382. #endif
  1383. {
  1384.    (*ppsLlistStack) = NULL;
  1385.  
  1386.    return(C_OK);
  1387. }
  1388.  
  1389.  
  1390. /******************************************************************************
  1391. *+
  1392. ** Function Name:   MemStkEmptyStack
  1393. ** 
  1394. ** Description:   Checks if a Stack is empty
  1395. **
  1396. ** Return Codes:
  1397. **               C_OK
  1398. **
  1399. ** Written by:  John Tal
  1400. **
  1401. **
  1402. ** Modification History:
  1403. **
  1404. ** Date          Programmer      Mod#     Modification
  1405. ** ---------------------------------------------------------------------------
  1406. ** 06/12/90      J. Tal          V1.0-000 New
  1407. **
  1408. *-
  1409. */
  1410.  
  1411. #if C_ANSI
  1412.  
  1413. SHORT APIENTRY
  1414. MemStkEmptyStack(LLIST_P psLlistStack, BOOL *fEmpty)
  1415.  
  1416. #else
  1417.  
  1418. SHORT APIENTRY
  1419. MemStkEmptyStack(psLlistStack,fEmpty)
  1420. LLIST_P  psLlistStack;
  1421. BOOL   * fEmpty;
  1422.  
  1423. #endif
  1424. {
  1425.    if(psLlistStack == NULL)
  1426.       *fEmpty = C_TRUE;
  1427.    else
  1428.       *fEmpty = C_FALSE;
  1429.   
  1430.  
  1431.    return(C_OK);
  1432. }
  1433.  
  1434.  
  1435.  
  1436. /******************************************************************************
  1437. *+
  1438. ** Function Name:   MemStkPop
  1439. ** 
  1440. ** Description:   Pops an element off the stack
  1441. **
  1442. ** Return Codes:
  1443. **               C_OK
  1444. **
  1445. ** Written by:  John Tal
  1446. **
  1447. **
  1448. ** Modification History:
  1449. **
  1450. ** Date          Programmer      Mod#     Modification
  1451. ** ---------------------------------------------------------------------------
  1452. ** 06/12/90      J. Tal          V1.0-000 New
  1453. **
  1454. *-
  1455. */
  1456.  
  1457. #if C_ANSI
  1458.  
  1459. SHORT APIENTRY
  1460. MemStkPop(LLIST_PP ppsLlistStackHead, PVOID *pvElementPointer)
  1461.  
  1462. #else
  1463.  
  1464. SHORT APIENTRY
  1465. MemStkPop(ppsLlistStackHead,pvElementPointer)
  1466. LLIST_PP  ppsLlistStackHead;
  1467. PVOID  *  pvElementPointer;
  1468.  
  1469. #endif
  1470. {
  1471.      LLIST_P  psLlistElement;
  1472.  
  1473.  
  1474.      if( (*ppsLlistStackHead) != NULL )
  1475.      {
  1476.          /*
  1477.          **  To modify a pointer inside of a function requires
  1478.          **  sending in the address of the pointer.
  1479.          */
  1480.  
  1481.          (*pvElementPointer) = (*ppsLlistStackHead) -> pvData;
  1482.  
  1483.          /*
  1484.          **   Reset to new stack head pointer
  1485.          */
  1486.  
  1487.          psLlistElement = (*ppsLlistStackHead) -> psNext;
  1488.  
  1489.          /*
  1490.          **    Free the old stack head pointer
  1491.          */
  1492.  
  1493.          free(*ppsLlistStackHead);   
  1494.  
  1495.          /*
  1496.          **   Reset the head to the new one for return
  1497.          */
  1498.  
  1499.          (*ppsLlistStackHead) = psLlistElement;
  1500.      }
  1501.      else
  1502.      {
  1503.          /*
  1504.          **   Stack is empty, return NULL
  1505.          */
  1506.  
  1507.         (*pvElementPointer) = NULL;
  1508.      }
  1509.  
  1510.      return(C_OK);
  1511. }
  1512.  
  1513.  
  1514. /******************************************************************************
  1515. *+
  1516. ** Function Name:   MemStkPush
  1517. ** 
  1518. ** Description:   Pushes an element onto the stack
  1519. **
  1520. ** Return Codes:
  1521. **               C_OK
  1522. **
  1523. ** Written by:  John Tal
  1524. **
  1525. **
  1526. ** Modification History:
  1527. **
  1528. ** Date          Programmer      Mod#     Modification
  1529. ** ---------------------------------------------------------------------------
  1530. ** 06/12/90      J. Tal          V1.0-000 New
  1531. **
  1532. *-
  1533. */
  1534.  
  1535. #if C_ANSI
  1536.  
  1537. SHORT APIENTRY
  1538. MemStkPush(LLIST_PP ppsLlistStackHead, PVOID pvElementPointer)
  1539.  
  1540. #else
  1541.  
  1542. SHORT APIENTRY
  1543. MemStkPush(ppsLlistStackHead,pvElementPointer)
  1544. LLIST_PP  ppsLlistStackHead;
  1545. PVOID     pvElementPointer;
  1546.  
  1547. #endif
  1548. {
  1549.      LLIST_P  psLlistStack;
  1550.  
  1551.  
  1552.      MemLstAllocMember(&psLlistStack);  /* allocate new member */
  1553.  
  1554.      if(psLlistStack == NULL)
  1555.         return(C_NOTOK);
  1556.  
  1557.      psLlistStack -> pvData = pvElementPointer;
  1558.  
  1559.      psLlistStack -> psNext = (*ppsLlistStackHead);
  1560.  
  1561.      (*ppsLlistStackHead) = psLlistStack;
  1562.  
  1563.      return(C_OK);
  1564. }
  1565.  
  1566.  
  1567. /******************************************************************************
  1568. *+
  1569. ** Function Name:   MemStkVacateStack
  1570. ** 
  1571. ** Description:   Actually clears a stack by popping all entries into 
  1572. **                the bit bucket.
  1573. **
  1574. ** Return Codes:
  1575. **               C_OK
  1576. **
  1577. ** Written by:  John Tal
  1578. **
  1579. **
  1580. ** Modification History:
  1581. **
  1582. ** Date          Programmer      Mod#     Modification
  1583. ** ---------------------------------------------------------------------------
  1584. ** 06/12/90      J. Tal          V1.0-000 New
  1585. **
  1586. *-
  1587. */
  1588.  
  1589. #if C_ANSI
  1590.  
  1591. SHORT APIENTRY
  1592. MemStkVacateStack(LLIST_PP ppsLlistStack, BOOL fFreeData)
  1593.  
  1594. #else
  1595.  
  1596. SHORT APIENTRY
  1597. MemStkVacateStack(ppsLlistStack,fFreeData)
  1598. LLIST_PP  ppsLlistStack;
  1599. BOOL  fFreeData;
  1600.  
  1601. #endif
  1602. {
  1603.    PVOID  pvData;
  1604.  
  1605.    while(*ppsLlistStack != NULL)
  1606.    {
  1607.       MemStkPop(ppsLlistStack,&pvData);
  1608.  
  1609.                 if(fFreeData)
  1610.          if(pvData != NULL)
  1611.             free(pvData);
  1612.    }
  1613.  
  1614.    (*ppsLlistStack) = NULL;
  1615.  
  1616.    return(C_OK);
  1617. }
  1618.  
  1619.  
  1620.  
  1621. /******************************************************************************
  1622. *+
  1623. ** Function Name:   MemTreAllocNode
  1624. ** 
  1625. ** Description:   Allocates memory for a new tree node.  
  1626. **                Initializes new node pointers.
  1627. **
  1628. ** Return Codes:
  1629. **               C_OK
  1630. **               C_NOTOK
  1631. **
  1632. ** Written by:  John Tal
  1633. **
  1634. **
  1635. ** Modification History:
  1636. **
  1637. ** Date          Programmer      Mod#     Modification
  1638. ** ---------------------------------------------------------------------------
  1639. ** 06/12/90      J. Tal          V1.0-000 New
  1640. **
  1641. *-
  1642. */
  1643.  
  1644. #if C_ANSI
  1645.  
  1646. SHORT APIENTRY
  1647. MemTreAllocNode(TNODE_PP ppsRetNode)
  1648.  
  1649. #else
  1650.  
  1651. SHORT APIENTRY
  1652. MemTreAllocNode(ppsRetNode)
  1653. TNODE_PP  ppsRetNode;
  1654.  
  1655. #endif
  1656. {                                 
  1657.    TNODE_P psItem;                      
  1658.  
  1659.    psItem = (TNODE_P) calloc(sizeof(TNODE_T),sizeof(BYTE));
  1660.  
  1661.    (*ppsRetNode) = psItem;
  1662.  
  1663.    if(psItem != NULL)
  1664.      return(C_OK);
  1665.         else
  1666.      return(C_NOTOK);
  1667.  
  1668. }               
  1669.  
  1670.  
  1671.  
  1672. /******************************************************************************
  1673. *+
  1674. ** Function Name:   MemTreDeletNode
  1675. ** 
  1676. ** Description:   Search for a node in a tree and deletes that node
  1677. **
  1678. ** External Functions:
  1679. **               MemTreLeaf
  1680. **               MemTreRotateNodeRight
  1681. **               MemTreRotateNodeLeft
  1682. **               MemTreDeleteNode (Recursive)               
  1683. **
  1684. ** Return Codes:
  1685. **               C_OK
  1686. **               C_NOTOK
  1687. **
  1688. ** Written by:  John Tal
  1689. **
  1690. **
  1691. ** Modification History:
  1692. **
  1693. ** Date          Programmer      Mod#     Modification
  1694. ** ---------------------------------------------------------------------------
  1695. ** 06/12/90      J. Tal          V1.0-000 New
  1696. **
  1697. *-
  1698. */
  1699. /***************************************************************************
  1700.  
  1701.       Function:  MemTreDeleteNode
  1702.  
  1703.    Description:  Searchs for a node in a tree and deletes that node
  1704.  
  1705.         Inputs:  Pointer to tree root
  1706.                  Char pointer of data value to search for.
  1707.                  Pointer to compare function for tree data type.
  1708.  
  1709.        Outputs:  Pointer to tree root.
  1710.        
  1711. ****************************************************************************/
  1712.  
  1713. #if C_ANSI
  1714.  
  1715. SHORT APIENTRY
  1716. MemTreDeleteNode(TNODE_P psTree,PVOID pvVal,SHORT (*compare_func)(PVOID,PVOID),TNODE_PP ppsRetNode)
  1717.  
  1718. #else
  1719.  
  1720. SHORT APIENTRY
  1721. MemTreDeleteNode(psTree,pvVal,compare_func,ppsRetNode)
  1722. TNODE_P  psTree;
  1723. PVOID    pvVal;
  1724. SHORT   (*compare_func)();
  1725. TNODE_PP ppsRetNode;
  1726.  
  1727. #endif
  1728. {        
  1729.  
  1730.     if(psTree == NULL)
  1731.     { 
  1732.        (*ppsRetNode) = NULL;
  1733.        return(C_NOTOK);
  1734.     }
  1735.  
  1736.     if( ((*compare_func)(pvVal,psTree -> pvData)) == 0)
  1737.     {
  1738.        if(MemTreLeaf(psTree))
  1739.        { 
  1740.           free(psTree);  /* new func - jt 03/09/89 */
  1741.           (*ppsRetNode) = NULL;
  1742.  
  1743.           return(C_OK);
  1744.        }
  1745.        else
  1746.        {      
  1747.           if(psTree -> psLeft != NULL)
  1748.           {
  1749.              MemTreRotateNodeRight(psTree,&psTree);
  1750.              MemTreDeleteNode(psTree,pvVal,compare_func,&psTree);
  1751.           }
  1752.           else
  1753.           {
  1754.              MemTreRotateNodeLeft(psTree,&psTree);
  1755.              MemTreDeleteNode(psTree,pvVal,compare_func,&psTree); 
  1756.           }
  1757.  
  1758.        }
  1759.     }
  1760.     else
  1761.     {
  1762.        if( ((*compare_func)(pvVal, psTree -> pvData)) < 0)
  1763.           MemTreDeleteNode(psTree -> psLeft,pvVal,compare_func,&psTree -> psLeft);
  1764.        else
  1765.           MemTreDeleteNode(psTree -> psRight,pvVal,compare_func,&psTree -> psRight);
  1766.     }
  1767.    
  1768.     (*ppsRetNode) = psTree;
  1769.  
  1770.     return(C_OK);
  1771. }
  1772.  
  1773.  
  1774. /******************************************************************************
  1775. *+
  1776. ** Function Name:   MemTreFindNode
  1777. ** 
  1778. ** Description:   Searches for a node in a tree.
  1779. **
  1780. ** Return Codes:
  1781. **               C_OK
  1782. **               (Check last parm, if NULL on return then did not find,
  1783. **                else is a pointer to the node found)
  1784. **
  1785. ** Written by:  John Tal
  1786. **
  1787. **
  1788. ** Modification History:
  1789. **
  1790. ** Date          Programmer      Mod#     Modification
  1791. ** ---------------------------------------------------------------------------
  1792. ** 06/12/90      J. Tal          V1.0-000 New
  1793. **
  1794. *-
  1795. */
  1796.  
  1797. #if C_ANSI
  1798.  
  1799. SHORT APIENTRY
  1800. MemTreFindNode(TNODE_P psTree,PVOID pvVal,SHORT (*compare_func)(PVOID,PVOID),TNODE_PP ppsRetNode)
  1801.  
  1802. #else
  1803.  
  1804. SHORT APIENTRY
  1805. MemTreFindNode(psTree,pvVal,compare_func,ppsRetNode)
  1806. TNODE_P  psTree;
  1807. PVOID    pvVal;
  1808. SHORT    (*compare_func)();
  1809. TNODE_PP ppsRetNode;
  1810.  
  1811. #endif
  1812. {
  1813.  
  1814.     SHORT  sCmp;
  1815.  
  1816.     if(psTree != NULL)
  1817.     {
  1818.        while (psTree != NULL)
  1819.        {
  1820.            sCmp = (*compare_func)(pvVal,psTree -> pvData);
  1821.  
  1822.            if(sCmp == 0)
  1823.               break;
  1824.            else if( sCmp > 0)
  1825.               psTree = psTree -> psRight;
  1826.            else
  1827.               psTree = psTree -> psLeft;
  1828.        }
  1829.     }
  1830.  
  1831.     (*ppsRetNode) = psTree;
  1832.  
  1833.     return(C_OK);
  1834. }
  1835.  
  1836.  
  1837. /******************************************************************************
  1838. *+
  1839. ** Function Name:   MemTreInsertNode
  1840. ** 
  1841. ** Description:   Inserts a newly allocated node into a tree.
  1842. **                This is a fairly-blind insert, duplicate keys 
  1843. **                are allowed (caution!)
  1844. **
  1845. ** External Functions:
  1846. **               MemTreInsertNode (Recursive)
  1847. **
  1848. ** Return Codes:
  1849. **               C_OK
  1850. **
  1851. ** Written by:  John Tal
  1852. **
  1853. **
  1854. ** Modification History:
  1855. **
  1856. ** Date          Programmer      Mod#     Modification
  1857. ** ---------------------------------------------------------------------------
  1858. ** 06/12/90      J. Tal          V1.0-000 New
  1859. **
  1860. *-
  1861. */
  1862.  
  1863. #if C_ANSI
  1864.  
  1865. SHORT APIENTRY
  1866. MemTreInsertNode(TNODE_P psTree,TNODE_P psNode,SHORT (*compare_func)(PVOID,PVOID),TNODE_PP ppsRetNode)
  1867.  
  1868. #else
  1869.  
  1870. SHORT APIENTRY
  1871. MemTreInsertNode(psTree,psNode,compare_func,ppsRetNode)
  1872. TNODE_P  psTree;
  1873. TNODE_P  psNode;
  1874. SHORT   (*compare_func)();
  1875. TNODE_PP  ppsRetNode;
  1876.  
  1877. #endif
  1878. {
  1879.  
  1880.    if(psTree == NULL)
  1881.    {
  1882.       psTree = psNode;
  1883.       (*ppsRetNode) = psTree;
  1884.  
  1885.       return(C_OK);
  1886.    }
  1887.    else
  1888.    {
  1889.       if( ((*compare_func)(psTree -> pvData, psNode -> pvData)) >= 0)
  1890.          MemTreInsertNode(psTree -> psLeft,psNode,compare_func,&psTree -> psLeft);
  1891.       else
  1892.          MemTreInsertNode(psTree -> psRight,psNode,compare_func,&psTree -> psRight);
  1893.  
  1894.       (*ppsRetNode) = psTree;
  1895.  
  1896.       return(C_OK);
  1897.  
  1898.    } /* if psTree != NULL */
  1899.  
  1900. }
  1901.  
  1902.  
  1903. /******************************************************************************
  1904. *+
  1905. ** Function Name:   MemTreLeaf
  1906. ** 
  1907. ** Description:   Determines if a node is a terminal leaf - no left or 
  1908. **                right children.
  1909. **
  1910. ** Return Codes:
  1911. **               C_TRUE
  1912. **               C_FALSE
  1913. **
  1914. ** Written by:  John Tal
  1915. **
  1916. **
  1917. ** Modification History:
  1918. **
  1919. ** Date          Programmer      Mod#     Modification
  1920. ** ---------------------------------------------------------------------------
  1921. ** 06/12/90      J. Tal          V1.0-000 New
  1922. **
  1923. *-
  1924. */
  1925.  
  1926. #if C_ANSI
  1927.  
  1928. SHORT APIENTRY
  1929. MemTreLeaf(TNODE_P psNode)
  1930.  
  1931. #else
  1932.  
  1933. SHORT APIENTRY
  1934. MemTreLeaf(psNode)
  1935. TNODE_P  psNode;
  1936.  
  1937. #endif
  1938. {
  1939.     if( (psNode -> psLeft == NULL) && (psNode -> psRight == NULL) )
  1940.          return(C_TRUE);
  1941.     else
  1942.          return(C_FALSE);
  1943. }
  1944.  
  1945.  
  1946. /******************************************************************************
  1947. *+
  1948. ** Function Name:   MemTreRotateNodeLeft
  1949. ** 
  1950. ** Description:   Performs a left rotate on a node
  1951. **
  1952. ** Return Codes:
  1953. **               C_OK
  1954. **
  1955. ** Written by:  John Tal
  1956. **
  1957. **
  1958. ** Modification History:
  1959. **
  1960. ** Date          Programmer      Mod#     Modification
  1961. ** ---------------------------------------------------------------------------
  1962. ** 06/12/90      J. Tal          V1.0-000 New
  1963. **
  1964. *-
  1965. */
  1966.  
  1967. #if C_ANSI
  1968.  
  1969. SHORT APIENTRY
  1970. MemTreRotateNodeLeft(TNODE_P psNode,TNODE_PP ppsRetNode)
  1971.  
  1972. #else
  1973.  
  1974. SHORT APIENTRY
  1975. MemTreRotateNodeLeft(psNode, ppsRetNode)
  1976. TNODE_P  psNode;
  1977. TNODE_PP ppsRetNode;
  1978.  
  1979. #endif
  1980. {                                       
  1981.    TNODE_P psTemp = psNode;
  1982.  
  1983.    if(psNode != NULL)
  1984.    {
  1985.       psNode = psNode -> psRight;
  1986.       psTemp -> psRight = psNode -> psLeft;
  1987.       psNode -> psLeft = psTemp;
  1988.    }
  1989.    (*ppsRetNode) = psNode;
  1990.  
  1991.    return(C_OK);
  1992. }
  1993.  
  1994.  
  1995. /******************************************************************************
  1996. *+
  1997. ** Function Name:   MemTreRotateNodeRight
  1998. ** 
  1999. ** Description:   Performs a right rotate on a node.
  2000. **
  2001. ** Return Codes:
  2002. **               C_OK
  2003. **
  2004. ** Written by:  John Tal
  2005. **
  2006. **
  2007. ** Modification History:
  2008. **
  2009. ** Date          Programmer      Mod#     Modification
  2010. ** ---------------------------------------------------------------------------
  2011. ** 06/12/90      J. Tal          V1.0-000 New
  2012. **
  2013. *-
  2014. */
  2015.  
  2016. #if C_ANSI
  2017.  
  2018. SHORT APIENTRY 
  2019. MemTreRotateNodeRight(TNODE_P psNode,TNODE_PP ppsRetNode)
  2020.  
  2021. #else
  2022.  
  2023. SHORT APIENTRY 
  2024. MemTreRotateNodeRight(psNode,ppsRetNode)
  2025. TNODE_P psNode;
  2026. TNODE_PP ppsRetNode;
  2027.  
  2028. #endif
  2029. {
  2030.    TNODE_P psTemp = psNode;
  2031.  
  2032.    if(psNode != NULL)
  2033.    {
  2034.       psNode = psNode -> psLeft;
  2035.       psTemp -> psLeft = psNode -> psRight;
  2036.       psNode -> psRight = psTemp;
  2037.    }
  2038.  
  2039.    (*ppsRetNode) = psNode;
  2040.  
  2041.    return(C_OK);
  2042. }  
  2043.  
  2044.  
  2045. /******************************************************************************
  2046. *+
  2047. ** Function Name:   MemTreVacateTree
  2048. ** 
  2049. ** Description:   Performs non-recursive removal of all a node and all its
  2050. **                children.  If used on the root of a tree, the entire
  2051. **                tree is removed.
  2052. **
  2053. **                Recursion is great, BUT, recursion relies heavily on
  2054. **                the stack.  Large amounts of recursion and stack pushing
  2055. **                will result in stack-overflow or core dump.
  2056. **
  2057. **                Dymnamic memory from heap (or system memory) is generally
  2058. **                more abundant than stack bytes.  So here we use the
  2059. **                MemStk***** routines which alloc from the heap.
  2060. **
  2061. **
  2062. ** Return Codes:
  2063. **               C_OK
  2064. **               C_NOTOK
  2065. **
  2066. ** Written by:  John Tal
  2067. **
  2068. **
  2069. ** Modification History:
  2070. **
  2071. ** Date          Programmer      Mod#     Modification
  2072. ** ---------------------------------------------------------------------------
  2073. ** 06/12/90      J. Tal          V1.0-000 New
  2074. **
  2075. *-
  2076. */
  2077.  
  2078. #if C_ANSI
  2079.  
  2080. SHORT APIENTRY
  2081. MemTreVacateTree(TNODE_PP ppsTree,BOOL fFreeData)
  2082.  
  2083. #else
  2084.  
  2085. SHORT APIENTRY
  2086. MemTreVacateTree(ppsTree,fFreeData)
  2087. TNODE_PP  ppsTree;    /* address of pointer to tree head (so we can set to NULL) */
  2088. BOOL     fFreeData;  /* if C_TRUE, then free  TNODE_P -> pvData  */
  2089.  
  2090. #endif
  2091. {
  2092.   TNODE_P  psTnode;  /*  main working TNODE_P var */
  2093.   BOOL     bEmpty;   /* whether stack is empty or not */
  2094.   LLIST_P  psStack;  /* working stack */
  2095.   TNODE_P  psDeleteNode;  /* working TNODE_P for delete */
  2096.   PVOID    pvWork;   /* hold area for TNODE_P after pop */
  2097.  
  2098.  
  2099.   psTnode = (*ppsTree);
  2100.  
  2101.   do
  2102.   {
  2103.      while( psTnode != NULL )
  2104.      {
  2105.         /*
  2106.         **  For non-recursive delete on a binary tree,
  2107.         **  follow left-size of tree and find left-most node.
  2108.         **  Drop a marker of the trail down by pushing addresses
  2109.         **  of the nodes as we go down.  Then we can pop them
  2110.         **  to go back up the tree.
  2111.         */
  2112.  
  2113.         MemStkPush(&psStack,(PVOID) psTnode);
  2114.         psTnode = psTnode -> psLeft;
  2115.  
  2116.      }
  2117.  
  2118.      MemStkEmptyStack(psStack,&bEmpty);
  2119.  
  2120.      if( !bEmpty )
  2121.      {
  2122.         /*
  2123.         **  As far left as we can go, we are currently at a NULL
  2124.         **  so pop off the last node (furthest left)
  2125.         */
  2126.  
  2127.         MemStkPop(&psStack,&pvWork);
  2128.  
  2129.         psTnode = (TNODE_P) pvWork;
  2130.  
  2131.         /*
  2132.         **  Got a node to delete, check if also free pvData;
  2133.         */
  2134.        
  2135.         if(fFreeData && (psTnode -> pvData != NULL))
  2136.         {
  2137.            free(psTnode -> pvData);
  2138.            psTnode -> pvData = NULL;
  2139.         }
  2140.  
  2141.         psDeleteNode = psTnode;
  2142.  
  2143.         /*
  2144.         **  Now try and go to the right.  We would then follow the
  2145.         **  same logic above by now falling down to the left-most
  2146.         **  node of our right sibling
  2147.         */
  2148.  
  2149.         psTnode = psTnode -> psRight;
  2150.  
  2151.         /*
  2152.         **  Free the node we were just at (left-most parent)
  2153.         */
  2154.  
  2155.         free(psDeleteNode);
  2156.  
  2157.      }
  2158.  
  2159.      MemStkEmptyStack(psStack,&bEmpty);
  2160.      
  2161.   } while ( (psTnode != NULL) && (! bEmpty) );
  2162.  
  2163.  
  2164.   /*
  2165.   **  Reset tree head pointer
  2166.   */
  2167.  
  2168.   (*ppsTree) = NULL;
  2169.  
  2170.   return(C_OK);
  2171.  
  2172. }
  2173.  
  2174.  
  2175.  
  2176.  
  2177.  
  2178.  
  2179.  
  2180.  
  2181.  
  2182.  
  2183.  
  2184.  
  2185.  
  2186.  
  2187.  
  2188. /******************************************************************************
  2189. *+
  2190. ** Function Name:   MemTreWalk
  2191. ** 
  2192. ** Description:   Performs recursive walk of tree
  2193. **
  2194. ** Return Codes:
  2195. **               C_OK
  2196. **               C_NOTOK
  2197. **
  2198. ** Written by:  John Tal
  2199. **
  2200. **
  2201. ** Modification History:
  2202. **
  2203. ** Date          Programmer      Mod#     Modification
  2204. ** ---------------------------------------------------------------------------
  2205. ** 05/06/92      J. Tal          V1.0-000 New
  2206. **
  2207. *-
  2208. */
  2209.  
  2210. #if C_ANSI
  2211.  
  2212. SHORT APIENTRY
  2213. MemTreWalk(TNODE_P psTnode, SHORT sOrder, SHORT (APIENTRY *AppFunc)(PVOID))
  2214.  
  2215. #else
  2216.  
  2217. SHORT APIENTRY
  2218. MemTreWalk(psTnode, sOrder, AppFunc)
  2219. TNODE_P psTnode;        /* address of pointer to tree head (so we can set to NULL) */
  2220. SHORT  sOrder;            /* traversal order */
  2221. SHORT (APIENTRY *AppFunc)();
  2222. #endif
  2223. {
  2224.  
  2225.     if(psTnode != NULL)
  2226.     {
  2227.       switch(sOrder)
  2228.         {
  2229.         case C_PRE_ORDER:
  2230.            (*AppFunc)(psTnode -> pvData);
  2231.            
  2232.            MemTreWalk(psTnode -> psLeft,sOrder,AppFunc);
  2233.  
  2234.            MemTreWalk(psTnode -> psRight,sOrder,AppFunc);
  2235.  
  2236.            break;
  2237.  
  2238.         case C_IN_ORDER:
  2239.            
  2240.            MemTreWalk(psTnode -> psLeft,sOrder,AppFunc);
  2241.  
  2242.            (*AppFunc)(psTnode -> pvData);
  2243.  
  2244.            MemTreWalk(psTnode -> psRight,sOrder,AppFunc);
  2245.  
  2246.            break;
  2247.  
  2248.         case C_POST_ORDER:
  2249.            
  2250.            MemTreWalk(psTnode -> psLeft,sOrder,AppFunc);
  2251.  
  2252.            MemTreWalk(psTnode -> psRight,sOrder,AppFunc);
  2253.  
  2254.            (*AppFunc)(psTnode -> pvData);
  2255.  
  2256.            break;
  2257.  
  2258.       }
  2259.     }
  2260.  
  2261.     return(C_OK);
  2262.  
  2263. }
  2264.  
  2265.  
  2266.  
  2267.  
  2268.  
  2269.  
  2270.  
  2271.  
  2272.  
  2273.  
  2274.  
  2275.  
  2276.  
  2277.  
  2278.  
  2279.  
  2280.  
  2281.  
  2282.  
  2283.  
  2284.  
  2285.  
  2286.  
  2287.  
  2288.  
  2289.  
  2290.  
  2291.  
  2292.  
  2293.  
  2294.  
  2295.  
  2296.  
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.  
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.  
  2309.  
  2310.  
  2311.  
  2312.