home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume29 / parseargs / part03 / arglist.c next >
Encoding:
C/C++ Source or Header  |  1992-05-19  |  6.0 KB  |  211 lines

  1. /*************************************************************************
  2. ** ^FILE: arglist.c - argList manipulation routines.
  3. **
  4. ** ^DESCRIPTION:
  5. **    This file contains routines to add an item to the end of an arglist,
  6. **    and to delete all items in an arglist.
  7. **
  8. ** ^HISTORY:
  9. **    27/08/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  10. **       - Use get_argpfx() when accessing arg_sname().
  11. **
  12. **    01/02/91    Brad Appleton    <brad@ssd.csd.harris.com>
  13. **       - Added structured comments
  14. **       - Changed arglists to always be kept in FIFO order (hence
  15. **         reverse_list() and cleanup_list() were no longer needed).
  16. **         The lists are maintained in FIFO order by forcing the very
  17. **         first item of the list to maintain an additional link to the
  18. **         last item of the list (to make it easy to append an item).
  19. **       - Added listFree() function
  20. **
  21. **    --/--/--    Peter da Silva    <peter@ferranti.com>    Created
  22. ***^^**********************************************************************/
  23.  
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include <useful.h>
  27. #include "strfuncs.h"
  28.  
  29. #define  PARSEARGS_NARGTYPES  /* exclude arg-type externs */
  30. #include "parseargs.h"
  31.  
  32. EXTERN  VOID    syserr  ARGS((const char *, ...));
  33. EXTERN  VOID    usrerr  ARGS((const char *, ...));
  34.  
  35. /***************************************************************************
  36. ** ^FUNCTION: listStr - string-list argument translation routine
  37. **
  38. ** ^SYNOPSIS:
  39. */
  40. #ifndef __ANSI_C__
  41.    BOOL listStr( ad, vp, copyf )
  42. /*  
  43. ** ^PARAMETERS:
  44. */
  45.    ARGDESC *ad;
  46. /*    -- the argument descriptor for this parameter.
  47. */
  48.    char *vp;
  49. /*    -- a pointer to the string input value.
  50. */
  51.    BOOL copyf;
  52. /*    -- if TRUE, the value will be destroyed later, and so should
  53. **       be copied if it will be retained (as for a string).
  54. */
  55. #endif  /* !__ANSI_C__ */
  56.  
  57. /* ^DESCRIPTION:
  58. **    ListStr converts a string-parameter value into its internal form,
  59. **    including validity checking. If <copyf> is TRUE then <vp> is copied
  60. **    to the end of the list, otherwise <vp> itself is placed at the end.
  61. **
  62. ** ^REQUIREMENTS:
  63. **    <ad> must point to the argdesc element corresponding to the matched
  64. **    string-list argument. The ad_valp field of ad MUST be either NULL or
  65. **    point to a valid arglist-head structure.
  66. **
  67. ** ^SIDE-EFFECTS:
  68. **    If successful, arglist pointed to by arg_valp(ad) is appended with
  69. **    the given string, <vp> is unchanged.
  70. **
  71. ** ^RETURN-VALUE:
  72. **    TRUE -- if the conversion was successful.  The actual
  73. **            value should be added appended to the list.
  74. **    FALSE -- if the conversion failed.  The reason for failure
  75. **             should be diagnosed using usrerr().
  76. **
  77. ** ^ALGORITHM:
  78. **    - verify the validity of <vp> as a string argument
  79. **    - if ( isEmpty(arglist) )
  80. **       - allocate a listhead structure
  81. **       - assign the item pointer to <vp> (or a copy of <vp>)
  82. **       - assign the NEXT and LAST elements to NULL
  83. **    - else
  84. **       - allocate a new arglist structure and append it after
  85. **         listhead.LAST
  86. **       - assign listhead.LAST to the address of the new item
  87. **       - assign the NEXT element of the new item to NULL
  88. **      end-if
  89. ***^^**********************************************************************/
  90. #ifdef __ANSI_C__
  91.    BOOL listStr( ARGDESC *ad, char *vp, BOOL copyf )
  92. #endif
  93. {
  94.    char *cp;
  95.    BOOL  badalloc = FALSE;
  96.    argName_t   argname;
  97.    ArgListHead *nl;
  98.    ArgList *nd;
  99.  
  100.    (VOID) get_argname( arg_sname(ad), argname );
  101.    if (copyf) {
  102.       register int i;
  103.  
  104.       i = strlen(vp) + 1;
  105.       cp = (char *) malloc(i * sizeof(char));
  106.       if(!cp) {
  107.          usrerr("out of memory saving string %s", argname );
  108.          return FALSE;
  109.       }
  110.       memcpy(cp, vp, i);
  111.    }
  112.    else {
  113.       cp = vp;
  114.    }
  115.  
  116.       /* if list is empty - need to new up a listhead,
  117.       ** otherwise just use a normal link.
  118.       */
  119.    nl = *((ArgListHead **) arg_valp(ad));
  120.    if ( nl ) {
  121.       nd = (ArgList *) malloc( sizeof(ArgList) );
  122.       if ( !nd )  badalloc = TRUE;
  123.    }
  124.    else {
  125.       nl = (ArgListHead *) malloc( sizeof(ArgListHead) );
  126.       nd = (ArgList *)NULL;
  127.       if ( !nl )  badalloc = TRUE;
  128.    }
  129.  
  130.    if ( badalloc ) {
  131.       usrerr("out of memory saving arg %.*s", get_argpfx(arg_sname(ad)),
  132.                                               arg_sname(ad));
  133.       if(copyf) free(cp);
  134.       return FALSE;
  135.    }
  136.  
  137.    if ( nd ) {
  138.       nl -> nl_tail -> nl_next = (ArgList *)nd;
  139.       nl -> nl_tail  = (ArgList *)nd;
  140.       nd -> nl_next  = (ArgList *)NULL;
  141.       nd -> nl_val   = (ARBPTR)cp;
  142.       nd -> nl_flags = arg_flags(ad);
  143.       if ( copyf )  BSET( nd->nl_flags, ARGCOPYF );
  144.    }
  145.    else {
  146.       *((ArgListHead **) arg_valp(ad)) = nl;
  147.       nl -> nl_tail  = (ArgList *)nl;
  148.       nl -> nl_next  = (ArgList *)NULL;
  149.       nl -> nl_val   = (ARBPTR)cp;
  150.       nl -> nl_flags = arg_flags(ad);
  151.       if ( copyf )  BSET( nl->nl_flags, ARGCOPYF );
  152.    }
  153.  
  154.    return (TRUE);
  155. }
  156.  
  157.  
  158. /***************************************************************************
  159. ** ^FUNCTION: listFree - free the items in an arglist
  160. **
  161. ** ^SYNOPSIS:
  162. */
  163. #ifndef __ANSI_C__
  164.    VOID listFree( argls )
  165. /*  
  166. ** ^PARAMETERS:
  167. */
  168.    ArgList *argls;
  169. /*    -- the list to be freed
  170. */
  171. #endif  /* !__ANSI_C__ */
  172.  
  173. /* ^DESCRIPTION:
  174. **    ListFree will free storage for each node in <argls>. Furthermore,
  175. **    if <copyf> is true then the actual storage for each item in the
  176. **    list is also released.
  177. **
  178. ** ^REQUIREMENTS:
  179. **    argls must point to a valid arglist-head structure.
  180. **
  181. ** ^SIDE-EFFECTS:
  182. **    each item in argls is removed, argls itself should be set to NULL
  183. **    after this routine is invoked.
  184. **
  185. ** ^RETURN-VALUE:
  186. **    None.
  187. **
  188. ** ^ALGORITHM:
  189. **    - For each node in argls
  190. **       - if ( copyf ) free the item storage
  191. **       - free the node
  192. **      end-for
  193. ***^^**********************************************************************/
  194. #ifdef __ANSI_C__
  195.    void listFree( ArgList *argls )
  196. #endif
  197. {
  198.    register  ArgList *ls = argls;
  199.    ArgList  *nd;
  200.  
  201.    if ( !ls )  return;
  202.  
  203.    while ( ls ) {
  204.       nd = L_NEXT(ls);
  205.       if ( BTEST(L_FLAGS(ls), ARGCOPYF) )  free( ls->nl_val );
  206.       free( ls );
  207.       ls = nd;
  208.    }/*while*/
  209. }
  210.  
  211.