Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / lib / libc / getopt / getopt.c
diff --git a/qemu/roms/SLOF/lib/libc/getopt/getopt.c b/qemu/roms/SLOF/lib/libc/getopt/getopt.c
new file mode 100644 (file)
index 0000000..be626dd
--- /dev/null
@@ -0,0 +1,470 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+
+/*
+ * includes
+ *******************************************************************************
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+/*
+ * global variables, types & constants
+ * may be removed if already defined
+ *******************************************************************************
+ */
+int opterr = 1;
+int optopt = 0;
+int optind = 1;
+char *optarg = NULL;
+
+/*
+ * internal values needed by getopt
+ * DO NOT CHANGE or REMOVE
+ */
+enum {
+       OPTIONAL_ARG = 0,
+       MANDATORY_ARG = 1,
+       NO_ARG = 2
+};
+
+/*
+ * variables needed by getopt & getopt_long!
+ * DO NOT REMOVE
+ */
+static char *optstart = NULL;
+
+int
+getopt(int argc, char **argv, const char *options)
+{
+       char *optptr;
+       char *argptr;
+       int optman;
+       int idx;
+       int ret = 0;
+       int argpresent;
+
+       /*
+        * reset used global values
+        */
+       optopt = 0;
+       optarg = NULL;
+
+       /*
+        * reset getopt if a new argv pointer is passed
+        */
+       if (optstart != argv[0]) {
+               optopt = 0;
+               optind = 1;
+               optarg = NULL;
+               optstart = argv[0];
+       }
+
+       /*
+        * return if no more arguments are available
+        */
+       if (optind >= argc) {
+               return -1;
+       }
+
+       /*
+        * start parsing argv[optind]
+        */
+       idx = 0;
+
+       /*
+        * return if the option does not begin with a '-' or has more than 2 characters
+        */
+       if (argv[optind][idx] != '-') {
+
+               if (opterr != 0) {
+                       printf("unknown option \'%s\', expecting \'-\'\n",
+                              argv[optind]);
+               }
+
+               optopt = (int) argv[optind][idx];
+               optind++;
+
+               return '?';
+       }
+
+       /*
+        * continue to the next character in argv[optind]
+        */
+       idx++;
+
+       /*
+        * identify the option
+        * make sure if an option contains a ':' to invalidate the option
+        */
+       optptr = strchr(argv[optind], ':');
+
+       if (optptr == NULL) {
+               optptr = strchr(options, (int) argv[optind][idx]);
+       } else {
+               optptr = NULL;
+       }
+
+       /*
+        * check whether the option is present
+        */
+       if (optptr == NULL) {
+               /*
+                * unknown option detected
+                */
+               if (opterr != 0) {
+                       printf("unknown option \'%s\'\n", argv[optind]);
+               }
+
+               optopt = (int) argv[optind][idx];
+               optind++;
+
+               return '?';
+       }
+
+       /*
+        * the option is present in the option string
+        * setup return value
+        */
+       ret = (int) *optptr;
+
+       /*
+        * get option argument if needed
+        */
+       optptr++;
+
+       /*
+        * determine between mandatory and optional argument
+        */
+       optman = NO_ARG;
+
+       if (*optptr == ':') {
+               optman--;       // now set to MANDATORY_ARG
+       }
+
+       if (optman == MANDATORY_ARG) {
+               optptr++;
+
+               if (*optptr == ':') {
+                       optman--;       // now set to OPTIONAL_ARG
+               }
+
+       }
+
+       /*
+        * if strlen( argv[optind ) is greater than 2,
+        * the argument is in the same argv
+        */
+       if (strlen(argv[optind]) > 2) {
+               argptr = &argv[optind][2];
+
+               /*
+                * do not allow '-' in an argument
+                */
+               if (strchr(argptr, '-') != NULL) {
+
+                       if (opterr != 0) {
+                               printf
+                                   ("illegal argument value \'%s\' for option \'-%c\'\n",
+                                    argptr, ret);
+                       }
+
+                       optopt = ret;
+
+                       return '?';
+               }
+
+       } else {
+               /*
+                * move on to the next argv
+                * it now either contains an argument or the next option
+                */
+               optind++;
+
+               /*
+                * make sure not to overflow
+                */
+               if (optind < argc) {
+                       argptr = argv[optind];
+               } else {
+                       argptr = NULL;
+               }
+
+       }
+
+       /*
+        * do the needed actions for the argument state
+        */
+       switch (optman) {
+       case OPTIONAL_ARG:
+
+               if (argptr == NULL) {
+                       break;
+               }
+
+               if (*argptr != '-') {
+                       /*
+                        * argument present
+                        */
+                       optarg = argptr;
+                       optind++;
+
+               }
+
+
+               break;
+
+       case MANDATORY_ARG:
+               argpresent = (argptr != NULL);
+
+               if (argpresent) {
+                       argpresent = (*argptr != '-');
+               }
+
+               if (argpresent) {
+                       /*
+                        * argument present
+                        */
+                       optarg = argptr;
+                       optind++;
+               } else {
+                       /*
+                        * mandatory argument missing
+                        */
+                       if (opterr != 0) {
+                               printf
+                                   ("missing argument for option \'-%c\'\n",
+                                    ret);
+                       }
+
+                       optopt = ret;
+
+                       /*
+                        * if the first character of options is a ':'
+                        * return a ':' instead of a '?' in case of
+                        * a missing argument
+                        */
+                       if (*options == ':') {
+                               ret = ':';
+                       } else {
+                               ret = '?';
+                       }
+
+               }
+
+
+               break;
+
+       case NO_ARG:
+
+               if (strlen(argv[optind - 1]) > 2) {
+
+                       if (opterr != 0) {
+                               printf
+                                   ("too many arguments for option \'-%c\'\n",
+                                    ret);
+                       }
+
+                       optopt = ret;
+                       ret = '?';
+               }
+
+
+               break;
+
+       }
+
+       return ret;
+}
+
+int
+getopt_long(int argc, char **argv, const char *shortopts,
+           const struct option *longopts, int *indexptr)
+{
+       struct option *optptr = (struct option *) longopts;
+       int optidx = 0;
+       int idx;
+       int ret = 0;
+       int argpresent;
+
+       /*
+        * reset used global values
+        */
+       optopt = 0;
+       optarg = NULL;
+
+       /*
+        * reset indexptr
+        */
+       *indexptr = -1;
+
+       /*
+        * reset getopt if a new argv pointer is passed
+        */
+       if (optstart != argv[0]) {
+               optopt = 0;
+               optind = 1;
+               optarg = NULL;
+               optstart = argv[0];
+       }
+
+       /*
+        * return if no more arguments are available
+        */
+       if (optind >= argc) {
+               return -1;
+       }
+
+       /*
+        * start parsing argv[optind]
+        */
+       idx = 0;
+
+       /*
+        * return if the option does not begin with a '-'
+        */
+       if (argv[optind][idx] != '-') {
+               printf("unknown option \'%s\', expecting \'-\'\n",
+                      argv[optind]);
+
+               optind++;
+
+               return '?';
+       }
+
+       /*
+        * move on to the next character in argv[optind]
+        */
+       idx++;
+
+       /*
+        * return getopt() in case of a short option
+        */
+       if (argv[optind][idx] != '-') {
+               return getopt(argc, argv, shortopts);
+       }
+
+       /*
+        * handle a long option
+        */
+       idx++;
+
+       while (optptr->name != NULL) {
+
+               if (strcmp(&argv[optind][idx], optptr->name) == 0) {
+                       break;
+               }
+
+               optptr++;
+               optidx++;
+       }
+
+       /*
+        * no matching option found
+        */
+       if (optptr->name == NULL) {
+               printf("unknown option \'%s\'\n", argv[optind]);
+
+               optind++;
+
+               return '?';
+       }
+
+       /*
+        * option was found, set up index pointer
+        */
+       *indexptr = optidx;
+
+       /*
+        * get argument
+        */
+       optind++;
+
+       switch (optptr->has_arg) {
+       case no_argument:
+               /*
+                * nothing to do
+                */
+
+               break;
+
+       case required_argument:
+               argpresent = (optind != argc);
+
+               if (argpresent) {
+                       argpresent = (argv[optind][0] != '-');
+               }
+
+               if (argpresent) {
+                       /*
+                        * argument present
+                        */
+                       optarg = argv[optind];
+                       optind++;
+               } else {
+                       /*
+                        * mandatory argument missing
+                        */
+                       printf("missing argument for option \'%s\'\n",
+                              argv[optind - 1]);
+
+                       ret = '?';
+               }
+
+
+               break;
+
+       case optional_argument:
+
+               if (optind == argc) {
+                       break;
+               }
+
+               if (argv[optind][0] != '-') {
+                       /*
+                        * argument present
+                        */
+                       optarg = argv[optind];
+                       optind++;
+               }
+
+
+               break;
+
+       default:
+               printf("unknown argument option for option \'%s\'\n",
+                      argv[optind - 1]);
+
+               ret = '?';
+
+               break;
+
+       }
+
+       /*
+        * setup return values
+        */
+       if (ret != '?') {
+
+               if (optptr->flag == NULL) {
+                       ret = optptr->val;
+               } else {
+                       *optptr->flag = optptr->val;
+                       ret = 0;
+               }
+
+       }
+
+       return ret;
+}