home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- ** ^FILE: arglist.c - argList manipulation routines.
- **
- ** ^DESCRIPTION:
- ** This file contains routines to add an item to the end of an arglist,
- ** and to delete all items in an arglist.
- **
- ** ^HISTORY:
- ** 27/08/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
- ** - Use get_argpfx() when accessing arg_sname().
- **
- ** 01/02/91 Brad Appleton <brad@ssd.csd.harris.com>
- ** - Added structured comments
- ** - Changed arglists to always be kept in FIFO order (hence
- ** reverse_list() and cleanup_list() were no longer needed).
- ** The lists are maintained in FIFO order by forcing the very
- ** first item of the list to maintain an additional link to the
- ** last item of the list (to make it easy to append an item).
- ** - Added listFree() function
- **
- ** --/--/-- Peter da Silva <peter@ferranti.com> Created
- ***^^**********************************************************************/
-
- #include <stdio.h>
- #include <ctype.h>
- #include <useful.h>
- #include "strfuncs.h"
-
- #define PARSEARGS_NARGTYPES /* exclude arg-type externs */
- #include "parseargs.h"
-
- EXTERN VOID syserr ARGS((const char *, ...));
- EXTERN VOID usrerr ARGS((const char *, ...));
-
- /***************************************************************************
- ** ^FUNCTION: listStr - string-list argument translation routine
- **
- ** ^SYNOPSIS:
- */
- #ifndef __ANSI_C__
- BOOL listStr( ad, vp, copyf )
- /*
- ** ^PARAMETERS:
- */
- ARGDESC *ad;
- /* -- the argument descriptor for this parameter.
- */
- char *vp;
- /* -- a pointer to the string input value.
- */
- BOOL copyf;
- /* -- if TRUE, the value will be destroyed later, and so should
- ** be copied if it will be retained (as for a string).
- */
- #endif /* !__ANSI_C__ */
-
- /* ^DESCRIPTION:
- ** ListStr converts a string-parameter value into its internal form,
- ** including validity checking. If <copyf> is TRUE then <vp> is copied
- ** to the end of the list, otherwise <vp> itself is placed at the end.
- **
- ** ^REQUIREMENTS:
- ** <ad> must point to the argdesc element corresponding to the matched
- ** string-list argument. The ad_valp field of ad MUST be either NULL or
- ** point to a valid arglist-head structure.
- **
- ** ^SIDE-EFFECTS:
- ** If successful, arglist pointed to by arg_valp(ad) is appended with
- ** the given string, <vp> is unchanged.
- **
- ** ^RETURN-VALUE:
- ** TRUE -- if the conversion was successful. The actual
- ** value should be added appended to the list.
- ** FALSE -- if the conversion failed. The reason for failure
- ** should be diagnosed using usrerr().
- **
- ** ^ALGORITHM:
- ** - verify the validity of <vp> as a string argument
- ** - if ( isEmpty(arglist) )
- ** - allocate a listhead structure
- ** - assign the item pointer to <vp> (or a copy of <vp>)
- ** - assign the NEXT and LAST elements to NULL
- ** - else
- ** - allocate a new arglist structure and append it after
- ** listhead.LAST
- ** - assign listhead.LAST to the address of the new item
- ** - assign the NEXT element of the new item to NULL
- ** end-if
- ***^^**********************************************************************/
- #ifdef __ANSI_C__
- BOOL listStr( ARGDESC *ad, char *vp, BOOL copyf )
- #endif
- {
- char *cp;
- BOOL badalloc = FALSE;
- argName_t argname;
- ArgListHead *nl;
- ArgList *nd;
-
- (VOID) get_argname( arg_sname(ad), argname );
- if (copyf) {
- register int i;
-
- i = strlen(vp) + 1;
- cp = (char *) malloc(i * sizeof(char));
- if(!cp) {
- usrerr("out of memory saving string %s", argname );
- return FALSE;
- }
- memcpy(cp, vp, i);
- }
- else {
- cp = vp;
- }
-
- /* if list is empty - need to new up a listhead,
- ** otherwise just use a normal link.
- */
- nl = *((ArgListHead **) arg_valp(ad));
- if ( nl ) {
- nd = (ArgList *) malloc( sizeof(ArgList) );
- if ( !nd ) badalloc = TRUE;
- }
- else {
- nl = (ArgListHead *) malloc( sizeof(ArgListHead) );
- nd = (ArgList *)NULL;
- if ( !nl ) badalloc = TRUE;
- }
-
- if ( badalloc ) {
- usrerr("out of memory saving arg %.*s", get_argpfx(arg_sname(ad)),
- arg_sname(ad));
- if(copyf) free(cp);
- return FALSE;
- }
-
- if ( nd ) {
- nl -> nl_tail -> nl_next = (ArgList *)nd;
- nl -> nl_tail = (ArgList *)nd;
- nd -> nl_next = (ArgList *)NULL;
- nd -> nl_val = (ARBPTR)cp;
- nd -> nl_flags = arg_flags(ad);
- if ( copyf ) BSET( nd->nl_flags, ARGCOPYF );
- }
- else {
- *((ArgListHead **) arg_valp(ad)) = nl;
- nl -> nl_tail = (ArgList *)nl;
- nl -> nl_next = (ArgList *)NULL;
- nl -> nl_val = (ARBPTR)cp;
- nl -> nl_flags = arg_flags(ad);
- if ( copyf ) BSET( nl->nl_flags, ARGCOPYF );
- }
-
- return (TRUE);
- }
-
-
- /***************************************************************************
- ** ^FUNCTION: listFree - free the items in an arglist
- **
- ** ^SYNOPSIS:
- */
- #ifndef __ANSI_C__
- VOID listFree( argls )
- /*
- ** ^PARAMETERS:
- */
- ArgList *argls;
- /* -- the list to be freed
- */
- #endif /* !__ANSI_C__ */
-
- /* ^DESCRIPTION:
- ** ListFree will free storage for each node in <argls>. Furthermore,
- ** if <copyf> is true then the actual storage for each item in the
- ** list is also released.
- **
- ** ^REQUIREMENTS:
- ** argls must point to a valid arglist-head structure.
- **
- ** ^SIDE-EFFECTS:
- ** each item in argls is removed, argls itself should be set to NULL
- ** after this routine is invoked.
- **
- ** ^RETURN-VALUE:
- ** None.
- **
- ** ^ALGORITHM:
- ** - For each node in argls
- ** - if ( copyf ) free the item storage
- ** - free the node
- ** end-for
- ***^^**********************************************************************/
- #ifdef __ANSI_C__
- void listFree( ArgList *argls )
- #endif
- {
- register ArgList *ls = argls;
- ArgList *nd;
-
- if ( !ls ) return;
-
- while ( ls ) {
- nd = L_NEXT(ls);
- if ( BTEST(L_FLAGS(ls), ARGCOPYF) ) free( ls->nl_val );
- free( ls );
- ls = nd;
- }/*while*/
- }
-
-