Rework argument parsing.

Heavily simplify the interface of CLI.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2017-06-30 02:14:01 -07:00
committed by yichoi
parent 6b0d9e1b6a
commit e6832f5f27
3 changed files with 368 additions and 433 deletions
+26 -102
View File
@@ -18,134 +18,58 @@
#include <string.h>
/*
* Types for CLI
*/
/**
* Command line option definition
* Command line option definition.
*/
typedef struct
{
int id; /**< unique ID of the option (CLI_OPT_END, CLI_OPT_POSITIONAL, or anything >= 0) */
const char *opt; /**< short option variant (in the form of "-x") */
const char *longopt; /**< long option variant (in the form of "--xxx") */
int argc; /**< number of arguments of the option */
int id; /**< unique ID of the option (CLI_OPT_DEFAULT, or anything >= 0) */
const char *opt; /**< short option variant (in the form of "x" without dashes) */
const char *longopt; /**< long option variant (in the form of "xxx" without dashes) */
const char *meta; /**< name(s) of the argument(s) of the option, for display only */
int quant; /**< quantifier of the option (CLI_QUANT_{Q,A,P,1} for ?,*,+,1), for display only */
const char *help; /**< descriptive help message of the option */
} cli_opt_t;
/**
* Quantifiers of command line options
* Special marker for default option which also marks the end of the option list.
*/
typedef enum
{
CLI_QUANT_Q, /**< ? (Question mark: optional, zero or one) */
CLI_QUANT_A, /**< * (Asterisk, star: zero or one or more) */
CLI_QUANT_P, /**< + (Plus sign: one or more) */
CLI_QUANT_1 /**< 1 (One: one) */
} cli_opt_quant_t;
#define CLI_OPT_DEFAULT -1
/**
* Common command line option IDs
* Returned by cli_consume_option () when no more options are available
* or an error occured.
*/
typedef enum
{
CLI_OPT_POSITIONAL = -1, /**< positional "option" */
CLI_OPT_END = -2, /**< end of options marker */
CLI_OPT_INCOMPLETE = -3, /**< incomplete option (too few arguments) */
CLI_OPT_UNKNOWN = -4 /**< unknown option */
} cli_opt_id_t;
/**
* State of the command line option processor.
* No fields should be accessed other than arg and opt.
*/
typedef struct
{
const cli_opt_t *opts;
int argc;
char **argv;
const cli_opt_t *opt; /**< found option or NULL */
char **arg; /**< array of strings for the last processed option */
} cli_opt_state_t;
/**
* Sub-command definition
*/
typedef struct
{
int id; /**< unique ID of the sub-command (CLI_CMD_END, or anything >= 0) */
const char *cmd; /**< sub-command name (in the form of "xxx") */
const cli_opt_t *opts; /**< array of associated command line option definitions, for display only */
const char *help; /**< descriptive help message of the sub-command */
} cli_cmd_t;
/**
* Common sub-command IDs
*/
typedef enum
{
CLI_CMD_END = -1, /**< end of sub-commands marker */
CLI_CMD_NONE = -1, /**< no sub-command */
CLI_CMD_UNKNOWN = -2 /**< unknown sub-command */
} cli_cmd_id_t;
#define CLI_OPT_END -2
/**
* State of the sub-command processor.
* No fields should be accessed other than arg and cmd.
* No fields should be accessed other than error and arg.
*/
typedef struct
{
const cli_cmd_t *cmds;
int argc;
char **argv;
const cli_cmd_t *cmd; /**< found command or NULL */
char **arg; /**< array of strings for the processed command */
} cli_cmd_state_t;
/* Public fields. */
const char *error; /**< public field for error message */
const char *arg; /**< last processed argument as string */
/*
* Functions for CLI
*/
cli_opt_state_t cli_opt_init (const cli_opt_t *opts, int argc, char **argv);
int cli_opt_process (cli_opt_state_t *state);
void cli_opt_usage (const char *progname, const cli_opt_t *opts);
void cli_opt_help (const cli_opt_t *opts);
cli_cmd_state_t cli_cmd_init (const cli_cmd_t *cmds, int argc, char **argv);
int cli_cmd_process (cli_cmd_state_t *state);
void cli_cmd_help (const cli_cmd_t *cmds);
void cli_cmd_usage (const char *progname, const cli_cmd_t *cmds);
/*
* Useful macros for CLI
*/
/* Private fields. */
int argc; /**< remaining number of arguments */
char **argv; /**< remaining arguments */
const cli_opt_t *opts; /**< options */
} cli_state_t;
/**
* Macro for writing command line option definition struct literals
* Macro for writing command line option definition struct literals.
*/
#define CLI_OPT_DEF(...) /*(cli_opt_t)*/ { __VA_ARGS__ }
/**
* Macro for writing sub-command definition struct literals
/*
* Functions for CLI.
*/
#define CLI_CMD_DEF(...) /*(cli_cmd_t)*/ { __VA_ARGS__ }
/**
* Declare a char VLA and concatenate a program name and a sub-command name
* (separated by a single space) into the new array. Useful for printing command
* line option usage summary for sub-commands.
*
* @param CMDNAME name of the new array variable.
* @param PROGNAME string containing the name of the program.
* @param CMD string continaing the name of the sub-command.
*/
#define CLI_CMD_NAME(CMDNAME, PROGNAME, CMD) \
char CMDNAME[strlen ((PROGNAME)) + strlen ((CMD)) + 2]; \
strncpy (CMDNAME, (PROGNAME), strlen ((PROGNAME))); \
CMDNAME[strlen ((PROGNAME))] = ' '; \
strncpy (CMDNAME + strlen ((PROGNAME)) + 1, (CMD), strlen ((CMD)) + 1)
cli_state_t cli_init (const cli_opt_t *options, int argc, char **argv);
int cli_consume_option (cli_state_t *state);
const char * cli_consume_string (cli_state_t *state);
int cli_consume_int (cli_state_t *state);
void cli_help (const char *progname, const cli_opt_t *options);
#endif /* CLI_H */