summaryrefslogtreecommitdiff
path: root/libc/unistd/getopt.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2000-10-11 22:51:00 +0000
committerEric Andersen <andersen@codepoet.org>2000-10-11 22:51:00 +0000
commit174dc1b8cd932fb5cd3d50fe5317e0c29ee26c59 (patch)
tree7683117cfc44f8f09610b5f1f48bcdb1524031bb /libc/unistd/getopt.c
parent1eb3e9989a8241c1654788fc7589e1f679e73dff (diff)
Reorg unistd dir
Diffstat (limited to 'libc/unistd/getopt.c')
-rw-r--r--libc/unistd/getopt.c111
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;
+}