Article View: comp.sys.ibm.pc.programmer
Article #893MKS argv code
From: Lee F Kolakowski
Date: Mon, 09 Jul 1990 12:12
Date: Mon, 09 Jul 1990 12:12
321 lines
9743 bytes
9743 bytes
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! |
======================================================================
Technical Details
Message-ID:
<1990Jul9.121300.3377@athena.mit.edu>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!snorkelwacker!bloom-beacon!bloom-beacon!lfkShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!snorkelwacker!bloom-beacon!bloom-beacon!lfk From: lfk@athena.mit.edu (Lee F Kolakowski) Newsgroups: comp.sys.ibm.pc.programmer Subject: MKS argv code Message-ID: <1990Jul9.121300.3377@athena.mit.edu> Date: 9 Jul 90 12:12:42 GMT Sender: daemon@athena.mit.edu (Mr Background) Distribution: comp Organization: Mass. Inst. of Tech., Dept. of Chemistry Lines: 321