Start implementing struct flashprog_programmer

Our libflashprog API was already prepared for a programmer level context
stored in an opaque `struct flashprog_programmer`. We start filling this
struct with a pointer to the programmer driver (entry in the programmer
table) and a mutable copy of the parameter string.

Change-Id: If9a795627b1e50ea6006569e723f400ff337be20
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/72525
diff --git a/flashprog.c b/flashprog.c
index a9bba8f..e8ab305 100644
--- a/flashprog.c
+++ b/flashprog.c
@@ -130,15 +130,16 @@
 	return rc;
 }
 
-int programmer_init(const struct programmer_entry *prog, const char *param)
+int programmer_init(struct flashprog_programmer *const prog)
 {
 	int ret;
 
-	if (prog == NULL) {
+	if (prog == NULL || prog->driver == NULL) {
 		msg_perr("Invalid programmer specified!\n");
 		return -1;
 	}
-	programmer = prog;
+	programmer = prog->driver;
+	programmer_param = prog->param;
 	/* Initialize all programmer specific data. */
 	/* Default to unlimited decode sizes. */
 	max_rom_decode = (const struct decode_sizes) {
@@ -154,16 +155,6 @@
 	/* Default to allowing writes. Broken programmers set this to 0. */
 	programmer_may_write = true;
 
-	if (param) {
-		programmer_param = strdup(param);
-		if (!programmer_param) {
-			msg_perr("Out of memory!\n");
-			return ERROR_FATAL;
-		}
-	} else {
-		programmer_param = NULL;
-	}
-
 	msg_pdbg("Initializing %s programmer\n", programmer->name);
 	ret = programmer->init();
 	if (programmer_param && strlen(programmer_param)) {
@@ -182,7 +173,6 @@
 			ret = ERROR_FATAL;
 		}
 	}
-	free(programmer_param);
 	programmer_param = NULL;
 	return ret;
 }
@@ -192,7 +182,7 @@
  * require a call to programmer_init() (afterwards).
  *
  * @return The OR-ed result values of all shutdown functions (i.e. 0 on success). */
-int programmer_shutdown(void)
+int programmer_shutdown(struct flashprog_programmer *const prog)
 {
 	int ret = 0;