Explorar el Código

libdpkg: Refactor parsedb_state into a new structure

Move state variables into a new struct and pass that instead of each of
them to the error, warning and field parsing functions. This is cleaner,
and should be “marginally” faster.
Guillem Jover hace 17 años
padre
commit
645a9e329f
Se han modificado 5 ficheros con 142 adiciones y 142 borrados
  1. 0 1
      TODO
  2. 74 85
      lib/fields.c
  3. 37 29
      lib/parse.c
  4. 15 10
      lib/parsedump.h
  5. 16 17
      lib/parsehelp.c

+ 0 - 1
TODO

@@ -37,7 +37,6 @@ squeeze + 1
    - Coalesce admindir / infodir / foodir generation.
    - Coalesce admindir / infodir / foodir generation.
    - Get rid of setjmp (at least in the general case, keep for dpkg itself?)
    - Get rid of setjmp (at least in the general case, keep for dpkg itself?)
    - Coalesce hash and checksum functions.
    - Coalesce hash and checksum functions.
-   - Move parseerr arguments into a struct (need to push the patch).
    - Split modstatdb_rw into mode and flags.
    - Split modstatdb_rw into mode and flags.
    - Move fd and block function out of mlib.
    - Move fd and block function out of mlib.
    - Cleanup status chars -> strings hardcoded mappings all over the place.
    - Cleanup status chars -> strings hardcoded mappings all over the place.

+ 74 - 85
lib/fields.c

@@ -34,7 +34,7 @@
 #include "parsedump.h"
 #include "parsedump.h"
 
 
 static int
 static int
-convert_string(const char *filename, int lno, const char *what, int otherwise,
+convert_string(struct parsedb_state *ps, const char *what, int otherwise,
                const struct pkginfo *pigp,
                const struct pkginfo *pigp,
                const char *startp, const struct namevalue *ivip,
                const char *startp, const struct namevalue *ivip,
                const char **endpp)
                const char **endpp)
@@ -43,7 +43,7 @@ convert_string(const char *filename, int lno, const char *what, int otherwise,
   const struct namevalue *nvip = ivip;
   const struct namevalue *nvip = ivip;
 
 
   if (!*startp)
   if (!*startp)
-    parse_error(filename, lno, pigp, _("%s is missing"), what);
+    parse_error(ps, pigp, _("%s is missing"), what);
   while (nvip->name) {
   while (nvip->name) {
     if (strncasecmp(nvip->name, startp, nvip->length))
     if (strncasecmp(nvip->name, startp, nvip->length))
       nvip++;
       nvip++;
@@ -52,7 +52,7 @@ convert_string(const char *filename, int lno, const char *what, int otherwise,
   }
   }
   if (!nvip->name) {
   if (!nvip->name) {
     if (otherwise != -1) return otherwise;
     if (otherwise != -1) return otherwise;
-    parse_error(filename, lno, pigp, _("`%.*s' is not allowed for %s"),
+    parse_error(ps, pigp, _("`%.*s' is not allowed for %s"),
                 strnlen(startp, 50), startp, what);
                 strnlen(startp, 50), startp, what);
   }
   }
 
 
@@ -60,17 +60,19 @@ convert_string(const char *filename, int lno, const char *what, int otherwise,
   while (isspace(*ep))
   while (isspace(*ep))
     ep++;
     ep++;
   if (*ep && !endpp)
   if (*ep && !endpp)
-    parse_error(filename, lno, pigp, _("junk after %s"), what);
+    parse_error(ps, pigp, _("junk after %s"), what);
   if (endpp) *endpp= ep;
   if (endpp) *endpp= ep;
   return nvip->value;
   return nvip->value;
 }
 }
 
 
-void f_name(struct pkginfo *pigp, struct pkginfoperfile *pifp, enum parsedbflags flags,
-            const char *filename, int lno, FILE *warnto, int *warncount,
-            const char *value, const struct fieldinfo *fip) {
+void
+f_name(struct pkginfo *pigp, struct pkginfoperfile *pifp,
+       struct parsedb_state *ps,
+       const char *value, const struct fieldinfo *fip)
+{
   const char *e;
   const char *e;
   if ((e= illegal_packagename(value,NULL)) != NULL)
   if ((e= illegal_packagename(value,NULL)) != NULL)
-    parse_error(filename, lno, pigp, _("invalid package name (%.250s)"), e);
+    parse_error(ps, pigp, _("invalid package name (%.250s)"), e);
   pigp->name= findpackage(value)->name;
   pigp->name= findpackage(value)->name;
   /* We use the new name, as findpackage() may have
   /* We use the new name, as findpackage() may have
      done a tolower for us.
      done a tolower for us.
@@ -78,17 +80,16 @@ void f_name(struct pkginfo *pigp, struct pkginfoperfile *pifp, enum parsedbflags
 }
 }
 
 
 void f_filecharf(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_filecharf(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-                 enum parsedbflags flags,
-                 const char *filename, int lno, FILE *warnto, int *warncount,
+                 struct parsedb_state *ps,
                  const char *value, const struct fieldinfo *fip) {
                  const char *value, const struct fieldinfo *fip) {
   struct filedetails *fdp, **fdpp;
   struct filedetails *fdp, **fdpp;
   char *cpos, *space;
   char *cpos, *space;
   int allowextend;
   int allowextend;
 
 
   if (!*value)
   if (!*value)
-    parse_error(filename, lno, pigp, _("empty file details field `%s'"), fip->name);
-  if (!(flags & pdb_recordavailable))
-    parse_error(filename, lno, pigp,
+    parse_error(ps, pigp, _("empty file details field `%s'"), fip->name);
+  if (!(ps->flags & pdb_recordavailable))
+    parse_error(ps, pigp,
                 _("file details field `%s' not allowed in status file"),
                 _("file details field `%s' not allowed in status file"),
                fip->name);
                fip->name);
   allowextend= !pigp->files;
   allowextend= !pigp->files;
@@ -101,7 +102,7 @@ void f_filecharf(struct pkginfo *pigp, struct pkginfoperfile *pifp,
     fdp= *fdpp;
     fdp= *fdpp;
     if (!fdp) {
     if (!fdp) {
       if (!allowextend)
       if (!allowextend)
-        parse_error(filename, lno, pigp,
+        parse_error(ps, pigp,
                     _("too many values in file details field `%s' "
                     _("too many values in file details field `%s' "
                       "(compared to others)"), fip->name);
                       "(compared to others)"), fip->name);
       fdp= nfmalloc(sizeof(struct filedetails));
       fdp= nfmalloc(sizeof(struct filedetails));
@@ -115,94 +116,86 @@ void f_filecharf(struct pkginfo *pigp, struct pkginfoperfile *pifp,
     cpos= space;
     cpos= space;
   }
   }
   if (*fdpp)
   if (*fdpp)
-    parse_error(filename, lno, pigp,
+    parse_error(ps, pigp,
                 _("too few values in file details field `%s' "
                 _("too few values in file details field `%s' "
                   "(compared to others)"), fip->name);
                   "(compared to others)"), fip->name);
 }
 }
 
 
 void f_charfield(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_charfield(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-                 enum parsedbflags flags,
-                 const char *filename, int lno, FILE *warnto, int *warncount,
+                 struct parsedb_state *ps,
                  const char *value, const struct fieldinfo *fip) {
                  const char *value, const struct fieldinfo *fip) {
   if (*value) PKGPFIELD(pifp,fip->integer,char*)= nfstrsave(value);
   if (*value) PKGPFIELD(pifp,fip->integer,char*)= nfstrsave(value);
 }
 }
 
 
 void f_boolean(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_boolean(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-               enum parsedbflags flags,
-               const char *filename, int lno, FILE *warnto, int *warncount,
+               struct parsedb_state *ps,
                const char *value, const struct fieldinfo *fip) {
                const char *value, const struct fieldinfo *fip) {
   int boolean;
   int boolean;
 
 
   if (!*value)
   if (!*value)
     return;
     return;
 
 
-  boolean = convert_string(filename, lno, _("yes/no in boolean field"),
+  boolean = convert_string(ps, _("yes/no in boolean field"),
                            -1, pigp, value, booleaninfos, NULL);
                            -1, pigp, value, booleaninfos, NULL);
   PKGPFIELD(pifp, fip->integer, int) = boolean;
   PKGPFIELD(pifp, fip->integer, int) = boolean;
 }
 }
 
 
 void f_section(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_section(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-               enum parsedbflags flags,
-               const char *filename, int lno, FILE *warnto, int *warncount,
+               struct parsedb_state *ps,
                const char *value, const struct fieldinfo *fip) {
                const char *value, const struct fieldinfo *fip) {
   if (!*value) return;
   if (!*value) return;
   pigp->section= nfstrsave(value);
   pigp->section= nfstrsave(value);
 }
 }
 
 
 void f_priority(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_priority(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-                enum parsedbflags flags,
-                const char *filename, int lno, FILE *warnto, int *warncount,
+                struct parsedb_state *ps,
                 const char *value, const struct fieldinfo *fip) {
                 const char *value, const struct fieldinfo *fip) {
   if (!*value) return;
   if (!*value) return;
-  pigp->priority = convert_string(filename, lno, _("word in `priority' field"),
+  pigp->priority = convert_string(ps, _("word in `priority' field"),
                                   pri_other, pigp, value, priorityinfos, NULL);
                                   pri_other, pigp, value, priorityinfos, NULL);
   if (pigp->priority == pri_other) pigp->otherpriority= nfstrsave(value);
   if (pigp->priority == pri_other) pigp->otherpriority= nfstrsave(value);
 }
 }
 
 
 void f_status(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_status(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-              enum parsedbflags flags,
-              const char *filename, int lno, FILE *warnto, int *warncount,
+              struct parsedb_state *ps,
               const char *value, const struct fieldinfo *fip) {
               const char *value, const struct fieldinfo *fip) {
   const char *ep;
   const char *ep;
 
 
-  if (flags & pdb_rejectstatus)
-    parse_error(filename, lno, pigp,
+  if (ps->flags & pdb_rejectstatus)
+    parse_error(ps, pigp,
                 _("value for `status' field not allowed in this context"));
                 _("value for `status' field not allowed in this context"));
-  if (flags & pdb_recordavailable) return;
+  if (ps->flags & pdb_recordavailable)
+    return;
   
   
-  pigp->want = convert_string(filename, lno,
-			     _("first (want) word in `status' field"), -1,
-                              pigp, value, wantinfos, &ep);
-  pigp->eflag = convert_string(filename, lno,
-			      _("second (error) word in `status' field"), -1,
-                               pigp, ep, eflaginfos, &ep);
+  pigp->want = convert_string(ps, _("first (want) word in `status' field"),
+                              -1, pigp, value, wantinfos, &ep);
+  pigp->eflag = convert_string(ps, _("second (error) word in `status' field"),
+                               -1, pigp, ep, eflaginfos, &ep);
   if (pigp->eflag & eflagf_obsoletehold) {
   if (pigp->eflag & eflagf_obsoletehold) {
     pigp->want= want_hold;
     pigp->want= want_hold;
     pigp->eflag &= ~eflagf_obsoletehold;
     pigp->eflag &= ~eflagf_obsoletehold;
   }
   }
-  pigp->status= convert_string(filename,lno,_("third (status) word in `status' field"), -1,
-                               pigp, ep, statusinfos, NULL);
+  pigp->status = convert_string(ps, _("third (status) word in `status' field"),
+                                -1, pigp, ep, statusinfos, NULL);
 }
 }
 
 
 void f_version(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_version(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-               enum parsedbflags flags,
-               const char *filename, int lno, FILE *warnto, int *warncount,
+               struct parsedb_state *ps,
                const char *value, const struct fieldinfo *fip) {
                const char *value, const struct fieldinfo *fip) {
   const char *emsg;
   const char *emsg;
   
   
   emsg= parseversion(&pifp->version,value);
   emsg= parseversion(&pifp->version,value);
   if (emsg)
   if (emsg)
-    parse_error(filename, lno, pigp,
+    parse_error(ps, pigp,
                 _("error in Version string `%.250s': %.250s"), value, emsg);
                 _("error in Version string `%.250s': %.250s"), value, emsg);
 }  
 }  
 
 
 void f_revision(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_revision(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-                enum parsedbflags flags,
-                const char *filename, int lno, FILE *warnto, int *warncount,
+                struct parsedb_state *ps,
                 const char *value, const struct fieldinfo *fip) {
                 const char *value, const struct fieldinfo *fip) {
   char *newversion;
   char *newversion;
 
 
-  parse_warn(filename, lno, warnto, warncount, pigp,
+  parse_warn(ps, pigp,
              _("obsolete `Revision' or `Package-Revision' field used"));
              _("obsolete `Revision' or `Package-Revision' field used"));
   if (!*value) return;
   if (!*value) return;
   if (pifp->version.revision && *pifp->version.revision) {
   if (pifp->version.revision && *pifp->version.revision) {
@@ -214,19 +207,19 @@ void f_revision(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 }  
 }  
 
 
 void f_configversion(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_configversion(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-                     enum parsedbflags flags,
-                     const char *filename, int lno, FILE *warnto, int *warncount,
+                     struct parsedb_state *ps,
                      const char *value, const struct fieldinfo *fip) {
                      const char *value, const struct fieldinfo *fip) {
   const char *emsg;
   const char *emsg;
   
   
-  if (flags & pdb_rejectstatus)
-    parse_error(filename, lno, pigp,
+  if (ps->flags & pdb_rejectstatus)
+    parse_error(ps, pigp,
                 _("value for `config-version' field not allowed in this context"));
                 _("value for `config-version' field not allowed in this context"));
-  if (flags & pdb_recordavailable) return;
+  if (ps->flags & pdb_recordavailable)
+    return;
 
 
   emsg= parseversion(&pigp->configversion,value);
   emsg= parseversion(&pigp->configversion,value);
   if (emsg)
   if (emsg)
-    parse_error(filename, lno, pigp,
+    parse_error(ps, pigp,
                 _("error in Config-Version string `%.250s': %.250s"),
                 _("error in Config-Version string `%.250s': %.250s"),
                 value, emsg);
                 value, emsg);
 }
 }
@@ -235,7 +228,7 @@ static void conffvalue_lastword(const char *value, const char *from,
                                 const char *endent,
                                 const char *endent,
                                 const char **word_start_r, int *word_len_r,
                                 const char **word_start_r, int *word_len_r,
                                 const char **new_from_r,
                                 const char **new_from_r,
-                                const char *filename, int lno,
+                                struct parsedb_state *ps,
                                 struct pkginfo *pigp)
                                 struct pkginfo *pigp)
 {
 {
   /* the code in f_conffiles ensures that value[-1]==' ', which is helpful */
   /* the code in f_conffiles ensures that value[-1]==' ', which is helpful */
@@ -251,14 +244,13 @@ static void conffvalue_lastword(const char *value, const char *from,
   return;
   return;
 
 
 malformed:
 malformed:
-  parse_error(filename, lno, pigp,
+  parse_error(ps, pigp,
               _("value for `conffiles' has malformatted line `%.*s'"),
               _("value for `conffiles' has malformatted line `%.*s'"),
               (int)min(endent - value, 250), value);
               (int)min(endent - value, 250), value);
 }
 }
 
 
 void f_conffiles(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_conffiles(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-                 enum parsedbflags flags,
-                 const char *filename, int lno, FILE *warnto, int *warncount,
+                 struct parsedb_state *ps,
                  const char *value, const struct fieldinfo *fip) {
                  const char *value, const struct fieldinfo *fip) {
   static const char obsolete_str[]= "obsolete";
   static const char obsolete_str[]= "obsolete";
   struct conffile **lastp, *newlink;
   struct conffile **lastp, *newlink;
@@ -271,24 +263,24 @@ void f_conffiles(struct pkginfo *pigp, struct pkginfoperfile *pifp,
     c= *value++;
     c= *value++;
     if (c == '\n') continue;
     if (c == '\n') continue;
     if (c != ' ')
     if (c != ' ')
-      parse_error(filename, lno, pigp,
+      parse_error(ps, pigp,
                   _("value for `conffiles' has line starting with non-space `%c'"),
                   _("value for `conffiles' has line starting with non-space `%c'"),
                   c);
                   c);
     for (endent = value; (c = *endent) != '\0' && c != '\n'; endent++) ;
     for (endent = value; (c = *endent) != '\0' && c != '\n'; endent++) ;
     conffvalue_lastword(value, endent, endent,
     conffvalue_lastword(value, endent, endent,
 			&hashstart, &hashlen, &endfn,
 			&hashstart, &hashlen, &endfn,
-                        filename, lno, pigp);
+                        ps, pigp);
     obsolete= (hashlen == sizeof(obsolete_str)-1 &&
     obsolete= (hashlen == sizeof(obsolete_str)-1 &&
 	       !memcmp(hashstart, obsolete_str, hashlen));
 	       !memcmp(hashstart, obsolete_str, hashlen));
     if (obsolete)
     if (obsolete)
       conffvalue_lastword(value, endfn, endent,
       conffvalue_lastword(value, endfn, endent,
 			  &hashstart, &hashlen, &endfn,
 			  &hashstart, &hashlen, &endfn,
-                          filename, lno, pigp);
+			  ps, pigp);
     newlink= nfmalloc(sizeof(struct conffile));
     newlink= nfmalloc(sizeof(struct conffile));
     value = path_skip_slash_dotslash(value);
     value = path_skip_slash_dotslash(value);
     namelen= (int)(endfn-value);
     namelen= (int)(endfn-value);
     if (namelen <= 0)
     if (namelen <= 0)
-      parse_error(filename, lno, pigp,
+      parse_error(ps, pigp,
                   _("root or null directory is listed as a conffile"));
                   _("root or null directory is listed as a conffile"));
     newptr = nfmalloc(namelen+2);
     newptr = nfmalloc(namelen+2);
     newptr[0]= '/';
     newptr[0]= '/';
@@ -308,8 +300,7 @@ void f_conffiles(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 }
 }
 
 
 void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-                  enum parsedbflags flags,
-                  const char *filename, int lno, FILE *warnto, int *warncount,
+                  struct parsedb_state *ps,
                   const char *value, const struct fieldinfo *fip) {
                   const char *value, const struct fieldinfo *fip) {
   char c1, c2;
   char c1, c2;
   const char *p, *emsg;
   const char *p, *emsg;
@@ -346,12 +337,12 @@ void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
       strncpy(depname, depnamestart, depnamelength);
       strncpy(depname, depnamestart, depnamelength);
       *(depname + depnamelength) = '\0';
       *(depname + depnamelength) = '\0';
       if (!*depname)
       if (!*depname)
-        parse_error(filename, lno, pigp,
+        parse_error(ps, pigp,
                     _("`%s' field, missing package name, or garbage where "
                     _("`%s' field, missing package name, or garbage where "
                       "package name expected"), fip->name);
                       "package name expected"), fip->name);
       emsg= illegal_packagename(depname,NULL);
       emsg= illegal_packagename(depname,NULL);
       if (emsg)
       if (emsg)
-        parse_error(filename, lno, pigp,
+        parse_error(ps, pigp,
                     _("`%s' field, invalid package name `%.255s': %s"),
                     _("`%s' field, invalid package name `%.255s': %s"),
                     fip->name, depname, emsg);
                     fip->name, depname, emsg);
       dop= nfmalloc(sizeof(struct deppossi));
       dop= nfmalloc(sizeof(struct deppossi));
@@ -381,13 +372,13 @@ void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
             dop->verrel |= (dvrf_strict | dvrf_builtup);
             dop->verrel |= (dvrf_strict | dvrf_builtup);
             p++;
             p++;
           } else if (c2 == '<' || c2 == '>') {
           } else if (c2 == '<' || c2 == '>') {
-            parse_error(filename, lno, pigp,
+            parse_error(ps, pigp,
                         _("`%s' field, reference to `%.255s':\n"
                         _("`%s' field, reference to `%.255s':\n"
                           " bad version relationship %c%c"),
                           " bad version relationship %c%c"),
                         fip->name, depname, c1, c2);
                         fip->name, depname, c1, c2);
             dop->verrel= dvr_none;
             dop->verrel= dvr_none;
           } else {
           } else {
-            parse_warn(filename, lno, warnto, warncount, pigp,
+            parse_warn(ps, pigp,
                        _("`%s' field, reference to `%.255s':\n"
                        _("`%s' field, reference to `%.255s':\n"
                          " `%c' is obsolete, use `%c=' or `%c%c' instead"),
                          " `%c' is obsolete, use `%c=' or `%c%c' instead"),
                        fip->name, depname, c1, c1, c1, c1);
                        fip->name, depname, c1, c1, c1, c1);
@@ -397,7 +388,7 @@ void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
           dop->verrel= dvr_exact;
           dop->verrel= dvr_exact;
           p++;
           p++;
         } else {
         } else {
-          parse_warn(filename, lno, warnto, warncount, pigp,
+          parse_warn(ps, pigp,
                      _("`%s' field, reference to `%.255s':\n"
                      _("`%s' field, reference to `%.255s':\n"
                        " implicit exact match on version number, "
                        " implicit exact match on version number, "
                        "suggest using `=' instead"),
                        "suggest using `=' instead"),
@@ -405,11 +396,11 @@ void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
           dop->verrel= dvr_exact;
           dop->verrel= dvr_exact;
         }
         }
 	if ((dop->verrel!=dvr_exact) && (fip->integer==dep_provides))
 	if ((dop->verrel!=dvr_exact) && (fip->integer==dep_provides))
-          parse_warn(filename, lno, warnto, warncount, pigp,
+          parse_warn(ps, pigp,
                      _("Only exact versions may be used for Provides"));
                      _("Only exact versions may be used for Provides"));
 
 
         if (!isspace(*p) && !isalnum(*p)) {
         if (!isspace(*p) && !isalnum(*p)) {
-          parse_warn(filename, lno, warnto, warncount, pigp,
+          parse_warn(ps, pigp,
                      _("`%s' field, reference to `%.255s':\n"
                      _("`%s' field, reference to `%.255s':\n"
                        " version value starts with non-alphanumeric, "
                        " version value starts with non-alphanumeric, "
                        "suggest adding a space"),
                        "suggest adding a space"),
@@ -426,15 +417,15 @@ void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 	versionlength= p - versionstart;
 	versionlength= p - versionstart;
         while (isspace(*p)) p++;
         while (isspace(*p)) p++;
         if (*p == '(')
         if (*p == '(')
-          parse_error(filename, lno, pigp,
+          parse_error(ps, pigp,
                       _("`%s' field, reference to `%.255s': "
                       _("`%s' field, reference to `%.255s': "
                         "version contains `%c'"), fip->name,depname, ')');
                         "version contains `%c'"), fip->name,depname, ')');
         else if (*p != ')')
         else if (*p != ')')
-          parse_error(filename, lno, pigp,
+          parse_error(ps, pigp,
                       _("`%s' field, reference to `%.255s': "
                       _("`%s' field, reference to `%.255s': "
                         "version contains `%c'"), fip->name,depname, ' ');
                         "version contains `%c'"), fip->name,depname, ' ');
         else if (*p == '\0')
         else if (*p == '\0')
-          parse_error(filename, lno, pigp,
+          parse_error(ps, pigp,
                       _("`%s' field, reference to `%.255s': "
                       _("`%s' field, reference to `%.255s': "
                         "version unterminated"), fip->name, depname);
                         "version unterminated"), fip->name, depname);
 	if (versionlength >=  versionused) {
 	if (versionlength >=  versionused) {
@@ -445,7 +436,7 @@ void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
         *(version + versionlength) = '\0';
         *(version + versionlength) = '\0';
         emsg= parseversion(&dop->version,version);
         emsg= parseversion(&dop->version,version);
         if (emsg)
         if (emsg)
-          parse_error(filename, lno, pigp,
+          parse_error(ps, pigp,
                       _("`%s' field, reference to `%.255s': "
                       _("`%s' field, reference to `%.255s': "
                         "error in version: %.255s"), fip->name, depname, emsg);
                         "error in version: %.255s"), fip->name, depname, emsg);
         p++; while (isspace(*p)) p++;
         p++; while (isspace(*p)) p++;
@@ -455,14 +446,14 @@ void f_dependency(struct pkginfo *pigp, struct pkginfoperfile *pifp,
       }
       }
       if (!*p || *p == ',') break;
       if (!*p || *p == ',') break;
       if (*p != '|')
       if (*p != '|')
-        parse_error(filename, lno, pigp,
+        parse_error(ps, pigp,
                     _("`%s' field, syntax error after reference to package `%.255s'"),
                     _("`%s' field, syntax error after reference to package `%.255s'"),
                     fip->name, dop->ed->name);
                     fip->name, dop->ed->name);
       if (fip->integer == dep_conflicts ||
       if (fip->integer == dep_conflicts ||
           fip->integer == dep_breaks ||
           fip->integer == dep_breaks ||
           fip->integer == dep_provides ||
           fip->integer == dep_provides ||
           fip->integer == dep_replaces)
           fip->integer == dep_replaces)
-        parse_error(filename, lno, pigp,
+        parse_error(ps, pigp,
                     _("alternatives (`|') not allowed in %s field"), fip->name);
                     _("alternatives (`|') not allowed in %s field"), fip->name);
       p++; while (isspace(*p)) p++;
       p++; while (isspace(*p)) p++;
     }
     }
@@ -515,53 +506,51 @@ scan_word(const char **valp)
 
 
 void
 void
 f_trigpend(struct pkginfo *pend, struct pkginfoperfile *pifp,
 f_trigpend(struct pkginfo *pend, struct pkginfoperfile *pifp,
-           enum parsedbflags flags,
-           const char *filename, int lno, FILE *warnto, int *warncount,
+           struct parsedb_state *ps,
            const char *value, const struct fieldinfo *fip)
            const char *value, const struct fieldinfo *fip)
 {
 {
   const char *word, *emsg;
   const char *word, *emsg;
 
 
-  if (flags & pdb_rejectstatus)
-    parse_error(filename, lno, pend,
+  if (ps->flags & pdb_rejectstatus)
+    parse_error(ps, pend,
                 _("value for `triggers-pending' field not allowed in "
                 _("value for `triggers-pending' field not allowed in "
                   "this context"));
                   "this context"));
 
 
   while ((word = scan_word(&value))) {
   while ((word = scan_word(&value))) {
     emsg = illegal_triggername(word);
     emsg = illegal_triggername(word);
     if (emsg)
     if (emsg)
-      parse_error(filename, lno, pend,
+      parse_error(ps, pend,
                   _("illegal pending trigger name `%.255s': %s"), word, emsg);
                   _("illegal pending trigger name `%.255s': %s"), word, emsg);
 
 
     if (!trig_note_pend_core(pend, nfstrsave(word)))
     if (!trig_note_pend_core(pend, nfstrsave(word)))
-      parse_error(filename, lno, pend,
+      parse_error(ps, pend,
                   _("duplicate pending trigger `%.255s'"), word);
                   _("duplicate pending trigger `%.255s'"), word);
   }
   }
 }
 }
 
 
 void
 void
 f_trigaw(struct pkginfo *aw, struct pkginfoperfile *pifp,
 f_trigaw(struct pkginfo *aw, struct pkginfoperfile *pifp,
-         enum parsedbflags flags,
-         const char *filename, int lno, FILE *warnto, int *warncount,
+         struct parsedb_state *ps,
          const char *value, const struct fieldinfo *fip)
          const char *value, const struct fieldinfo *fip)
 {
 {
   const char *word, *emsg;
   const char *word, *emsg;
   struct pkginfo *pend;
   struct pkginfo *pend;
 
 
-  if (flags & pdb_rejectstatus)
-    parse_error(filename, lno, aw,
+  if (ps->flags & pdb_rejectstatus)
+    parse_error(ps, aw,
                 _("value for `triggers-awaited' field not allowed in "
                 _("value for `triggers-awaited' field not allowed in "
                   "this context"));
                   "this context"));
 
 
   while ((word = scan_word(&value))) {
   while ((word = scan_word(&value))) {
     emsg = illegal_packagename(word, NULL);
     emsg = illegal_packagename(word, NULL);
     if (emsg)
     if (emsg)
-      parse_error(filename, lno, aw,
+      parse_error(ps, aw,
                   _("illegal package name in awaited trigger `%.255s': %s"),
                   _("illegal package name in awaited trigger `%.255s': %s"),
                   word, emsg);
                   word, emsg);
     pend = findpackage(word);
     pend = findpackage(word);
 
 
     if (!trig_note_aw(pend, aw))
     if (!trig_note_aw(pend, aw))
-      parse_error(filename, lno, aw,
+      parse_error(ps, aw,
                   _("duplicate awaited trigger package `%.255s'"), word);
                   _("duplicate awaited trigger package `%.255s'"), word);
 
 
     trig_enqueue_awaited_pend(pend);
     trig_enqueue_awaited_pend(pend);

+ 37 - 29
lib/parse.c

@@ -95,7 +95,6 @@ int parsedb(const char *filename, enum parsedbflags flags,
   struct pkginfoperfile *newpifp, *pifp;
   struct pkginfoperfile *newpifp, *pifp;
   struct arbitraryfield *arp, **larpp;
   struct arbitraryfield *arp, **larpp;
   struct trigaw *ta;
   struct trigaw *ta;
-  int lno;
   int pdone;
   int pdone;
   int fieldencountered[sizeof_array(fieldinfos)];
   int fieldencountered[sizeof_array(fieldinfos)];
   const struct fieldinfo *fip;
   const struct fieldinfo *fip;
@@ -106,8 +105,14 @@ int parsedb(const char *filename, enum parsedbflags flags,
   int fieldlen= 0, valuelen= 0;
   int fieldlen= 0, valuelen= 0;
   int *ip, c;
   int *ip, c;
   struct stat stat;
   struct stat stat;
+  struct parsedb_state ps;
+
+  ps.filename = filename;
+  ps.flags = flags;
+  ps.lno = 0;
+  ps.warnto = warnto;
+  ps.warncount = 0;
 
 
-  if (warncount) *warncount= 0;
   newpifp= (flags & pdb_recordavailable) ? &newpig.available : &newpig.installed;
   newpifp= (flags & pdb_recordavailable) ? &newpig.available : &newpig.installed;
   fd= open(filename, O_RDONLY);
   fd= open(filename, O_RDONLY);
   if (fd == -1) ohshite(_("failed to open package info file `%.255s' for reading"),filename);
   if (fd == -1) ohshite(_("failed to open package info file `%.255s' for reading"),filename);
@@ -132,7 +137,6 @@ int parsedb(const char *filename, enum parsedbflags flags,
     data= dataptr= endptr= NULL;
     data= dataptr= endptr= NULL;
   }
   }
 
 
-  lno = 0;
   pdone= 0;
   pdone= 0;
 #define EOF_mmap(dataptr, endptr)	(dataptr >= endptr)
 #define EOF_mmap(dataptr, endptr)	(dataptr >= endptr)
 #define getc_mmap(dataptr)		*dataptr++;
 #define getc_mmap(dataptr)		*dataptr++;
@@ -145,7 +149,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
 /* Skip adjacent new lines */
 /* Skip adjacent new lines */
     while(!EOF_mmap(dataptr, endptr)) {
     while(!EOF_mmap(dataptr, endptr)) {
       c= getc_mmap(dataptr); if (c!='\n' && c!=MSDOS_EOF_CHAR ) break;
       c= getc_mmap(dataptr); if (c!='\n' && c!=MSDOS_EOF_CHAR ) break;
-      lno++;
+      ps.lno++;
     }
     }
     if (EOF_mmap(dataptr, endptr)) break;
     if (EOF_mmap(dataptr, endptr)) break;
     for (;;) { /* loop per field */
     for (;;) { /* loop per field */
@@ -155,17 +159,17 @@ int parsedb(const char *filename, enum parsedbflags flags,
       fieldlen= dataptr - fieldstart - 1;
       fieldlen= dataptr - fieldstart - 1;
       while (!EOF_mmap(dataptr, endptr) && c != '\n' && isspace(c)) c= getc_mmap(dataptr);
       while (!EOF_mmap(dataptr, endptr) && c != '\n' && isspace(c)) c= getc_mmap(dataptr);
       if (EOF_mmap(dataptr, endptr))
       if (EOF_mmap(dataptr, endptr))
-        parse_error(filename, lno, &newpig,
+        parse_error(&ps, &newpig,
                     _("EOF after field name `%.*s'"), fieldlen, fieldstart);
                     _("EOF after field name `%.*s'"), fieldlen, fieldstart);
       if (c == '\n')
       if (c == '\n')
-        parse_error(filename, lno, &newpig,
+        parse_error(&ps, &newpig,
                     _("newline in field name `%.*s'"), fieldlen, fieldstart);
                     _("newline in field name `%.*s'"), fieldlen, fieldstart);
       if (c == MSDOS_EOF_CHAR)
       if (c == MSDOS_EOF_CHAR)
-        parse_error(filename, lno, &newpig,
+        parse_error(&ps, &newpig,
                     _("MSDOS EOF (^Z) in field name `%.*s'"),
                     _("MSDOS EOF (^Z) in field name `%.*s'"),
                     fieldlen, fieldstart);
                     fieldlen, fieldstart);
       if (c != ':')
       if (c != ':')
-        parse_error(filename, lno, &newpig,
+        parse_error(&ps, &newpig,
                     _("field name `%.*s' must be followed by colon"),
                     _("field name `%.*s' must be followed by colon"),
                     fieldlen, fieldstart);
                     fieldlen, fieldstart);
 /* Skip space after ':' but before value and eol */
 /* Skip space after ':' but before value and eol */
@@ -174,17 +178,17 @@ int parsedb(const char *filename, enum parsedbflags flags,
         if (c == '\n' || !isspace(c)) break;
         if (c == '\n' || !isspace(c)) break;
       }
       }
       if (EOF_mmap(dataptr, endptr))
       if (EOF_mmap(dataptr, endptr))
-        parse_error(filename, lno, &newpig,
+        parse_error(&ps, &newpig,
                     _("EOF before value of field `%.*s' (missing final newline)"),
                     _("EOF before value of field `%.*s' (missing final newline)"),
                  fieldlen,fieldstart);
                  fieldlen,fieldstart);
       if (c == MSDOS_EOF_CHAR)
       if (c == MSDOS_EOF_CHAR)
-        parse_error(filename, lno, &newpig,
+        parse_error(&ps, &newpig,
                     _("MSDOS EOF char in value of field `%.*s' (missing newline?)"),
                     _("MSDOS EOF char in value of field `%.*s' (missing newline?)"),
                     fieldlen,fieldstart);
                     fieldlen,fieldstart);
       valuestart= dataptr - 1;
       valuestart= dataptr - 1;
       for (;;) {
       for (;;) {
         if (c == '\n' || c == MSDOS_EOF_CHAR) {
         if (c == '\n' || c == MSDOS_EOF_CHAR) {
-          lno++;
+          ps.lno++;
 	  if (EOF_mmap(dataptr, endptr)) break;
 	  if (EOF_mmap(dataptr, endptr)) break;
           c= getc_mmap(dataptr);
           c= getc_mmap(dataptr);
 /* Found double eol, or start of new field */
 /* Found double eol, or start of new field */
@@ -192,7 +196,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
           ungetc_mmap(c,dataptr, data);
           ungetc_mmap(c,dataptr, data);
           c= '\n';
           c= '\n';
         } else if (EOF_mmap(dataptr, endptr)) {
         } else if (EOF_mmap(dataptr, endptr)) {
-          parse_error(filename, lno, &newpig,
+          parse_error(&ps, &newpig,
                       _("EOF during value of field `%.*s' (missing final newline)"),
                       _("EOF during value of field `%.*s' (missing final newline)"),
                       fieldlen,fieldstart);
                       fieldlen,fieldstart);
         }
         }
@@ -217,18 +221,18 @@ int parsedb(const char *filename, enum parsedbflags flags,
 	memcpy(value,valuestart,valuelen);
 	memcpy(value,valuestart,valuelen);
         *(value + valuelen) = '\0';
         *(value + valuelen) = '\0';
         if (*ip++)
         if (*ip++)
-          parse_error(filename, lno, &newpig,
+          parse_error(&ps, &newpig,
                       _("duplicate value for `%s' field"), fip->name);
                       _("duplicate value for `%s' field"), fip->name);
-        fip->rcall(&newpig,newpifp,flags,filename,lno,warnto,warncount,value,fip);
+        fip->rcall(&newpig, newpifp, &ps, value, fip);
       } else {
       } else {
         if (fieldlen<2)
         if (fieldlen<2)
-          parse_error(filename, lno, &newpig,
+          parse_error(&ps, &newpig,
                       _("user-defined field name `%.*s' too short"),
                       _("user-defined field name `%.*s' too short"),
                       fieldlen, fieldstart);
                       fieldlen, fieldstart);
         larpp= &newpifp->arbs;
         larpp= &newpifp->arbs;
         while ((arp= *larpp) != NULL) {
         while ((arp= *larpp) != NULL) {
           if (!strncasecmp(arp->name,fieldstart,fieldlen))
           if (!strncasecmp(arp->name,fieldstart,fieldlen))
-            parse_error(filename, lno, &newpig,
+            parse_error(&ps, &newpig,
                        _("duplicate value for user-defined field `%.*s'"),
                        _("duplicate value for user-defined field `%.*s'"),
                        fieldlen, fieldstart);
                        fieldlen, fieldstart);
           larpp= &arp->next;
           larpp= &arp->next;
@@ -242,20 +246,20 @@ int parsedb(const char *filename, enum parsedbflags flags,
       if (EOF_mmap(dataptr, endptr) || c == '\n' || c == MSDOS_EOF_CHAR) break;
       if (EOF_mmap(dataptr, endptr) || c == '\n' || c == MSDOS_EOF_CHAR) break;
     } /* loop per field */
     } /* loop per field */
     if (pdone && donep)
     if (pdone && donep)
-      parse_error(filename, lno, &newpig,
+      parse_error(&ps, &newpig,
                   _("several package info entries found, only one allowed"));
                   _("several package info entries found, only one allowed"));
-    parse_must_have_field(filename, lno, &newpig, newpig.name, "package name");
+    parse_must_have_field(&ps, &newpig, newpig.name, "package name");
     if ((flags & pdb_recordavailable) || newpig.status != stat_notinstalled) {
     if ((flags & pdb_recordavailable) || newpig.status != stat_notinstalled) {
-      parse_ensure_have_field(filename, lno, warnto, warncount, &newpig,
+      parse_ensure_have_field(&ps, &newpig,
                               &newpifp->description, "description");
                               &newpifp->description, "description");
-      parse_ensure_have_field(filename, lno, warnto, warncount, &newpig,
+      parse_ensure_have_field(&ps, &newpig,
                               &newpifp->maintainer, "maintainer");
                               &newpifp->maintainer, "maintainer");
       if (newpig.status != stat_halfinstalled)
       if (newpig.status != stat_halfinstalled)
-        parse_must_have_field(filename, lno, &newpig,
+        parse_must_have_field(&ps, &newpig,
                               newpifp->version.version, "version");
                               newpifp->version.version, "version");
     }
     }
     if (flags & pdb_recordavailable)
     if (flags & pdb_recordavailable)
-      parse_ensure_have_field(filename, lno, warnto, warncount, &newpig,
+      parse_ensure_have_field(&ps, &newpig,
                               &newpifp->architecture, "architecture");
                               &newpifp->architecture, "architecture");
 
 
     /* Check the Config-Version information:
     /* Check the Config-Version information:
@@ -267,7 +271,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
     if (!(flags & pdb_recordavailable)) {
     if (!(flags & pdb_recordavailable)) {
       if (newpig.configversion.version) {
       if (newpig.configversion.version) {
         if (newpig.status == stat_installed || newpig.status == stat_notinstalled)
         if (newpig.status == stat_installed || newpig.status == stat_notinstalled)
-          parse_error(filename, lno, &newpig,
+          parse_error(&ps, &newpig,
                       _("Configured-Version for package with inappropriate Status"));
                       _("Configured-Version for package with inappropriate Status"));
       } else {
       } else {
         if (newpig.status == stat_installed) newpig.configversion= newpifp->version;
         if (newpig.status == stat_installed) newpig.configversion= newpifp->version;
@@ -277,22 +281,22 @@ int parsedb(const char *filename, enum parsedbflags flags,
     if (newpig.trigaw.head &&
     if (newpig.trigaw.head &&
         (newpig.status <= stat_configfiles ||
         (newpig.status <= stat_configfiles ||
          newpig.status >= stat_triggerspending))
          newpig.status >= stat_triggerspending))
-      parse_error(filename, lno, &newpig,
+      parse_error(&ps, &newpig,
                   _("package has status %s but triggers are awaited"),
                   _("package has status %s but triggers are awaited"),
                   statusinfos[newpig.status].name);
                   statusinfos[newpig.status].name);
     else if (newpig.status == stat_triggersawaited && !newpig.trigaw.head)
     else if (newpig.status == stat_triggersawaited && !newpig.trigaw.head)
-      parse_error(filename, lno, &newpig,
+      parse_error(&ps, &newpig,
                   _("package has status triggers-awaited but no triggers "
                   _("package has status triggers-awaited but no triggers "
                     "awaited"));
                     "awaited"));
 
 
     if (!(newpig.status == stat_triggerspending ||
     if (!(newpig.status == stat_triggerspending ||
           newpig.status == stat_triggersawaited) &&
           newpig.status == stat_triggersawaited) &&
         newpig.trigpend_head)
         newpig.trigpend_head)
-      parse_error(filename, lno, &newpig,
+      parse_error(&ps, &newpig,
                   _("package has status %s but triggers are pending"),
                   _("package has status %s but triggers are pending"),
                   statusinfos[newpig.status].name);
                   statusinfos[newpig.status].name);
     else if (newpig.status == stat_triggerspending && !newpig.trigpend_head)
     else if (newpig.status == stat_triggerspending && !newpig.trigpend_head)
-      parse_error(filename, lno, &newpig,
+      parse_error(&ps, &newpig,
                   _("package has status triggers-pending but no triggers "
                   _("package has status triggers-pending but no triggers "
                     "pending"));
                     "pending"));
 
 
@@ -303,7 +307,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
     if (!(flags & pdb_recordavailable) &&
     if (!(flags & pdb_recordavailable) &&
         newpig.status == stat_notinstalled &&
         newpig.status == stat_notinstalled &&
         newpifp->conffiles) {
         newpifp->conffiles) {
-      parse_warn(filename, lno, warnto, warncount, &newpig,
+      parse_warn(&ps, &newpig,
                  _("Package which in state not-installed has conffiles, "
                  _("Package which in state not-installed has conffiles, "
                    "forgetting them"));
                    "forgetting them"));
       newpifp->conffiles= NULL;
       newpifp->conffiles= NULL;
@@ -361,7 +365,8 @@ int parsedb(const char *filename, enum parsedbflags flags,
     if (donep) *donep= pigp;
     if (donep) *donep= pigp;
     pdone++;
     pdone++;
     if (EOF_mmap(dataptr, endptr)) break;
     if (EOF_mmap(dataptr, endptr)) break;
-    if (c == '\n') lno++;
+    if (c == '\n')
+      ps.lno++;
   }
   }
   if (data != NULL) {
   if (data != NULL) {
 #ifdef HAVE_MMAP
 #ifdef HAVE_MMAP
@@ -375,6 +380,9 @@ int parsedb(const char *filename, enum parsedbflags flags,
   if (close(fd)) ohshite(_("failed to close after read: `%.255s'"),filename);
   if (close(fd)) ohshite(_("failed to close after read: `%.255s'"),filename);
   if (donep && !pdone) ohshit(_("no package information in `%.255s'"),filename);
   if (donep && !pdone) ohshit(_("no package information in `%.255s'"),filename);
 
 
+  if (warncount)
+    *warncount = ps.warncount;
+
   return pdone;
   return pdone;
 }
 }
 
 

+ 15 - 10
lib/parsedump.h

@@ -25,6 +25,14 @@
 
 
 struct fieldinfo;
 struct fieldinfo;
 
 
+struct parsedb_state {
+	enum parsedbflags flags;
+	const char *filename;
+	int lno;
+	FILE *warnto;
+	int warncount;
+};
+
 #define PKGIFPOFF(f) (offsetof(struct pkginfoperfile, f))
 #define PKGIFPOFF(f) (offsetof(struct pkginfoperfile, f))
 #define PKGPFIELD(pifp,of,type) (*(type*)((char*)(pifp)+(of)))
 #define PKGPFIELD(pifp,of,type) (*(type*)((char*)(pifp)+(of)))
 
 
@@ -32,8 +40,7 @@ struct fieldinfo;
 #define FILEFFIELD(filedetail,of,type) (*(type*)((char*)(filedetail)+(of)))
 #define FILEFFIELD(filedetail,of,type) (*(type*)((char*)(filedetail)+(of)))
 
 
 typedef void freadfunction(struct pkginfo *pigp, struct pkginfoperfile *pifp,
 typedef void freadfunction(struct pkginfo *pigp, struct pkginfoperfile *pifp,
-                           enum parsedbflags flags,
-                           const char *filename, int lno, FILE *warnto, int *warncount,
+                           struct parsedb_state *ps,
                            const char *value, const struct fieldinfo *fip);
                            const char *value, const struct fieldinfo *fip);
 freadfunction f_name, f_charfield, f_priority, f_section, f_status, f_filecharf;
 freadfunction f_name, f_charfield, f_priority, f_section, f_status, f_filecharf;
 freadfunction f_boolean, f_dependency, f_conffiles, f_version, f_revision;
 freadfunction f_boolean, f_dependency, f_conffiles, f_version, f_revision;
@@ -59,16 +66,14 @@ struct fieldinfo {
   size_t integer;
   size_t integer;
 };
 };
 
 
-void parse_error(const char *filename, int lno, const struct pkginfo *pigp,
-                 const char *fmt, ...) PRINTFFORMAT(4,5);
-void parse_warn(const char *filename, int lno, FILE *warnto, int *warncount,
-                const struct pkginfo *pigp,
-                const char *fmt, ...) PRINTFFORMAT(6,7);
-void parse_must_have_field(const char *filename, int lno,
+void parse_error(struct parsedb_state *ps, const struct pkginfo *pigp,
+                 const char *fmt, ...) PRINTFFORMAT(3,4);
+void parse_warn(struct parsedb_state *ps, const struct pkginfo *pigp,
+                const char *fmt, ...) PRINTFFORMAT(3,4);
+void parse_must_have_field(struct parsedb_state *ps,
                            const struct pkginfo *pigp,
                            const struct pkginfo *pigp,
                            const char *value, const char *what);
                            const char *value, const char *what);
-void parse_ensure_have_field(const char *filename, int lno,
-                             FILE *warnto, int *warncount,
+void parse_ensure_have_field(struct parsedb_state *ps,
                              const struct pkginfo *pigp,
                              const struct pkginfo *pigp,
                              const char **value, const char *what);
                              const char **value, const char *what);
 
 

+ 16 - 17
lib/parsehelp.c

@@ -35,25 +35,25 @@
 #include "parsedump.h"
 #include "parsedump.h"
 
 
 static void
 static void
-parse_error_msg(const char *filename, int lno, const struct pkginfo *pigp,
+parse_error_msg(struct parsedb_state *ps, const struct pkginfo *pigp,
                 const char *type, char *buf)
                 const char *type, char *buf)
 {
 {
   if (pigp && pigp->name)
   if (pigp && pigp->name)
     sprintf(buf, _("%s, in file '%.255s' near line %d package '%.255s':\n "),
     sprintf(buf, _("%s, in file '%.255s' near line %d package '%.255s':\n "),
-            type, filename, lno, pigp->name);
+            type, ps->filename, ps->lno, pigp->name);
   else
   else
     sprintf(buf, _("%s, in file '%.255s' near line %d:\n "),
     sprintf(buf, _("%s, in file '%.255s' near line %d:\n "),
-            type, filename, lno);
+            type, ps->filename, ps->lno);
 }
 }
 
 
 void
 void
-parse_error(const char *filename, int lno,
+parse_error(struct parsedb_state *ps,
             const struct pkginfo *pigp, const char *fmt, ...)
             const struct pkginfo *pigp, const char *fmt, ...)
 {
 {
   va_list al;
   va_list al;
   char buf1[768], buf2[1000], *q;
   char buf1[768], buf2[1000], *q;
 
 
-  parse_error_msg(filename, lno, pigp, _("parse error"), buf1);
+  parse_error_msg(ps, pigp, _("parse error"), buf1);
   q = str_escape_fmt(buf2, buf1);
   q = str_escape_fmt(buf2, buf1);
   strcat(q,fmt);
   strcat(q,fmt);
 
 
@@ -62,21 +62,21 @@ parse_error(const char *filename, int lno,
 }
 }
 
 
 void
 void
-parse_warn(const char *filename, int lno, FILE *warnto, int *warncount,
+parse_warn(struct parsedb_state *ps,
            const struct pkginfo *pigp, const char *fmt, ...)
            const struct pkginfo *pigp, const char *fmt, ...)
 {
 {
   va_list al;
   va_list al;
   char buf1[768], buf2[1000], *q;
   char buf1[768], buf2[1000], *q;
 
 
-  parse_error_msg(filename, lno, pigp, _("warning"), buf1);
+  parse_error_msg(ps, pigp, _("warning"), buf1);
   q = str_escape_fmt(buf2, buf1);
   q = str_escape_fmt(buf2, buf1);
   strcat(q, fmt);
   strcat(q, fmt);
 
 
   va_start(al, fmt);
   va_start(al, fmt);
-  if (warncount) (*warncount)++;
-  if (warnto) {
+  ps->warncount++;
+  if (ps->warnto) {
     strcat(q,"\n");
     strcat(q,"\n");
-    if (vfprintf(warnto,buf2,al) == EOF)
+    if (vfprintf(ps->warnto, buf2, al) == EOF)
       ohshite(_("failed to write parsing warning"));
       ohshite(_("failed to write parsing warning"));
   }
   }
   va_end(al);
   va_end(al);
@@ -251,29 +251,28 @@ const char *parseversion(struct versionrevision *rversion, const char *string) {
 }
 }
 
 
 void
 void
-parse_must_have_field(const char *filename, int lno,
+parse_must_have_field(struct parsedb_state *ps,
                       const struct pkginfo *pigp,
                       const struct pkginfo *pigp,
                       const char *value, const char *what)
                       const char *value, const char *what)
 {
 {
   if (!value)
   if (!value)
-    parse_error(filename, lno, pigp, _("missing %s"), what);
+    parse_error(ps, pigp, _("missing %s"), what);
   else if (!*value)
   else if (!*value)
-    parse_error(filename, lno, pigp, _("empty value for %s"), what);
+    parse_error(ps, pigp, _("empty value for %s"), what);
 }
 }
 
 
 void
 void
-parse_ensure_have_field(const char *filename, int lno,
-                        FILE *warnto, int *warncount,
+parse_ensure_have_field(struct parsedb_state *ps,
                         const struct pkginfo *pigp,
                         const struct pkginfo *pigp,
                         const char **value, const char *what)
                         const char **value, const char *what)
 {
 {
   static const char *empty = "";
   static const char *empty = "";
 
 
   if (!*value) {
   if (!*value) {
-    parse_warn(filename, lno, warnto, warncount, pigp, _("missing %s"), what);
+    parse_warn(ps, pigp, _("missing %s"), what);
     *value = empty;
     *value = empty;
   } else if (!**value) {
   } else if (!**value) {
-    parse_warn(filename, lno, warnto, warncount, pigp, _("empty value for %s"), what);
+    parse_warn(ps, pigp, _("empty value for %s"), what);
   }
   }
 }
 }