diff options
Diffstat (limited to 'lib/headerfmt.c')
-rw-r--r-- | lib/headerfmt.c | 83 |
1 files changed, 45 insertions, 38 deletions
diff --git a/lib/headerfmt.c b/lib/headerfmt.c index a865ee7a8..fdb3aadb7 100644 --- a/lib/headerfmt.c +++ b/lib/headerfmt.c @@ -4,6 +4,7 @@ #include "system.h" +#include <stdarg.h> #include <rpm/header.h> #include <rpm/rpmtag.h> #include <rpm/rpmstring.h> @@ -20,7 +21,7 @@ */ typedef struct sprintfTag_s * sprintfTag; struct sprintfTag_s { - headerTagFormatFunction fmt; + headerFmt fmt; rpmTagVal tag; int justOne; char * format; @@ -217,6 +218,25 @@ static char * hsaReserve(headerSprintfArgs hsa, size_t need) return hsa->val + hsa->vallen; } +RPM_GNUC_PRINTF(2, 3) +static void hsaError(headerSprintfArgs hsa, const char *fmt, ...) +{ + /* Use thread local static buffer as headerFormat() errmsg arg is const */ + static __thread char errbuf[BUFSIZ]; + + if (fmt == NULL) { + hsa->errmsg = NULL; + } else { + va_list ap; + + va_start(ap, fmt); + vsnprintf(errbuf, sizeof(errbuf), fmt, ap); + va_end(ap); + + hsa->errmsg = errbuf; + } +} + /** * Search tags for a name. * @param hsa headerSprintf args @@ -246,7 +266,7 @@ static int findTag(headerSprintfArgs hsa, sprintfToken token, const char * name) /* Search extensions for specific format. */ if (stag->type != NULL) - stag->fmt = rpmHeaderFormatFuncByName(stag->type); + stag->fmt = rpmHeaderFormatByName(stag->type); return stag->fmt ? 0 : 1; } @@ -333,13 +353,13 @@ static int parseFormat(headerSprintfArgs hsa, char * str, chptr = start; while (*chptr && *chptr != '{' && *chptr != '%') { if (!risdigit(*chptr) && *chptr != '-') { - hsa->errmsg = _("invalid field width"); + hsaError(hsa, _("invalid field width")); goto errxit; } chptr++; } if (!*chptr || *chptr == '%') { - hsa->errmsg = _("missing { after %"); + hsaError(hsa, _("missing { after %%")); goto errxit; } @@ -361,7 +381,7 @@ static int parseFormat(headerSprintfArgs hsa, char * str, dst = next = start; while (*next && *next != '}') next++; if (!*next) { - hsa->errmsg = _("missing } after %{"); + hsaError(hsa, _("missing } after %%{")); goto errxit; } *next++ = '\0'; @@ -372,7 +392,7 @@ static int parseFormat(headerSprintfArgs hsa, char * str, if (*chptr != '\0') { *chptr++ = '\0'; if (!*chptr) { - hsa->errmsg = _("empty tag format"); + hsaError(hsa, _("empty tag format")); goto errxit; } token->u.tag.type = chptr; @@ -383,14 +403,14 @@ static int parseFormat(headerSprintfArgs hsa, char * str, } if (!*start) { - hsa->errmsg = _("empty tag name"); + hsaError(hsa, _("empty tag name")); goto errxit; } token->type = PTOK_TAG; if (findTag(hsa, token, start)) { - hsa->errmsg = _("unknown tag"); + hsaError(hsa, _("unknown tag: \"%s\""), start); goto errxit; } @@ -410,7 +430,7 @@ static int parseFormat(headerSprintfArgs hsa, char * str, } if (!start) { - hsa->errmsg = _("] expected at end of array"); + hsaError(hsa, _("] expected at end of array")); goto errxit; } @@ -422,7 +442,7 @@ static int parseFormat(headerSprintfArgs hsa, char * str, case ']': if (state != PARSER_IN_ARRAY) { - hsa->errmsg = _("unexpected ]"); + hsaError(hsa, _("unexpected ]")); goto errxit; } *start++ = '\0'; @@ -432,7 +452,7 @@ static int parseFormat(headerSprintfArgs hsa, char * str, case '}': if (state != PARSER_IN_EXPR) { - hsa->errmsg = _("unexpected }"); + hsaError(hsa, _("unexpected }")); goto errxit; } *start++ = '\0'; @@ -483,19 +503,19 @@ static int parseExpression(headerSprintfArgs hsa, sprintfToken token, char * chptr; char * end; - hsa->errmsg = NULL; + hsaError(hsa, NULL); chptr = str; while (*chptr && *chptr != '?') chptr++; if (*chptr != '?') { - hsa->errmsg = _("? expected in expression"); + hsaError(hsa, _("? expected in expression")); return 1; } *chptr++ = '\0';; if (*chptr != '{') { - hsa->errmsg = _("{ expected after ? in expression"); + hsaError(hsa, _("{ expected after ? in expression")); return 1; } @@ -507,7 +527,7 @@ static int parseExpression(headerSprintfArgs hsa, sprintfToken token, /* XXX fix segfault on "rpm -q rpm --qf='%|NAME?{%}:{NAME}|\n'"*/ if (!(end && *end)) { - hsa->errmsg = _("} expected in expression"); + hsaError(hsa, _("} expected in expression")); token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); return 1; @@ -515,7 +535,7 @@ static int parseExpression(headerSprintfArgs hsa, sprintfToken token, chptr = end; if (*chptr != ':' && *chptr != '|') { - hsa->errmsg = _(": expected following ? subexpression"); + hsaError(hsa, _(": expected following ? subexpression")); token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); return 1; @@ -533,7 +553,7 @@ static int parseExpression(headerSprintfArgs hsa, sprintfToken token, chptr++; if (*chptr != '{') { - hsa->errmsg = _("{ expected after : in expression"); + hsaError(hsa, _("{ expected after : in expression")); token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); return 1; @@ -547,7 +567,7 @@ static int parseExpression(headerSprintfArgs hsa, sprintfToken token, /* XXX fix segfault on "rpm -q rpm --qf='%|NAME?{a}:{%}|{NAME}\n'" */ if (!(end && *end)) { - hsa->errmsg = _("} expected in expression"); + hsaError(hsa, _("} expected in expression")); token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); return 1; @@ -555,7 +575,7 @@ static int parseExpression(headerSprintfArgs hsa, sprintfToken token, chptr = end; if (*chptr != '|') { - hsa->errmsg = _("| expected at end of expression"); + hsaError(hsa, _("| expected at end of expression")); token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); token->u.cond.elseFormat = @@ -624,9 +644,9 @@ static char * formatValue(headerSprintfArgs hsa, sprintfTag tag, int element) char * t, * te; rpmtd td; - if ((td = getData(hsa, tag->tag))) { + if ((td = getData(hsa, tag->tag)) && td->count > element) { td->ix = element; /* Ick, use iterators instead */ - val = tag->fmt(td); + val = rpmHeaderFormatCall(tag->fmt, td); } else { val = xstrdup("(none)"); } @@ -748,16 +768,10 @@ static char * singleSprintf(headerSprintfArgs hsa, sprintfToken token, found = 1; count = rpmtdCount(td); - if (numElements > 1 && count != numElements) - switch (td->type) { - default: - hsa->errmsg = - _("array iterator used with different sized arrays"); + if (numElements > 0 && count != numElements) { + hsaError(hsa, + _("array iterator used with different sized arrays")); return NULL; - break; - case RPM_BIN_TYPE: - case RPM_STRING_TYPE: - break; } if (count > numElements) numElements = count; @@ -821,13 +835,6 @@ static unsigned int tagId(rpmTagVal tag) return tag; } -static rpmtd tagFree(rpmtd td) -{ - rpmtdFreeData(td); - rpmtdFree(td); - return NULL; -} - char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg) { struct headerSprintfArgs_s hsa; @@ -845,7 +852,7 @@ char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg) if (parseFormat(&hsa, hsa.fmt, &hsa.format, &hsa.numTokens, NULL, PARSER_BEGIN)) goto exit; - hsa.cache = tagCacheCreate(128, tagId, tagCmp, NULL, tagFree); + hsa.cache = tagCacheCreate(128, tagId, tagCmp, NULL, rpmtdFree); hsa.val = xstrdup(""); tag = |