cli: Extract flash argument parsing into cli_common
Move the parsing logic for `-c` and `-p` into the new function
cli_parse_flash_args(). This way it can be shared with other CLIs.
We start a new header file `cli.h` for common CLI functions.
Change-Id: If3f5eff0a2f56a1235038b19b3c1d6586536fd5d
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/72982
diff --git a/cli_classic.c b/cli_classic.c
index a9e8770..2621219 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -29,6 +29,7 @@
#include "fmap.h"
#include "programmer.h"
#include "libflashprog.h"
+#include "cli.h"
static void cli_classic_usage(const char *name)
{
@@ -270,8 +271,7 @@
char *fmapfile = NULL;
char *logfile = NULL;
char *tempstr = NULL;
- char *pname = NULL;
- char *pparam = NULL;
+ struct flash_args flash_args = { 0 };
struct layout_include_args *include_args = NULL;
/*
@@ -328,7 +328,12 @@
dont_verify_all = true;
break;
case 'c':
- chip_to_probe = strdup(optarg);
+ case 'p':
+ ret = cli_parse_flash_args(&flash_args, opt, optarg);
+ if (ret == 1)
+ cli_classic_abort_usage(NULL);
+ else if (ret)
+ exit(1);
break;
case 'V':
verbose_screen++;
@@ -413,26 +418,6 @@
"compiled in. Aborting.\n");
#endif
break;
- case 'p':
- if (pname != NULL) {
- cli_classic_abort_usage("Error: --programmer specified "
- "more than once. You can separate "
- "multiple\nparameters for a programmer "
- "with \",\". Please see the man page "
- "for details.\n");
- }
- const char *const colon = strchr(optarg, ':');
- if (colon) {
- pname = strndup(optarg, colon - optarg);
- pparam = strdup(colon + 1);
- } else {
- pname = strdup(optarg);
- }
- if (!pname || (colon && !pparam)) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
- }
- break;
case 'R':
/* print_version() is always called during startup. */
cli_classic_validate_singleop(&operation_specified);
@@ -510,12 +495,12 @@
goto out;
}
/* Does a chip with the requested name exist in the flashchips array? */
- if (chip_to_probe) {
+ if (flash_args.chip) {
for (chip = flashchips; chip && chip->name; chip++)
- if (!strcmp(chip->name, chip_to_probe))
+ if (!strcmp(chip->name, flash_args.chip))
break;
if (!chip || !chip->name) {
- msg_cerr("Error: Unknown chip '%s' specified.\n", chip_to_probe);
+ msg_cerr("Error: Unknown chip '%s' specified.\n", flash_args.chip);
msg_gerr("Run flashprog -L to view the hardware supported in this flashprog version.\n");
ret = 1;
goto out;
@@ -523,20 +508,20 @@
/* Keep chip around for later usage in case a forced read is requested. */
}
- if (pname == NULL) {
+ if (flash_args.prog_name == NULL) {
const char *const default_programmer = CONFIG_DEFAULT_PROGRAMMER_NAME;
if (default_programmer[0]) {
/* We need to strdup here because we free() unconditionally later. */
- pname = strdup(default_programmer);
- pparam = strdup(CONFIG_DEFAULT_PROGRAMMER_ARGS);
- if (!pname || !pparam) {
+ flash_args.prog_name = strdup(default_programmer);
+ flash_args.prog_args = strdup(CONFIG_DEFAULT_PROGRAMMER_ARGS);
+ if (!flash_args.prog_name || !flash_args.prog_args) {
fprintf(stderr, "Out of memory!\n");
ret = 1;
goto out;
}
msg_pinfo("Using default programmer \"%s\" with arguments \"%s\".\n",
- pname, pparam);
+ flash_args.prog_name, flash_args.prog_args);
} else {
msg_perr("Please select a programmer with the --programmer parameter.\n"
#if CONFIG_INTERNAL == 1
@@ -550,7 +535,7 @@
}
}
- if (flashprog_programmer_init(&prog, pname, pparam)) {
+ if (flashprog_programmer_init(&prog, flash_args.prog_name, flash_args.prog_args)) {
msg_perr("Error: Programmer initialization failed.\n");
ret = 1;
goto out;
@@ -559,6 +544,7 @@
msg_pdbg("The following protocols are supported: %s.\n", tempstr);
free(tempstr);
+ chip_to_probe = flash_args.chip;
struct registered_master *matched_master = NULL;
for (j = 0; j < registered_master_count; j++) {
startchip = 0;
@@ -583,18 +569,18 @@
goto out_shutdown;
} else if (!chipcount) {
msg_cinfo("No EEPROM/flash device found.\n");
- if (!force || !chip_to_probe) {
+ if (!force || !flash_args.chip) {
msg_cinfo("Note: flashprog can never write if the flash chip isn't found "
"automatically.\n");
}
- if (force && read_it && chip_to_probe) {
+ if (force && read_it && flash_args.chip) {
struct registered_master *mst;
int compatible_masters = 0;
msg_cinfo("Force read (-f -r -c) requested, pretending the chip is there:\n");
/* This loop just counts compatible controllers. */
for (j = 0; j < registered_master_count; j++) {
mst = ®istered_masters[j];
- /* chip is still set from the chip_to_probe earlier in this function. */
+ /* chip is still set from the search earlier in this function. */
if (mst->buses_supported & chip->bustype)
compatible_masters++;
}
@@ -614,7 +600,7 @@
}
if (startchip == -1) {
// FIXME: This should never happen! Ask for a bug report?
- msg_cinfo("Probing for flash chip '%s' failed.\n", chip_to_probe);
+ msg_cinfo("Probing for flash chip '%s' failed.\n", flash_args.chip);
ret = 1;
goto out_shutdown;
}
@@ -626,7 +612,7 @@
}
ret = 1;
goto out_shutdown;
- } else if (!chip_to_probe) {
+ } else if (!flash_args.chip) {
/* repeat for convenience when looking at foreign logs */
tempstr = flashbuses_to_text(flashes[0].chip->bustype);
msg_gdbg("Found %s flash chip \"%s\" (%d kB, %s).\n",
@@ -754,10 +740,10 @@
free(fmapfile);
free(referencefile);
free(layoutfile);
- free(pparam);
- free(pname);
+ free(flash_args.prog_args);
+ free(flash_args.prog_name);
+ free(flash_args.chip);
/* clean up global variables */
- free((char *)chip_to_probe); /* Silence! Freeing is not modifying contents. */
chip_to_probe = NULL;
free(logfile);
ret |= close_logfile();