This is getarg.c in view mode; [Download] [Up]
#include "incl.h"
#ifndef NULL
#define NULL (void *)(0)
#endif
static int optind = 0;
extern char *optarg;
extern char *getenv();
/* Note that the above declarations can cause problems with programs
that use getopt(3) if this module is scanned first in the link phase.
This means that if you use getopt sometimes then you should keep this
module separate and link it in specifically when needed. Alternatively
you can change the names of the above externs (perhaps declare optind as
static as programs don't really need it anyway) and have a #define so
that the program still uses the above name(s). I considered using a
different name for optarg but was afraid that anything I picked would
conflict with user's names.
*/
static char **pargv = NULL;
static int pargc = 0;
int
initarg(argc, argv)
int argc;
char **argv;
{
int k = argc * sizeof(char *);
/* check for trivial case */
if (!argc)
return(0);
/* get or expand space */
if (pargc == 0)
pargv = (char **)malloc((size_t)k);
else
pargv = (char **)realloc(pargv, (size_t)(pargc + k));
if (pargv == NULL)
return(-1); /* not enough memory for argument pointers */
/* if adding arguments insert them at current argument */
if (pargc)
for (k = pargc - 1; k >= optind; k--)
pargv[k + argc] = pargv[k];
for (k = 0; k < argc; k++)
pargv[optind + k] = argv[k];
pargc += argc;
return(pargc);
}
int
initarge(argc, argv)
int argc;
char **argv;
{
char *env_str, *env_args[64];
int k, j = 0;
#ifdef __MSDOS__
char prog_name[64];
#endif
if ((k = initarg(argc - 1, argv + 1)) == -1)
return(-1); /* not enough memory for argument pointers */
#ifdef __MSDOS__
if ((env_str = strrchr(argv[0], '\\')) == NULL)
{
strcpy(prog_name, argv[0]);
if ((env_str = strchr(prog_name, ':')) != NULL)
strcpy(prog_name, env_str + 1);
}
else
strcpy(prog_name, env_str + 1);
if ((env_str = strchr(prog_name, '.')) != NULL)
*env_str = 0;
if ((env_str = getenv(prog_name)) == NULL)
#else
if ((env_str = strrchr(argv[0], '/')) != NULL)
env_str++;
else
env_str = argv[0];
if ((env_str = getenv(env_str)) == NULL)
#endif
return(k);
if ((env_args[0] =
(char *)malloc((size_t)(strlen(env_str) + 1))) == NULL)
return(-1); /* not enough memory for argument pointers */
env_str = strcpy(env_args[0], env_str);
while (isspace(*env_str))
env_str++;
while (*env_str)
{
if (*env_str == '"')
{
env_args[j++] = ++env_str;
while (*env_str && *env_str != '"')
{
if (*env_str == '\\')
{
strcpy(env_str, env_str + 1);
env_str++;
}
env_str++;
}
}
else
{
env_args[j++] = env_str;
while (*env_str && !isspace(*env_str))
env_str++;
}
if (*env_str)
*env_str++ = 0;
while (*env_str && isspace(*env_str))
env_str++;
}
if ((j = initarg(k, env_args)) == 0)
return(-1); /* not enough memory for argument pointers */
return(j + k);
}
/*
The meat of the module. This returns options and arguments similar to
getopt() as described above.
*/
/*** int getarg(const char *opts) ***/
int
getarg(opts)
char *opts;
{
static int sp = 0;
int c;
char *cp;
optarg = NULL;
/* return 0 if we have read all the arguments */
if(optind >= pargc)
{
if (pargv != NULL)
free(pargv);
pargc = 0;
return(0);
}
/* Are we starting to look at a new argument? */
if(sp == 0)
{
/* return it if it is a file name */
if (*pargv[optind] != '-')
{
optarg = pargv[optind++];
return(-1);
}
/* special return for standard input */
if (strcmp(pargv[optind], "-") == 0)
return('-');
/* otherwise point to option letter */
sp = 1;
}
else if (pargv[optind][++sp] == 0)
{
/* recursive call if end of this argument */
sp = 0;
optind++;
return(getarg(opts));
}
c = pargv[optind][sp];
if(c == ':' || (cp = index(opts, c)) == NULL)
return('?');
if(*++cp == ':')
{
/* Note the following code does not allow leading
spaces or all spaces in an argument */
while (isspace(pargv[optind][++sp]))
;
if(pargv[optind][sp])
optarg = pargv[optind++] + sp;
else if(++optind >= pargc)
c = '?';
else
optarg = pargv[optind++];
sp = 0;
}
else if (*cp == ';')
{
while (isspace(pargv[optind][++sp]))
;
if (pargv[optind][sp])
optarg = pargv[optind] + sp;
optind++;
sp = 0;
}
return(c);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.