forked from len0rd/rockbox
plugin lib/arg_helper parse 'command line' args
add a helper function to allow plugins to parse the parameter string passed into plugins support included for bool, char, string and numbers+decimals Change-Id: I39f35c8bd3c21b83097a538c19f46d362c468fa4
This commit is contained in:
parent
cab8cea0f0
commit
965572705b
3 changed files with 341 additions and 0 deletions
|
@ -3,6 +3,7 @@ gcc-support.c
|
||||||
pluginlib_actions.c
|
pluginlib_actions.c
|
||||||
helper.c
|
helper.c
|
||||||
icon_helper.c
|
icon_helper.c
|
||||||
|
arg_helper.c
|
||||||
md5.c
|
md5.c
|
||||||
jhash.c
|
jhash.c
|
||||||
configfile.c
|
configfile.c
|
||||||
|
|
287
apps/plugins/lib/arg_helper.c
Normal file
287
apps/plugins/lib/arg_helper.c
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 William Wilgus
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "plugin.h"
|
||||||
|
#include "arg_helper.h"
|
||||||
|
|
||||||
|
#ifndef logf
|
||||||
|
#define logf(...) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SWCHAR '-'
|
||||||
|
#define DECSEPCHAR '.'
|
||||||
|
|
||||||
|
int string_parse(const char **parameter, char* buf, size_t buf_sz)
|
||||||
|
{
|
||||||
|
/* fills buf with a string upto buf_sz, null terminates the buffer
|
||||||
|
* strings break on WS by default but can be enclosed in single or double quotes
|
||||||
|
* opening and closing quotes will not be included in the buffer but will be counted
|
||||||
|
* use alternating quotes if you really want them included '"text"' or "'text'"
|
||||||
|
* failure to close the string will result in eating all remaining args till \0
|
||||||
|
* If buffer full remaining chars are discarded till stopchar or \0 is reached */
|
||||||
|
|
||||||
|
char stopchar = ' ';
|
||||||
|
char stopchars[] = "\'\"";
|
||||||
|
int skipped = 0;
|
||||||
|
int found = 0;
|
||||||
|
const char* start = *parameter;
|
||||||
|
|
||||||
|
if (strchr(stopchars, *start))
|
||||||
|
{
|
||||||
|
logf("stop char %c\n", *start);
|
||||||
|
stopchar = *start;
|
||||||
|
skipped++;
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
while (*start && *start != stopchar)
|
||||||
|
{
|
||||||
|
if (buf_sz > 1)
|
||||||
|
{
|
||||||
|
*buf++ = *start;
|
||||||
|
buf_sz--;
|
||||||
|
}
|
||||||
|
found++;
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
if (*start == stopchar && skipped)
|
||||||
|
{
|
||||||
|
start++;
|
||||||
|
skipped++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buf = '\0';
|
||||||
|
|
||||||
|
if (found > 0)
|
||||||
|
*parameter = start;
|
||||||
|
else
|
||||||
|
skipped = 0;
|
||||||
|
|
||||||
|
return found + skipped;
|
||||||
|
}
|
||||||
|
|
||||||
|
int char_parse(const char **parameter, char* character)
|
||||||
|
{
|
||||||
|
/* passes *character a single character eats remaining non-WS characters */
|
||||||
|
char buf[2];
|
||||||
|
int ret = string_parse(parameter, buf, sizeof(buf));
|
||||||
|
if (ret && character)
|
||||||
|
*character = buf[0];
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int bool_parse(const char **parameter, bool *choice)
|
||||||
|
{
|
||||||
|
/* determine true false using the first character the rest are skipped/ignored */
|
||||||
|
int found = 0;
|
||||||
|
const char tf_val[]="fn0ty1";/* false chars on left f/t should be balanced fffttt */
|
||||||
|
const char* start = *parameter;
|
||||||
|
|
||||||
|
|
||||||
|
char c = tolower(*start);
|
||||||
|
const char *tfval = strchr(tf_val, c);
|
||||||
|
while(isalnum(*++start)) {;}
|
||||||
|
|
||||||
|
if (tfval)
|
||||||
|
{
|
||||||
|
found = start - (*parameter);
|
||||||
|
*parameter = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (choice)
|
||||||
|
*choice = (tfval - tf_val) > (signed int) (sizeof(tf_val) / 2) - 1;
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int longnum_parse(const char **parameter, long *number, long *decimal)
|
||||||
|
{
|
||||||
|
/* passes number and or decimal portion of number base 10 only.. */
|
||||||
|
long num = 0;
|
||||||
|
long dec = 0;
|
||||||
|
int found = 0;
|
||||||
|
int neg = 0;
|
||||||
|
logf ("n: %s\n", *parameter);
|
||||||
|
const char *start = *parameter;
|
||||||
|
|
||||||
|
if (*start == '-')
|
||||||
|
{
|
||||||
|
neg = 1;
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
while (isdigit(*start))
|
||||||
|
{
|
||||||
|
found++;
|
||||||
|
num = num *10 + *start - '0';
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*start == DECSEPCHAR)
|
||||||
|
{
|
||||||
|
start++;
|
||||||
|
while (isdigit(*start))
|
||||||
|
{
|
||||||
|
dec = dec *10 + *start - '0';
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found > 0)
|
||||||
|
{
|
||||||
|
found = start - (*parameter);
|
||||||
|
*parameter = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(number)
|
||||||
|
*number = neg ? -num : num;
|
||||||
|
|
||||||
|
if (decimal)
|
||||||
|
*decimal = dec;
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_parse(const char **parameter, int *number, int *decimal)
|
||||||
|
{
|
||||||
|
long num, dec;
|
||||||
|
int ret = longnum_parse(parameter, &num, &dec);
|
||||||
|
|
||||||
|
if(number)
|
||||||
|
*number = num;
|
||||||
|
|
||||||
|
if (decimal)
|
||||||
|
*decimal = dec;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*argparse(const char *parameter, int parameter_len,
|
||||||
|
* int (*arg_callback)(char argchar, const char **parameter))
|
||||||
|
* parameter : constant char string of arguments
|
||||||
|
* parameter_len : may be set to -1 if your parameter string is NULL (\0) terminated
|
||||||
|
* arg_callback : function gets called for each SWCHAR found in the parameter string
|
||||||
|
* Note: WS at beginning is stripped, **parameter starts at the first NON WS char
|
||||||
|
* return 0 for arg_callback to quit parsing immediately
|
||||||
|
*/
|
||||||
|
void argparse(const char *parameter, int parameter_len, int (*arg_callback)(char argchar, const char **parameter))
|
||||||
|
{
|
||||||
|
bool lastchr;
|
||||||
|
char argchar;
|
||||||
|
const char *start = parameter;
|
||||||
|
while (parameter_len < 0 || (parameter - start) < parameter_len)
|
||||||
|
{
|
||||||
|
switch (*parameter++)
|
||||||
|
{
|
||||||
|
case SWCHAR:
|
||||||
|
{
|
||||||
|
if ((*parameter) == '\0')
|
||||||
|
return;
|
||||||
|
logf ("%s\n",parameter);
|
||||||
|
argchar = *parameter;
|
||||||
|
lastchr = (*(parameter + 1) == '\0');
|
||||||
|
while (*++parameter || lastchr)
|
||||||
|
{
|
||||||
|
lastchr = false;
|
||||||
|
if (isspace(*parameter))
|
||||||
|
continue; /* eat spaces at beginning */
|
||||||
|
if (!arg_callback(argchar, ¶meter))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\0':
|
||||||
|
{
|
||||||
|
if (parameter_len <= 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EXAMPLE USAGE
|
||||||
|
argparse("-n 42 -N 9.9 -n -78.9009 -f -P /rockbox/path/f -s 'Yestest' -B false -B 0 -B true -b n -by -b 1-c ops -c s -k", -1, &arg_callback);
|
||||||
|
|
||||||
|
int arg_callback(char argchar, const char **parameter)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int num, dec;
|
||||||
|
char c;
|
||||||
|
char buf[32];
|
||||||
|
bool bret;
|
||||||
|
logf ("Arg: %c\n", argchar);
|
||||||
|
switch (tolower(argchar))
|
||||||
|
{
|
||||||
|
case 'k' :
|
||||||
|
logf("Option K!");
|
||||||
|
break;
|
||||||
|
case 'c' :
|
||||||
|
ret = char_parse(parameter, &c);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
logf ("Val: %c\n", c);
|
||||||
|
logf("ate %d chars\n", ret);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n' :
|
||||||
|
ret = num_parse(parameter, &num, &dec);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
logf ("Val: %d.%d\n", num, dec);
|
||||||
|
logf("ate %d chars\n", ret);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's' :
|
||||||
|
ret = string_parse(parameter, buf, sizeof(buf));
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
logf ("Val: %s\n", buf);
|
||||||
|
logf("ate %d chars\n", ret);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'p' :
|
||||||
|
ret = string_parse(parameter, buf, sizeof(buf));
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
logf ("Path: %s\n", buf);
|
||||||
|
logf("ate %d chars\n", ret);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'b' :
|
||||||
|
ret = bool_parse(parameter, &bret);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
logf ("Val: %s\n", bret ? "true" : "false");
|
||||||
|
logf("ate %d chars\n", ret);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
logf ("Unknown switch '%c'\n",argchar);
|
||||||
|
//return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
53
apps/plugins/lib/arg_helper.h
Normal file
53
apps/plugins/lib/arg_helper.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 William Wilgus
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef _LIB_ARG_HELPER_H_
|
||||||
|
#define _LIB_ARG_HELPER_H_
|
||||||
|
|
||||||
|
#include "plugin.h"
|
||||||
|
|
||||||
|
/* fills buf with a string upto buf_sz, null terminates the buffer
|
||||||
|
* strings break on WS by default but can be enclosed in single or double quotes
|
||||||
|
* opening and closing quotes will not be included in the buffer but will be counted
|
||||||
|
* use alternating quotes if you really want them included '"text"' or "'text'"
|
||||||
|
* failure to close the string will result in eating all remaining args till \0
|
||||||
|
* If buffer full remaining chars are discarded till stopchar or \0 is reached */
|
||||||
|
int string_parse(const char **parameter, char* buf, size_t buf_sz);
|
||||||
|
/* passes *character a single character eats remaining non-WS characters */
|
||||||
|
int char_parse(const char **parameter, char* character);
|
||||||
|
/* determine true false using the first character the rest are skipped/ignored */
|
||||||
|
int bool_parse(const char **parameter, bool *choice);
|
||||||
|
/* passes number and or decimal portion of number base 10 only.. */
|
||||||
|
int longnum_parse(const char **parameter, long *number, long *decimal);
|
||||||
|
int num_parse(const char **parameter, int *number, int *decimal);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*argparse(const char *parameter, int parameter_len,
|
||||||
|
* int (*arg_callback)(char argchar, const char **parameter))
|
||||||
|
* parameter : constant char string of arguments
|
||||||
|
* parameter_len : may be set to -1 if your parameter string is NULL (\0) terminated
|
||||||
|
* arg_callback : function gets called for each SWCHAR found in the parameter string
|
||||||
|
* Note: WS at beginning is stripped, **parameter starts at the first NON WS char
|
||||||
|
* return 0 for arg_callback to quit parsing immediately
|
||||||
|
*/
|
||||||
|
void argparse(const char *parameter, int parameter_len,
|
||||||
|
int (*arg_callback)(char argchar, const char **parameter));
|
||||||
|
|
||||||
|
#endif /* _LIB_ARG_HELPER_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue