diff options
author | Eric Andersen <andersen@codepoet.org> | 2000-10-11 22:51:00 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2000-10-11 22:51:00 +0000 |
commit | 174dc1b8cd932fb5cd3d50fe5317e0c29ee26c59 (patch) | |
tree | 7683117cfc44f8f09610b5f1f48bcdb1524031bb /libc/unistd/getopt.c | |
parent | 1eb3e9989a8241c1654788fc7589e1f679e73dff (diff) |
Reorg unistd dir
Diffstat (limited to 'libc/unistd/getopt.c')
-rw-r--r-- | libc/unistd/getopt.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/libc/unistd/getopt.c b/libc/unistd/getopt.c new file mode 100644 index 000000000..70d20b06b --- /dev/null +++ b/libc/unistd/getopt.c @@ -0,0 +1,111 @@ + +/* + * From: gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) Newsgroups: net.sources + * Subject: getopt library routine Date: 30 Mar 85 04:45:33 GMT + */ +/* + * getopt -- public domain version of standard System V routine + * + * Strictly enforces the System V Command Syntax Standard; provided by D A + * Gwyn of BRL for generic ANSI C implementations + * + * #define STRICT to prevent acceptance of clustered options with arguments + * and ommision of whitespace between option and arg. + */ + +#include <stdio.h> +#include <string.h> + +int opterr = 1; /* error => print message */ +int optind = 1; /* next argv[] index */ +int optopt = 1; /* Set for unknown arguments */ +char *optarg = NULL; /* option parameter if any */ + +static int Err(name, mess, c) /* returns '?' */ +char *name; /* program name argv[0] */ +char *mess; /* specific message */ +int c; /* defective option letter */ +{ + optopt = c; + if (opterr) { + (void) fprintf(stderr, "%s: %s -- %c\n", name, mess, c); + } + + return '?'; /* erroneous-option marker */ +} + +int getopt(argc, argv, optstring) /* returns letter, '?', EOF */ +int argc; /* argument count from main */ +char *argv[]; /* argument vector from main */ +char *optstring; /* allowed args, e.g. "ab:c" */ +{ + static int sp = 1; /* position within argument */ + register int osp; /* saved `sp' for param test */ + +#ifndef STRICT + register int oind; /* saved `optind' for param test */ +#endif + register int c; /* option letter */ + register char *cp; /* -> option in `optstring' */ + + optarg = NULL; + + if (sp == 1) { /* fresh argument */ + if (optind >= argc /* no more arguments */ + || argv[optind][0] != '-' /* no more options */ + || argv[optind][1] == '\0' /* not option; stdin */ + ) + return EOF; + else if (strcmp(argv[optind], "--") == 0) { + ++optind; /* skip over "--" */ + return EOF; /* "--" marks end of options */ + } + } + + c = argv[optind][sp]; /* option letter */ + osp = sp++; /* get ready for next letter */ + +#ifndef STRICT + oind = optind; /* save optind for param test */ +#endif + if (argv[optind][sp] == '\0') { /* end of argument */ + ++optind; /* get ready for next try */ + sp = 1; /* beginning of next argument */ + } + + if (c == ':' || c == '?' /* optstring syntax conflict */ + || (cp = strchr(optstring, c)) == NULL /* not found */ ) { + return Err(argv[0], "illegal option", c); + } + + if (cp[1] == ':') { /* option takes parameter */ +#ifdef STRICT + if (osp != 1) { + return Err(argv[0], "option must not be clustered", c); + } + + /* reset by end of argument */ + if (sp != 1) { + return Err(argv[0], "option must be followed by white space", + c); + } +#else + if (oind == optind) { /* argument w/o whitespace */ + optarg = &argv[optind][sp]; + sp = 1; /* beginning of next argument */ + } + + else +#endif + if (optind >= argc) { + return Err(argv[0], "option requires an argument", c); + } + + else /* argument w/ whitespace */ + optarg = argv[optind]; + + ++optind; /* skip over parameter */ + } + + return c; +} |