home *** CD-ROM | disk | FTP | other *** search
- /*
- * setargv.c -> parse arguments
- *
- * This code evolved out of a requirement for expansion of wild-card
- * arguments given on the command line. Turbo C's wildarg.obj
- * actually produces a reference to __wildargv, which still doesn't
- * do the job I needed (for example, directory names are not
- * expanded).
- *
- * This version both expands wild-card arguments and converts them
- * to lower case (a cosmetic thing for me). Arguments that are
- * quoted (with either " or ') are left alone, but the quote
- * characters are stripped. A leading quote may be escaped with
- * a backslash (\" or \'). Quotes within arguments (ARG="a b c")
- * are not handled in the Un*x fashion. If no matching filename
- * is found, the argument is passed unchanged.
- *
- * Two conditional-compilation flags are provided:
- * FIXARG0: convert argv[0] to lower case and switch
- * all backslashes to slashes (cosmetic)
- * SORTARGS: use qsort() to sort the expansions of
- * each argument
- *
- * Further enhancements greatly appreciated.
- *
- * This code placed in the public domain on October 25, 1989 by
- * its original author, Frank Whaley.
- */
-
- #define MAXARG 1024 /* max arguments */
-
- #include <ctype.h>
- #include <dir.h>
- #include <dos.h>
- #include <mem.h>
- #include <string.h>
- #include <alloc.h>
-
- /* let's do some things with macros... */
- #define ISQUOTE(c) (((c)=='"')||((c)=='\''))
- #define ISBLANK(c) (((c)==' ')||((c)=='\t'))
-
-
- static char *cl; /* -> local copy of command line */
-
- /* the following are used by run-time startup (c0?.obj) */
- extern int _argc; /* number of args */
- extern char **_argv; /* arg ptrs */
-
- /* forward declarations */
- static void *allocopy(void *src, int len);
- static void getreg(char *av[]);
- static void getwild(char *av[]);
-
-
- /*
- * _setargv() -> set argument vector
- */
- void
- _setargv()
- {
- char buf[128]; /* working buffer */
- char far *cline; /* generic far ptr */
- char *av[MAXARG]; /* working vector */
- int len; /* command line length */
-
- /* copy program name from environment */
- cl = buf;
- cline = MK_FP(*(int far *)MK_FP(_psp, 0x2c), 0);
- while ( *cline )
- {
- if ( !*++cline )
- {
- cline++;
- }
- }
- cline += 3;
- while ( *cline )
- {
- #ifdef FIXARG0
- *cl = tolower(*cline++);
- if ( *cl == '\\' )
- {
- *cl = '/';
- }
- cl++;
- #else
- *cl++ = *cline++;
- #endif
- }
- *cl = '\0';
- av[0] = allocopy(buf, strlen(buf) + 1);
-
- /* copy cmd line from PSP */
- cl = buf;
- cline = MK_FP(_psp, 0x80);
- len = *cline++;
- while ( len )
- {
- *cl++ = *cline++;
- len--;
- }
- *cl = 0;
-
- _argc = 1;
- cl = buf;
- while ( *cl )
- {
- /* deblank */
- while ( ISBLANK(*cl) )
- {
- cl++;
- }
-
- /* pick next argument */
- while ( *cl && (_argc < MAXARG) )
- {
- if ( iswild() )
- {
- getwild(av);
- }
- else
- {
- getreg(av);
- }
-
- /* deblank */
- while ( ISBLANK(*cl) )
- {
- cl++;
- }
- }
- }
-
- /* copy argument vector */
- _argv = allocopy(av, _argc * sizeof(char *));
- }
-
-
- /*
- * does current argument contain a wildcard ??
- */
- static int
- iswild()
- {
- char *s = cl;
-
- if ( ISQUOTE(*s) )
- {
- return ( 0 );
- }
-
- while ( *s && !ISBLANK(*s) )
- {
- if ( (*s == '\\') && ISQUOTE(*(s + 1)) )
- {
- s += 2;
- }
- else if ( (*s == '?') || (*s == '*') )
- {
- return ( 1 );
- }
-
- s++;
- }
-
- return ( 0 );
- }
-
-
- /*
- * allocopy() -> allocate space for a copy of something
- */
- static void *
- allocopy(void *src, int len)
- {
- void *copy;
-
- copy = sbrk(len);
- if ( copy == (void *)(-1) )
- {
- write(2, "\nMemory shortage\n", 17);
- exit(1);
- }
- return ( memcpy(copy, src, len) );
- }
-
-
- /*
- * getreg() -> pick a regular argument from command line
- */
- static void
- getreg(char *av[])
- {
- char buf[128];
- char *bp = buf;
- char quote;
-
- /* copy argument (minus quotes) into local buffer */
- if ( ISQUOTE(*cl) )
- {
- quote = *cl++;
- while ( *cl&& (*cl != quote) )
- {
- *bp++ = *cl++;
- }
- }
- else
- {
- while ( *cl && !ISBLANK(*cl) )
- {
- if ( (*cl == '\\') && ISQUOTE(*(cl + 1)) )
- {
- cl++;
- }
-
- *bp++ = *cl++;
- }
- }
- *bp = '\0';
-
- /* skip over terminator char */
- if ( *cl )
- {
- cl++;
- }
-
- /* store ptr to copy of string */
- av[_argc++] = allocopy(buf, strlen(buf) + 1);
- }
-
-
- /*
- * lwrcat() -> concatenate strings, conver to lower case
- */
- static char *
- lwrcat(char *s, char *t)
- {
- char *cp = s;
-
- while ( *cp )
- {
- cp++;
- }
- /* avoid a warning */
- while ( *t )
- {
- *cp++ = tolower(*t++);
- }
- *cp = '\0';
-
- return ( s );
- }
-
-
- /*
- * pickpath() -> pick pathname from argument
- */
- static void
- pickpath(char *arg, char *path)
- {
- char *t;
- int n;
-
- /* find beginning of basename */
- for ( t = arg + strlen(arg) - 1; t >= arg; t-- )
- {
- if ( (*t == '\\') || (*t == '/') || (*t == ':') )
- {
- break;
- }
- }
-
- /* pick off path */
- for ( n = (t - arg) + 1, t = arg; n--; )
- {
- *path = tolower(*t);
- path++;
- t++;
- }
- *path = '\0';
- }
-
-
- #ifdef SORTARGS
- /*
- * mycmp() -> comparison routine for qsort()
- */
- static int
- mycmp(char **s, char **t)
- {
- return ( strcmp(*s, *t) );
- }
- #endif
-
-
- /*
- * getwild() -> get wildcard argument from command line
- */
- static void
- getwild(char *av[])
- {
- char path[128];
- char srch[128];
- char *s = srch;
- struct ffblk f;
- #ifdef SORTARGS
- char **firstv = &av[_argc];
- int nmatched = 0;
- #endif
-
- /* pick search string */
- while ( *cl && !ISBLANK(*cl) )
- {
- *s++ = *cl++;
- }
- *s = '\0';
-
- pickpath(srch, path);
-
- if ( findfirst(srch, &f, 0x17) )
- {
- /* no match, just copy argument */
- av[_argc++] = allocopy(srch, strlen(srch) + 1);
- return;
- }
-
- /* add name if not "." or ".." */
- if ( f.ff_name[0] != '.' )
- {
- strcpy(srch, path);
- lwrcat(srch, f.ff_name);
- av[_argc++] = allocopy(srch, strlen(srch) + 1);
- #ifdef SORTARGS
- nmatched++;
- #endif
- }
-
- /* find the rest */
- while ( !findnext(&f) && (_argc < MAXARG) )
- {
- if ( f.ff_name[0] != '.' )
- {
- strcpy(srch, path);
- lwrcat(srch, f.ff_name);
- av[_argc++] = allocopy(srch, strlen(srch) + 1);
- #ifdef SORTARGS
- nmatched++;
- #endif
- }
- }
-
- #ifdef SORTARGS
- /* sort these entries */
- qsort(firstv, nmatched, sizeof(char *), mycmp);
- #endif
- }
-
-
- /*
- * END of setargv.c
- */
- --
- Frank Whaley
- Senior Development Engineer
- Quadratron Systems Incorporated
- few@quad1.quad.com
- uunet!ccicpg!quad1!few
-
- Water separates the people of the world;
- Wine unites them.
-
-
-