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.