217 lines
6.1 KiB
C
217 lines
6.1 KiB
C
/****************************************************************************
|
|
* 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 <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|