The following commit has been merged in the master branch:
commit 645a9e329f874a470ae837d93525c769a0df4ec8
Author: Guillem Jover <[email protected]>
Date: Thu Jul 2 11:24:08 2009 +0200
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.
diff --git a/TODO b/TODO
index 77760d3..be9a8e0 100644
--- a/TODO
+++ b/TODO
@@ -37,7 +37,6 @@ squeeze + 1
- Coalesce admindir / infodir / foodir generation.
- Get rid of setjmp (at least in the general case, keep for dpkg itself?)
- Coalesce hash and checksum functions.
- - Move parseerr arguments into a struct (need to push the patch).
- Split modstatdb_rw into mode and flags.
- Move fd and block function out of mlib.
- Cleanup status chars -> strings hardcoded mappings all over the place.
diff --git a/lib/fields.c b/lib/fields.c
index 3d1331d..8840710 100644
--- a/lib/fields.c
+++ b/lib/fields.c
@@ -34,7 +34,7 @@
#include "parsedump.h"
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 char *startp, const struct namevalue *ivip,
const char **endpp)
@@ -43,7 +43,7 @@ convert_string(const char *filename, int lno, const char
*what, int otherwise,
const struct namevalue *nvip = ivip;
if (!*startp)
- parse_error(filename, lno, pigp, _("%s is missing"), what);
+ parse_error(ps, pigp, _("%s is missing"), what);
while (nvip->name) {
if (strncasecmp(nvip->name, startp, nvip->length))
nvip++;
@@ -52,7 +52,7 @@ convert_string(const char *filename, int lno, const char
*what, int otherwise,
}
if (!nvip->name) {
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);
}
@@ -60,17 +60,19 @@ convert_string(const char *filename, int lno, const char
*what, int otherwise,
while (isspace(*ep))
ep++;
if (*ep && !endpp)
- parse_error(filename, lno, pigp, _("junk after %s"), what);
+ parse_error(ps, pigp, _("junk after %s"), what);
if (endpp) *endpp= ep;
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;
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;
/* We use the new name, as findpackage() may have
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,
- enum parsedbflags flags,
- const char *filename, int lno, FILE *warnto, int *warncount,
+ struct parsedb_state *ps,
const char *value, const struct fieldinfo *fip) {
struct filedetails *fdp, **fdpp;
char *cpos, *space;
int allowextend;
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"),
fip->name);
allowextend= !pigp->files;
@@ -101,7 +102,7 @@ void f_filecharf(struct pkginfo *pigp, struct
pkginfoperfile *pifp,
fdp= *fdpp;
if (!fdp) {
if (!allowextend)
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("too many values in file details field `%s' "
"(compared to others)"), fip->name);
fdp= nfmalloc(sizeof(struct filedetails));
@@ -115,94 +116,86 @@ void f_filecharf(struct pkginfo *pigp, struct
pkginfoperfile *pifp,
cpos= space;
}
if (*fdpp)
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("too few values in file details field `%s' "
"(compared to others)"), fip->name);
}
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) {
if (*value) PKGPFIELD(pifp,fip->integer,char*)= nfstrsave(value);
}
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) {
int boolean;
if (!*value)
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);
PKGPFIELD(pifp, fip->integer, int) = boolean;
}
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) {
if (!*value) return;
pigp->section= nfstrsave(value);
}
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) {
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);
if (pigp->priority == pri_other) pigp->otherpriority= nfstrsave(value);
}
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 *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"));
- 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) {
pigp->want= want_hold;
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,
- 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 *emsg;
emsg= parseversion(&pifp->version,value);
if (emsg)
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("error in Version string `%.250s': %.250s"), value, emsg);
}
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) {
char *newversion;
- parse_warn(filename, lno, warnto, warncount, pigp,
+ parse_warn(ps, pigp,
_("obsolete `Revision' or `Package-Revision' field used"));
if (!*value) return;
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,
- 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 *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"));
- if (flags & pdb_recordavailable) return;
+ if (ps->flags & pdb_recordavailable)
+ return;
emsg= parseversion(&pigp->configversion,value);
if (emsg)
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("error in Config-Version string `%.250s': %.250s"),
value, emsg);
}
@@ -235,7 +228,7 @@ static void conffvalue_lastword(const char *value, const
char *from,
const char *endent,
const char **word_start_r, int *word_len_r,
const char **new_from_r,
- const char *filename, int lno,
+ struct parsedb_state *ps,
struct pkginfo *pigp)
{
/* 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;
malformed:
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("value for `conffiles' has malformatted line `%.*s'"),
(int)min(endent - value, 250), value);
}
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) {
static const char obsolete_str[]= "obsolete";
struct conffile **lastp, *newlink;
@@ -271,24 +263,24 @@ void f_conffiles(struct pkginfo *pigp, struct
pkginfoperfile *pifp,
c= *value++;
if (c == '\n') continue;
if (c != ' ')
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("value for `conffiles' has line starting with non-space
`%c'"),
c);
for (endent = value; (c = *endent) != '\0' && c != '\n'; endent++) ;
conffvalue_lastword(value, endent, endent,
&hashstart, &hashlen, &endfn,
- filename, lno, pigp);
+ ps, pigp);
obsolete= (hashlen == sizeof(obsolete_str)-1 &&
!memcmp(hashstart, obsolete_str, hashlen));
if (obsolete)
conffvalue_lastword(value, endfn, endent,
&hashstart, &hashlen, &endfn,
- filename, lno, pigp);
+ ps, pigp);
newlink= nfmalloc(sizeof(struct conffile));
value = path_skip_slash_dotslash(value);
namelen= (int)(endfn-value);
if (namelen <= 0)
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("root or null directory is listed as a conffile"));
newptr = nfmalloc(namelen+2);
newptr[0]= '/';
@@ -308,8 +300,7 @@ void f_conffiles(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) {
char c1, c2;
const char *p, *emsg;
@@ -346,12 +337,12 @@ void f_dependency(struct pkginfo *pigp, struct
pkginfoperfile *pifp,
strncpy(depname, depnamestart, depnamelength);
*(depname + depnamelength) = '\0';
if (!*depname)
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("`%s' field, missing package name, or garbage where "
"package name expected"), fip->name);
emsg= illegal_packagename(depname,NULL);
if (emsg)
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("`%s' field, invalid package name `%.255s': %s"),
fip->name, depname, emsg);
dop= nfmalloc(sizeof(struct deppossi));
@@ -381,13 +372,13 @@ void f_dependency(struct pkginfo *pigp, struct
pkginfoperfile *pifp,
dop->verrel |= (dvrf_strict | dvrf_builtup);
p++;
} else if (c2 == '<' || c2 == '>') {
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("`%s' field, reference to `%.255s':\n"
" bad version relationship %c%c"),
fip->name, depname, c1, c2);
dop->verrel= dvr_none;
} else {
- parse_warn(filename, lno, warnto, warncount, pigp,
+ parse_warn(ps, pigp,
_("`%s' field, reference to `%.255s':\n"
" `%c' is obsolete, use `%c=' or `%c%c' instead"),
fip->name, depname, c1, c1, c1, c1);
@@ -397,7 +388,7 @@ void f_dependency(struct pkginfo *pigp, struct
pkginfoperfile *pifp,
dop->verrel= dvr_exact;
p++;
} else {
- parse_warn(filename, lno, warnto, warncount, pigp,
+ parse_warn(ps, pigp,
_("`%s' field, reference to `%.255s':\n"
" implicit exact match on version number, "
"suggest using `=' instead"),
@@ -405,11 +396,11 @@ void f_dependency(struct pkginfo *pigp, struct
pkginfoperfile *pifp,
dop->verrel= dvr_exact;
}
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"));
if (!isspace(*p) && !isalnum(*p)) {
- parse_warn(filename, lno, warnto, warncount, pigp,
+ parse_warn(ps, pigp,
_("`%s' field, reference to `%.255s':\n"
" version value starts with non-alphanumeric, "
"suggest adding a space"),
@@ -426,15 +417,15 @@ void f_dependency(struct pkginfo *pigp, struct
pkginfoperfile *pifp,
versionlength= p - versionstart;
while (isspace(*p)) p++;
if (*p == '(')
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("`%s' field, reference to `%.255s': "
"version contains `%c'"), fip->name,depname, ')');
else if (*p != ')')
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("`%s' field, reference to `%.255s': "
"version contains `%c'"), fip->name,depname, ' ');
else if (*p == '\0')
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("`%s' field, reference to `%.255s': "
"version unterminated"), fip->name, depname);
if (versionlength >= versionused) {
@@ -445,7 +436,7 @@ void f_dependency(struct pkginfo *pigp, struct
pkginfoperfile *pifp,
*(version + versionlength) = '\0';
emsg= parseversion(&dop->version,version);
if (emsg)
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("`%s' field, reference to `%.255s': "
"error in version: %.255s"), fip->name, depname, emsg);
p++; while (isspace(*p)) p++;
@@ -455,14 +446,14 @@ void f_dependency(struct pkginfo *pigp, struct
pkginfoperfile *pifp,
}
if (!*p || *p == ',') break;
if (*p != '|')
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("`%s' field, syntax error after reference to package
`%.255s'"),
fip->name, dop->ed->name);
if (fip->integer == dep_conflicts ||
fip->integer == dep_breaks ||
fip->integer == dep_provides ||
fip->integer == dep_replaces)
- parse_error(filename, lno, pigp,
+ parse_error(ps, pigp,
_("alternatives (`|') not allowed in %s field"),
fip->name);
p++; while (isspace(*p)) p++;
}
@@ -515,53 +506,51 @@ scan_word(const char **valp)
void
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 *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 "
"this context"));
while ((word = scan_word(&value))) {
emsg = illegal_triggername(word);
if (emsg)
- parse_error(filename, lno, pend,
+ parse_error(ps, pend,
_("illegal pending trigger name `%.255s': %s"), word, emsg);
if (!trig_note_pend_core(pend, nfstrsave(word)))
- parse_error(filename, lno, pend,
+ parse_error(ps, pend,
_("duplicate pending trigger `%.255s'"), word);
}
}
void
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 *word, *emsg;
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 "
"this context"));
while ((word = scan_word(&value))) {
emsg = illegal_packagename(word, NULL);
if (emsg)
- parse_error(filename, lno, aw,
+ parse_error(ps, aw,
_("illegal package name in awaited trigger `%.255s': %s"),
word, emsg);
pend = findpackage(word);
if (!trig_note_aw(pend, aw))
- parse_error(filename, lno, aw,
+ parse_error(ps, aw,
_("duplicate awaited trigger package `%.255s'"), word);
trig_enqueue_awaited_pend(pend);
diff --git a/lib/parse.c b/lib/parse.c
index b0b64fe..a61c8c7 100644
--- a/lib/parse.c
+++ b/lib/parse.c
@@ -95,7 +95,6 @@ int parsedb(const char *filename, enum parsedbflags flags,
struct pkginfoperfile *newpifp, *pifp;
struct arbitraryfield *arp, **larpp;
struct trigaw *ta;
- int lno;
int pdone;
int fieldencountered[sizeof_array(fieldinfos)];
const struct fieldinfo *fip;
@@ -106,8 +105,14 @@ int parsedb(const char *filename, enum parsedbflags flags,
int fieldlen= 0, valuelen= 0;
int *ip, c;
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;
fd= open(filename, O_RDONLY);
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;
}
- lno = 0;
pdone= 0;
#define EOF_mmap(dataptr, endptr) (dataptr >= endptr)
#define getc_mmap(dataptr) *dataptr++;
@@ -145,7 +149,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
/* Skip adjacent new lines */
while(!EOF_mmap(dataptr, endptr)) {
c= getc_mmap(dataptr); if (c!='\n' && c!=MSDOS_EOF_CHAR ) break;
- lno++;
+ ps.lno++;
}
if (EOF_mmap(dataptr, endptr)) break;
for (;;) { /* loop per field */
@@ -155,17 +159,17 @@ int parsedb(const char *filename, enum parsedbflags flags,
fieldlen= dataptr - fieldstart - 1;
while (!EOF_mmap(dataptr, endptr) && c != '\n' && isspace(c)) c=
getc_mmap(dataptr);
if (EOF_mmap(dataptr, endptr))
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("EOF after field name `%.*s'"), fieldlen, fieldstart);
if (c == '\n')
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("newline in field name `%.*s'"), fieldlen, fieldstart);
if (c == MSDOS_EOF_CHAR)
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("MSDOS EOF (^Z) in field name `%.*s'"),
fieldlen, fieldstart);
if (c != ':')
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("field name `%.*s' must be followed by colon"),
fieldlen, fieldstart);
/* 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 (EOF_mmap(dataptr, endptr))
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("EOF before value of field `%.*s' (missing final
newline)"),
fieldlen,fieldstart);
if (c == MSDOS_EOF_CHAR)
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("MSDOS EOF char in value of field `%.*s' (missing
newline?)"),
fieldlen,fieldstart);
valuestart= dataptr - 1;
for (;;) {
if (c == '\n' || c == MSDOS_EOF_CHAR) {
- lno++;
+ ps.lno++;
if (EOF_mmap(dataptr, endptr)) break;
c= getc_mmap(dataptr);
/* 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);
c= '\n';
} else if (EOF_mmap(dataptr, endptr)) {
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("EOF during value of field `%.*s' (missing final
newline)"),
fieldlen,fieldstart);
}
@@ -217,18 +221,18 @@ int parsedb(const char *filename, enum parsedbflags flags,
memcpy(value,valuestart,valuelen);
*(value + valuelen) = '\0';
if (*ip++)
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("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 {
if (fieldlen<2)
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("user-defined field name `%.*s' too short"),
fieldlen, fieldstart);
larpp= &newpifp->arbs;
while ((arp= *larpp) != NULL) {
if (!strncasecmp(arp->name,fieldstart,fieldlen))
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("duplicate value for user-defined field `%.*s'"),
fieldlen, fieldstart);
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;
} /* loop per field */
if (pdone && donep)
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("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) {
- parse_ensure_have_field(filename, lno, warnto, warncount, &newpig,
+ parse_ensure_have_field(&ps, &newpig,
&newpifp->description, "description");
- parse_ensure_have_field(filename, lno, warnto, warncount, &newpig,
+ parse_ensure_have_field(&ps, &newpig,
&newpifp->maintainer, "maintainer");
if (newpig.status != stat_halfinstalled)
- parse_must_have_field(filename, lno, &newpig,
+ parse_must_have_field(&ps, &newpig,
newpifp->version.version, "version");
}
if (flags & pdb_recordavailable)
- parse_ensure_have_field(filename, lno, warnto, warncount, &newpig,
+ parse_ensure_have_field(&ps, &newpig,
&newpifp->architecture, "architecture");
/* Check the Config-Version information:
@@ -267,7 +271,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
if (!(flags & pdb_recordavailable)) {
if (newpig.configversion.version) {
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"));
} else {
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 &&
(newpig.status <= stat_configfiles ||
newpig.status >= stat_triggerspending))
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("package has status %s but triggers are awaited"),
statusinfos[newpig.status].name);
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 "
"awaited"));
if (!(newpig.status == stat_triggerspending ||
newpig.status == stat_triggersawaited) &&
newpig.trigpend_head)
- parse_error(filename, lno, &newpig,
+ parse_error(&ps, &newpig,
_("package has status %s but triggers are pending"),
statusinfos[newpig.status].name);
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 "
"pending"));
@@ -303,7 +307,7 @@ int parsedb(const char *filename, enum parsedbflags flags,
if (!(flags & pdb_recordavailable) &&
newpig.status == stat_notinstalled &&
newpifp->conffiles) {
- parse_warn(filename, lno, warnto, warncount, &newpig,
+ parse_warn(&ps, &newpig,
_("Package which in state not-installed has conffiles, "
"forgetting them"));
newpifp->conffiles= NULL;
@@ -361,7 +365,8 @@ int parsedb(const char *filename, enum parsedbflags flags,
if (donep) *donep= pigp;
pdone++;
if (EOF_mmap(dataptr, endptr)) break;
- if (c == '\n') lno++;
+ if (c == '\n')
+ ps.lno++;
}
if (data != NULL) {
#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 (donep && !pdone) ohshit(_("no package information in
`%.255s'"),filename);
+ if (warncount)
+ *warncount = ps.warncount;
+
return pdone;
}
diff --git a/lib/parsedump.h b/lib/parsedump.h
index 636a4d2..10d2d97 100644
--- a/lib/parsedump.h
+++ b/lib/parsedump.h
@@ -25,6 +25,14 @@
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 PKGPFIELD(pifp,of,type) (*(type*)((char*)(pifp)+(of)))
@@ -32,8 +40,7 @@ struct fieldinfo;
#define FILEFFIELD(filedetail,of,type) (*(type*)((char*)(filedetail)+(of)))
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);
freadfunction f_name, f_charfield, f_priority, f_section, f_status,
f_filecharf;
freadfunction f_boolean, f_dependency, f_conffiles, f_version, f_revision;
@@ -59,16 +66,14 @@ struct fieldinfo {
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 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 char **value, const char *what);
diff --git a/lib/parsehelp.c b/lib/parsehelp.c
index c850132..af2fd1f 100644
--- a/lib/parsehelp.c
+++ b/lib/parsehelp.c
@@ -35,25 +35,25 @@
#include "parsedump.h"
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)
{
if (pigp && pigp->name)
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
sprintf(buf, _("%s, in file '%.255s' near line %d:\n "),
- type, filename, lno);
+ type, ps->filename, ps->lno);
}
void
-parse_error(const char *filename, int lno,
+parse_error(struct parsedb_state *ps,
const struct pkginfo *pigp, const char *fmt, ...)
{
va_list al;
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);
strcat(q,fmt);
@@ -62,21 +62,21 @@ parse_error(const char *filename, int lno,
}
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, ...)
{
va_list al;
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);
strcat(q, fmt);
va_start(al, fmt);
- if (warncount) (*warncount)++;
- if (warnto) {
+ ps->warncount++;
+ if (ps->warnto) {
strcat(q,"\n");
- if (vfprintf(warnto,buf2,al) == EOF)
+ if (vfprintf(ps->warnto, buf2, al) == EOF)
ohshite(_("failed to write parsing warning"));
}
va_end(al);
@@ -251,29 +251,28 @@ const char *parseversion(struct versionrevision
*rversion, const char *string) {
}
void
-parse_must_have_field(const char *filename, int lno,
+parse_must_have_field(struct parsedb_state *ps,
const struct pkginfo *pigp,
const char *value, const char *what)
{
if (!value)
- parse_error(filename, lno, pigp, _("missing %s"), what);
+ parse_error(ps, pigp, _("missing %s"), what);
else if (!*value)
- parse_error(filename, lno, pigp, _("empty value for %s"), what);
+ parse_error(ps, pigp, _("empty value for %s"), what);
}
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 char **value, const char *what)
{
static const char *empty = "";
if (!*value) {
- parse_warn(filename, lno, warnto, warncount, pigp, _("missing %s"), what);
+ parse_warn(ps, pigp, _("missing %s"), what);
*value = empty;
} else if (!**value) {
- parse_warn(filename, lno, warnto, warncount, pigp, _("empty value for
%s"), what);
+ parse_warn(ps, pigp, _("empty value for %s"), what);
}
}
--
dpkg's main repository
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]