home *** CD-ROM | disk | FTP | other *** search
- From decwrl!ucbvax!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!usc!cs.utexas.edu!uunet!allbery Sat Mar 3 18:24:39 PST 1990
- Article 1346 of comp.sources.misc:
- Path: decwrl!ucbvax!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!usc!cs.utexas.edu!uunet!allbery
- From: peter@ficc.uu.net (Peter da Silva)
- Newsgroups: comp.sources.misc
- Subject: v10i075: Patches to parseargs posting
- Message-ID: <79684@uunet.UU.NET>
- Date: 21 Feb 90 02:11:01 GMT
- Sender: allbery@uunet.UU.NET
- Organization: Xenix Support, FICC
- Lines: 608
- Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 10, Issue 75
- Submitted-by: peter@ficc.uu.net (Peter da Silva)
- Archive-name: parseargs.p1
-
- [A short pause while a large submission accretes... not this one. ++bsa]
-
- This set of patches covers the two complaints with the parseargs version
- I sent out a few days ago. First, lists are reversed before returning: I
- thought this would be easier on users than going to a doubly-linked list
- or circular list. Second, ARGLIST is now a *flag* instead of a type, so
- new list arguments can be implemented. I also fixed a potential bug in
- unix_args.c.
-
- *** post/Makefile
- --- Makefile
- ***************
- *** 15,20 ****
- --- 15,21 ----
-
- OFILES= ckalloc.o \
- argtype.o \
- + arglist.o \
- fp_argtype.o \
- funclist.o \
- openpath.o \
- ***************
- *** 29,34 ****
- --- 30,36 ----
-
- CFILES= ckalloc.c \
- argtype.c \
- + arglist.c \
- fp_argtype.c \
- funclist.c \
- openpath.c \
- *** post/README.PDS
- --- README.PDS
- ***************
- *** 20,54 ****
- The second change was to allow for a trailing list of arguments. I
- originally implemented this by changing the calling sequence to parseargs.
- On reflection this would just produce incompatibilities, so I added a
- ! new "type", argList. This handles a pointer to a list of names:
-
- ! struct namelist {
- ! struct namelist *nl_next;
- ! char *nl_name;
- ! };
-
- ! This is implemented with some "magic" in parseargs, and perhaps it would
- ! do better as an additional flag, ARGLIST, and a set of listType routines
- ! to handle them. Also, it currently keeps the list in LIFO order. It would
- ! be more convenient in FIFO order, though this would take a little more
- ! work to implement (basically just stepping through the list in argList to
- ! find the tail, instead of inserting at the head), and can be fixed in a
- ! single pass after parseargs returns with (say) !argv = reverselist(argv)!:
-
- ! struct namelist *reverselist(from)
- ! struct namelist *from;
- ! {
- ! struct namelist *to, *tmp;
- !
- ! to = NULL;
- ! while(from) {
- ! tmp = from->nl_next; /* remove top from old list */
- ! from = from->nl_next;
- ! tmp->nl_next = to; /* insert top in new list */
- ! to = tmp;
- ! }
- ! return to;
- ! }
-
- The final change is the addition of a 'argChar' type. This parses character
- arguments (such as the '-T' option to 'awk'), accepting single characters,
- --- 20,36 ----
- The second change was to allow for a trailing list of arguments. I
- originally implemented this by changing the calling sequence to parseargs.
- On reflection this would just produce incompatibilities, so I added a
- ! new flag, ARGLIST, and a new type, listStr. Later, other kinds of lists
- ! can presumably be added. A list handles a pointer to a list of objects:
-
- ! struct arglist *fred;
-
- ! Operations are defined on arglists, L_NEXT(fred) produces the next element
- ! in fred. L_STRING(fred) produces the value of fred cast to "char *".
-
- ! During evaluation the list is kept in LIFO order, and it's reversed just
- ! before returning to parseargs. This simplifies the coding of the list
- ! routines, but still lets you step through the list in a reasonable order.
-
- The final change is the addition of a 'argChar' type. This parses character
- arguments (such as the '-T' option to 'awk'), accepting single characters,
- *** post/amiga_args.c
- --- amiga_args.c
- ***************
- *** 35,42 ****
- #define ALL_AD ad = argd; ad->ad_name != '\0'; ad++
- #define ALL_DEFS ad = _DefaultArgs; ad->ad_name != '\0'; ad++
-
- ! char *ProgName;
-
- #ifdef TRACESTUFF
- extern BOOL argTrace ARGS((ARGDESC *, char *, BOOL));
- #endif
- --- 35,44 ----
- #define ALL_AD ad = argd; ad->ad_name != '\0'; ad++
- #define ALL_DEFS ad = _DefaultArgs; ad->ad_name != '\0'; ad++
-
- ! #define HANDLE(a,n,f) ((*(a)->ad_type)(a,n,f))
-
- + char *ProgName;
- +
- #ifdef TRACESTUFF
- extern BOOL argTrace ARGS((ARGDESC *, char *, BOOL));
- #endif
- ***************
- *** 100,106 ****
- if(ad)
- {
- /* try to convert the type */
- ! if (!(*ad->ad_type)(ad, *av, FALSE))
- error = TRUE;
- else
- ad->ad_flags |= ARGGIVEN;
- --- 102,108 ----
- if(ad)
- {
- /* try to convert the type */
- ! if (!HANDLE(ad, *av, FALSE))
- error = TRUE;
- else
- ad->ad_flags |= ARGGIVEN;
- ***************
- *** 130,136 ****
- {
- p++;
- /* try to convert the type */
- ! if (!(*ad->ad_type)(ad, p, FALSE))
- error = TRUE;
- else
- ad->ad_flags |= ARGGIVEN;
- --- 132,138 ----
- {
- p++;
- /* try to convert the type */
- ! if (!HANDLE(ad, p, FALSE))
- error = TRUE;
- else
- ad->ad_flags |= ARGGIVEN;
- ***************
- *** 150,156 ****
- ad->ad_flags |= ARGGIVEN;
- ad = NULL;
- }
- ! else if (ad->ad_type == argList)
- {
- list = ad;
- ad = NULL;
- --- 152,158 ----
- ad->ad_flags |= ARGGIVEN;
- ad = NULL;
- }
- ! else if (ad->ad_flags & ARGLIST)
- {
- list = ad;
- ad = NULL;
- ***************
- *** 160,166 ****
- else /* it's a positional argument */
- {
- if(list) {
- ! if (!argList(list, *av, FALSE))
- error = TRUE;
- list->ad_flags |= ARGGIVEN;
- continue;
- --- 162,168 ----
- else /* it's a positional argument */
- {
- if(list) {
- ! if (!HANDLE(list, *av, FALSE))
- error = TRUE;
- list->ad_flags |= ARGGIVEN;
- continue;
- ***************
- *** 170,176 ****
- for (ALL_AD)
- {
- if (ad->ad_name == ' ' &&
- ! (ad->ad_type == argList ||
- !BITSET(ARGGIVEN, ad->ad_flags))
- )
- break;
- --- 172,178 ----
- for (ALL_AD)
- {
- if (ad->ad_name == ' ' &&
- ! ( (ad->ad_flags & ARGLIST) ||
- !BITSET(ARGGIVEN, ad->ad_flags))
- )
- break;
- ***************
- *** 184,190 ****
- else
- {
- /* try to convert */
- ! if (!(*ad->ad_type)(ad, *av, FALSE))
- error = TRUE;
- else
- ad->ad_flags |= ARGGIVEN;
- --- 186,192 ----
- else
- {
- /* try to convert */
- ! if (!HANDLE(ad, *av, FALSE))
- error = TRUE;
- else
- ad->ad_flags |= ARGGIVEN;
- ***************
- *** 231,236 ****
- --- 233,239 ----
- usage(argd);
- exit(20);
- }
- + cleanup_lists(argd);
- }
- /*
- ** USAGE -- print a usage message
- ***************
- *** 302,308 ****
- }
- if (!BITSET(ARGREQ, ad->ad_flags))
- pl += 2; /* [ ] */
- ! if (ad->ad_type == argList)
- pl += 3; /* ... */
- pl += 1; /* leading sp */
-
- --- 305,311 ----
- }
- if (!BITSET(ARGREQ, ad->ad_flags))
- pl += 2; /* [ ] */
- ! if (ad->ad_flags & ARGLIST)
- pl += 3; /* ... */
- pl += 1; /* leading sp */
-
- ***************
- *** 333,339 ****
- fprintf(stderr, "<%s>", name);
- if (!BITSET(ARGREQ, ad->ad_flags))
- fprintf(stderr, "]");
- ! if (ad->ad_type == argList)
- fprintf(stderr, "...");
- }
- fprintf(stderr, "\n");
- --- 336,342 ----
- fprintf(stderr, "<%s>", name);
- if (!BITSET(ARGREQ, ad->ad_flags))
- fprintf(stderr, "]");
- ! if (ad->ad_flags & ARGLIST)
- fprintf(stderr, "...");
- }
- fprintf(stderr, "\n");
- *** post/argtype.c
- --- argtype.c
- ***************
- *** 252,293 ****
- {
- return (FALSE);
- }
- -
- - BOOL
- - argList(ad, vp, copyf)
- - register ARGDESC *ad;
- - register char *vp;
- - BOOL copyf;
- - {
- - char *cp;
- - struct namelist *nl;
- -
- - if (copyf)
- - {
- - register int i;
- -
- - i = strlen(vp) + 1;
- - cp = (char *) malloc(i);
- - if(!cp) {
- - usrerr("out of memory saving string %s", ad->ad_prompt);
- - return FALSE;
- - }
- - bcopy(vp, cp, i);
- - }
- - else
- - {
- - cp = vp;
- - }
- -
- - nl = (struct namelist *) malloc(sizeof *nl);
- - if(!nl) {
- - usrerr("out of memory saving arg %s", ad->ad_prompt);
- - if(copyf) free(cp);
- - return FALSE;
- - }
- -
- - nl->nl_next = *(struct namelist **) ad->ad_valp;
- - nl->nl_name = cp;
- - *(struct namelist **) ad->ad_valp = nl;
- - return (TRUE);
- - }
- --- 252,254 ----
- *** post/parseargs.h
- --- parseargs.h
- ***************
- *** 31,36 ****
- --- 31,37 ----
- #define ARGOPT 0x00 /* optional argument pseudo-flag */
- #define ARGHIDDEN 0x02 /* don't display in usage message */
- #define ARGGIVEN 0x08 /* (internal) argument has been specified */
- + #define ARGLIST 0x10 /* Argument is a list handler */
-
- /* types available for ad_type */
- extern BOOL argBool ARGS((ARGDESC *, char *, BOOL));
- ***************
- *** 41,52 ****
- extern BOOL argLong ARGS((ARGDESC *, char *, BOOL));
- extern BOOL argFloat ARGS((ARGDESC *, char *, BOOL));
- extern BOOL argDouble ARGS((ARGDESC *, char *, BOOL));
- ! extern BOOL argList ARGS((ARGDESC *, char *, BOOL));
-
- ! struct namelist {
- ! struct namelist *nl_next;
- ! char *nl_name;
- };
-
- #define ENDOFARGS { '\0' }
-
- --- 42,56 ----
- extern BOOL argLong ARGS((ARGDESC *, char *, BOOL));
- extern BOOL argFloat ARGS((ARGDESC *, char *, BOOL));
- extern BOOL argDouble ARGS((ARGDESC *, char *, BOOL));
- ! extern BOOL listStr ARGS((ARGDESC *, char *, BOOL));
-
- ! struct arglist {
- ! struct arglist *nl_next;
- ! ARBPTR nl_val;
- };
- +
- + #define L_NEXT(l) ((l)->nl_next) /* Next elt of list */
- + #define L_STRING(e) ((char *)((e)->nl_val)) /* Elt as a string */
-
- #define ENDOFARGS { '\0' }
-
- *** post/stest.c
- --- stest.c
- ***************
- *** 18,30 ****
- BOOL YFlag = FALSE;
- BOOL ZFlag = FALSE;
- char TabChar = ':';
- ! struct namelist *Argv = NULL;
- ! struct namelist *Groups = NULL;
-
- ARGDESC Args[] =
- {
- ' ', ARGREQ, argStr, __ &Name, "Name",
- ! 'n', ARGOPT, argList, __ &Groups, "newsGROUP",
- 'c', ARGOPT, argInt, __ &RepCount, "REPcount",
- 'd', ARGOPT, argStr, __ &DirName, "DIRname",
- 'x', ARGOPT, argBool, __ &XFlag, "Xflag",
- --- 18,30 ----
- BOOL YFlag = FALSE;
- BOOL ZFlag = FALSE;
- char TabChar = ':';
- ! struct arglist *Argv = NULL;
- ! struct arglist *Groups = NULL;
-
- ARGDESC Args[] =
- {
- ' ', ARGREQ, argStr, __ &Name, "Name",
- ! 'n', ARGOPT|ARGLIST, listStr, __ &Groups, "newsGROUP",
- 'c', ARGOPT, argInt, __ &RepCount, "REPcount",
- 'd', ARGOPT, argStr, __ &DirName, "DIRname",
- 'x', ARGOPT, argBool, __ &XFlag, "Xflag",
- ***************
- *** 31,37 ****
- 'y', ARGOPT, argBool, __ &YFlag, "Yflag",
- 'z', ARGOPT, argBool, __ &ZFlag, "Zflag",
- 't', ARGOPT, argChar, __ &TabChar, "TABchar",
- ! ' ', ARGOPT, argList, __ &Argv, "File",
- ENDOFARGS
- };
-
- --- 31,37 ----
- 'y', ARGOPT, argBool, __ &YFlag, "Yflag",
- 'z', ARGOPT, argBool, __ &ZFlag, "Zflag",
- 't', ARGOPT, argChar, __ &TabChar, "TABchar",
- ! ' ', ARGOPT|ARGLIST, listStr, __ &Argv, "File",
- ENDOFARGS
- };
-
- ***************
- *** 49,56 ****
- if(Groups) {
- printf("Newsgroups: ");
- while(Groups) {
- ! printf("%s", Groups->nl_name);
- ! Groups = Groups->nl_next;
- if(Groups)
- putchar(' ');
- else
- --- 49,56 ----
- if(Groups) {
- printf("Newsgroups: ");
- while(Groups) {
- ! printf("%s", L_STRING(Groups));
- ! Groups = L_NEXT(Groups);
- if(Groups)
- putchar(' ');
- else
- ***************
- *** 61,68 ****
- if(Argv) {
- printf("Remaining args: ");
- while(Argv) {
- ! printf("%s", Argv->nl_name);
- ! Argv = Argv->nl_next;
- if(Argv)
- putchar(' ');
- else
- --- 61,68 ----
- if(Argv) {
- printf("Remaining args: ");
- while(Argv) {
- ! printf("%s", L_STRING(Argv));
- ! Argv = L_NEXT(Argv);
- if(Argv)
- putchar(' ');
- else
- *** post/unix_args.c
- --- unix_args.c
- ***************
- *** 35,42 ****
- #define ALL_AD ad = argd; ad->ad_name != '\0'; ad++
- #define ALL_DEFS ad = _DefaultArgs; ad->ad_name != '\0'; ad++
-
- ! char *ProgName;
-
- #ifdef TRACESTUFF
- extern BOOL argTrace ARGS((ARGDESC *, char *, BOOL));
- #endif
- --- 35,44 ----
- #define ALL_AD ad = argd; ad->ad_name != '\0'; ad++
- #define ALL_DEFS ad = _DefaultArgs; ad->ad_name != '\0'; ad++
-
- ! #define HANDLE(a,n,f) ((*(a)->ad_type)(a,n,f))
-
- + char *ProgName;
- +
- #ifdef TRACESTUFF
- extern BOOL argTrace ARGS((ARGDESC *, char *, BOOL));
- #endif
- ***************
- *** 176,186 ****
- }
-
- /* try to convert the type */
- ! if (!(*ad->ad_type)(ad, p, FALSE))
- error = TRUE;
- else
- ad->ad_flags |= ARGGIVEN;
- ! if(ad->ad_type == argList)
- list = ad;
- else
- list = NULL;
- --- 178,188 ----
- }
-
- /* try to convert the type */
- ! if (!HANDLE(ad, p, FALSE))
- error = TRUE;
- else
- ad->ad_flags |= ARGGIVEN;
- ! if(ad->ad_flags & ARGLIST)
- list = ad;
- else
- list = NULL;
- ***************
- *** 191,197 ****
- {
- /* parsing a list of arguments */
- if(list) {
- ! if (!argList(list, p, FALSE))
- error = TRUE;
- continue;
- }
- --- 193,199 ----
- {
- /* parsing a list of arguments */
- if(list) {
- ! if (!HANDLE(list, p, FALSE))
- error = TRUE;
- continue;
- }
- ***************
- *** 199,205 ****
- for (ALL_AD)
- {
- if (ad->ad_name == ' ' &&
- ! (ad->ad_type == argList ||
- !BITSET(ARGGIVEN, ad->ad_flags))
- )
- break;
- --- 201,207 ----
- for (ALL_AD)
- {
- if (ad->ad_name == ' ' &&
- ! ( (ad->ad_flags & ARGLIST) ||
- !BITSET(ARGGIVEN, ad->ad_flags))
- )
- break;
- ***************
- *** 212,218 ****
- }
-
- /* try to convert */
- ! if (!(*ad->ad_type)(ad, p, FALSE))
- error = TRUE;
- else
- ad->ad_flags |= ARGGIVEN;
- --- 214,220 ----
- }
-
- /* try to convert */
- ! if (!HANDLE(ad, p, FALSE))
- error = TRUE;
- else
- ad->ad_flags |= ARGGIVEN;
- ***************
- *** 242,248 ****
- usrerr("value required");
- continue;
- }
- ! if ((*ad->ad_type)(ad, buf, TRUE))
- {
- ad->ad_flags |= ARGGIVEN;
- break;
- --- 244,250 ----
- usrerr("value required");
- continue;
- }
- ! if (HANDLE(ad, buf, TRUE))
- {
- ad->ad_flags |= ARGGIVEN;
- break;
- ***************
- *** 274,280 ****
- exit(2);
- }
-
- ! return argc;
- }
- /*
- ** USAGE -- print a usage message
- --- 276,282 ----
- exit(2);
- }
-
- ! cleanup_lists(argd);
- }
- /*
- ** USAGE -- print a usage message
- ***************
- *** 327,333 ****
- }
- if (!BITSET(ARGREQ, ad->ad_flags))
- pl += 2; /* [ ] */
- ! if (ad->ad_type == argList) /* ... */
- pl += 3;
- pl += 1; /* leading sp */
-
- --- 329,335 ----
- }
- if (!BITSET(ARGREQ, ad->ad_flags))
- pl += 2; /* [ ] */
- ! if (ad->ad_flags & ARGLIST) /* ... */
- pl += 3;
- pl += 1; /* leading sp */
-
- ***************
- *** 358,364 ****
- fprintf(stderr, "<%s>", ad->ad_prompt);
- if (!BITSET(ARGREQ, ad->ad_flags))
- fprintf(stderr, "]");
- ! if (ad->ad_type == argList)
- fprintf(stderr, "...");
- }
- fprintf(stderr, "\n");
- --- 360,366 ----
- fprintf(stderr, "<%s>", ad->ad_prompt);
- if (!BITSET(ARGREQ, ad->ad_flags))
- fprintf(stderr, "]");
- ! if (ad->ad_flags & ARGLIST)
- fprintf(stderr, "...");
- }
- fprintf(stderr, "\n");
- --
- _--_|\ Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>.
- / \
- \_.--._/ Xenix Support -- it's not just a job, it's an adventure!
- v "Have you hugged your wolf today?" `-_-'
-
-
-