void getopt_register_opt(const char * os, size_t ln, int hasarg) { /* Can't reset here. */ if (optreset) DIE("Can't reset in the middle of getopt loop"); /* We should only be called during initialization. */ assert(!getopt_initialized); /* We should have space allocated for registering options. */ assert(opts != NULL); /* We should not have registered an option here yet. */ assert(opts[ln].os == NULL); /* Options should be "-X" or "--foo". */ if ((os[0] != '-') || (os[1] == '\0') || ((os[1] == '-') && (os[2] == '\0')) || ((os[1] != '-') && (os[2] != '\0'))) DIE("Not a valid command-line option: %s", os); /* Make sure we haven't already registered this option. */ if (searchopt(os) != opt_default) DIE("Command-line option registered twice: %s", os); /* Record option. */ opts[ln].os = os; opts[ln].olen = strlen(os); opts[ln].hasarg = hasarg; }
/* load options ---------------------------------------------------------------- * load options from file * args : char *file I options file * opt_t *opts IO options table * (terminated with table[i].name="") * return : status (1:ok,0:error) *-----------------------------------------------------------------------------*/ extern int loadopts(const char *file, opt_t *opts) { FILE *fp; opt_t *opt; char buff[2048],*p; int n=0; trace(3,"loadopts: file=%s\n",file); if (!(fp=fopen(file,"r"))) { trace(1,"loadopts: options file open error (%s)\n",file); return 0; } while (fgets(buff,sizeof(buff),fp)) { n++; chop(buff); if (buff[0]=='\0') continue; if (!(p=strstr(buff,"="))) { fprintf(stderr,"invalid option %s (%s:%d)\n",buff,file,n); continue; } *p++='\0'; chop(buff); if (!(opt=searchopt(buff,opts))) continue; if (!str2opt(opt,p)) { fprintf(stderr,"invalid option value %s (%s:%d)\n",buff,file,n); continue; } } fclose(fp); return 1; }
const char * getopt(int argc, char * const argv[]) { const char * os = NULL; const char * canonical_os = NULL; /* No argument yet. */ optarg = NULL; /* Reset the getopt state if needed. */ if (optreset) reset(argc, argv); /* If not initialized, return dummy option. */ if (!getopt_initialized) return (GETOPT_DUMMY); /* If we've run out of arguments, we're done. */ if (optind >= argc) return (NULL); /* * If we're not already in the middle of a packed single-character * options, see if we should start. */ if ((packedopts == NULL) && (argv[optind][0] == '-') && (argv[optind][1] != '-') && (argv[optind][1] != '\0')) { /* We have one or more single-character options. */ packedopts = &argv[optind][1]; } /* If we're processing single-character options, fish one out. */ if (packedopts != NULL) { /* Construct the option string. */ popt[0] = '-'; popt[1] = *packedopts; popt[2] = '\0'; os = popt; /* We've done this character. */ packedopts++; /* Are we done with this string? */ if (*packedopts == '\0') { packedopts = NULL; optind++; } } /* If we don't have an option yet, do we have dash-dash? */ if ((os == NULL) && (argv[optind][0] == '-') && (argv[optind][1] == '-')) { /* If this is not "--\0", it's an option. */ if (argv[optind][2] != '\0') os = argv[optind]; /* Either way, we want to eat the string. */ optind++; } /* If we have found nothing which looks like an option, we're done. */ if (os == NULL) return (NULL); /* Search for the potential option. */ opt_found = searchopt(os); /* If the option is not registered, give up now. */ if (opt_found == opt_default) { WARN("unknown option: %s", os); return (os); } /* The canonical option string is the one registered. */ canonical_os = opts[opt_found].os; /* Does the option take an argument? */ if (opts[opt_found].hasarg) { /* * If we're processing packed single-character options, the * rest of the string is the argument to this option. */ if (packedopts != NULL) { optarg = packedopts; packedopts = NULL; optind++; } /* * If the option string is <option>=<value>, extract that * value as the option argument. */ if (os[opts[opt_found].olen] == '=') optarg = &os[opts[opt_found].olen + 1]; /* * If we don't have an argument yet, take one from the * remaining command line. */ if ((optarg == NULL) && (optind < argc)) optarg = argv[optind++]; /* If we still have no option, declare it MIA. */ if (optarg == NULL) { WARN("option requires an argument: %s", opts[opt_found].os); opt_found = opt_missing; } } else { /* If we have --foo=bar, something went wrong. */ if (os[opts[opt_found].olen] == '=') { WARN("option doesn't take an argument: %s", opts[opt_found].os); opt_found = opt_default; } } /* Return the canonical option string. */ return (canonical_os); }