Index: third_party/getopt/getopt.c |
diff --git a/third_party/getopt/getopt.c b/third_party/getopt/getopt.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..11ab8baeb0d9e484f5b7851094117b656fa4f95b |
--- /dev/null |
+++ b/third_party/getopt/getopt.c |
@@ -0,0 +1,410 @@ |
+/**************************************************************************** |
+ |
+getopt.c - Read command line options |
+ |
+AUTHOR: Gregory Pietsch |
+CREATED Fri Jan 10 21:13:05 1997 |
+ |
+DESCRIPTION: |
+ |
+The getopt() function parses the command line arguments. Its arguments argc |
+and argv are the argument count and array as passed to the main() function |
+on program invocation. The argument optstring is a list of available option |
+characters. If such a character is followed by a colon (`:'), the option |
+takes an argument, which is placed in optarg. If such a character is |
+followed by two colons, the option takes an optional argument, which is |
+placed in optarg. If the option does not take an argument, optarg is NULL. |
+ |
+The external variable optind is the index of the next array element of argv |
+to be processed; it communicates from one call to the next which element to |
+process. |
+ |
+The getopt_long() function works like getopt() except that it also accepts |
+long options started by two dashes `--'. If these take values, it is either |
+in the form |
+ |
+--arg=value |
+ |
+ or |
+ |
+--arg value |
+ |
+It takes the additional arguments longopts which is a pointer to the first |
+element of an array of type GETOPT_LONG_OPTION_T. The last element of the |
+array has to be filled with NULL for the name field. |
+ |
+The longind pointer points to the index of the current long option relative |
+to longopts if it is non-NULL. |
+ |
+The getopt() function returns the option character if the option was found |
+successfully, `:' if there was a missing parameter for one of the options, |
+`?' for an unknown option character, and EOF for the end of the option list. |
+ |
+The getopt_long() function's return value is described in the header file. |
+ |
+The function getopt_long_only() is identical to getopt_long(), except that a |
+plus sign `+' can introduce long options as well as `--'. |
+ |
+The following describes how to deal with options that follow non-option |
+argv-elements. |
+ |
+If the caller did not specify anything, the default is REQUIRE_ORDER if the |
+environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. |
+ |
+REQUIRE_ORDER means don't recognize them as options; stop option processing |
+when the first non-option is seen. This is what Unix does. This mode of |
+operation is selected by either setting the environment variable |
+POSIXLY_CORRECT, or using `+' as the first character of the optstring |
+parameter. |
+ |
+PERMUTE is the default. We permute the contents of ARGV as we scan, so that |
+eventually all the non-options are at the end. This allows options to be |
+given in any order, even with programs that were not written to expect this. |
+ |
+RETURN_IN_ORDER is an option available to programs that were written to |
+expect options and other argv-elements in any order and that care about the |
+ordering of the two. We describe each non-option argv-element as if it were |
+the argument of an option with character code 1. Using `-' as the first |
+character of the optstring parameter selects this mode of operation. |
+ |
+The special argument `--' forces an end of option-scanning regardless of the |
+value of ordering. In the case of RETURN_IN_ORDER, only `--' can cause |
+getopt() and friends to return EOF with optind != argc. |
+ |
+COPYRIGHT NOTICE AND DISCLAIMER: |
+ |
+Copyright (C) 1997 Gregory Pietsch |
+ |
+This file and the accompanying getopt.h header file are hereby placed in the |
+public domain without restrictions. Just give the author credit, don't |
+claim you wrote it or prevent anyone else from using it. |
+ |
+Gregory Pietsch's current e-mail address: |
+gpietsch@comcast.net |
+****************************************************************************/ |
+ |
+/* include files */ |
+#include <stdio.h> |
+#include <stdlib.h> |
+#include <string.h> |
+#ifndef GETOPT_H |
+#include "getopt.h" |
+#endif |
+ |
+/* macros */ |
+ |
+/* types */ |
+typedef enum GETOPT_ORDERING_T |
+{ |
+ PERMUTE, |
+ RETURN_IN_ORDER, |
+ REQUIRE_ORDER |
+} GETOPT_ORDERING_T; |
+ |
+/* globally-defined variables */ |
+char *optarg = NULL; |
+int optind = 0; |
+int opterr = 1; |
+int optopt = '?'; |
+ |
+/* functions */ |
+ |
+/* reverse_argv_elements: reverses num elements starting at argv */ |
+static void |
+reverse_argv_elements (char **argv, int num) |
+{ |
+ int i; |
+ char *tmp; |
+ |
+ for (i = 0; i < (num >> 1); i++) |
+ { |
+ tmp = argv[i]; |
+ argv[i] = argv[num - i - 1]; |
+ argv[num - i - 1] = tmp; |
+ } |
+} |
+ |
+/* permute: swap two blocks of argv-elements given their lengths */ |
+static void |
+permute (char **argv, int len1, int len2) |
+{ |
+ reverse_argv_elements (argv, len1); |
+ reverse_argv_elements (argv, len1 + len2); |
+ reverse_argv_elements (argv, len2); |
+} |
+ |
+/* is_option: is this argv-element an option or the end of the option list? */ |
+static int |
+is_option (char *argv_element, int only) |
+{ |
+ return ((argv_element == NULL) |
+ || (argv_element[0] == '-') || (only && argv_element[0] == '+')); |
+} |
+ |
+/* getopt_internal: the function that does all the dirty work */ |
+static int |
+getopt_internal (int argc, char **argv, char *shortopts, |
+ GETOPT_LONG_OPTION_T * longopts, int *longind, int only) |
+{ |
+ GETOPT_ORDERING_T ordering = PERMUTE; |
+ static size_t optwhere = 0; |
+ size_t permute_from = 0; |
+ int num_nonopts = 0; |
+ int optindex = 0; |
+ size_t match_chars = 0; |
+ char *possible_arg = NULL; |
+ int longopt_match = -1; |
+ int has_arg = -1; |
+ char *cp = NULL; |
+ int arg_next = 0; |
+ |
+ /* first, deal with silly parameters and easy stuff */ |
+ if (argc == 0 || argv == NULL || (shortopts == NULL && longopts == NULL)) |
+ return (optopt = '?'); |
+ if (optind >= argc || argv[optind] == NULL) |
+ return EOF; |
+ if (strcmp (argv[optind], "--") == 0) |
+ { |
+ optind++; |
+ return EOF; |
+ } |
+ /* if this is our first time through */ |
+ if (optind == 0) { |
+ optind = 1; |
+ optwhere = 1; |
+ } |
+ |
+ /* define ordering */ |
+ if (shortopts != NULL && (*shortopts == '-' || *shortopts == '+')) |
+ { |
+ ordering = (*shortopts == '-') ? RETURN_IN_ORDER : REQUIRE_ORDER; |
+ shortopts++; |
+ } |
+ else |
+ ordering = (getenv ("POSIXLY_CORRECT") != NULL) ? REQUIRE_ORDER : PERMUTE; |
+ |
+ /* |
+ * based on ordering, find our next option, if we're at the beginning of |
+ * one |
+ */ |
+ if (optwhere == 1) |
+ { |
+ switch (ordering) |
+ { |
+ case PERMUTE: |
+ permute_from = optind; |
+ num_nonopts = 0; |
+ while (!is_option (argv[optind], only)) |
+ { |
+ optind++; |
+ num_nonopts++; |
+ } |
+ if (argv[optind] == NULL) |
+ { |
+ /* no more options */ |
+ optind = (int)permute_from; |
+ return EOF; |
+ } |
+ else if (strcmp (argv[optind], "--") == 0) |
+ { |
+ /* no more options, but have to get `--' out of the way */ |
+ permute (argv + permute_from, num_nonopts, 1); |
+ optind = (int)(permute_from + 1); |
+ return EOF; |
+ } |
+ break; |
+ case RETURN_IN_ORDER: |
+ if (!is_option (argv[optind], only)) |
+ { |
+ optarg = argv[optind++]; |
+ return (optopt = 1); |
+ } |
+ break; |
+ case REQUIRE_ORDER: |
+ if (!is_option (argv[optind], only)) |
+ return EOF; |
+ break; |
+ } |
+ } |
+ /* we've got an option, so parse it */ |
+ |
+ /* first, is it a long option? */ |
+ if (longopts != NULL |
+ && (memcmp (argv[optind], "--", 2) == 0 |
+ || (only && argv[optind][0] == '+')) && optwhere == 1) |
+ { |
+ /* handle long options */ |
+ if (memcmp (argv[optind], "--", 2) == 0) |
+ optwhere = 2; |
+ longopt_match = -1; |
+ possible_arg = strchr (argv[optind] + optwhere, '='); |
+ if (possible_arg == NULL) |
+ { |
+ /* no =, so next argv might be arg */ |
+ match_chars = strlen (argv[optind]); |
+ possible_arg = argv[optind] + match_chars; |
+ match_chars = match_chars - optwhere; |
+ } |
+ else |
+ match_chars = (possible_arg - argv[optind]) - optwhere; |
+ for (optindex = 0; longopts[optindex].name != NULL; optindex++) |
+ { |
+ if (memcmp (argv[optind] + optwhere, |
+ longopts[optindex].name, match_chars) == 0) |
+ { |
+ /* do we have an exact match? */ |
+ if (match_chars == strlen (longopts[optindex].name)) |
+ { |
+ longopt_match = optindex; |
+ break; |
+ } |
+ /* do any characters match? */ |
+ else |
+ { |
+ if (longopt_match < 0) |
+ longopt_match = optindex; |
+ else |
+ { |
+ /* we have ambiguous options */ |
+ if (opterr) |
+ fprintf (stderr, "%s: option `%s' is ambiguous " |
+ "(could be `--%s' or `--%s')\n", |
+ argv[0], |
+ argv[optind], |
+ longopts[longopt_match].name, |
+ longopts[optindex].name); |
+ return (optopt = '?'); |
+ } |
+ } |
+ } |
+ } |
+ if (longopt_match >= 0) |
+ has_arg = longopts[longopt_match].has_arg; |
+ } |
+ /* if we didn't find a long option, is it a short option? */ |
+ if (longopt_match < 0 && shortopts != NULL) |
+ { |
+ cp = strchr (shortopts, argv[optind][optwhere]); |
+ if (cp == NULL) |
+ { |
+ /* couldn't find option in shortopts */ |
+ if (opterr) |
+ fprintf (stderr, |
+ "%s: invalid option -- `-%c'\n", |
+ argv[0], argv[optind][optwhere]); |
+ optwhere++; |
+ if (argv[optind][optwhere] == '\0') |
+ { |
+ optind++; |
+ optwhere = 1; |
+ } |
+ return (optopt = '?'); |
+ } |
+ has_arg = ((cp[1] == ':') |
+ ? ((cp[2] == ':') ? OPTIONAL_ARG : required_argument) : no_argument); |
+ possible_arg = argv[optind] + optwhere + 1; |
+ optopt = *cp; |
+ } |
+ /* get argument and reset optwhere */ |
+ arg_next = 0; |
+ switch (has_arg) |
+ { |
+ case OPTIONAL_ARG: |
+ if (*possible_arg == '=') |
+ possible_arg++; |
+ if (*possible_arg != '\0') |
+ { |
+ optarg = possible_arg; |
+ optwhere = 1; |
+ } |
+ else |
+ optarg = NULL; |
+ break; |
+ case required_argument: |
+ if (*possible_arg == '=') |
+ possible_arg++; |
+ if (*possible_arg != '\0') |
+ { |
+ optarg = possible_arg; |
+ optwhere = 1; |
+ } |
+ else if (optind + 1 >= argc) |
+ { |
+ if (opterr) |
+ { |
+ fprintf (stderr, "%s: argument required for option `", argv[0]); |
+ if (longopt_match >= 0) |
+ fprintf (stderr, "--%s'\n", longopts[longopt_match].name); |
+ else |
+ fprintf (stderr, "-%c'\n", *cp); |
+ } |
+ optind++; |
+ return (optopt = ':'); |
+ } |
+ else |
+ { |
+ optarg = argv[optind + 1]; |
+ arg_next = 1; |
+ optwhere = 1; |
+ } |
+ break; |
+ case no_argument: |
+ if (longopt_match < 0) |
+ { |
+ optwhere++; |
+ if (argv[optind][optwhere] == '\0') |
+ optwhere = 1; |
+ } |
+ else |
+ optwhere = 1; |
+ optarg = NULL; |
+ break; |
+ } |
+ |
+ /* do we have to permute or otherwise modify optind? */ |
+ if (ordering == PERMUTE && optwhere == 1 && num_nonopts != 0) |
+ { |
+ permute (argv + permute_from, num_nonopts, 1 + arg_next); |
+ optind = (int)(permute_from + 1 + arg_next); |
+ } |
+ else if (optwhere == 1) |
+ optind = optind + 1 + arg_next; |
+ |
+ /* finally return */ |
+ if (longopt_match >= 0) |
+ { |
+ if (longind != NULL) |
+ *longind = longopt_match; |
+ if (longopts[longopt_match].flag != NULL) |
+ { |
+ *(longopts[longopt_match].flag) = longopts[longopt_match].val; |
+ return 0; |
+ } |
+ else |
+ return longopts[longopt_match].val; |
+ } |
+ else |
+ return optopt; |
+} |
+ |
+int |
+getopt (int argc, char **argv, char *optstring) |
+{ |
+ return getopt_internal (argc, argv, optstring, NULL, NULL, 0); |
+} |
+ |
+int |
+getopt_long (int argc, char **argv, const char *shortopts, |
+ const GETOPT_LONG_OPTION_T * longopts, int *longind) |
+{ |
+ return getopt_internal (argc, argv, (char*)shortopts, (GETOPT_LONG_OPTION_T*)longopts, longind, 0); |
+} |
+ |
+int |
+getopt_long_only (int argc, char **argv, const char *shortopts, |
+ const GETOPT_LONG_OPTION_T * longopts, int *longind) |
+{ |
+ return getopt_internal (argc, argv, (char*)shortopts, (GETOPT_LONG_OPTION_T*)longopts, longind, 1); |
+} |
+ |
+/* end of file GETOPT.C */ |