Add getopt
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@286 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
eff35dc99f
commit
00d1800b76
@ -182,5 +182,7 @@
|
||||
* tools/mkdeps.sh & arch/arm/src/Makefile: Corrected a problem makeing dependencies
|
||||
* tools/zipme.sh: Force directory name to be nuttx-xx.yy.zz
|
||||
* fs/fs_opendir.c: Correct errors in semaphore usage that can cause deadlock.
|
||||
* lib/lib_getopt.c: Added getopt() support
|
||||
* examples/nsh: NSH now supports mount, umount, and mkdir.
|
||||
* Started m68322
|
||||
|
||||
|
@ -617,6 +617,8 @@ Other memory:
|
||||
* tools/mkdeps.sh & arch/arm/src/Makefile: Corrected a problem makeing dependencies
|
||||
* tools/zipme.sh: Force directory name to be nuttx-xx.yy.zz
|
||||
* fs/fs_opendir.c: Correct errors in semaphore usage that can cause deadlock.
|
||||
* lib/lib_getopt.c: Added getopt() support
|
||||
* examples/nsh: NSH now supports mount, umount, and mkdir.
|
||||
* Started m68322
|
||||
</pre></ul>
|
||||
|
||||
|
@ -97,7 +97,7 @@
|
||||
#define fdatasync(f) fsync(f)
|
||||
|
||||
/************************************************************
|
||||
* Global Function Prototypes
|
||||
* Global Variables
|
||||
************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
@ -108,6 +108,16 @@ extern "C" {
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* Used by getopt (obviously NOT thread safe!) */
|
||||
|
||||
EXTERN char *optarg; /* Optional argument following option */
|
||||
EXTERN int optind; /* Index into argv */
|
||||
EXTERN int optopt; /* unrecognized option character */
|
||||
|
||||
/************************************************************
|
||||
* Global Function Prototypes
|
||||
************************************************************/
|
||||
|
||||
/* Task Control Interfaces */
|
||||
|
||||
EXTERN pid_t getpid(void);
|
||||
@ -131,6 +141,10 @@ EXTERN int write(int fd, const void *buf, unsigned int nbytes);
|
||||
EXTERN int unlink(const char *pathname);
|
||||
EXTERN int rmdir(const char *pathname);
|
||||
|
||||
/* Other */
|
||||
|
||||
EXTERN int getopt(int argc, char *const argv[], const char *optstring);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -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)
|
||||
|
259
lib/lib_getopt.c
Normal file
259
lib/lib_getopt.c
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user