diff options
Diffstat (limited to 'qemu/roms/SLOF/lib/libc/getopt/getopt.c')
-rw-r--r-- | qemu/roms/SLOF/lib/libc/getopt/getopt.c | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/lib/libc/getopt/getopt.c b/qemu/roms/SLOF/lib/libc/getopt/getopt.c new file mode 100644 index 000000000..be626ddc2 --- /dev/null +++ b/qemu/roms/SLOF/lib/libc/getopt/getopt.c @@ -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; +} |