Article View: alt.msdos.programmer
Article #226Turbo C wildcard expansion
From: Frank Whaley
Date: Wed, 25 Oct 1989 21:43
Date: Wed, 25 Oct 1989 21:43
372 lines
6973 bytes
6973 bytes
/*
* 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.
Technical Details
Message-ID:
<3574@gouda.quad.com>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!wuarchive!gem.mps.ohio-state.edu!usc!srhqla!quad1!fewShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!wuarchive!gem.mps.ohio-state.edu!usc!srhqla!quad1!few From: few@quad1.quad.com (Frank Whaley) Newsgroups: alt.msdos.programmer,comp.sys.ibm.pc Subject: Turbo C wildcard expansion Keywords: TurboC wildcard Message-ID: <3574@gouda.quad.com> Date: 25 Oct 89 21:43:24 GMT Organization: Quadratron Systems, Westlake Village, CA Lines: 372