Category : Batch File Utilities - mostly for DOS
Archive   : RBSETENV.ZIP
Filename : WILDARGV.C
* 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.
*
* Added check for '[' and ']' R. Brittain 4/21/90
* for use with wildunix TSR
*/
#define MAXARG 1024 /* max arguments */
#include
#include
#include
#include
#include
#include
/* 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 == '*') || (*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
*/
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/