The following commit has been merged in the master branch:
commit e84c47aa298e9bd501f2ea353b4483f02c249eb8
Author: Guillem Jover <guil...@debian.org>
Date:   Tue Aug 9 07:19:09 2011 +0200

    libdpkg: Use a generic pointer to pass the parsed object data around
    
    This will allow code not parsing binary package control files to be
    able to easily reuse the parser, by supplying their own object
    structure.
    
    Unfortunately this sacrifices the type-safety of the parse_stanza()
    and parse_field() functions, but that only affects one variable,
    which should be an acceptable tradeoff given the gain in code reuse.

diff --git a/lib/dpkg/parse.c b/lib/dpkg/parse.c
index 5760eba..c31b1f6 100644
--- a/lib/dpkg/parse.c
+++ b/lib/dpkg/parse.c
@@ -94,12 +94,24 @@ static const struct nickname nicknames[] = {
 };
 
 /**
+ * Package object being parsed.
+ *
+ * Structure used to hold the parsed data for the package being constructed,
+ * before it gets properly inserted into the package database.
+ */
+struct pkg_parse_object {
+  struct pkginfo *pkg;
+  struct pkgbin *pkgbin;
+};
+
+/**
  * Parse the field and value into the package being constructed.
  */
 static void
 pkg_parse_field(struct parsedb_state *ps, struct field_state *fs,
-                struct pkginfo *pkg, struct pkgbin *pkgbin)
+                void *parse_obj)
 {
+  struct pkg_parse_object *pkg_obj = parse_obj;
   const struct nickname *nick;
   const struct fieldinfo *fip;
   int *ip;
@@ -125,7 +137,7 @@ pkg_parse_field(struct parsedb_state *ps, struct 
field_state *fs,
     varbuf_add_buf(&fs->value, fs->valuestart, fs->valuelen);
     varbuf_end_str(&fs->value);
 
-    fip->rcall(pkg, pkgbin, ps, fs->value.buf, fip);
+    fip->rcall(pkg_obj->pkg, pkg_obj->pkgbin, ps, fs->value.buf, fip);
   } else {
     struct arbitraryfield *arp, **larpp;
 
@@ -133,7 +145,7 @@ pkg_parse_field(struct parsedb_state *ps, struct 
field_state *fs,
       parse_error(ps,
                   _("user-defined field name `%.*s' too short"),
                   fs->fieldlen, fs->fieldstart);
-    larpp = &pkgbin->arbs;
+    larpp = &pkg_obj->pkgbin->arbs;
     while ((arp = *larpp) != NULL) {
       if (!strncasecmp(arp->name, fs->fieldstart, fs->fieldlen))
         parse_error(ps,
@@ -356,8 +368,7 @@ parse_open(struct parsedb_state *ps, const char *filename,
  */
 bool
 parse_stanza(struct parsedb_state *ps, struct field_state *fs,
-             parse_field_func *parse_field,
-             struct pkginfo *pkg, struct pkgbin *pkgbin)
+             parse_field_func *parse_field, void *parse_obj)
 {
   int c;
 
@@ -458,7 +469,7 @@ parse_stanza(struct parsedb_state *ps, struct field_state 
*fs,
     while (fs->valuelen && isspace(*(fs->valuestart + fs->valuelen - 1)))
       fs->valuelen--;
 
-    parse_field(ps, fs, pkg, pkgbin);
+    parse_field(ps, fs, parse_obj);
 
     if (parse_EOF(ps) || c == '\n' || c == MSDOS_EOF_CHAR)
       break;
@@ -497,6 +508,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
   struct pkginfo tmp_pkg;
   struct pkginfo *new_pkg, *db_pkg;
   struct pkgbin *new_pkgbin, *db_pkgbin;
+  struct pkg_parse_object pkg_obj;
   int fieldencountered[array_count(fieldinfos)];
   int pdone;
   struct parsedb_state ps;
@@ -516,6 +528,9 @@ int parsedb(const char *filename, enum parsedbflags flags,
   ps.pkg = new_pkg;
   ps.pkgbin = new_pkgbin;
 
+  pkg_obj.pkg = new_pkg;
+  pkg_obj.pkgbin = new_pkgbin;
+
   pdone= 0;
 
   /* Loop per package. */
@@ -523,7 +538,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
     memset(fieldencountered, 0, sizeof(fieldencountered));
     pkg_blank(new_pkg);
 
-    if (!parse_stanza(&ps, &fs, pkg_parse_field, new_pkg, new_pkgbin))
+    if (!parse_stanza(&ps, &fs, pkg_parse_field, &pkg_obj))
       break;
 
     if (pdone && donep)
diff --git a/lib/dpkg/parsedump.h b/lib/dpkg/parsedump.h
index 3563adb..45735c3 100644
--- a/lib/dpkg/parsedump.h
+++ b/lib/dpkg/parsedump.h
@@ -53,11 +53,10 @@ void parse_open(struct parsedb_state *ps, const char 
*filename,
 void parse_close(struct parsedb_state *ps);
 
 typedef void parse_field_func(struct parsedb_state *ps, struct field_state *fs,
-                              struct pkginfo *pkg, struct pkgbin *pkgbin);
+                              void *parse_obj);
 
 bool parse_stanza(struct parsedb_state *ps, struct field_state *fs,
-                  parse_field_func *parse_field,
-                  struct pkginfo *pkg, struct pkgbin *pkgbin);
+                  parse_field_func *parse_field, void *parse_obj);
 
 #define PKGIFPOFF(f) (offsetof(struct pkgbin, f))
 #define PKGPFIELD(pifp,of,type) (*(type*)((char*)(pifp)+(of)))

-- 
dpkg's main repository


-- 
To UNSUBSCRIBE, email to debian-dpkg-cvs-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to