cli: Extract layout argument processing

Move the processing of layout arguments (i.e. actual reading
of layout files / data from flash) into a shared function,
cli_process_layout_args().

This changes the sequence in `cli_classic.c` slightly: A layout
file is now read and parsed after the programmer init / chip
probing.

Change-Id: Ibb6574a27bcabc923a53ec355afd384da0665e4c
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/72985
diff --git a/cli_classic.c b/cli_classic.c
index 7ee3b07..701c3f5 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -432,16 +432,6 @@
 	}
 	msg_gdbg("\n");
 
-	if (layout_args.layoutfile && layout_from_file(&layout, layout_args.layoutfile)) {
-		ret = 1;
-		goto out;
-	}
-
-	if (!layout_args.ifd && !layout_args.fmap && !layout_args.fmapfile &&
-	    process_include_args(layout, include_args)) {
-		ret = 1;
-		goto out;
-	}
 	/* Does a chip with the requested name exist in the flashchips array? */
 	if (flash_args.chip) {
 		for (chip = flashchips; chip && chip->name; chip++)
@@ -603,43 +593,12 @@
 		goto out_shutdown;
 	}
 
-	if (layout_args.ifd && (flashprog_layout_read_from_ifd(&layout, fill_flash, NULL, 0) ||
-							process_include_args(layout, include_args))) {
-		ret = 1;
+	ret = cli_process_layout_args(&layout, fill_flash, &layout_args);
+	if (ret)
 		goto out_shutdown;
-	} else if (layout_args.fmapfile) {
-		struct stat s;
-		if (stat(layout_args.fmapfile, &s) != 0) {
-			msg_gerr("Failed to stat fmapfile \"%s\"\n", layout_args.fmapfile);
-			ret = 1;
-			goto out_shutdown;
-		}
-
-		size_t fmapfile_size = s.st_size;
-		uint8_t *fmapfile_buffer = malloc(fmapfile_size);
-		if (!fmapfile_buffer) {
-			ret = 1;
-			goto out_shutdown;
-		}
-
-		if (read_buf_from_file(fmapfile_buffer, fmapfile_size, layout_args.fmapfile)) {
-			ret = 1;
-			free(fmapfile_buffer);
-			goto out_shutdown;
-		}
-
-		if (flashprog_layout_read_fmap_from_buffer(&layout, fill_flash, fmapfile_buffer, fmapfile_size) ||
-		    process_include_args(layout, include_args)) {
-			ret = 1;
-			free(fmapfile_buffer);
-			goto out_shutdown;
-		}
-		free(fmapfile_buffer);
-	} else if (layout_args.fmap && (flashprog_layout_read_fmap_from_rom(&layout, fill_flash, 0,
-			flashprog_flash_getsize(fill_flash)) || process_include_args(layout, include_args))) {
-		ret = 1;
+	ret = process_include_args(layout, include_args);
+	if (ret)
 		goto out_shutdown;
-	}
 
 	flashprog_layout_set(fill_flash, layout);
 	flashprog_flag_set(fill_flash, FLASHPROG_FLAG_FORCE, force);
diff --git a/cli_common.c b/cli_common.c
index 64bb38a..a772057 100644
--- a/cli_common.c
+++ b/cli_common.c
@@ -18,6 +18,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
 
 #include "flash.h"
 #include "cli.h"
@@ -111,6 +112,50 @@
 	return 0;
 }
 
+int cli_process_layout_args(struct flashprog_layout **const layout,
+			    struct flashprog_flashctx *const flash,
+			    const struct layout_args *const args)
+{
+	*layout = NULL;
+
+	if (args->layoutfile) {
+		if (layout_from_file(layout, args->layoutfile))
+			return 1;
+	} else if (args->ifd) {
+		if (flashprog_layout_read_from_ifd(layout, flash, NULL, 0))
+			return 1;
+	} else if (args->fmap) {
+		if (flashprog_layout_read_fmap_from_rom(layout, flash, 0, flashprog_flash_getsize(flash)))
+			return 1;
+	} else if (args->fmapfile) {
+		struct stat s;
+		if (stat(args->fmapfile, &s) != 0) {
+			msg_gerr("Failed to stat fmapfile \"%s\"\n", args->fmapfile);
+			return 1;
+		}
+
+		size_t fmapfile_size = s.st_size;
+		uint8_t *fmapfile_buffer = malloc(fmapfile_size);
+		if (!fmapfile_buffer) {
+			fprintf(stderr, "Out of memory!\n");
+			return 1;
+		}
+
+		if (read_buf_from_file(fmapfile_buffer, fmapfile_size, args->fmapfile)) {
+			free(fmapfile_buffer);
+			return 1;
+		}
+
+		if (flashprog_layout_read_fmap_from_buffer(layout, flash, fmapfile_buffer, fmapfile_size)) {
+			free(fmapfile_buffer);
+			return 1;
+		}
+		free(fmapfile_buffer);
+	}
+
+	return 0;
+}
+
 void print_chip_support_status(const struct flashchip *chip)
 {
 	if (chip->feature_bits & FEATURE_OTP) {
diff --git a/include/cli.h b/include/cli.h
index b243f1d..4ef264d 100644
--- a/include/cli.h
+++ b/include/cli.h
@@ -15,6 +15,8 @@
 #ifndef FLASHPROG_CLI_H
 #define FLASHPROG_CLI_H
 
+#include "libflashprog.h"
+
 enum {
 	OPTION_CHIP = 'c',
 	OPTION_PROGRAMMER = 'p',
@@ -47,5 +49,6 @@
 
 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 *);
 
 #endif