int getopt(int argc, char* const *argv, const char* optstr) { static int optchr = 0; static int dash = 0; /* have already seen the - */ char *cp; if (optreset) optreset = optchr = dash = 0; if (optind >= argc) return(EOF); if (!dash && (argv[optind][0] != '-')) return(EOF); if (!dash && (argv[optind][0] == '-') && !argv[optind][1]) { /* * use to specify stdin. Need to let pgm process this and * the following args */ return(EOF); } if ((argv[optind][0] == '-') && (argv[optind][1] == '-')) { /* -- indicates end of args */ optind++; return(EOF); } if (!dash) { assert((argv[optind][0] == '-') && argv[optind][1]); dash = 1; optchr = 1; } /* Check if the guy tries to do a -: kind of flag */ assert(dash); if (argv[optind][optchr] == ':') { dash = 0; optind++; return(optiserr(argc, argv, optind - 1, optstr, optchr, OPTERRCOLON)); } if (!(cp = strchr(optstr, argv[optind][optchr]))) { int errind = optind; int errchr = optchr; if (!argv[optind][optchr + 1]) { dash = 0; optind++; } else optchr++; return(optiserr(argc, argv, errind, optstr, errchr, OPTERRNF)); } if (cp[1] == ':') { dash = 0; optind++; if (optind == argc) return(optiserr(argc, argv, optind - 1, optstr, optchr, OPTERRARG)); optarg = argv[optind++]; return(*cp); } else { if (!argv[optind][optchr + 1]) { dash = 0; optind++; } else optchr++; return(*cp); } assert(0); return(0); }
int spamc_getopt_long(int argc, char * const argv[], const char *optstring, struct option *longopts, int *longindex) { static int optchr = 0; static int dash = 0; char *cp, *longopt; char *bp, *opt = NULL; int i, longoptlen;; spamc_optarg = NULL; /* clear any left over state from previous option */ if(spamc_optreset) spamc_optreset = optchr = dash = 0; if(spamc_optind >= argc) { return(EOF); } if(!dash && (argv[spamc_optind][0] != '-')) { return(EOF); } if(!dash && (argv[spamc_optind][0] == '-') && !argv[spamc_optind][1]) { /* used to specify stdin */ return(EOF); } if((argv[spamc_optind][0] == '-') && (argv[spamc_optind][1] == '-') && !argv[spamc_optind][2]) { /* used to specify end of args */ return(EOF); } if((argv[spamc_optind][0] == '-') && argv[spamc_optind][1] && (argv[spamc_optind][1] != '-')) { /* short option */ optchr = 1; if(argv[spamc_optind][optchr] == ':') return(optiserr(argc, argv, spamc_optind++, optstring, optchr, OPTERRCOLON)); cp = strchr(optstring, argv[spamc_optind++][optchr]); if(cp == NULL) return(optiserr(argc, argv, spamc_optind-1, optstring, optchr, OPTERRNF)); if(cp[1] == ':') { /* requires an argument */ if(!argv[spamc_optind] || (argv[spamc_optind][0] == '-') || (spamc_optind >= argc)) { return(optiserr(argc, argv, spamc_optind-1, optstring, optchr, OPTERRARG)); } spamc_optarg = argv[spamc_optind++]; return(*cp); } else { dash = 0; return(*cp); } } if((argv[spamc_optind][0] == '-') && (argv[spamc_optind][1] == '-') && argv[spamc_optind][2]) { /* long option */ optchr = 2; longopt = argv[spamc_optind++]; if(longopt[2] == ':') return(longoptiserr(argc, argv, spamc_optind, OPTERRCOLON)); longoptlen = strlen(longopt) - 2; if((bp = strchr(longopt, '='))) { opt = strdup(bp+1); longoptlen -= strlen(bp); } for(i=0; ; i++) { if((longopts[i].name == NULL) || (longopts[i].name == 0)) return(longoptiserr(argc, argv, spamc_optind-1, OPTERRNF)); if((memcmp(longopt+2, longopts[i].name, longoptlen)) == 0) { *longindex = i; if(longopts[i].has_arg == required_argument) { if(((spamc_optind >= argc) || (!argv[spamc_optind]) || (argv[spamc_optind][0] == '-')) && (opt == NULL)) return(longoptiserr(argc, argv, spamc_optind-1, OPTERRARG)); if(opt != NULL) { spamc_optarg = opt; } else { spamc_optarg = argv[spamc_optind++]; } } else if(longopts[i].has_arg == optional_argument) { if(((spamc_optind < argc) && (argv[spamc_optind]) && (argv[spamc_optind][0] != '-')) || (opt != NULL)) { if(opt != NULL) { spamc_optarg = opt; } else { spamc_optarg = argv[spamc_optind++]; } } } if(longopts[i].flag == NULL) { return(longopts[i].val); } else { *longopts[i].flag = longopts[i].val; return(0); } } } } return(0); /* should never reach here */ }