home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / flist.zip / list.c < prev    next >
C/C++ Source or Header  |  1996-09-10  |  10KB  |  367 lines

  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. List
  4.  
  5. Double-linked list functions
  6. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7. */
  8.  
  9. #define INCL_DOSSEMAPHORES
  10. #include <os2.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "list.h"
  14.  
  15. /*-------------------------------------------------------------------------
  16.                               LPListCreate
  17. --------------------------------------------------------------------------*/
  18. LPLIST * EXTFUNC LPListCreate( )
  19. {
  20.  LPLIST *list;
  21.  LPINFO *lpinfo;
  22.  
  23.    list = LPElemCreate( );
  24.  
  25.    if (list) {
  26.       lpinfo = ( LPINFO * )malloc( sizeof( LPINFO ) );
  27.       if (lpinfo == NULL) {
  28.          LPElemDestroy( list );
  29.          list = ( LPLIST * )NULL;
  30.       } else {
  31.          lpinfo->maxlines = ~0;
  32.          lpinfo->maxlen = ~0;
  33.          lpinfo->lines = lpinfo->mklines = 0;
  34.          lpinfo->lastmk = list;
  35.          list->data = lpinfo;
  36.          list->next = list->prev = list->nextmk = list;
  37.       }
  38.    }
  39.  
  40.    return list;
  41. }
  42. /*-------------------------------------------------------------------------
  43.                               LPListDestroy
  44. --------------------------------------------------------------------------*/
  45. BOOL EXTFUNC LPListDestroy( LPLIST *list )
  46. {
  47.    if (list == NULL)
  48.       return FALSE;
  49.  
  50.    LPListClear( list );
  51.    LPElemDestroy( list );
  52.  
  53.    return TRUE;
  54. }
  55. /*-------------------------------------------------------------------------
  56.                               LPListClear
  57. --------------------------------------------------------------------------*/
  58. BOOL EXTFUNC LPListClear( LPLIST *list )
  59. {
  60.  LPINFO *lpinfo;
  61.  LPELEM *elem, *nextelem;
  62.  
  63.    if (list == NULL)
  64.       return FALSE;
  65.  
  66.    elem = list->next;
  67.  
  68.    while (elem != list) {
  69.       nextelem = elem->next;
  70.       LPElemDestroy( elem );
  71.       elem = nextelem;
  72.    }
  73.  
  74.    lpinfo = ( LPINFO * )list->data;
  75.    lpinfo->lines = lpinfo->mklines = 0;
  76.    lpinfo->lastmk = list;
  77.    list->next = list->prev = list->nextmk = list;
  78.  
  79.    return TRUE;
  80. }
  81. /*-------------------------------------------------------------------------
  82.                            LPListClearMarked
  83. --------------------------------------------------------------------------*/
  84. BOOL EXTFUNC LPListClearMarked( LPLIST *list )
  85. {
  86.  LPELEM *elem, *nextelem;
  87.  
  88.    if (list == NULL)
  89.       return FALSE;
  90.  
  91.    elem = list->nextmk;
  92.  
  93.    while (elem != list) {
  94.       nextelem = elem->nextmk;
  95.       LPElemDelete( list, elem );
  96.       elem = nextelem;
  97.    }
  98.  
  99.    return TRUE;
  100. }
  101. /*-------------------------------------------------------------------------
  102.                               LPElemCreate
  103. --------------------------------------------------------------------------*/
  104. LPELEM * EXTFUNC LPElemCreate( void )
  105. {
  106.  LPELEM *elem;
  107.  
  108.    elem = ( LPELEM * )malloc( sizeof( LPELEM ) );
  109.    if (elem) {
  110.       elem->data = ( char * )NULL;
  111.       elem->next = elem->prev = elem->nextmk = ( LPELEM * )NULL;
  112.       elem->userdata = 0L;
  113.    }
  114.  
  115.    return elem;
  116. }
  117. /*-------------------------------------------------------------------------
  118.                               LPElemDestroy
  119. --------------------------------------------------------------------------*/
  120. BOOL EXTFUNC LPElemDestroy( LPELEM *elem )
  121. {
  122.    if (elem == NULL)
  123.       return FALSE;
  124.  
  125.    if (elem->data)
  126.       free( elem->data );
  127.  
  128.    free( elem );
  129.  
  130.    return TRUE;
  131. }
  132. /*-------------------------------------------------------------------------
  133.                               LPElemAppend
  134. --------------------------------------------------------------------------*/
  135. BOOL EXTFUNC LPElemAppend( LPLIST *list, LPELEM *elem )
  136. {
  137.    LPElemInsert( list, list->prev, elem );
  138.  
  139.    return TRUE;
  140. }
  141. /*-------------------------------------------------------------------------
  142.                               LPElemInsert
  143. --------------------------------------------------------------------------*/
  144. BOOL EXTFUNC LPElemInsert( LPLIST *list, LPELEM *afterelem, LPELEM *elem )
  145. {
  146.  LPINFO *lpinfo;
  147.  
  148.    if (afterelem == NULL || elem == NULL || list == NULL)
  149.       return FALSE;
  150.  
  151.    lpinfo = ( LPINFO * )list->data;
  152.    if (lpinfo == NULL)
  153.       return FALSE;
  154.  
  155.    if (lpinfo->lines == lpinfo->maxlines)
  156.       LPElemDelete( list, list->next );
  157.  
  158.    elem->prev = afterelem;
  159.    elem->next = afterelem->next;
  160.    elem->next->prev = elem;
  161.    afterelem->next = elem;
  162.    ++lpinfo->lines;
  163.  
  164.    return TRUE;
  165. }
  166. /*-------------------------------------------------------------------------
  167.                               LPElemDelete
  168. --------------------------------------------------------------------------*/
  169. BOOL EXTFUNC LPElemDelete( LPLIST *list, LPELEM *elem )
  170. {
  171.    if (LPElemRemove( list, elem ) == FALSE)
  172.       return FALSE;
  173.  
  174.    if (elem->nextmk)
  175.       if (LPElemUnmark( list, elem ) == FALSE)
  176.          return FALSE;
  177.  
  178.    LPElemDestroy( elem );
  179.  
  180.    return TRUE;
  181. }
  182. /*-------------------------------------------------------------------------
  183.                               LPElemRemove
  184. --------------------------------------------------------------------------*/
  185. BOOL EXTFUNC LPElemRemove( LPLIST *list, LPELEM *elem )
  186. {
  187.  LPINFO *lpinfo;
  188.  
  189.    if (list == NULL || elem == NULL || elem == list)
  190.       return FALSE;
  191.  
  192.    lpinfo = ( LPINFO * )list->data;
  193.    if (lpinfo == NULL)
  194.       return FALSE;
  195.  
  196.    if (lpinfo->lines == 0)
  197.       return FALSE;
  198.  
  199.    if (elem->prev)
  200.       elem->prev->next = elem->next;
  201.  
  202.    if (elem->next)
  203.       elem->next->prev = elem->prev;
  204.  
  205.    --lpinfo->lines;
  206.  
  207.    return TRUE;
  208. }
  209.  
  210. /*-------------------------------------------------------------------------
  211.                               LPElemSetData
  212. --------------------------------------------------------------------------*/
  213. BOOL EXTFUNC LPElemSetData( LPLIST *list, LPELEM *elem,
  214.                             char *data, USHORT len )
  215. {
  216.  LPINFO  *lpinfo;
  217.  char    *dest;
  218.  
  219.   if (  list == NULL || list->data == NULL || elem == NULL
  220.      || data == NULL || elem == list)
  221.       return FALSE;
  222.  
  223.   lpinfo = list->data;
  224.  
  225.   if (elem->data != NULL)
  226.      free( elem->data );
  227.  
  228.   len = min( len, lpinfo->maxlen );
  229.  
  230.   elem->data = malloc( ( size_t )len + 1 );
  231.   dest = elem->data;
  232.   if (dest != NULL) {
  233.      memcpy( dest, data, len );
  234.      *( dest + len ) = '\0';
  235.   }
  236.  
  237.   if (dest == NULL)
  238.      return FALSE;
  239.  
  240.   return TRUE;
  241. }
  242. /*-------------------------------------------------------------------------
  243.                               LPElemExchange
  244. Retains position in mark list, not just value swapping.
  245. --------------------------------------------------------------------------*/
  246. BOOL EXTFUNC LPElemExchange( LPLIST *list, LPELEM *elem1, LPELEM *elem2 )
  247. {
  248.  LPELEM *tmp;
  249.  
  250.   if (list == NULL || elem1 == NULL || elem2 == NULL)
  251.      return FALSE;
  252.  
  253.   tmp = elem2->prev;
  254.  
  255.   LPElemRemove( list, elem2 );
  256.   LPElemInsert( list, elem1->prev, elem2 );
  257.  
  258.   if (tmp != elem1) {
  259.      LPElemRemove( list, elem1 );
  260.      LPElemInsert( list, tmp, elem1 );
  261.   }
  262.  
  263.   return TRUE;
  264. }
  265. /*-------------------------------------------------------------------------
  266.                               LPElemTrack
  267. --------------------------------------------------------------------------*/
  268. LPELEM * EXTFUNC LPElemTrack( LPLIST *list, LPELEM *elem, int delta )
  269. {
  270.  LPINFO *lpinfo;
  271.  int direction;
  272.  
  273.    if (elem == NULL || list == NULL)
  274.       return ( LPELEM * )NULL;
  275.  
  276.    direction = ( delta < 0 ) ? 1 : -1;
  277.  
  278.    lpinfo = ( LPINFO * )list->data;
  279.    if (abs( delta ) > lpinfo->lines)
  280.       return list;
  281.  
  282.    while (delta != 0) {
  283.       elem = ( direction == 1 ) ? elem->prev : elem->next;
  284.       delta += direction;
  285.       if (elem == list)
  286.          break;
  287.    }
  288.  
  289.    return elem;
  290. }
  291. /*-------------------------------------------------------------------------
  292.                               LPElemRotate
  293. --------------------------------------------------------------------------*/
  294. LPELEM * EXTFUNC LPElemRotate( LPLIST *list, LPELEM *elem, int delta )
  295. {
  296.  LPINFO *lpinfo;
  297.  int direction;
  298.  
  299.    if (elem == NULL && list == NULL)
  300.       return ( LPELEM * )NULL;
  301.  
  302.    direction = ( delta < 0 ) ? 1 : -1;
  303.  
  304.    lpinfo = ( LPINFO * )list->data;
  305.  
  306.    if (delta > lpinfo->lines && lpinfo->lines != 0)
  307.       delta %= lpinfo->lines;
  308.  
  309.    if (abs( delta ) > ( lpinfo->lines / 2 + 1 )) {
  310.       delta += lpinfo->lines * direction;
  311.       direction = -direction;
  312.    }
  313.  
  314.    while (delta != 0) {
  315.       elem = ( direction == 1 ) ? elem->prev : elem->next;
  316.       if (elem != list)
  317.          delta += direction;
  318.    }
  319.  
  320.    return elem;
  321. }
  322. /*-------------------------------------------------------------------------
  323.                               LPElemMark
  324. --------------------------------------------------------------------------*/
  325. BOOL EXTFUNC LPElemMark( LPLIST *list, LPELEM *elem )
  326. {
  327.  LPINFO *lpinfo;
  328.  
  329.    if (list == NULL || elem == NULL || elem == list || elem->nextmk)
  330.       return FALSE;
  331.  
  332.    lpinfo = list->data;
  333.    lpinfo->lastmk->nextmk = elem;
  334.    lpinfo->lastmk = elem;
  335.    elem->nextmk = list;
  336.    lpinfo->mklines++;
  337.  
  338.    return TRUE;
  339. }
  340. /*-------------------------------------------------------------------------
  341.                              LPElemUnmark
  342. --------------------------------------------------------------------------*/
  343. BOOL EXTFUNC LPElemUnmark( LPLIST *list, LPELEM *elem )
  344. {
  345.  LPINFO *lpinfo;
  346.  LPELEM *xelem;
  347.  
  348.    if (list == NULL || elem == NULL || elem->nextmk == NULL || elem == list)
  349.       return FALSE;
  350.  
  351.    lpinfo = list->data;
  352.    xelem = list;
  353.    while (xelem->nextmk != list) {
  354.       if (xelem->nextmk == elem) {
  355.          xelem->nextmk = elem->nextmk;
  356.          elem->nextmk = ( LPELEM * )NULL;
  357.          if (elem == lpinfo->lastmk)
  358.             lpinfo->lastmk = xelem;
  359.          lpinfo->mklines--;
  360.          return TRUE;
  361.       }
  362.       xelem = xelem->nextmk;
  363.    }
  364.  
  365.    return FALSE;
  366. }
  367.