Add lightweight command line processor to jerry-main (#1809)

Eases command line option and sub-command definition, usage summary
and detailed help message printing, and argv processing.

JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
This commit is contained in:
Akos Kiss 2017-05-16 10:29:27 +02:00 committed by GitHub
parent 1501699f48
commit 7837440cbb
5 changed files with 757 additions and 139 deletions

View File

@ -43,8 +43,8 @@ endif()
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_COMMIT_HASH="${JERRY_COMMIT_HASH}")
macro(jerry_create_executable JERRY_NAME SOURCE_JERRY_STANDALONE_MAIN)
add_executable(${JERRY_NAME} ${SOURCE_JERRY_STANDALONE_MAIN})
macro(jerry_create_executable JERRY_NAME)
add_executable(${JERRY_NAME} ${ARGN})
set_property(TARGET ${JERRY_NAME}
PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}")
target_compile_definitions(${JERRY_NAME} PRIVATE ${DEFINES_JERRY})
@ -57,7 +57,7 @@ endmacro()
# Jerry standalones
if(JERRY_CMDLINE)
jerry_create_executable("jerry" "main-unix.c")
jerry_create_executable("jerry" "main-unix.c" "cli.c")
target_link_libraries("jerry" jerry-ext jerry-port-default)
endif()

429
jerry-main/cli.c Normal file
View File

@ -0,0 +1,429 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include "cli.h"
/*
* Fixed layout settings
*/
/**
* Wrap lines at:
*/
#define CLI_LINE_LENGTH 80
/**
* Indent various lines with:
*/
#define CLI_LINE_INDENT 2
/**
* Tab stop (for multi-column display) at:
*/
#define CLI_LINE_TAB 24
/*
* Print helper functions
*/
/**
* Pad with spaces.
*/
static void
cli_print_pad (int cnt) /**< number of spaces to print */
{
for (int i = 0; i < cnt; i++)
{
printf (" ");
}
} /* cli_print_pad */
/**
* Print the prefix of a string.
*/
static void
cli_print_prefix (const char *str, /**< string to print */
int len) /**< length of the prefix to print */
{
for (int i = 0; i < len; i++)
{
printf ("%c", *str++);
}
} /* cli_print_prefix */
/**
* Print a help message wrapped into the second column.
*/
static void
cli_print_help (const char *help) /**< the help message to print */
{
while (help != NULL && *help != 0)
{
int length = -1;
int i = 0;
for (; i < CLI_LINE_LENGTH - CLI_LINE_TAB && help[i] != 0; i++)
{
if (help[i] == ' ')
{
length = i;
}
}
if (length < 0 || i < CLI_LINE_LENGTH - CLI_LINE_TAB)
{
length = i;
}
cli_print_prefix (help, length);
help += length;
while (*help == ' ' && *help != 0)
{
help++;
}
if (*help != 0)
{
printf ("\n");
cli_print_pad (CLI_LINE_TAB);
}
}
} /* cli_print_help */
/*
* Command line option handling
*/
/**
* Initialize a command line option processor.
*
* @return the state that should be passed iteratively to cli_opt_process.
*/
cli_opt_state_t
cli_opt_init (const cli_opt_t *opts, /**< array of option definitions, terminated by CLI_OPT_END */
int argc, /**< number of command line arguments */
char **argv) /**< array of command line arguments */
{
return (cli_opt_state_t)
{
.opts = opts,
.argc = argc,
.argv = argv,
.opt = NULL,
.arg = NULL
};
} /* cli_opt_init */
/**
* Perform one step of the command line option processor.
*
* @return the ID of the option that was found. (The definition of the found
* option (if any) is available via state->opt, while the option
* string and its arguments are available via state->arg[0..].)
* CLI_OPT_END signals that all command line arguments are consumed.
*/
int
cli_opt_process (cli_opt_state_t *state) /**< state of the command line option processor */
{
if (state->argc <= 0)
{
state->opt = NULL;
state->arg = NULL;
return CLI_OPT_END;
}
state->arg = state->argv;
for (const cli_opt_t *o = state->opts; o->id != CLI_OPT_END; o++)
{
state->opt = o;
if (o->id == CLI_OPT_POSITIONAL && (state->arg[0][0] != '-' || !strcmp (state->arg[0], "-")))
{
state->argc--;
state->argv++;
return CLI_OPT_POSITIONAL;
}
else if ((o->opt != NULL && !strcmp (o->opt, state->arg[0]))
|| (o->longopt != NULL && !strcmp (o->longopt, state->arg[0])))
{
if (state->argc > o->argc)
{
state->argc -= 1 + o->argc;
state->argv += 1 + o->argc;
return o->id;
}
else
{
state->argv += state->argc;
state->argc = 0;
return CLI_OPT_INCOMPLETE;
}
}
}
state->opt = NULL;
state->argc--;
state->argv++;
return CLI_OPT_UNKNOWN;
} /* cli_opt_process */
/**
* Print usage summary of options.
*/
void
cli_opt_usage (const char *progname, /**< program name, typically argv[0] */
const cli_opt_t *opts) /**< array of command line option definitions, terminated by CLI_OPT_END */
{
int length = (int) strlen (progname);
printf ("%s", progname);
for (const cli_opt_t *o = opts; o->id != CLI_OPT_END; o++)
{
const char *opt = o->opt != NULL ? o->opt : o->longopt;
opt = opt != NULL ? opt : o->meta;
int opt_length = (int) strlen (opt);
if (o->argc > 0)
{
opt_length += o->meta != NULL ? 1 + (int) strlen (o->meta) : o->argc * 2;
}
opt_length += o->quant == CLI_QUANT_Q || o->quant == CLI_QUANT_A ? 2 : 0;
opt_length += o->quant == CLI_QUANT_P || o->quant == CLI_QUANT_A ? 3 : 0;
if (length + 1 + opt_length >= CLI_LINE_LENGTH)
{
length = CLI_LINE_INDENT - 1;
printf ("\n");
cli_print_pad (length);
}
length += opt_length;
printf (" ");
if (o->quant == CLI_QUANT_Q || o->quant == CLI_QUANT_A)
{
printf ("[");
}
printf ("%s", opt);
if (o->argc > 0)
{
if (o->meta != NULL)
{
printf (" %s", o->meta);
}
else
{
for (int i = 0; i < o->argc; i++)
{
printf (" _");
}
}
}
if (o->quant == CLI_QUANT_Q || o->quant == CLI_QUANT_A)
{
printf ("]");
}
if (o->quant == CLI_QUANT_P || o->quant == CLI_QUANT_A)
{
printf ("...");
}
}
printf ("\n");
} /* cli_opt_usage */
/**
* Print detailed help for options.
*/
void
cli_opt_help (const cli_opt_t *opts) /**< array of command line option definitions, terminated by CLI_OPT_END */
{
for (const cli_opt_t *o = opts; o->id != CLI_OPT_END; o++)
{
int length = CLI_LINE_INDENT;
cli_print_pad (length);
if (o->opt != NULL)
{
printf ("%s", o->opt);
length += (int) strlen (o->opt);
}
if (o->opt != NULL && o->longopt != NULL)
{
printf (", ");
length += 2;
}
if (o->longopt != NULL)
{
printf ("%s", o->longopt);
length += (int) strlen (o->longopt);
}
if (o->opt == NULL && o->longopt == NULL)
{
printf ("%s", o->meta);
length += (int) strlen (o->meta);
}
else if (o->argc > 0)
{
if (o->meta != NULL)
{
printf (" %s", o->meta);
length += 1 + (int) strlen (o->meta);
}
else
{
for (int i = 0; i < o->argc; i++)
{
printf (" _");
}
length += o->argc * 2;
}
}
if (o->help != NULL)
{
if (length >= CLI_LINE_TAB)
{
printf ("\n");
length = 0;
}
cli_print_pad (CLI_LINE_TAB - length);
length = CLI_LINE_TAB;
cli_print_help (o->help);
}
printf ("\n");
}
} /* cli_opt_help */
/*
* Sub-command handling
*/
/**
* Initialize a sub-command processor.
*
* @return the state that should be passed to cli_cmd_process.
*/
cli_cmd_state_t
cli_cmd_init (const cli_cmd_t *cmds, /**< array of sub-command definitions, terminated by CLI_CMD_END */
int argc, /**< number of command line arguments */
char **argv) /**< array of command line arguments */
{
return (cli_cmd_state_t)
{
.cmds = cmds,
.argc = argc,
.argv = argv,
.cmd = NULL,
.arg = NULL
};
} /* cli_cmd_init */
/**
* Process first element of the command line and determine whether it is a
* defined sub-command or not.
*
* @return the ID of the sub-command that was found.
*/
int
cli_cmd_process (cli_cmd_state_t *state) /**< state of the sub-command processor */
{
if (state->argc <= 0 || state->argv[0][0] == '-')
{
state->cmd = NULL;
state->arg = NULL;
return CLI_CMD_NONE;
}
state->arg = state->argv;
for (const cli_cmd_t *c = state->cmds; c->id != CLI_CMD_END; c++)
{
state->cmd = c;
if (!strcmp (c->cmd, state->argv[0]))
{
state->argc--;
state->argv++;
state->cmd = c;
return c->id;
}
}
state->cmd = NULL;
state->argc--;
state->argv++;
return CLI_CMD_UNKNOWN;
} /* cli_cmd_process */
/**
* Print usage summary of all sub-commands.
*/
void
cli_cmd_usage (const char *progname, /**< program name, typically argv[0] */
const cli_cmd_t *cmds) /**< array of sub-command definitions, terminated by CLI_CMD_END */
{
for (const cli_cmd_t *c = cmds; c->id != CLI_CMD_END; c++)
{
if (c->cmd != NULL)
{
CLI_CMD_NAME (cmdname, progname, c->cmd);
cli_opt_usage (cmdname, c->opts);
}
}
} /* cli_cmd_usage */
/**
* Print help of all sub-commands.
*/
void
cli_cmd_help (const cli_cmd_t *cmds) /**< array of sub-command definitions, terminated by CLI_CMD_END */
{
for (const cli_cmd_t *c = cmds; c->id != CLI_CMD_END; c++)
{
int length = CLI_LINE_INDENT;
cli_print_pad (length);
printf ("%s", c->cmd);
length += (int) strlen (c->cmd);
if (c->help != NULL)
{
if (length >= CLI_LINE_TAB)
{
printf ("\n");
length = 0;
}
cli_print_pad (CLI_LINE_TAB - length);
length = CLI_LINE_TAB;
cli_print_help (c->help);
}
printf ("\n");
}
} /* cli_cmd_help */

151
jerry-main/cli.h Normal file
View File

@ -0,0 +1,151 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CLI_H
#define CLI_H
#include <string.h>
/*
* Types for CLI
*/
/**
* 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 */
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
*/
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;
/**
* Common command line option IDs
*/
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;
/**
* State of the sub-command processor.
* No fields should be accessed other than arg and cmd.
*/
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;
/*
* 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
*/
/**
* 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
*/
#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)
#endif /* CLI_H */

View File

@ -23,6 +23,8 @@
#include "jerryscript-port.h"
#include "jerryscript-port-default.h"
#include "cli.h"
/**
* Maximum size of source code
*/
@ -79,40 +81,6 @@ read_file (const char *file_name,
return (const uint32_t *) buffer;
} /* read_file */
static void
print_usage (const char *name)
{
printf ("Usage: %s [OPTION]... [FILE]...\n"
"Try '%s --help' for more information.\n",
name,
name);
} /* print_usage */
static void
print_help (const char *name)
{
printf ("Usage: %s [OPTION]... [FILE]...\n"
"\n"
"Options:\n"
" -h, --help\n"
" -v, --version\n"
" --mem-stats\n"
" --parse-only\n"
" --show-opcodes\n"
" --show-regexp-opcodes\n"
" --start-debug-server\n"
" --save-snapshot-for-global FILE\n"
" --save-snapshot-for-eval FILE\n"
" --save-literals-list-format FILE\n"
" --save-literals-c-format FILE\n"
" --exec-snapshot FILE\n"
" --log-level [0-3]\n"
" --abort-on-fail\n"
" --no-prompt\n"
"\n",
name);
} /* print_help */
/**
* Check whether an error is a SyntaxError or not
*
@ -323,6 +291,68 @@ register_js_function (const char *name_p, /**< name of the function */
jerry_release_value (result_val);
} /* register_js_function */
/**
* Command line option IDs
*/
typedef enum
{
OPT_HELP,
OPT_VERSION,
OPT_MEM_STATS,
OPT_PARSE_ONLY,
OPT_SHOW_OP,
OPT_SHOW_RE_OP,
OPT_DEBUG_SERVER,
OPT_SAVE_SNAP_GLOBAL,
OPT_SAVE_SNAP_EVAL,
OPT_SAVE_LIT_LIST,
OPT_SAVE_LIT_C,
OPT_EXEC_SNAP,
OPT_LOG_LEVEL,
OPT_ABORT_ON_FAIL,
OPT_NO_PROMPT
} main_opt_id_t;
/**
* Command line options
*/
static cli_opt_t main_opts[] =
{
CLI_OPT_DEF (.id = OPT_HELP, .opt = "-h", .longopt = "--help",
.help = "print this help and exit"),
CLI_OPT_DEF (.id = OPT_VERSION, .opt = "-v", .longopt = "--version",
.help = "print tool and library version and exit"),
CLI_OPT_DEF (.id = OPT_MEM_STATS, .longopt = "--mem-stats",
.help = "dump memory statistics"),
CLI_OPT_DEF (.id = OPT_PARSE_ONLY, .longopt = "--parse-only",
.help = "don't execute JS input"),
CLI_OPT_DEF (.id = OPT_SHOW_OP, .longopt = "--show-opcodes",
.help = "dump parser byte-code"),
CLI_OPT_DEF (.id = OPT_SHOW_RE_OP, .longopt = "--show-regexp-opcodes",
.help = "dump regexp byte-code"),
CLI_OPT_DEF (.id = OPT_DEBUG_SERVER, .longopt = "--start-debug-server",
.help = "start debug server and wait for a connecting client"),
CLI_OPT_DEF (.id = OPT_SAVE_SNAP_GLOBAL, .longopt = "--save-snapshot-for-global", .argc = 1, .meta = "FILE",
.help = "save binary snapshot of parsed JS input (for execution in global context)"),
CLI_OPT_DEF (.id = OPT_SAVE_SNAP_EVAL, .longopt = "--save-snapshot-for-eval", .argc = 1, .meta = "FILE",
.help = "save binary snapshot of parsed JS input (for execution in local context by eval)"),
CLI_OPT_DEF (.id = OPT_SAVE_LIT_LIST, .longopt = "--save-literals-list-format", .argc = 1, .meta = "FILE",
.help = "export literals found in parsed JS input (in list format)"),
CLI_OPT_DEF (.id = OPT_SAVE_LIT_C, .longopt = "--save-literals-c-format", .argc = 1, .meta = "FILE",
.help = "export literals found in parsed JS input (in C source format)"),
CLI_OPT_DEF (.id = OPT_EXEC_SNAP, .longopt = "--exec-snapshot", .argc = 1, .meta = "FILE", .quant = CLI_QUANT_A,
.help = "execute input snapshot file(s)"),
CLI_OPT_DEF (.id = OPT_LOG_LEVEL, .longopt = "--log-level", .argc = 1, .meta = "NUM",
.help = "set log level (0-3)"),
CLI_OPT_DEF (.id = OPT_ABORT_ON_FAIL, .longopt = "--abort-on-fail",
.help = "segfault on internal failure (instead of non-zero exit code)"),
CLI_OPT_DEF (.id = OPT_NO_PROMPT, .longopt = "--no-prompt",
.help = "don't print prompt in REPL mode"),
CLI_OPT_DEF (.id = CLI_OPT_POSITIONAL, .meta = "FILE", .quant = CLI_QUANT_A,
.help = "input JS file(s)"),
CLI_OPT_DEF (.id = CLI_OPT_END)
};
/**
* Check whether JerryScript has a requested feature enabled or not. If not,
* print a warning message.
@ -354,14 +384,8 @@ check_usage (bool condition, /**< the condition that must hold */
{
if (!condition)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%s", msg);
if (opt != NULL)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%s", opt);
}
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "\n");
print_usage (name);
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%s%s\n", msg, opt != NULL ? opt : "");
cli_opt_usage (name, main_opts);
exit (JERRY_STANDALONE_EXIT_CODE_FAIL);
}
} /* check_usage */
@ -390,115 +414,129 @@ main (int argc,
bool is_repl_mode = false;
bool no_prompt = false;
for (int i = 1; i < argc; i++)
cli_opt_state_t cli_state = cli_opt_init (main_opts, argc - 1, argv + 1);
for (int id = cli_opt_process (&cli_state); id != CLI_OPT_END; id = cli_opt_process (&cli_state))
{
if (!strcmp ("-h", argv[i]) || !strcmp ("--help", argv[i]))
switch (id)
{
print_help (argv[0]);
return JERRY_STANDALONE_EXIT_CODE_OK;
}
else if (!strcmp ("-v", argv[i]) || !strcmp ("--version", argv[i]))
{
printf ("Version: %d.%d%s\n", JERRY_API_MAJOR_VERSION, JERRY_API_MINOR_VERSION, JERRY_COMMIT_HASH);
return JERRY_STANDALONE_EXIT_CODE_OK;
}
else if (!strcmp ("--mem-stats", argv[i]))
{
if (check_feature (JERRY_FEATURE_MEM_STATS, argv[i]))
case OPT_HELP:
{
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
flags |= JERRY_INIT_MEM_STATS;
cli_opt_usage (argv[0], main_opts);
printf ("\n");
cli_opt_help (main_opts);
return JERRY_STANDALONE_EXIT_CODE_OK;
}
}
else if (!strcmp ("--parse-only", argv[i]))
{
is_parse_only = true;
}
else if (!strcmp ("--show-opcodes", argv[i]))
{
if (check_feature (JERRY_FEATURE_PARSER_DUMP, argv[i]))
case OPT_VERSION:
{
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
flags |= JERRY_INIT_SHOW_OPCODES;
printf ("Version: %d.%d%s\n", JERRY_API_MAJOR_VERSION, JERRY_API_MINOR_VERSION, JERRY_COMMIT_HASH);
return JERRY_STANDALONE_EXIT_CODE_OK;
}
}
else if (!strcmp ("--show-regexp-opcodes", argv[i]))
{
if (check_feature (JERRY_FEATURE_REGEXP_DUMP, argv[i]))
case OPT_MEM_STATS:
{
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
flags |= JERRY_INIT_SHOW_REGEXP_OPCODES;
if (check_feature (JERRY_FEATURE_MEM_STATS, cli_state.arg[0]))
{
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
flags |= JERRY_INIT_MEM_STATS;
}
break;
}
}
else if (!strcmp ("--start-debug-server", argv[i]))
{
if (check_feature (JERRY_FEATURE_DEBUGGER, argv[i]))
case OPT_PARSE_ONLY:
{
flags |= JERRY_INIT_DEBUGGER;
is_parse_only = true;
break;
}
}
else if (!strcmp ("--save-snapshot-for-global", argv[i])
|| !strcmp ("--save-snapshot-for-eval", argv[i]))
{
check_usage (i + 1 < argc, argv[0], "Error: no file specified for ", argv[i]);
check_usage (save_snapshot_file_name_p == NULL, argv[0], "Error: snapshot file name already specified", NULL);
case OPT_SHOW_OP:
{
if (check_feature (JERRY_FEATURE_PARSER_DUMP, cli_state.arg[0]))
{
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
flags |= JERRY_INIT_SHOW_OPCODES;
}
break;
}
case OPT_SHOW_RE_OP:
{
if (check_feature (JERRY_FEATURE_REGEXP_DUMP, cli_state.arg[0]))
{
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
flags |= JERRY_INIT_SHOW_REGEXP_OPCODES;
}
break;
}
case OPT_DEBUG_SERVER:
{
if (check_feature (JERRY_FEATURE_DEBUGGER, cli_state.arg[0]))
{
flags |= JERRY_INIT_DEBUGGER;
}
break;
}
case OPT_SAVE_SNAP_GLOBAL:
case OPT_SAVE_SNAP_EVAL:
{
check_usage (save_snapshot_file_name_p == NULL, argv[0], "Error: snapshot file name already specified", NULL);
if (check_feature (JERRY_FEATURE_SNAPSHOT_SAVE, cli_state.arg[0]))
{
is_save_snapshot_mode = true;
is_save_snapshot_mode_for_global_or_eval = cli_state.opt->id == OPT_SAVE_SNAP_GLOBAL;
save_snapshot_file_name_p = cli_state.arg[1];
}
break;
}
case OPT_SAVE_LIT_LIST:
case OPT_SAVE_LIT_C:
{
check_usage (save_literals_file_name_p == NULL, argv[0], "Error: literal file name already specified", NULL);
if (check_feature (JERRY_FEATURE_SNAPSHOT_SAVE, cli_state.arg[0]))
{
is_save_literals_mode = true;
is_save_literals_mode_in_c_format_or_list = cli_state.opt->id == OPT_SAVE_LIT_C;
save_literals_file_name_p = cli_state.arg[1];
}
break;
}
case OPT_EXEC_SNAP:
{
if (check_feature (JERRY_FEATURE_SNAPSHOT_EXEC, cli_state.arg[0]))
{
exec_snapshot_file_names[exec_snapshots_count++] = cli_state.arg[1];
}
break;
}
case OPT_LOG_LEVEL:
{
check_usage (strlen (cli_state.arg[1]) == 1 && cli_state.arg[1][0] >= '0' && cli_state.arg[1][0] <= '3',
argv[0], "Error: wrong format for ", cli_state.arg[0]);
if (check_feature (JERRY_FEATURE_SNAPSHOT_SAVE, argv[i++]))
{
is_save_snapshot_mode = true;
is_save_snapshot_mode_for_global_or_eval = !strcmp ("--save-snapshot-for-global", argv[i - 1]);
save_snapshot_file_name_p = argv[i];
jerry_port_default_set_log_level ((jerry_log_level_t) (cli_state.arg[1][0] - '0'));
break;
}
}
else if (!strcmp ("--exec-snapshot", argv[i]))
{
check_usage (i + 1 < argc, argv[0], "Error: no file specified for ", argv[i]);
if (check_feature (JERRY_FEATURE_SNAPSHOT_EXEC, argv[i++]))
case OPT_ABORT_ON_FAIL:
{
exec_snapshot_file_names[exec_snapshots_count++] = argv[i];
jerry_port_default_set_abort_on_fail (true);
break;
}
}
else if (!strcmp ("--save-literals-list-format", argv[i])
|| !strcmp ("--save-literals-c-format", argv[i]))
{
check_usage (i + 1 < argc, argv[0], "Error: no file specified for ", argv[i]);
check_usage (save_literals_file_name_p == NULL, argv[0], "Error: literal file name already specified", NULL);
if (check_feature (JERRY_FEATURE_SNAPSHOT_SAVE, argv[i++]))
case OPT_NO_PROMPT:
{
is_save_literals_mode = true;
is_save_literals_mode_in_c_format_or_list = !strcmp ("--save-literals-c-format", argv[i - 1]);
save_literals_file_name_p = argv[i];
no_prompt = true;
break;
}
case CLI_OPT_POSITIONAL:
{
file_names[files_counter++] = cli_state.arg[0];
break;
}
case CLI_OPT_INCOMPLETE:
{
check_usage (false, argv[0], "Error: incomplete option: ", cli_state.arg[0]);
break;
}
case CLI_OPT_UNKNOWN:
default:
{
check_usage (false, argv[0], "Error: unrecognized option: ", cli_state.arg[0]);
break;
}
}
else if (!strcmp ("--log-level", argv[i]))
{
check_usage (i + 1 < argc, argv[0], "Error: no level specified for ", argv[i]);
check_usage (strlen (argv[i + 1]) == 1 && argv[i + 1][0] >= '0' && argv[i + 1][0] <= '3',
argv[0], "Error: wrong format for ", argv[i]);
jerry_port_default_set_log_level ((jerry_log_level_t) (argv[++i][0] - '0'));
}
else if (!strcmp ("--abort-on-fail", argv[i]))
{
jerry_port_default_set_abort_on_fail (true);
}
else if (!strcmp ("--no-prompt", argv[i]))
{
no_prompt = true;
}
else if (!strcmp ("-", argv[i]))
{
file_names[files_counter++] = argv[i];
}
else if (!strncmp ("-", argv[i], 1))
{
check_usage (false, argv[0], "Error: unrecognized option: %s\n", argv[i]);
}
else
{
file_names[files_counter++] = argv[i];
}
}

View File

@ -2,4 +2,4 @@ wrongmathcall:tests/unit-libm/test-libm.inc.h
variableScope:jerry-libm/*.c
invalidPointerCast:jerry-libm/*.c
arithOperationsOnVoidPointer:jerry-libc/*.c
commaSeparatedReturn:jerry-ext/include/jerryscript-ext/arg.impl.h
commaSeparatedReturn:*