Thread View: alt.msdos.programmer
7 messages
7 total messages
Started by Frank Whaley
Wed, 25 Oct 1989 21:43
Turbo C wildcard expansion
Author: 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.
Re: Turbo C wildcard expansion
Author: Russ Nelson
Date: Thu, 26 Oct 1989 02:35
Date: Thu, 26 Oct 1989 02:35
9 lines
1129 bytes
1129 bytes
Please remember that anything posted to comp.sys.ibm.pc, alt.msdos.programmer, and/or comp.binaries.ibm.pc.d doesn't get archived on grape.ecs.clarkson.edu. For something as valuable as the setargv() function posted in the parent of this article, that's sad. Because eventually someone is going to want to fetch a copy of it, and there won't be any. -- --russ (nelson@clutx [.bitnet | .clarkson.edu]) Live up to the light thou hast, and more will be granted thee. A recession now appears more than 2 years away -- John D. Mathon, 4 Oct 1989.
Make My Mother Happy!
Author: Mike Percy
Date: Fri, 27 Oct 1989 17:34
Date: Fri, 27 Oct 1989 17:34
27 lines
1537 bytes
1537 bytes
My mother works at Med. Univ. of SC doing sleep study research. Sh recently asked me to help her out by making it easier for her to extract the information she needs from the EEGs. She sent me a demo copy of the software the department _won't_ buy because it is too expensive -- they only want 1 part out of the package and don't want to pay 95% of the cost for softaware which won't be used. Anyway, the problem is simple, but I would like to make the data-entry as easy as possible for her. I have never done data-entry under C before and so far my attempts at writing field entry/edit functions has been frustrating and time-consuming. I don't want to buy a screen painter, but this is really what I need. I tried looking around grape.ecs.clarkson.edu but didn't see anything that fit the bill... Can anyone help me out by pointing the way to some field entry/edit functions - source which is TurboC compatible would be great. Thanks. Mike Percy -- grimlok@hubcap.clemson.edu -- 'I just couldn't convince the voters that Dukakis was Greek for "Bubba".' -- Lloyd Benson explaining why the Democrats didn't carry Texas
Re: Turbo C wildcard expansion
Author: Charles Hannum
Date: Sun, 29 Oct 1989 04:51
Date: Sun, 29 Oct 1989 04:51
6 lines
755 bytes
755 bytes
ARGH! That has to be some of the most convoluted code I have ever seen! If you only have 1 statement in a block (an IF or ELSE clause, for example), there is *NO* reason to include begin and end-block braces! It just makes the code longer and harder to read. Not being mean, but I like short and concise.
Re: Make My Mother Happy!
Author: Charles Hannum
Date: Sun, 29 Oct 1989 05:05
Date: Sun, 29 Oct 1989 05:05
4 lines
728 bytes
728 bytes
There is a package called CXL available for both Microsoft and Turbo C (and several others, as well). Sorry, but I don't know what FTP sites it is available on. (I downloaded it from a bulletin board.) Your best bet is SIMTEL20. If anyone knows where to get it, speak! (ehrr, write ...)
Re: Turbo C wildcard expansion
Author: Can't ya tell by the name
Date: Tue, 31 Oct 1989 02:26
Date: Tue, 31 Oct 1989 02:26
30 lines
2066 bytes
2066 bytes
In article <89302.005130CMH117@PSUVM.BITNET> CMH117@PSUVM.BITNET (Charles Hannum) writes: >ARGH! That has to be some of the most convoluted code I have ever seen! If >you only have 1 statement in a block (an IF or ELSE clause, for example), there >is *NO* reason to include begin and end-block braces! It just makes the code >longer and harder to read. > >Not being mean, but I like short and concise. Not to start a discussion on this issue, but I have found that the little extra space you use for this kind of coding saves hours of time debuging. I have help hundreds of people debug thier code and have found that those who like thier code THAT short and concise are the ones that have the mose difficult time debugging it. In fact thier have been those who I would not help untill they "expanded and formatted" thier code, and strange thing happened, they didn't need my help - they found it themselves. The most common reason for this is that without the begin and end braces they add a line of code to the for/while/if statement and forget to add the braces and . . . Well they are just to close to the tree to see the forest. I will not discuss this further in this group, but didn't want possibly new programmers to think that because you could and someone said you should that it was gospel, there are VERY good reasons for doing it the way the original poster did. flames to /dev/null or alt.religion.lang (or whatever that group is that I find so amusing to read).
Re: Turbo C wildcard expansion
Author: Edward J Driscoll
Date: Tue, 31 Oct 1989 15:56
Date: Tue, 31 Oct 1989 15:56
25 lines
1729 bytes
1729 bytes
In article <89302.005130CMH117@PSUVM.BITNET> CMH117@PSUVM.BITNET
(Charles Hannum) writes:
>ARGH! That has to be some of the most convoluted code I have ever seen! If
>you only have 1 statement in a block (an IF or ELSE clause, for example), there
>is *NO* reason to include begin and end-block braces! It just makes the code
>longer and harder to read.
>
There's no *technical* reason. It might make it harder for you to
read, but others might find it easier to read (I, for one, appreciate
the parallel structure it gives to ALL the if statements). It
certainly makes it less likely that you'll add in statements later
and forget to block them off with braces. I do this all the time
to add in debugging code, and typing in the braces ahead of time
saves a lot of extra mental processing. I'd say it's more a matter
of taste and style than a never-to-be-violated rule.
>Not being mean, but I like short and concise.
^^^^^^
And I like braces that make it blatantly obvious which
statements are in the block. See what I mean?
--
Ed Driscoll
The University of Michigan
ejd@caen.engin.umich.edu
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads