/**************************************************************************** * apps/system/hexed/src/cmdargs.c * Command line argument parsing * * Copyright (c) 2011, B.ZaaR, All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 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. * * The names of contributors may not 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 #include #include #include "cmdargs.h" /**************************************************************************** * Public Data ****************************************************************************/ FAR struct cmdargs_s *g_cmdargs = NULL; /**************************************************************************** * Private Data ****************************************************************************/ /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: parsecmdargs * * Description: * Parse the command line arguments * * Input parameters: * argv - The command line arguments * arglist - The array or supported arguments * * Returned Value: * One success, the argument ID is returned. EOF is returned on any * failure. * ****************************************************************************/ int parsecmdargs(FAR char *argv[], FAR const struct arglist_s *arglist) { FAR char *arg; int i; /* Get next arg */ g_cmdargs->argid = 0; if ((g_cmdargs->flags & CMDARGS_FL_SINGLE) == 0) { g_cmdargs->idx++; arg = argv[g_cmdargs->idx]; g_cmdargs->flags = 0; } else { /* Skip over this argument */ arg = g_cmdargs->arg + 1; g_cmdargs->flags &= CMDARGS_FL_RESET; } /* End of command line */ if (argv[g_cmdargs->idx] == NULL) { memset(g_cmdargs, 0, sizeof(struct cmdargs_s)); return EOF; } /* Check for argument */ g_cmdargs->arg = arg; if (*arg == '-') { g_cmdargs->flags |= CMDARGS_FL_SETARG; arg++; if (*arg == '-') { arg++; g_cmdargs->flags |= CMDARGS_FL_LONGARG; } } /* Scan arglist */ if ((g_cmdargs->flags & CMDARGS_FL_SETARG) != 0) { for (i = 1; arglist->name != NULL; i++, arglist++) { /* Skip long args in single step mode */ if ((g_cmdargs->flags & CMDARGS_FL_SINGLE) != 0 && strlen(arglist->name) > 1) { continue; } /* Check arg for match in arglist */ if (strncmp(arg, arglist->name, strlen(arglist->name)) == 0) { /* The long arg flag is set but we've found a single arg match */ if (strlen(arglist->name) == 1 && (g_cmdargs->flags & CMDARGS_FL_LONGARG) != 0) { break; } g_cmdargs->argid = i; break; } } } /* Found argument */ if (g_cmdargs->argid > 0) { g_cmdargs->arg = arg; g_cmdargs->opt = NULL; g_cmdargs->flags |= CMDARGS_FL_CALLMASK(arglist->flags); arg += strlen(arglist->name); /* Argument accepts options */ if ((g_cmdargs->flags & CMDARGS_FL_OPT) != 0) { /* Option in same arg */ if (*arg != '\0') { /* Option set after ":=" */ if (strchr(":=", *arg)) { arg++; g_cmdargs->opt = arg; /* Error setting arg/option */ } else { g_cmdargs->opt = NULL; } /* Option in next arg */ } else if (argv[g_cmdargs->idx + 1] != NULL && *argv[g_cmdargs->idx + 1] != '\0' && *argv[g_cmdargs->idx + 1] != '-') { g_cmdargs->idx++; g_cmdargs->opt = argv[g_cmdargs->idx]; } } /* Single step through this arg */ if (strlen(arglist->name) == 1 && *arg != '\0' && (g_cmdargs->flags & CMDARGS_FL_OPTREQ) != CMDARGS_FL_OPTREQ && g_cmdargs->opt == NULL) { g_cmdargs->flags |= CMDARGS_FL_SINGLE; } else { g_cmdargs->flags &= ~CMDARGS_FL_SINGLE; } } /* No valid argument found */ else { g_cmdargs->flags = 0; g_cmdargs->opt = NULL; } return g_cmdargs->argid; }