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/libflashprog.c b/libflashprog.c
index ea1142d..a7f15b5 100644
--- a/libflashprog.c
+++ b/libflashprog.c
@@ -143,7 +143,33 @@
 		msg_ginfo(".\n");
 		return 1;
 	}
-	return programmer_init(programmer_table[prog], prog_param);
+
+	*flashprog = malloc(sizeof(**flashprog));
+	if (!*flashprog) {
+		msg_gerr("Out of memory!\n");
+		return 1;
+	}
+
+	(*flashprog)->driver = programmer_table[prog];
+	if (prog_param) {
+		(*flashprog)->param = strdup(prog_param);
+		if (!(*flashprog)->param) {
+			msg_gerr("Out of memory!\n");
+			goto _free_err;
+		}
+	} else {
+		(*flashprog)->param = NULL;
+	}
+
+	if (programmer_init(*flashprog))
+		goto _free_err;
+
+	return 0;
+
+_free_err:
+	free((*flashprog)->param);
+	free(*flashprog);
+	return 1;
 }
 
 /**
@@ -154,7 +180,10 @@
  */
 int flashprog_programmer_shutdown(struct flashprog_programmer *const flashprog)
 {
-	return programmer_shutdown();
+	if (programmer_shutdown(flashprog))
+		return 1;
+	free(flashprog);
+	return 0;
 }
 
 /* TODO: flashprog_programmer_capabilities()? */