few@quad1.quad.com (Frank Whaley) (10/26/89)
/* * 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.
nelson@sun.soe.clarkson.edu (Russ Nelson) (10/26/89)
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.
CMH117@PSUVM.BITNET (Charles Hannum) (10/29/89)
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.
dopey%looney@Sun.COM (Can't ya tell by the name) (10/31/89)
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).
wew@naucse.UUCP (Bill Wilson) (10/31/89)
> 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 > Here is a good example of the statement that exceptional programmers master every high level language but english. Let's police our flame based mail before sending it out. Also discussions on style normally do not get anywhere and are a waste of band width. -- Let sleeping dragons lie........ | The Bit Chaser ---------------------------------------------------------------- Bill Wilson (Bitnet: ucc2wew@nauvm | wilson@nauvax) Northern AZ Univ Flagstaff, AZ 86011
ejd@caen.engin.umich.edu (Edward J Driscoll) (10/31/89)
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
ralphc@tekcae.CAX.TEK.COM (Ralph Carpenter) (11/04/89)
In article <1773@naucse.UUCP>, wew@naucse.UUCP (Bill Wilson) writes: > > 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 > Here is a good example of the statement that exceptional programmers > master every high level language but english. Let's police our > flame based mail before sending it out. Also discussions on style > normally do not get anywhere and are a waste of band width. > Bill Wilson (Bitnet: ucc2wew@nauvm | wilson@nauvax) I have read many good postings by Bill Wilson, but I would disagree a little with him here. I personally like the insight that comes from watching two learned people engage in a (well-mannered) discussion. As far as the typo-s, if it's something worthwhile, I can overlook most of them. Ralph Carpenter Tektronix, Inc. M/S 19-075 Beaverton, OR 97077