home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 308_01 / list.doc < prev    next >
Text File  |  1990-06-17  |  21KB  |  847 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6. /*
  7.     HEADER:        CUG308;
  8.     TITLE:        documentation for generic linked list module;
  9.     DATE:        5/6/90;
  10.     VERSION:    2.01;
  11.     FILENAME:    LIST.DOC;
  12.     SEE-ALSO:    LIST.H, LIST.C;
  13.     AUTHOR:     Michael Kelly
  14.             254 Gold Street, Boston Ma. 02127;
  15.     COPYRIGHT:    May be used freely if authorship is acknowledged;
  16.  
  17. */
  18.  
  19.  
  20.                   - 2 -
  21.  
  22.                ***    CONTENTS  ***
  23.  
  24.     OVERVIEW    ---------------------------------    PAGE 3
  25.  
  26.     WARNINGS    ---------------------------------    PAGE 3
  27.  
  28.     REQUIREMENTS    -------------------------    PAGE 3
  29.  
  30.     COMMENTS    ---------------------------------    PAGE 4
  31.  
  32.     NOTE        ---------------------------------    PAGE 4
  33.  
  34.     EXAMPLE DECLARATION    ---------------------    PAGE 5
  35.  
  36.     EXTERNAL LIST FUNCTION PROTOTYPES   ------    PAGE 5
  37.  
  38.     EXTERNAL LIST FUNCTION DESCRIPTIONS ------    PAGE 6 to PAGE 8
  39.  
  40.     LIST MEMBER FUNCTION CALLS  -----------------    PAGE 9
  41.  
  42.     LIST MEMBER FUNCTION PROTOTYPES ----------    PAGE 9
  43.  
  44.     LIST MEMBER FUNCTION DESCRIPTIONS   ------    PAGE 10 to PAGE 25
  45.  
  46.  
  47.                   - 3 -
  48.  
  49.  
  50.                ***    OVERVIEW  ***
  51.  
  52.      The List module provides generic doubly linked list management
  53. functions that can operate on data blocks of non-uniform size.    The List
  54. routines are accessed through List structure member function pointers to
  55. allow changes in the implementation while minimizing client module
  56. source changes.
  57.  
  58.      Two external functions are also provided, initlist(), to initialize
  59. a List variable, and compact_list_table(), to free unused list table
  60. memory and move the remaining table entries to contiguous slots.  The
  61. latter is provided for applications that may use a large number of lists
  62. initially, and delete most of them during program execution.
  63.  
  64.      One example that comes to mind would be a "merge sort" with each
  65. list containing a sorted "run".  If this were developed on say, an MsDos
  66. machine, using a version of the List code modified to include a
  67. disk-swapping scheme, it may be possible to simply recompile the
  68. application with the unmodified List code on a system that supports
  69. virtual memory.
  70.  
  71.                ***    WARNINGS  ***
  72.  
  73.      The function listsfree() has been removed.  See COMMENTS.
  74.  
  75.      An integer member variable, "id" was added to the List structure.
  76. See COMMENTS.  See LIST.H.
  77.  
  78.      The enumeration definition for the Lerror (List error indicator)
  79. variable has been updated.  See LIST.H.
  80.  
  81.              ***  REQUIREMENTS  ***
  82.  
  83.      Code written for prior versions will require minor modifications to
  84. work with Version 2.0.    See COMMENTS.
  85.  
  86.      You MUST initialize your program List variables with the initlist()
  87. function before calling any member List functions or a hung program will
  88. be the most likely result.
  89.  
  90.      If you have a problem, it may concern your C compiler, see
  91. "requirements" note in LIST.C concerning dereferencing of function
  92. pointers.
  93.  
  94.  
  95.                   - 4 -
  96.  
  97.  
  98.                ***    COMMENTS  ***
  99.  
  100.      In Versions prior to 2.0, static list tables were used, limiting
  101. the number of available lists, no matter how much memory was available
  102. in the system.    Since the number of possible active lists is no longer
  103. static, the function listsfree() has been removed.
  104.  
  105.      Also, intermediary functions were used to pass a hidden list
  106. pointer to the function that actually operated on the list.  This was
  107. done as a kind of experiment in simulating the C++ "this" pointer.
  108.  
  109.      Version 2.0 uses a dynamically allocated array of list pointers to
  110. make better use of system memory.  An integer member variable, "id" was
  111. added to the List structure.  This variable is set in the initlist()
  112. function and must be passed as the first parameter in list member
  113. function calls.  In Version 2.0 this "id" is used as an index into the
  114. List table but it could also be used as a "handle" to implement a
  115. disk-swapping scheme on systems without virtual memory.
  116.  
  117.      Although this approach is not as much fun as the kludge in prior
  118. versions (the "include" files have been eliminated), the code is now
  119. smaller, faster and more flexible.  Some global search and replace
  120. should be able to update old client code.
  121.  
  122.  
  123.                  ***  NOTE    ***
  124.  
  125.      The destroy() member function in Versions prior to 2.0 set the List
  126. structure variable to all zeros.  If the program subsequently made a
  127. call through a destroyed List, it would use a NULL function pointer to
  128. unhappy results.  In Version 2.0, after freeing the memory owned by the
  129. List, the List member variable "id" is set to -1 and the function
  130. pointers left intact.  When List member functions are called they check
  131. the List id, and if it is not valid, set "lerror" and return 0 or NULL.
  132. This makes the module more robust, reducing system "lockup" during
  133. debugging in unprotected environments.
  134.  
  135.  
  136.                   - 5 -
  137.  
  138.              ***  EXAMPLE DECLARATION  ***
  139.  
  140.     #include "list.h"
  141.  
  142.     List *mylist1, mylist2;
  143.  
  144.  
  145.           ***  EXTERNAL LIST FUNCTION PROTOTYPES  ***
  146.  
  147.  
  148.      extern int initlist(List *newlist, int (*cmpfunc)());
  149.      extern int compact_list_table(void);
  150.  
  151.  
  152.  
  153.                   - 6 -
  154.  
  155.          ***  EXTERNAL LIST FUNCTION DESCRIPTIONS  ***
  156.  
  157.      extern int initlist(List *newlist, int (*cmpfunc)());
  158.  
  159.     ACTION:
  160.         Initializes the List member variables and functions.
  161.         Stores the address of the List variable.
  162.  
  163.     RETURNS:
  164.         1 on success
  165.  
  166.         0 on failure and sets lerror to an error code (see list.h)
  167.  
  168.     ARGUMENTS:
  169.         newlist is a pointer to a variable of type List
  170.  
  171.         cmpfunc is a pointer to a function to compare two List items
  172.         that returns a signed integer that is:
  173.  
  174.                 == 0 if item1 == item2
  175.                  < 0 if item1 <  item2
  176.                  > 0 if item1 >  item2
  177.  
  178.     WARNINGS:
  179.         A List variable MUST be initialized with this function
  180.         before any member functions for that List are called.
  181.  
  182.              (    see example on next page )
  183.  
  184.  
  185.                   - 7 -
  186.  
  187.          ***  EXTERNAL LIST FUNCTION DESCRIPTIONS  ***
  188.  
  189.               ***  initlist() EXAMPLE  ***
  190.  
  191.         #include <stdio.h>
  192.         #include <string.h>
  193.         #include "list.h"
  194.  
  195.         List *mylist1, mylist2;
  196.  
  197.         char list_ptr_use[] = "using List pointer variable";
  198.         char list_var_use[] = "using List variable";
  199.  
  200.         main()
  201.         {
  202.             int status;
  203.  
  204.             mylist1 = (List *) malloc(sizeof(List));
  205.             if(! mylist1)  {
  206.             printf("\nmalloc() Failure!\n");
  207.             exit(EXIT_FAILURE);
  208.             }
  209.  
  210.             if(! initlist(mylist1, strcmp))  {
  211.             printf("\nInitialization failed\n");
  212.             exit(EXIT_FAILURE);
  213.             }
  214.  
  215.             /*
  216.              *    need "&" to point to static List structure
  217.              */
  218.             if(! initlist(&mylist2, strcmp))  {
  219.             printf("\nInitialization failed\n");
  220.             exit(EXIT_FAILURE);
  221.             }
  222.  
  223.             status = mylist1->add(mylist1->id, list_ptr_use,
  224.                 strlen(list_ptr_use) + 1, CURRENT);
  225.  
  226.             status += mylist2.add(mylist2.id, list_var_use,
  227.                 strlen(list_var_use) + 1, CURRENT);
  228.  
  229.             if(status != 2)  {
  230.             printf("\nError adding items to Lists\n");
  231.             exit(EXIT_FAILURE);
  232.             }
  233.             ...
  234.         }
  235.  
  236.  
  237.                   - 8 -
  238.  
  239.          ***  EXTERNAL LIST FUNCTION DESCRIPTIONS  ***
  240.  
  241.           extern int compact_list_table(void);
  242.  
  243.     ACTION:
  244.         Moves active List pointers to lowest position in List
  245.         table and frees unused table memory.
  246.  
  247.     RETURNS:
  248.         1 on success
  249.  
  250.         0 on failure and sets lerror to an error code (see list.h)
  251.  
  252.     ARGUMENTS:
  253.         None.
  254.  
  255.     EXAMPLE:
  256.         /*
  257.          *    mylist is a dynamic array of List *
  258.          *    purge 3 of every 4 Lists (for some purpose or other)
  259.          *    and reclaim the memory
  260.          */
  261.         for(i = 0;i < TOTAL_LISTS;i++)
  262.         if(i % 4)
  263.             mylist[i]->destroy(mylist[i]->id);
  264.  
  265.         if(compact_list_table())  {
  266.           List **tmplist;
  267.             tmplist = realloc(mylist, (TOTAL_LISTS / 4));
  268.             if(tmplist)
  269.             mylist = tmplist;
  270.             else  {
  271.             printf("\nList compaction error\n");
  272.             exit(EXIT_FAILURE);
  273.             }
  274.         }
  275.         ...
  276.  
  277.  
  278.                   - 9 -
  279.  
  280.  
  281.           ***  LIST MEMBER FUNCTION CALLS  ***
  282.  
  283.      These are the List member functions that are bound to the List on
  284. which they operate by the initlist() function.    They are called as a
  285. member of the List variable ( e.g.  mylist.next(mylist.id) ).  All the
  286. examples in this section will assume a variable of type List named
  287. mylist.
  288.  
  289.            ***  LIST MEMBER FUNCTION PROTOTYPES  ***
  290.  
  291.     /*
  292.      *    int add(int id, void *item, size_t itemsize, enum Place place);
  293.      *    int chgcompare(int id, int (int id, *newcompare)());
  294.      *    int cmpitem(int id, void *item1);
  295.      *    int delete(int id);
  296.      *    int destroy(int id);
  297.      *    int find(int id, void *item1);
  298.      *    int first(int id);
  299.      *    int getitem(int id, void *itembuf);
  300.      *    void *getptr(int id);
  301.      *    size_t getsize(int id);
  302.      *    int last(int id);
  303.      *    int next(int id);
  304.      *    int prev(int id);
  305.      *    int remitem(int id, void *itembuf);
  306.      *    int replitem(int id, void *newitem, size_t newsize);
  307.      *    int sort(int id);
  308.      */
  309.  
  310.  
  311.                   - 10 -
  312.  
  313.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  314.  
  315.     int add(int id, void *item, size_t itemsize, enum Place place);
  316.  
  317.     ACTION:
  318.         Adds an item to a particular List.
  319.  
  320.     RETURNS:
  321.         1 on success
  322.  
  323.         0 on failure and sets lerror to an error code (see list.h)
  324.  
  325.     ARGUMENTS:
  326.         id is the List member variable whose value is assigned
  327.         by initlist()
  328.  
  329.         item is a void pointer to the item to store
  330.  
  331.         itemsize is an unsigned integer that is the size in bytes
  332.         of the item ( must be > 0 )
  333.  
  334.         place is one of FIRST, LAST or CURRENT (defined in list.h)
  335.         position in the List
  336.  
  337.         FIRST stores the item at the head of the List
  338.  
  339.         LAST stores the item at the tail end of the List
  340.  
  341.         CURRENT stores the item immediately after the "current"
  342.             item in the List
  343.  
  344.         in all three cases the stored item becomes the "current" item
  345.  
  346.  
  347.     EXAMPLE:
  348.         main()
  349.         {
  350.         FILE *fp;
  351.         List mylist;
  352.         struct record {
  353.         char name[40];
  354.         char phone[20];
  355.         }rec;
  356.  
  357.         if(initlist(&mylist,strcmp))  {
  358.         fp = fopen("phone.dat","rb");
  359.         while(!feof(fp))
  360.             if(fread(&rec,sizeof rec,1,fp) == 1)
  361.             if(!mylist.add(mylist.id, &rec, sizeof rec, LAST))
  362.                 break;
  363.         }
  364.  
  365.  
  366.                   - 11 -
  367.  
  368.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  369.  
  370.           int chgcompare(int id, int (*newcompare)());
  371.  
  372.     ACTION:
  373.         Binds a different compare function to the List variable.
  374.  
  375.     RETURNS:
  376.         1 on success
  377.  
  378.         0 on failure and sets lerror to an error code (see list.h)
  379.  
  380.     ARGUMENTS:
  381.         id is the List member variable whose value is assigned
  382.         by initlist()
  383.  
  384.         newcompare() follows the description given for cmpfunc()
  385.         in initlist()
  386.  
  387.     COMMENTS:
  388.  
  389.     You may have called initlist() with a function that compares two
  390.     structures using the "last_name" field as the key, but now you wish to
  391.     sort the List by telephone number area code.  chgcompare() allows
  392.     the substitution of another compare function.
  393.  
  394.     EXAMPLE:
  395.         if(! mylist.chgcompare(mylist.id, cmpnums))  {
  396.             printf("\nError changing compare function\n");
  397.             exit(EXIT_FAILURE);
  398.         }
  399.         ...
  400.  
  401.  
  402.                   - 12 -
  403.  
  404.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  405.  
  406.            int cmpitem(int id, void *item1);
  407.  
  408.     ACTION:
  409.         Compares item1 to the "current" item in the List.
  410.  
  411.     RETURNS:
  412.         The integer result of a comparison between item1 and
  413.         the "current" item, using the compare function    that
  414.         was passed to initlist() or chgcompare().
  415.  
  416.     ARGUMENTS:
  417.         id is the List member variable whose value is
  418.         assigned by initlist()
  419.  
  420.         item1 is a void pointer to the item to compare.
  421.  
  422.     EXAMPLE:    if(mylist.cmpitem(mylist.id, &rec1) == 0)
  423.             mylist.replitem(mylist.id, &rec1, sizeof rec1);
  424.  
  425.  
  426.                   - 13 -
  427.  
  428.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  429.  
  430.               int delete(int id);
  431.  
  432.     ACTION:
  433.         Deletes the "current" item from the List.
  434.         Sets the "current" pointer to the first item in the List.
  435.  
  436.     RETURNS:
  437.         1 on success
  438.  
  439.         0 on failure and sets lerror to an error code (see list.h)
  440.  
  441.     ARGUMENTS:
  442.         id is the List member variable whose value is assigned
  443.         by initlist()
  444.  
  445.     EXAMPLE:
  446.         if(! mylist.delete(mylist.id))
  447.             if(lerror == EMPTY_LIST)
  448.             return;
  449.  
  450.  
  451.                   - 14 -
  452.  
  453.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  454.  
  455.               int destroy(int id);
  456.  
  457.     ACTION:
  458.         Returns dynamic memory allocated to the List.
  459.         Removes table entry for the List.
  460.         Sets id member variable to an "invalid" value.
  461.  
  462.     RETURNS:
  463.         1  on success
  464.  
  465.         0  on failure and sets lerror to an error code (see list.h)
  466.  
  467.     ARGUMENTS:
  468.         id is the List member variable whose value is assigned
  469.         by initlist()
  470.  
  471.     EXAMPLE:
  472.         do  {
  473.             printf("\n%s",mylist.getptr(mylist.id))
  474.         }
  475.         while(mylist.next(mylist.id));
  476.  
  477.         mylist.destroy(mylist.id);
  478.         return;
  479.  
  480.  
  481.     COMMENTS:
  482.  
  483.     Instead of setting the List member functions to NULL, V.  2.0
  484.     sets the id variable to -1 so that calls from Lists that have
  485.     been destroyed set lerror to an error code and return NULL or 0.
  486.  
  487.  
  488.                   - 15 -
  489.  
  490.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  491.  
  492.              int find(int id, void *item1);
  493.  
  494.     ACTION:
  495.         Performs a linear search of the List for an item that
  496.         compares equal to item1, using the comparison function
  497.         that was passed to initlist() or chgcompare().
  498.  
  499.     RETURNS:
  500.         0 if no match is found
  501.  
  502.         1 if a match is found and the matching item in the List
  503.           is now the "current" item
  504.  
  505.     ARGUMENTS:
  506.         id is the List member variable whose value is assigned
  507.         by initlist()
  508.  
  509.         item1 is a void pointer to the item to match
  510.  
  511.     EXAMPLE:
  512.         if(! mylist.find(mylist.id, &employee_rec))
  513.             mylist.add(mylist.id, &employee_rec,
  514.             sizeof employee_rec, LAST);
  515.  
  516.  
  517.                   - 16 -
  518.  
  519.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  520.  
  521.                int first(int id);
  522.  
  523.     ACTION:
  524.         Makes the first item in List the "current" item.
  525.  
  526.     RETURNS:
  527.         1 on success
  528.  
  529.         0 on failure and sets lerror to an error code (see list.h)
  530.  
  531.     ARGUMENTS:
  532.         id is the List member variable whose value is assigned
  533.         by initlist()
  534.  
  535.     EXAMPLE:
  536.         if(! mylist.first(mylist.id))  /* quit if List empty */
  537.             exit(0);
  538.         else
  539.             do_something();
  540.  
  541.  
  542.  
  543.                   - 17 -
  544.  
  545.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  546.  
  547.           int getitem(int id, void *itembuf);
  548.  
  549.     ACTION:
  550.         Copies the "current" item in the List to itembuf.
  551.  
  552.     RETURNS:
  553.         1 on success
  554.  
  555.         0 on failure and sets lerror to an error code (see list.h)
  556.  
  557.     ARGUMENTS:
  558.         id is the List member variable whose value is assigned
  559.         by initlist()
  560.  
  561.         itembuf is a void pointer to the memory destination
  562.         of the copy operation
  563.  
  564.     WARNINGS:
  565.         Make sure itembuf is large enough to hold the "current"
  566.         item.  You can get the size in bytes of the "current"
  567.         item with the getsize() member function.
  568.  
  569.     EXAMPLE:
  570.         mylist.first(mylist.id);
  571.         if(mylist.entries > 0)
  572.         do  {
  573.             mylist.getitem(mylist.id, &record);
  574.             fwrite(&record,sizeof record, 1, fp);
  575.         }
  576.         while(mylist.next(mylist.id));
  577.  
  578.  
  579.                   - 18 -
  580.  
  581.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  582.  
  583.              void *getptr(int id);
  584.  
  585.     ACTION:
  586.         Returns the address of the "current" item in the List.
  587.  
  588.     RETURNS:
  589.         on success:
  590.  
  591.             void pointer to the "current" item in the List
  592.  
  593.         on failure:
  594.  
  595.             NULL and sets lerror to an error code (see list.h)
  596.  
  597.     ARGUMENTS:
  598.         id is the List member variable whose value is assigned
  599.         by initlist()
  600.  
  601.     WARNINGS:
  602.         Included for efficiency.  Beware of corrupting the
  603.         memory block if you write data to this address that
  604.         is larger than that allocated for the "current" item.
  605.         You can get the size in bytes of the "current" item in
  606.         the List with the getsize() member function.
  607.  
  608.     EXAMPLE:
  609.         if(! mylist.first(mylist.id)) { /* List is empty */
  610.             fclose(fp);
  611.             exit(0);
  612.         }
  613.  
  614.         do  {
  615.             fwrite(mylist.getptr(mylist.id),
  616.             mylist.getsize(mylist.id), 1, fp);
  617.         }
  618.         while(mylist.next(mylist.id));
  619.  
  620.         fclose(fp);
  621.  
  622.  
  623.                   - 19 -
  624.  
  625.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  626.  
  627.             size_t getsize(int id);
  628.  
  629.     ACTION:
  630.         Returns the size in bytes of the "current" item in the List.
  631.  
  632.     RETURNS:
  633.         on success:
  634.  
  635.             an unsigned integer equal to the size of the current
  636.             item in bytes ( must be > 0 )
  637.  
  638.         on failure:
  639.  
  640.             0 and sets lerror to an error code (see list.h)
  641.  
  642.     ARGUMENTS:
  643.         id is the List member variable whose value is assigned
  644.         by initlist()
  645.  
  646.     EXAMPLE:
  647.         if(mylist.getsize(mylist.id) > buffer_size)  {
  648.           void *tmpbuf;
  649.             buffer_size = mylist.getsize(mylist.id);
  650.             tmpbuf = realloc(buffer, buffer_size);
  651.             if(! tmpbuf)  {
  652.             printf("realloc failure!");
  653.             exit(EXIT_FAILURE);
  654.             }
  655.             buffer = tmpbuf;
  656.         }
  657.         mylist.remitem(mylist.id, buffer);
  658.  
  659.  
  660.                   - 20 -
  661.  
  662.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  663.  
  664.                int last(int id);
  665.  
  666.     ACTION:
  667.         Makes the last item in the List the "current" item.
  668.  
  669.     RETURNS:
  670.         1 on success
  671.  
  672.         0 on failure and sets lerror to an error code (see list.h)
  673.  
  674.     ARGUMENTS:
  675.         id is the List member variable whose value is assigned
  676.         by initlist()
  677.  
  678.     EXAMPLE:
  679.         /* show sorted List in rev order */
  680.  
  681.         mylist.sort(mylist.id);
  682.         if(mylist.last(mylist.id))
  683.             do    {
  684.             printf("\n%s",mylist.getptr(mylist.id))
  685.             }
  686.             while(mylist.prev(mylist.id));
  687.  
  688.  
  689.                   - 21 -
  690.  
  691.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  692.  
  693.                int next(int id);
  694.  
  695.     ACTION:
  696.         Makes the next item in the List the "current" item.
  697.  
  698.     RETURNS:
  699.         0  if next link is NULL ( does not move pointer ) or
  700.            sets lerror to error code if id is invalid (see list.h)
  701.  
  702.         1  on success
  703.  
  704.     ARGUMENTS:
  705.         id is the List member variable whose value is assigned
  706.         by initlist()
  707.  
  708.     EXAMPLE:
  709.         if(mylist.first(mylist.id))  {
  710.             int i;
  711.  
  712.             i = 1;
  713.             while(mylist.next(mylist.id))
  714.             ++i;
  715.             if(i != mylist.entries)  {
  716.             printf("List Module Error : Big Bug!");
  717.             exit(EXIT_FAILURE);
  718.             }
  719.         }
  720.         else
  721.             list_is_empty();
  722.  
  723.  
  724.                   - 22 -
  725.  
  726.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  727.  
  728.                int prev(int id);
  729.  
  730.     ACTION:
  731.         Makes the previous item in the List the "current" item.
  732.  
  733.     RETURNS:
  734.         0  if previous link is NULL ( does not move pointer ) or
  735.            sets lerror to error code if id is invalid (see list.h)
  736.  
  737.         1  on success
  738.  
  739.     ARGUMENTS:
  740.         id is the List member variable whose value is assigned
  741.         by initlist()
  742.  
  743.     EXAMPLE:
  744.         mylist.last(mylist.id);
  745.         while((mylist.cmpitem(mylist.id, &newrecord) < 0)
  746.             &&    mylist.prev(mylist.id))
  747.         ;   /* empty loop -- insert in List in sorted order */
  748.  
  749.         mylist.add(mylist.id, &newrecord,sizeof newrecord, CURRENT);
  750.  
  751.  
  752.                   - 23 -
  753.  
  754.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  755.  
  756.           int remitem(int id, void *itembuf);
  757.  
  758.     ACTION:
  759.         Copies the "current" item in the List to itembuf,
  760.         then removes the "current" item from the List.
  761.         Makes the first item in the List the "current" item.
  762.  
  763.     RETURNS:
  764.         1 on success
  765.  
  766.         0 on failure and sets lerror to an error code (see list.h)
  767.  
  768.     ARGUMENTS:
  769.         id is the List member variable whose value is assigned
  770.         by initlist()
  771.  
  772.     WARNINGS:
  773.         Make sure itembuf is large enough to hold the "current"
  774.         item.  You can get the size in bytes of the "current"
  775.         item with the getsize() member function.
  776.  
  777.     EXAMPLE:
  778.         if(sizeof buffer >= mylist.getsize(mylist.id))
  779.             mylist.remitem(mylist.id, buffer);
  780.  
  781.  
  782.                   - 24 -
  783.  
  784.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  785.  
  786.       int replitem(int id, void *newitem, size_t newsize);
  787.  
  788.     ACTION:
  789.         Replaces the "current" item in the List with the item
  790.         pointed to by newitem.    If the replacement is successful
  791.         the old "current" item is deleted from the List.
  792.  
  793.     RETURNS:
  794.         1 on success
  795.  
  796.         0 on failure and sets lerror to an error code (see list.h)
  797.  
  798.     ARGUMENTS:
  799.         id is the List member variable whose value is assigned
  800.         by initlist()
  801.  
  802.         newitem is a void pointer to the item that is to take
  803.         the place of the "current" item in the List
  804.  
  805.         newsize is the size in bytes of the new item
  806.  
  807.     EXAMPLE:
  808.         if(mylist.find(mylist.id, &newrecord))
  809.             mylist.replitem(mylist.id, &newrecord,
  810.             sizeof newrecord);
  811.  
  812.  
  813.                   - 25 -
  814.  
  815.           ***  LIST MEMBER FUNCTION DESCRIPTIONS  ***
  816.  
  817.                int sort(int id);
  818.  
  819.     ACTION:
  820.         Sorts the List in ascending order according to the
  821.         comparison function installed with the initlist()
  822.         or chgcompare() functions, using the host qsort()
  823.         function. The first item in the sorted List becomes
  824.         the "current" item.
  825.  
  826.     RETURNS:
  827.         1 on success
  828.  
  829.         0 on failure and sets lerror to an error code (see list.h)
  830.  
  831.     ARGUMENTS:
  832.         id is the List member variable whose value is assigned
  833.         by initlist()
  834.  
  835.     EXAMPLE:
  836.         /* display in reverse order */
  837.  
  838.         if(mylist.sort(mylist.id))  {
  839.             mylist.last(mylist.id);
  840.  
  841.             do    {
  842.             printf("\n%s",mylist.getptr(mylist.id))
  843.             }
  844.             while(mylist.prev(mylist.id));
  845.         }
  846.  
  847.