cli: Extract layout argument parsing into cli_common

Move the parsing logic for layout sources into the new function
cli_parse_layout_args(). This way it can be shared with other CLIs.

Signed-off-by: Nico Huber <nico.h@gmx.de>

Change-Id: Idcbb136d31477cdb0aebec4af0c4cbc873f26011
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/72984
Tested-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Nico Huber <nico.h@gmx.de>
diff --git a/cli_common.c b/cli_common.c
index c364efa..64bb38a 100644
--- a/cli_common.c
+++ b/cli_common.c
@@ -22,6 +22,18 @@
 #include "flash.h"
 #include "cli.h"
 
+int cli_check_filename(const char *const filename, const char *const type)
+{
+	if (!filename || (filename[0] == '\0')) {
+		fprintf(stderr, "Error: No %s file specified.\n", type);
+		return 1;
+	}
+	/* Not an error, but maybe the user intended to specify a CLI option instead of a file name. */
+	if (filename[0] == '-' && filename[1] != '\0')
+		fprintf(stderr, "Warning: Supplied %s file name starts with -\n", type);
+	return 0;
+}
+
 int cli_parse_flash_args(struct flash_args *const args, const int opt, const char *const optarg)
 {
 	switch (opt) {
@@ -60,6 +72,45 @@
 	return 0;
 }
 
+int cli_parse_layout_args(struct layout_args *const args, const int opt, const char *const optarg)
+{
+	if (args->layoutfile || args->ifd || args->fmap || args->fmapfile) {
+		fprintf(stderr, "Error: Only one layout source may be specified.\n");
+		return 1;
+	}
+
+	switch (opt) {
+	case OPTION_LAYOUT:
+		if (cli_check_filename(optarg, "layout"))
+			return 1;
+
+		args->layoutfile = strdup(optarg);
+		if (!args->layoutfile) {
+			fprintf(stderr, "Out of memory!\n");
+			return 2;
+		}
+		break;
+	case OPTION_IFD:
+		args->ifd = true;
+		break;
+	case OPTION_FMAP:
+		args->fmap = true;
+		break;
+	case OPTION_FMAP_FILE:
+		if (cli_check_filename(optarg, "fmap"))
+			return 1;
+
+		args->fmapfile = strdup(optarg);
+		if (!args->fmapfile) {
+			fprintf(stderr, "Out of memory!\n");
+			return 2;
+		}
+		break;
+	}
+
+	return 0;
+}
+
 void print_chip_support_status(const struct flashchip *chip)
 {
 	if (chip->feature_bits & FEATURE_OTP) {