ken@turtlevax.UUCP (Ken Turkowski) (08/20/84)
echo x - README cat >README <<'!Funky!Stuff!' Lately I've seen several programs that use scanargs() and getopt() for argument scanning. Several systems do not have these subroutines in their standard libraries, so it makes such code difficult to compile. I am enclosing here a program I call "stdmain.c", which resides in my home directory, and which I read in every time I generate a new program. It has a builtin argument scanner that looks at all arguments before doing anything else, and accommodates several different types of flag formats: 1) Flags as separate arguments (-c -O -n -x); 2) concatenated (-cOnx); 3) attached flag parameters (-DDEBUG -b1200 -ooutput.file); 4) and/or separate parameters (-D DEBUG -b 1200 -o output.file). You may mix or match formats. It checks to make sure that there is an argument for the last flag if one is expected. One type of format not accommodated is that with flags longer than one character (-baud=1200 -verbose). Needless to say, if a flag requires an additional argument, that flag must either be separate or the last flag in a concatenated argument (-cOnxooutput.file -- pretty obscure, but accommodated). Two examples are given, '-v', a Boolean flag, and '-o', a flag with a value. Other flags may be added by using the same format for these two. !Funky!Stuff! echo x - stdmain.c cat >stdmain.c <<'!Funky!Stuff!' # include <stdio.h> int verbose; int exitcode = { -1 }; char *progname; Usage() { fprintf(stderr, "Usage: %s\n", progname); } static char SccsId[] = "%W%\t%G%"; # define ARGVAL() (*++(*argv) || (--argc && *++argv)) /* stdmain.c -- (C) 1984 Ken Turkowski (turtlevax!ken) * distrubuted to USENET 8/19/84, but may not be sold for profit */ main(argc, argv) int argc; char **argv; { char *ifname, *ofname; /* Initialization */ progname = *argv; ifname = NULL; ofname = NULL; verbose = 0; /* Argument Processing */ for (argc--, argv++; argc > 0; argc--, argv++) { if (**argv == '-') { /* A flag argument */ while (*++(*argv)) { /* Process all flags in this arg */ switch (**argv) { case 'v'; verbose = 1; break; case 'o': /* Output file name */ if (!ARGVAL()) exeunt("Missing output file name\n"); ofname = *argv; goto nextarg; default: fprintf(stderr, "Unknown flag: '%c'; ", **argv); Usage(); } } } else { /* Input file name */ if (ifname) { fprintf(stderr, "Discarding extra input file name: %s\n", *argv); goto nextarg; } ifname = *argv; goto nextarg; } nextarg: continue; } /* Open input file */ if (ifname && (freopen(ifname, "r", stdin) == NULL)) { perror(ifname ? ifname : "stdin"); exit(-1); } /* Open output file */ if (ofname && (freopen(ofname, "w", stdout) == NULL)) { perror(ofname ? ofname : "stdout"); exit(-1); } exit(0); } /* Exeunt -- a graceful exit for abnormal conditions */ exeunt(mess, arg1, arg2, arg3, arg4) char *mess; int arg1, arg2, arg3, arg4; { fprintf(stderr, mess, arg1, arg2, arg3, arg4); exit(exitcode); } !Funky!Stuff! exit 0 -- Ken Turkowski @ CADLINC, Palo Alto, CA UUCP: {amd,decwrl,dual,flairvax,nsc}!turtlevax!ken ARPA: turtlevax!ken@DECWRL.ARPA