cli: Extract log argument parsing into cli_common
Move log argument parsing into `cli_common.c` as it's also useful for
other CLIs. Also add a NULL-check for the strdup() return value.
Change-Id: I9b1c9ae2e490edd3560b11b84fddd79e4d396e1d
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/72986
diff --git a/cli_classic.c b/cli_classic.c
index 701c3f5..711db5b 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -246,8 +246,8 @@
char *filename = NULL;
char *referencefile = NULL;
- char *logfile = NULL;
char *tempstr = NULL;
+ struct log_args log_args = { FLASHPROG_MSG_INFO, FLASHPROG_MSG_DEBUG2, NULL };
struct flash_args flash_args = { 0 };
struct layout_args layout_args = { 0 };
struct layout_include_args *include_args = NULL;
@@ -314,9 +314,12 @@
exit(1);
break;
case 'V':
- verbose_screen++;
- if (verbose_screen > FLASHPROG_MSG_DEBUG2)
- verbose_logfile = verbose_screen;
+ case 'o':
+ ret = cli_parse_log_args(&log_args, opt, optarg);
+ if (ret == 1)
+ cli_classic_abort_usage(NULL);
+ else if (ret)
+ exit(1);
break;
case 'E':
cli_classic_validate_singleop(&operation_specified);
@@ -379,17 +382,6 @@
cli_classic_usage(argv[0]);
exit(0);
break;
- case 'o':
- if (logfile) {
- fprintf(stderr, "Warning: -o/--output specified multiple times.\n");
- free(logfile);
- }
-
- logfile = strdup(optarg);
- if (logfile[0] == '\0') {
- cli_classic_abort_usage("No log filename specified.\n");
- }
- break;
case OPTION_PROGRESS:
show_progress = true;
break;
@@ -405,10 +397,10 @@
cli_classic_abort_usage(NULL);
if (referencefile && cli_check_filename(referencefile, "reference"))
cli_classic_abort_usage(NULL);
- if (logfile && cli_check_filename(logfile, "log"))
+ if (log_args.logfile && open_logfile(log_args.logfile))
cli_classic_abort_usage(NULL);
- if (logfile && open_logfile(logfile))
- cli_classic_abort_usage(NULL);
+ verbose_screen = log_args.screen_level;
+ verbose_logfile = log_args.logfile_level;
#if CONFIG_PRINT_WIKI == 1
if (list_supported_wiki) {
@@ -650,9 +642,9 @@
free(flash_args.prog_args);
free(flash_args.prog_name);
free(flash_args.chip);
+ free(log_args.logfile);
/* clean up global variables */
chip_to_probe = NULL;
- free(logfile);
ret |= close_logfile();
return ret;
}
diff --git a/cli_common.c b/cli_common.c
index a772057..787e47d 100644
--- a/cli_common.c
+++ b/cli_common.c
@@ -35,6 +35,34 @@
return 0;
}
+int cli_parse_log_args(struct log_args *const args, const int opt, const char *const optarg)
+{
+ switch (opt) {
+ case OPTION_VERBOSE:
+ args->screen_level++;
+ if (args->screen_level > args->logfile_level)
+ args->logfile_level = args->screen_level;
+ break;
+ case OPTION_LOGFILE:
+ if (cli_check_filename(optarg, "log"))
+ return 1;
+
+ if (args->logfile) {
+ fprintf(stderr, "Warning: -o/--output specified multiple times.\n");
+ free(args->logfile);
+ }
+
+ args->logfile = strdup(optarg);
+ if (!args->logfile) {
+ fprintf(stderr, "Out of memory!\n");
+ return 2;
+ }
+ break;
+ }
+
+ return 0;
+}
+
int cli_parse_flash_args(struct flash_args *const args, const int opt, const char *const optarg)
{
switch (opt) {
diff --git a/include/cli.h b/include/cli.h
index 4ef264d..aec1a46 100644
--- a/include/cli.h
+++ b/include/cli.h
@@ -18,6 +18,8 @@
#include "libflashprog.h"
enum {
+ OPTION_VERBOSE = 'V',
+ OPTION_LOGFILE = 'o',
OPTION_CHIP = 'c',
OPTION_PROGRAMMER = 'p',
OPTION_LAYOUT = 'l',
@@ -32,6 +34,12 @@
OPTION_PROGRESS,
};
+struct log_args {
+ enum flashprog_log_level screen_level;
+ enum flashprog_log_level logfile_level;
+ char *logfile;
+};
+
struct flash_args {
char *chip;
char *prog_name;
@@ -47,6 +55,7 @@
int cli_check_filename(const char *filename, const char *type);
+int cli_parse_log_args(struct log_args *, int opt, const char *optarg);
int cli_parse_flash_args(struct flash_args *, int opt, const char *optarg);
int cli_parse_layout_args(struct layout_args *, int opt, const char *optarg);
int cli_process_layout_args(struct flashprog_layout **, struct flashprog_flashctx *, const struct layout_args *);