lfk@athena.mit.edu (Lee F Kolakowski) (07/09/90)
Here is what I use to get the arguments from the MKS shell. This is for the MS-C compiler. I don't know about TC. It should work if TCs startup puts all the environment into the startup variable *env[]. I have yet to figure out how to use the glob they supply. This works under the shell and under DOS if the wild card expander in linked in. Frank Kolakowski ====================================================================== |lfk@athena.mit.edu || Lee F. Kolakowski | |lfk@eastman2.mit.edu || M.I.T. | |kolakowski@wccf.mit.edu || Dept of Chemistry | |lfk@mbio.med.upenn.edu || Room 18-506 | |lfk@hx.lcs.mit.edu || 77 Massachusetts Ave.| |AT&T: 1-617-253-1866 || Cambridge, MA 02139 | |--------------------------------------------------------------------| | #include <woes.h> | | One-Liner Here! | ====================================================================== #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # readme # skeleton.c # etc.h # This archive created: Sun Jul 08 19:24:38 1990 export PATH; PATH=/bin:$PATH if test -f 'readme' then echo shar: will not over-write existing file "'readme'" else cat << \SHAR_EOF > 'readme' In this c file is the code I use to get the arguments from the MKS shell. MKS puts all the arguments expanded in the environment. Each argument is preceeded by a '~'. For eample: $ set | grep "^~" ~jove ~readme finally they put the full path of the executable in the environment as follows $ set | grep "^_" _=c:/bin/jove.exe So all you have to do is add to main()'s parameters void main ( int argc, char *argv[], char *env[] ) | | ^environment table | ^argument list ^contains argument count and then use the code provided here in your applications that run under the MKS shell. There is one small gotcha. If you start a process under the shell, which spawns a process, the second process cannot get its arguments from the environment because the shell do not put then there. SO, in that case you have to use the args provided by your startup code. To test for this just compare your startups argv[0] with the _=value. So here is a simple test program that I use as the skeleton for most of my c code. If you compile it with -DMKS you can start it under the shell like this: $ skeleton /bin/* (112 entries) Using shell supplied args Process...../bin/asa.exe......done [ lots deleted ] Process...../bin/zcat.exe......done Under normal DOS (command.com) or when you shell out of your editor: !skeleton /bin/* Using startup supplied args Process...../bin/*......done tool: can't access '/bin/*' not a readable file Note I used /bin/* and '*' under dos expands to files with no extension and there are none. so you have to remember to use *.* !skeleton /bin/*.* Using startup supplied args Process...../bin/ASA.EXE......done [ lots deleted ] Process...../bin/ZCAT.EXE......done SHAR_EOF fi # end of overwriting check if test -f 'skeleton.c' then echo shar: will not over-write existing file "'skeleton.c'" else cat << \SHAR_EOF > 'skeleton.c' /* This is a skeleton file for the generation of arguments and the * parsing of command line options. * * If you want to be able to get the arguments pre-parsed from the * MKS shell, define MKS. * * Lee F. Kolakowski, Jr. * 20 Reyem Street * Waltham, MA 02154 */ /* DEFINES */ #define MKS /* INCLUDES */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <io.h> #include <sys/types.h> #include <sys/stat.h> #include <etc.h> /* ANSI Prototypes */ void process(char *filename); void die(char *fmt,...); void warn(char *fmt,...); /* GLOBAL VARIABLES */ char *progname = "tool"; char *usage = "Usage: tool [-v] [-o fname] [-ln] [filenames...]"; int lpp; char *ofname; bool verbose = FALSE; /* Main */ int main(int argc, char *argv[], char *env[]) { char *opt; struct stat filestat; #ifdef MKS int z = 0; int ARGC = 0; char **tmp; char *env_name; # define MAXARGS 500 /* This means 500 items on the command line */ if (!(tmp = (char **)malloc(sizeof(char *)*(MAXARGS+1)))) { fprintf(stderr, "%s: can't allocate space for arguments\n",progname); exit(1); } for ( z = 0 ; env[z] != NULL; z++) { /* loop through environment */ if (*env[z] == '~') { /* testing for entries begining with '~' */ *++env[z]; /* increment pointer to delete '~' */ tmp[ARGC++] = env[z]; /* add it to our new array */ if (z >= MAXARGS) { fprintf(stderr, "%s: can't handle any more arguments\n", progname); goto list; } } else if (*env[z] == '_') { /* testing for entries begining with _ */ *++env[z] ; *++env[z]; /* move past the '_' and the '=' */ env_name = env[z]; /* copy the name */ } } list: if ( STREQ( (char *) argv[0] , env_name ) ) { /* test name against startup args */ /* environment arguments meant for this program */ # ifdef DEBUG printf("Using shell supplied args\n"); # endif argc = ARGC; tmp[ARGC] = NULL; /* the terminal NULL */ argv = tmp; } # ifdef DEBUG else printf("Using startup supplied args\n"); # endif /* debug */ #endif /* MKS */ /* Parse command line manually (faster than getopt) */ nextarg: while (--argc > 0 && *(opt = *++argv) == '-') { while (*++opt != '\0') switch (*opt) { case 'v' : verbose++; break; case 'o' : ofname = getarg(opt); goto nextarg; case 'l' : lpp = atoi(getarg(opt)); goto nextarg; default : die("unknown option '%c'. %s", *opt, usage); exit(FAILURE); } /* * an arg of "-" starts list of files, usually interpreted as * stdin */ if (opt - *argv == 1) /* believe it or not, this catches '-' */ break; } /* Do the Stuff of the program */ do { /* test state of *argv */ if( (!stat(*argv, &filestat)) && ((filestat.st_mode & S_IFMT) == S_IFDIR) ) warn("can't process '%s' a directory\n", *argv); else if ( access(*argv, READ) != 0 ) { warn("can't access '%s' not a readable file\n", *argv); } else if (argc && freopen(*argv, "r", stdin) == NULL) { die("can't open '%s'\n", *argv); } if (ofname && freopen(ofname, "w", stdout) == NULL) { die("can't create %s\n", ofname); } process(*argv); printf("done\n"); } while (++argv, --argc > 0); return (SUCCESS); } void process(char *filename) { printf("Process.....%s......", filename); return; } void die(char *fmt,...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s: ", progname); vfprintf(stderr, fmt, ap); exit(FAILURE); } void warn(char *fmt,...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s: ", progname); vfprintf(stderr, fmt, ap); } SHAR_EOF fi # end of overwriting check if test -f 'etc.h' then echo shar: will not over-write existing file "'etc.h'" else cat << \SHAR_EOF > 'etc.h' /* * etc.h * useful definitions */ #ifndef etc #define etc /* Common Types */ typedef short fchar; /* Either input char, or EOF, which is int */ typedef char tbool; /* Flag, tested only for zero || non-zero */ typedef unsigned short bits; /* Data type for doing bit operations */ typedef enum { NO , YES } bool; /* Boolean, TRUE || FALSE */ /* Constants */ #define FALSE NO #define TRUE YES #define FAILURE 1 /* error exit code */ #define SUCCESS 0 /* successful exit, opposite of FAILURE */ enum FILEATTRIB { EXIST, WRITE = 2, READ = 4, READ_WRITE = 6 }; #ifndef SYSV_STRINGS # define SYSV_STRINGS # include <string.h> # define index strchr # define rindex strrchr #else /* what ever */ #endif /* Macros */ /* * getarg() - return a pointer to a parameter for a command-line switch * "-sBLAH" returns a pointer to "BLAH" * "-s BLAH" also returns a pointer to "BLAH" * "-s<no-more-args>" returns a pointer to an empty string */ #define getarg(p) (p[1] ? &p[1] : (argc>1 ? (--argc,*(++argv)) : "")) #define STREQ(a,b) ( strcmp( (a), (b) ) == 0 ) #endif /* etc */ SHAR_EOF fi # end of overwriting check # End of shell archive exit 0 -- Frank Kolakowski ====================================================================== |lfk@athena.mit.edu || Lee F. Kolakowski | |lfk@eastman2.mit.edu || M.I.T. | |kolakowski@wccf.mit.edu || Dept of Chemistry | |lfk@mbio.med.upenn.edu || Room 18-506 | |lfk@hx.lcs.mit.edu || 77 Massachusetts Ave.| |AT&T: 1-617-253-1866 || Cambridge, MA 02139 | |--------------------------------------------------------------------| | #include <woes.h> | | One-Liner Here! | ======================================================================