From 2a7aeaa7428c24ea7520a012eb84786e7812e592 Mon Sep 17 00:00:00 2001
From: Joerg Wunsch <j@uriah.heep.sax.de>
Date: Mon, 29 Jan 2007 20:41:47 +0000
Subject: [PATCH] More backend/library abstraction and generalization: turn the
 list_parts() and list_programmers() functions into general list iteration
 functions that call a caller-supplied callback for each element.  Implement
 list_parts() and list_programmers() as private functions in main.c based on
 that approach.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@724 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 avrdude/ChangeLog | 13 +++++++++++++
 avrdude/avrpart.c | 20 ++++++++++++++------
 avrdude/avrpart.h |  6 +++++-
 avrdude/main.c    | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 avrdude/pgm.c     | 21 ++++++++++++++-------
 avrdude/pgm.h     |  6 +++++-
 6 files changed, 97 insertions(+), 15 deletions(-)

diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog
index e2b1d94e..94f6e43f 100644
--- a/avrdude/ChangeLog
+++ b/avrdude/ChangeLog
@@ -1,3 +1,16 @@
+2007-01-29 Joerg Wunsch <j@uriah.heep.sax.de>
+
+	* avrpart.c: More backend/library abstraction and generalization:
+	turn the list_parts() and list_programmers() functions into
+	general list iteration functions that call a caller-supplied
+	callback for each element.  Implement list_parts() and
+	list_programmers() as private functions in main.c based on that
+	approach.
+	* avrpart.h: (Ditto.)
+	* main.c: (Ditto.)
+	* pgm.c: (Ditto.)
+	* pgm.h: (Ditto.)
+
 2007-01-25 Joerg Wunsch <j@uriah.heep.sax.de>
 
 	* Makefile.am: Rearrange everything so it is now built into a
diff --git a/avrdude/avrpart.c b/avrdude/avrpart.c
index 0c4eeeb5..35caee02 100644
--- a/avrdude/avrpart.c
+++ b/avrdude/avrpart.c
@@ -434,21 +434,29 @@ AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode)
   return NULL;
 }
 
-void list_parts(FILE * f, char * prefix, LISTID parts)
+/*
+ * Iterate over the list of avrparts given as "avrparts", and
+ * call the callback function cb for each entry found.  cb is being
+ * passed the following arguments:
+ * . the name of the avrpart (for -p)
+ * . the descriptive text given in the config file
+ * . the name of the config file this avrpart has been defined in
+ * . the line number of the config file this avrpart has been defined at
+ * . the "cookie" passed into walk_avrparts() (opaque client data)
+ */
+void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie)
 {
   LNODEID ln1;
   AVRPART * p;
 
-  for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
+  for (ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) {
     p = ldata(ln1);
-    fprintf(f, "%s%-4s = %-15s [%s:%d]\n",
-            prefix, p->id, p->desc, p->config_file, p->lineno);
+    cb(p->id, p->desc, p->config_file, p->lineno, cookie);
   }
-
-  return;
 }
 
 
+
 static char * reset_disp_str(int r)
 {
   switch (r) {
diff --git a/avrdude/avrpart.h b/avrdude/avrpart.h
index 5b5f6714..693e06e5 100644
--- a/avrdude/avrpart.h
+++ b/avrdude/avrpart.h
@@ -204,9 +204,13 @@ AVRPART * avr_new_part(void);
 AVRPART * avr_dup_part(AVRPART * d);
 AVRPART * locate_part(LISTID parts, char * partdesc);
 AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode);
-void list_parts(FILE * f, char * prefix, LISTID parts);
 void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose);
 
+typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
+                                 const char *cfgname, int cfglineno,
+                                 void *cookie);
+void walk_avrparts(LISTID programmers, walk_avrparts_cb cb, void *cookie);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/avrdude/main.c b/avrdude/main.c
index 8c4e3d7a..1e20a320 100644
--- a/avrdude/main.c
+++ b/avrdude/main.c
@@ -64,6 +64,12 @@ char   progbuf[PATH_MAX]; /* temporary buffer of spaces the same
                              length as progname; used for lining up
                              multiline messages */
 
+struct list_walk_cookie
+{
+    FILE *f;
+    const char *prefix;
+};
+
 static LISTID updates;
 
 /*
@@ -173,6 +179,46 @@ static void update_progress_no_tty (int percent, double etime, char *hdr)
     last = (percent>>1)*2;    /* Make last a multiple of 2. */
 }
 
+static void list_programmers_callback(const char *name, const char *desc,
+                                      const char *cfgname, int cfglineno,
+                                      void *cookie)
+{
+    struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
+
+    fprintf(c->f, "%s%-8s = %-30s [%s:%d]\n",
+            c->prefix, name, desc, cfgname, cfglineno);
+}
+
+static void list_programmers(FILE * f, const char *prefix, LISTID programmers)
+{
+    struct list_walk_cookie c;
+
+    c.f = f;
+    c.prefix = prefix;
+
+    walk_programmers(programmers, list_programmers_callback, &c);
+}
+
+static void list_avrparts_callback(const char *name, const char *desc,
+                                   const char *cfgname, int cfglineno,
+                                   void *cookie)
+{
+    struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
+
+    fprintf(c->f, "%s%-4s = %-15s [%s:%d]\n",
+            c->prefix, name, desc, cfgname, cfglineno);
+}
+
+static void list_parts(FILE * f, const char *prefix, LISTID avrparts)
+{
+    struct list_walk_cookie c;
+
+    c.f = f;
+    c.prefix = prefix;
+
+    walk_avrparts(avrparts, list_avrparts_callback, &c);
+}
+
 /*
  * main routine
  */
diff --git a/avrdude/pgm.c b/avrdude/pgm.c
index 2cd42289..45e66e0a 100644
--- a/avrdude/pgm.c
+++ b/avrdude/pgm.c
@@ -199,17 +199,24 @@ PROGRAMMER * locate_programmer(LISTID programmers, char * configid)
   return NULL;
 }
 
-void list_programmers(FILE * f, char * prefix, LISTID programmers)
+/*
+ * Iterate over the list of programmers given as "programmers", and
+ * call the callback function cb for each entry found.  cb is being
+ * passed the following arguments:
+ * . the name of the programmer (for -c)
+ * . the descriptive text given in the config file
+ * . the name of the config file this programmer has been defined in
+ * . the line number of the config file this programmer has been defined at
+ * . the "cookie" passed into walk_programmers() (opaque client data)
+ */
+void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie)
 {
   LNODEID ln1;
   PROGRAMMER * p;
 
-  for (ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) {
+  for (ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
     p = ldata(ln1);
-    fprintf(f, "%s%-8s = %-30s [%s:%d]\n",
-            prefix, (char *)ldata(lfirst(p->id)), p->desc,
-            p->config_file, p->lineno);
+    cb((char *)ldata(lfirst(p->id)), p->desc, p->config_file, p->lineno, cookie);
   }
-
-  return;
 }
+
diff --git a/avrdude/pgm.h b/avrdude/pgm.h
index 4064b597..247bbc2b 100644
--- a/avrdude/pgm.h
+++ b/avrdude/pgm.h
@@ -112,7 +112,11 @@ PROGRAMMER * pgm_new(void);
 
 void programmer_display(PROGRAMMER * pgm, char * p);
 PROGRAMMER * locate_programmer(LISTID programmers, char * configid);
-void list_programmers(FILE * f, char * prefix, LISTID programmers);
+
+typedef void (*walk_programmers_cb)(const char *name, const char *desc,
+                                    const char *cfgname, int cfglineno,
+                                    void *cookie);
+void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie);
 
 #ifdef __cplusplus
 }