diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-06-10 18:13:03 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-06-10 18:13:03 +0000 |
commit | a9dc123d70ff797d53263df6806d48a3a8def394 (patch) | |
tree | f0eb57d3ce64f26bfdae3a326bdc8d04faf779f9 /nuttx/lib | |
parent | 3a72b47c0c54a63a0abfc3bfd8510ed7f2fc10b9 (diff) | |
download | px4-nuttx-a9dc123d70ff797d53263df6806d48a3a8def394.tar.gz px4-nuttx-a9dc123d70ff797d53263df6806d48a3a8def394.tar.bz2 px4-nuttx-a9dc123d70ff797d53263df6806d48a3a8def394.zip |
Add getopt
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@286 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/lib')
-rw-r--r-- | nuttx/lib/Makefile | 4 | ||||
-rw-r--r-- | nuttx/lib/lib_getopt.c | 259 |
2 files changed, 262 insertions, 1 deletions
diff --git a/nuttx/lib/Makefile b/nuttx/lib/Makefile index d13cc7b1e..107ab055c 100644 --- a/nuttx/lib/Makefile +++ b/nuttx/lib/Makefile @@ -74,6 +74,8 @@ STDLIB_SRCS = lib_getenv.c lib_rand.c MATH_SRCS = lib_rint.c +UNISTD_SRCS = lib_getopt.c + SQ_SRCS = sq_addlast.c sq_addfirst.c sq_addafter.c \ sq_rem.c sq_remlast.c sq_remfirst.c sq_remafter.c @@ -81,7 +83,7 @@ DQ_SRCS = dq_addlast.c dq_addfirst.c dq_addafter.c dq_addbefore.c \ dq_rem.c dq_remlast.c dq_remfirst.c CSRCS = $(MISC_SRCS) $(STRING_SRCS) $(CTYPE_SRCS) $(STDIO_SRCS) \ - $(STDLIB_SRCS) $(MATH_SRCS) $(SQ_SRCS) $(DQ_SRCS) + $(STDLIB_SRCS) $(MATH_SRCS) $(UNISTD_SRCS) $(SQ_SRCS) $(DQ_SRCS) COBJS = $(CSRCS:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) diff --git a/nuttx/lib/lib_getopt.c b/nuttx/lib/lib_getopt.c new file mode 100644 index 000000000..21b7b1aca --- /dev/null +++ b/nuttx/lib/lib_getopt.c @@ -0,0 +1,259 @@ +/**************************************************************************** + * lib_getopt.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <sys/types.h> +#include <unistd.h> +#include <string.h> + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +char *optarg; /* Optional argument following option */ +int optind = 1; /* Index into argv */ +int optopt = '?'; /* unrecognized option character */ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +static char *g_optptr = NULL; +static boolean g_binitialized = FALSE; + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Name + * + * Description: getopt() parses command-line arguments. Its arguments argc + * and argv are the argument count and array as passed to the main() + * function on program invocation. An element of argv that starts with + * '-' is an option element. The characters of this element (aside from + * the initial '-') are option characters. If getopt() is called repeatedly, + * it returns successively each of the option characters from each of the + * option elements. + * + * If getopt() finds another option character, it returns that character, + * updating the external variable optind and a static variable nextchar so + * that the next call to getopt() can resume the scan with the following + * option character or argv-element. + * + * If there are no more option characters, getopt() returns -1. Then optind + * is the index in argv of the first argv-element that is not an option. + * + * The 'optstring argument is a string containing the legitimate option + * characters. If such a character is followed by a colon, this indicates + * that the option requires an argument. If an argument is required for an + * option so getopt() places a pointer to the following text in the same + * argv-element, or the text of the following argv-element, in optarg. + * + * NOTES: + * 1. opterr is not supported and this implementation of getopt() never + * printfs error messages. + * 2. getopt is NOT threadsafe! + * + * Return: If an option was successfully found, then getopt() returns the + * option character. If all command-line options have been parsed, then + * getopt() returns -1. If getopt() encounters an option character that + * was not in optstring, then '?' is returned. If getopt() encounters an + * option with a missing argument, then the return value depends on the + * first character in optstring: if it is ':', then ':' is returned; + * otherwise '?' is returned. + * + ****************************************************************************/ + +int getopt(int argc, char *const argv[], const char *optstring) +{ + if (argv && optstring) + { + int noarg_ret = '?'; + char *optchar; + + /* The inital value of optind is 1. If getopt() is called again in the + * program, optind must be reset to some value <= 1. + */ + + if (optind < 1 || !g_binitialized) + { + optind = 1; /* Skip over the program name */ + g_optptr = NULL; /* Start at the beginning of the first argument */ + g_binitialized = TRUE; /* Now we are initialized */ + } + + /* If the first character of opstring s ':', then ':' is in the event of + * a missing argument. Otherwise '?' is returned. + */ + + if (*optstring == ':') + { + noarg_ret = ':'; + optstring++; + } + + /* Are we resuming in the middle, or at the end of a string of arguments? + * g_optptr == NULL means that we are started at the beginning of argv[optind]; + * *g_optptr == means that we are starting at the beginning of optind+1 + */ + + while (!g_optptr || !*g_optptr) + { + /* We need to start at the beginning of the next argv. Check if we need + * to increment optind + */ + + if (g_optptr) + { + /* Yes.. Increment it and check for the case where where we have + * processed everything in the argv[] array. + */ + + optind++; + if (!argv[optind]) + { + /* There are no more arguments, we are finished */ + + g_optptr = NULL; + g_binitialized = FALSE; + + /* Return -1 with optind == all of the arguments */ + + return ERROR; + } + } + + /* We are starting at the beginning of argv[optind]. In this case, the + * first character must be '-' + */ + + g_optptr = argv[optind]; + if (*g_optptr != '-') + { + /* The argument does not start with '-', we are finished */ + + g_optptr = NULL; + g_binitialized = FALSE; + + /* Return the -1 with optind set to the non-option argument */ + + return ERROR; + } + + /* Skip over the '-' */ + + g_optptr++; + } + + /* Special case handling of "-" and "-:" */ + + if (!*g_optptr) + { + optopt = '\0'; /* We'll fix up g_optptr the next time we are called */ + return '?'; + } + + /* Handle the case of "-:" */ + + if (*g_optptr == ':') + { + optopt = ':'; + g_optptr++; + return '?'; + } + + /* g_optptr now points at the next option and it is not something crazy. + * check if the option is in the list of valid options. + */ + + optchar = strchr(optstring, *g_optptr); + if (!optchar) + { + /* No this character is not in the list of valid options */ + + optopt = *g_optptr; + g_optptr++; + return '?'; + } + + /* Yes, the character is in the list of valid options. Does it have an + * required argument? + */ + + if (optchar[1] != ':') + { + /* No, just return the character that we found */ + + g_optptr++; + return *optchar; + } + + /* Yes. Is the required argument after the command in this same argument? */ + + if (g_optptr[1] != '\0') + { + /* Yes, return a pointer into the current argument */ + + optarg = &g_optptr[1]; + optind++; + g_optptr = NULL; + return *optchar; + } + + /* No.. is the optional argument the next argument in argv[] ? */ + if (argv[optind+1] && *argv[optind+1] != '-') + { + /* Yes.. retun that */ + optarg = argv[optind+1]; + optind += 2; + g_optptr = NULL; + return *optchar; + } + + /* No argument was supplied */ + optarg = NULL; + optopt = *optchar; + optind++; + return noarg_ret; + } + + optind = 1; + return ERROR; +} |