From b58ca441e66148fa7f206729898943551c6c4c19 Mon Sep 17 00:00:00 2001 From: jbj Date: Mon, 10 Mar 2003 14:39:07 +0000 Subject: [PATCH] Minimize ars passed throuch headerSprintf call chain. CVS patchset: 6670 CVS date: 2003/03/10 14:39:07 --- rpmdb/header.c | 575 +++++++++++++++++++++++++-------------------------------- 1 file changed, 250 insertions(+), 325 deletions(-) diff --git a/rpmdb/header.c b/rpmdb/header.c index cdad7c0..c7eef80 100644 --- a/rpmdb/header.c +++ b/rpmdb/header.c @@ -2264,101 +2264,106 @@ freeFormat( /*@only@*/ /*@null@*/ sprintfToken format, int num) /** */ -static void findTag(char * name, const headerTagTableEntry tags, - const headerSprintfExtension extensions, - /*@out@*/ headerTagTableEntry * tagMatch, - /*@out@*/ headerSprintfExtension * extMatch) +typedef struct headerSprintfArgs_s { + Header h; + char * fmt; +/*@temp@*/ + headerTagTableEntry tags; +/*@temp@*/ + headerSprintfExtension exts; +/*@observer@*/ /*@null@*/ + const char * errmsg; + sprintfToken format; + int numTokens; + rpmec ec; +/*@owned@*/ + char * val; + size_t vallen; + size_t alloced; +} * headerSprintfArgs; + +/** + * @param hsa headerSprintf args + * @param tagname + * @retval *tagMatch + * @retval *extMatch + */ +static void findTag(headerSprintfArgs hsa, const char * tagname, + /*@out@*/ headerTagTableEntry *const tagMatch, + /*@out@*/ headerSprintfExtension *const extMatch) /*@modifies *tagMatch, *extMatch @*/ /*@requires maxSet(tagMatch) >= 0 /\ maxSet(extMatch) >= 0 @*/ { headerTagTableEntry entry; headerSprintfExtension ext; - const char * tagname; *tagMatch = NULL; *extMatch = NULL; - if (strncmp("RPMTAG_", name, sizeof("RPMTAG_")-1)) { +/*@-branchstate@*/ + if (strncmp("RPMTAG_", tagname, sizeof("RPMTAG_")-1)) { /*@-boundswrite@*/ - char * t = alloca(strlen(name) + sizeof("RPMTAG_")); - (void) stpcpy( stpcpy(t, "RPMTAG_"), name); + char * t = alloca(strlen(tagname) + sizeof("RPMTAG_")); + (void) stpcpy( stpcpy(t, "RPMTAG_"), tagname); tagname = t; /*@=boundswrite@*/ - } else { - tagname = name; } +/*@=branchstate@*/ /* Search extensions first to permit overriding header tags. */ - ext = extensions; - while (ext->type != HEADER_EXT_LAST) { - if (ext->name != NULL && ext->type == HEADER_EXT_TAG - && !xstrcasecmp(ext->name, tagname)) - break; - - if (ext->type == HEADER_EXT_MORE) - ext = ext->u.more; - else - ext++; - } - - if (ext->type == HEADER_EXT_TAG) { - *extMatch = ext; - return; + for (ext = hsa->exts; ext != NULL && ext->type != HEADER_EXT_LAST; + ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1)) + { + if (ext->name == NULL || ext->type != HEADER_EXT_TAG) + continue; + if (!xstrcasecmp(ext->name, tagname)) { + *extMatch = ext; + return; + } } /* Search header tags. */ - for (entry = tags; entry->name; entry++) - if (entry->name && !xstrcasecmp(entry->name, tagname)) - break; - - if (entry->name) { - *tagMatch = entry; - return; + for (entry = hsa->tags; entry->name != NULL; entry++) { + if (!xstrcasecmp(entry->name, tagname)) { + *tagMatch = entry; + return; + } } } /* forward ref */ /** + * @param hsa headerSprintf args * @param token * @param str - * @param tags - * @param extensions * @retval *endPtr - * @retval *errmsg error message (if any) * @return 0 on success */ -static int parseExpression(sprintfToken token, char * str, - const headerTagTableEntry tags, - const headerSprintfExtension extensions, - /*@out@*/char ** endPtr, /*@null@*/ /*@out@*/ errmsg_t * errmsg) - /*@modifies str, *str, *token, *endPtr, *errmsg @*/ - /*@requires maxSet(endPtr) >= 0 /\ maxSet(errmsg) >= 0 @*/; +static int parseExpression(headerSprintfArgs hsa, sprintfToken token, + char * str, /*@out@*/char ** endPtr) + /*@modifies hsa, str, *token, *endPtr @*/ + /*@requires maxSet(endPtr) >= 0 @*/; /** + * @param hsa headerSprintf args * @param str - * @param tags - * @param extensions * @retval *formatPtr * @retval *numTokensPtr * @retval *endPtr * @param state - * @retval *errmsg error message (if any) * @return 0 on success */ -/*@-boundswrite@*/ -static int parseFormat(/*@null@*/ char * str, const headerTagTableEntry tags, - const headerSprintfExtension extensions, +static int parseFormat(headerSprintfArgs hsa, /*@null@*/ char * str, /*@out@*/sprintfToken * formatPtr, /*@out@*/int * numTokensPtr, - /*@null@*/ /*@out@*/ char ** endPtr, int state, - /*@null@*/ /*@out@*/ errmsg_t * errmsg) - /*@modifies str, *str, *formatPtr, *numTokensPtr, *endPtr, *errmsg @*/ + /*@null@*/ /*@out@*/ char ** endPtr, int state) + /*@modifies hsa, str, *formatPtr, *numTokensPtr, *endPtr @*/ /*@requires maxSet(formatPtr) >= 0 /\ maxSet(numTokensPtr) >= 0 - /\ maxSet(endPtr) >= 0 /\ maxSet(errmsg) >= 0 @*/ + /\ maxSet(endPtr) >= 0 @*/ { char * chptr, * start, * next, * dst; sprintfToken format; + sprintfToken token; int numTokens; - int currToken; headerTagTableEntry tag; headerSprintfExtension ext; int i; @@ -2376,209 +2381,218 @@ static int parseFormat(/*@null@*/ char * str, const headerTagTableEntry tags, /*@-infloops@*/ /* LCL: can't detect done termination */ dst = start = str; - currToken = -1; + numTokens = 0; + token = NULL; if (start != NULL) while (*start != '\0') { switch (*start) { case '%': /* handle %% */ if (*(start + 1) == '%') { - if (currToken < 0 || format[currToken].type != PTOK_STRING) { - currToken++; - format[currToken].type = PTOK_STRING; + if (token == NULL || token->type != PTOK_STRING) { + token = format + numTokens++; + token->type = PTOK_STRING; /*@-temptrans -assignexpose@*/ - dst = format[currToken].u.string.string = start; + dst = token->u.string.string = start; /*@=temptrans =assignexpose@*/ } start++; +/*@-boundswrite@*/ *dst++ = *start++; +/*@=boundswrite@*/ /*@switchbreak@*/ break; } - currToken++; + token = format + numTokens++; +/*@-boundswrite@*/ *dst++ = '\0'; +/*@=boundswrite@*/ start++; if (*start == '|') { char * newEnd; start++; - if (parseExpression(format + currToken, start, tags, - extensions, &newEnd, errmsg)) +/*@-boundswrite@*/ + if (parseExpression(hsa, token, start, &newEnd)) { format = freeFormat(format, numTokens); return 1; } +/*@=boundswrite@*/ start = newEnd; /*@switchbreak@*/ break; } /*@-assignexpose@*/ - format[currToken].u.tag.format = start; + token->u.tag.format = start; /*@=assignexpose@*/ - format[currToken].u.tag.pad = 0; - format[currToken].u.tag.justOne = 0; - format[currToken].u.tag.arrayCount = 0; + token->u.tag.pad = 0; + token->u.tag.justOne = 0; + token->u.tag.arrayCount = 0; chptr = start; while (*chptr && *chptr != '{' && *chptr != '%') chptr++; if (!*chptr || *chptr == '%') { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("missing { after %"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("missing { after %"); format = freeFormat(format, numTokens); return 1; } +/*@-boundswrite@*/ *chptr++ = '\0'; +/*@=boundswrite@*/ while (start < chptr) { if (xisdigit(*start)) { i = strtoul(start, &start, 10); - format[currToken].u.tag.pad += i; + token->u.tag.pad += i; } else { start++; } } if (*start == '=') { - format[currToken].u.tag.justOne = 1; + token->u.tag.justOne = 1; start++; } else if (*start == '#') { - format[currToken].u.tag.justOne = 1; - format[currToken].u.tag.arrayCount = 1; + token->u.tag.justOne = 1; + token->u.tag.arrayCount = 1; start++; } next = start; while (*next && *next != '}') next++; if (!*next) { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("missing } after %{"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("missing } after %{"); format = freeFormat(format, numTokens); return 1; } +/*@-boundswrite@*/ *next++ = '\0'; +/*@=boundswrite@*/ chptr = start; while (*chptr && *chptr != ':') chptr++; if (*chptr != '\0') { +/*@-boundswrite@*/ *chptr++ = '\0'; +/*@=boundswrite@*/ if (!*chptr) { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("empty tag format"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("empty tag format"); format = freeFormat(format, numTokens); return 1; } /*@-assignexpose@*/ - format[currToken].u.tag.type = chptr; + token->u.tag.type = chptr; /*@=assignexpose@*/ } else { - format[currToken].u.tag.type = NULL; + token->u.tag.type = NULL; } if (!*start) { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("empty tag name"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("empty tag name"); format = freeFormat(format, numTokens); return 1; } i = 0; - findTag(start, tags, extensions, &tag, &ext); +/*@-boundswrite@*/ + findTag(hsa, start, &tag, &ext); +/*@=boundswrite@*/ if (tag) { - format[currToken].u.tag.ext = NULL; - format[currToken].u.tag.tag = tag->val; + token->u.tag.ext = NULL; + token->u.tag.tag = tag->val; } else if (ext) { - format[currToken].u.tag.ext = ext->u.tagFunction; - format[currToken].u.tag.extNum = ext - extensions; + token->u.tag.ext = ext->u.tagFunction; + token->u.tag.extNum = ext - hsa->exts; } else { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("unknown tag"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("unknown tag"); format = freeFormat(format, numTokens); return 1; } - format[currToken].type = PTOK_TAG; + token->type = PTOK_TAG; start = next; /*@switchbreak@*/ break; case '[': +/*@-boundswrite@*/ *dst++ = '\0'; *start++ = '\0'; - currToken++; +/*@=boundswrite@*/ + token = format + numTokens++; - if (parseFormat(start, tags, extensions, - &format[currToken].u.array.format, - &format[currToken].u.array.numTokens, - &start, PARSER_IN_ARRAY, errmsg)) { +/*@-boundswrite@*/ + if (parseFormat(hsa, start, + &token->u.array.format, + &token->u.array.numTokens, + &start, PARSER_IN_ARRAY)) + { format = freeFormat(format, numTokens); return 1; } +/*@=boundswrite@*/ if (!start) { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("] expected at end of array"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("] expected at end of array"); format = freeFormat(format, numTokens); return 1; } dst = start; - format[currToken].type = PTOK_ARRAY; + token->type = PTOK_ARRAY; /*@switchbreak@*/ break; case ']': if (state != PARSER_IN_ARRAY) { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("unexpected ]"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("unexpected ]"); format = freeFormat(format, numTokens); return 1; } +/*@-boundswrite@*/ *start++ = '\0'; +/*@=boundswrite@*/ if (endPtr) *endPtr = start; done = 1; /*@switchbreak@*/ break; case '}': if (state != PARSER_IN_EXPR) { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("unexpected }"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("unexpected }"); format = freeFormat(format, numTokens); return 1; } +/*@-boundswrite@*/ *start++ = '\0'; +/*@=boundswrite@*/ if (endPtr) *endPtr = start; done = 1; /*@switchbreak@*/ break; default: - if (currToken < 0 || format[currToken].type != PTOK_STRING) { - currToken++; - format[currToken].type = PTOK_STRING; + if (token == NULL || token->type != PTOK_STRING) { + token = format + numTokens++; + token->type = PTOK_STRING; /*@-temptrans -assignexpose@*/ - dst = format[currToken].u.string.string = start; + dst = token->u.string.string = start; /*@=temptrans =assignexpose@*/ } +/*@-boundswrite@*/ if (*start == '\\') { start++; *dst++ = escapedChar(*start++); } else { *dst++ = *start++; } +/*@=boundswrite@*/ /*@switchbreak@*/ break; } if (done) @@ -2586,65 +2600,57 @@ static int parseFormat(/*@null@*/ char * str, const headerTagTableEntry tags, } /*@=infloops@*/ +/*@-boundswrite@*/ if (dst != NULL) *dst = '\0'; +/*@=boundswrite@*/ - currToken++; - for (i = 0; i < currToken; i++) { - if (format[i].type == PTOK_STRING) - format[i].u.string.len = strlen(format[i].u.string.string); + for (i = 0; i < numTokens; i++) { + token = format + i; + if (token->type == PTOK_STRING) + token->u.string.len = strlen(token->u.string.string); } - *numTokensPtr = currToken; + *numTokensPtr = numTokens; *formatPtr = format; return 0; } -/*@=boundswrite@*/ /*@-boundswrite@*/ -static int parseExpression(sprintfToken token, char * str, - const headerTagTableEntry tags, - const headerSprintfExtension extensions, - /*@out@*/ char ** endPtr, - /*@null@*/ /*@out@*/ errmsg_t * errmsg) +static int parseExpression(headerSprintfArgs hsa, sprintfToken token, + char * str, /*@out@*/ char ** endPtr) { headerTagTableEntry tag; headerSprintfExtension ext; char * chptr; char * end; - if (errmsg) *errmsg = NULL; + hsa->errmsg = NULL; chptr = str; while (*chptr && *chptr != '?') chptr++; if (*chptr != '?') { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("? expected in expression"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("? expected in expression"); return 1; } *chptr++ = '\0';; if (*chptr != '{') { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("{ expected after ? in expression"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("{ expected after ? in expression"); return 1; } chptr++; - if (parseFormat(chptr, tags, extensions, &token->u.cond.ifFormat, - &token->u.cond.numIfTokens, &end, PARSER_IN_EXPR, errmsg)) + if (parseFormat(hsa, chptr, &token->u.cond.ifFormat, + &token->u.cond.numIfTokens, &end, PARSER_IN_EXPR)) return 1; /* XXX fix segfault on "rpm -q rpm --qf='%|NAME?{%}:{NAME}|\n'"*/ if (!(end && *end)) { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("} expected in expression"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("} expected in expression"); token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); return 1; @@ -2652,17 +2658,15 @@ static int parseExpression(sprintfToken token, char * str, chptr = end; if (*chptr != ':' && *chptr != '|') { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _(": expected following ? subexpression"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _(": expected following ? subexpression"); token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); return 1; } if (*chptr == '|') { - if (parseFormat(NULL, tags, extensions, &token->u.cond.elseFormat, - &token->u.cond.numElseTokens, &end, PARSER_IN_EXPR, errmsg)) + if (parseFormat(hsa, NULL, &token->u.cond.elseFormat, + &token->u.cond.numElseTokens, &end, PARSER_IN_EXPR)) { token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); @@ -2672,9 +2676,7 @@ static int parseExpression(sprintfToken token, char * str, chptr++; if (*chptr != '{') { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("{ expected after : in expression"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("{ expected after : in expression"); token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); return 1; @@ -2682,16 +2684,13 @@ static int parseExpression(sprintfToken token, char * str, chptr++; - if (parseFormat(chptr, tags, extensions, &token->u.cond.elseFormat, - &token->u.cond.numElseTokens, &end, PARSER_IN_EXPR, - errmsg)) + if (parseFormat(hsa, chptr, &token->u.cond.elseFormat, + &token->u.cond.numElseTokens, &end, PARSER_IN_EXPR)) return 1; /* XXX fix segfault on "rpm -q rpm --qf='%|NAME?{a}:{%}|{NAME}\n'" */ if (!(end && *end)) { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("} expected in expression"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("} expected in expression"); token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); return 1; @@ -2699,9 +2698,7 @@ static int parseExpression(sprintfToken token, char * str, chptr = end; if (*chptr != '|') { - /*@-observertrans -readonlytrans@*/ - if (errmsg) *errmsg = _("| expected at end of expression"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("| expected at end of expression"); token->u.cond.ifFormat = freeFormat(token->u.cond.ifFormat, token->u.cond.numIfTokens); token->u.cond.elseFormat = @@ -2714,14 +2711,14 @@ static int parseExpression(sprintfToken token, char * str, *endPtr = chptr; - findTag(str, tags, extensions, &tag, &ext); + findTag(hsa, str, &tag, &ext); if (tag) { token->u.cond.tag.ext = NULL; token->u.cond.tag.tag = tag->val; } else if (ext) { token->u.cond.tag.ext = ext->u.tagFunction; - token->u.cond.tag.extNum = ext - extensions; + token->u.cond.tag.extNum = ext - hsa->exts; } else { token->u.cond.tag.ext = NULL; token->u.cond.tag.tag = -1; @@ -2735,15 +2732,15 @@ static int parseExpression(sprintfToken token, char * str, /** * Call a header extension only once, saving results. - * @param h header + * @param hsa headerSprintf args * @param fn * @retval *typeptr * @retval *data * @retval *countptr - * @param ec extension cache + * @retval ec extension cache * @return 0 on success, 1 on failure */ -static int getExtension(Header h, headerTagTagFunction fn, +static int getExtension(headerSprintfArgs hsa, headerTagTagFunction fn, /*@out@*/ hTYP_t typeptr, /*@out@*/ hPTR_t * data, /*@out@*/ hCNT_t countptr, @@ -2753,7 +2750,7 @@ static int getExtension(Header h, headerTagTagFunction fn, /\ maxSet(countptr) >= 0 @*/ { if (!ec->avail) { - if (fn(h, &ec->type, &ec->data, &ec->count, &ec->freeit)) + if (fn(hsa->h, &ec->type, &ec->data, &ec->count, &ec->freeit)) return 1; ec->avail = 1; } @@ -2766,29 +2763,36 @@ static int getExtension(Header h, headerTagTagFunction fn, } /** + * Reserve sufficient buffer space for next output value. + * @param hsa headerSprintf args + * @param need no. of bytes to reserve + * @return pointer to reserved space + */ +/*@dependent@*/ /*@exposed@*/ +static char * hsaReserve(headerSprintfArgs hsa, size_t need) + /*@modifies hsa */ +{ + if ((hsa->vallen + need) >= hsa->alloced) { + if (hsa->alloced <= need) + hsa->alloced += need; + hsa->alloced <<= 1; + hsa->val = xrealloc(hsa->val, hsa->alloced+1); + } + return hsa->val + hsa->vallen; +} + +/** + * @param hsa headerSprintf args * @param tag - * @param h header - * @param extensions - * @param ec extension cache * @param element - * @retval *valp - * @retval *vallenp - * @retval *allocedp - * @retval *errmsg error message (if any) * @return end of formatted string (NULL on error) */ /*@observer@*/ /*@null@*/ -static char * formatValue(sprintfTag tag, Header h, - const headerSprintfExtension extensions, - rpmec ec, int element, - char ** valp, int * vallenp, int * allocedp, - /*@null@*/ /*@out@*/ errmsg_t * errmsg) - /*@modifies ec, *valp, *vallenp, *allocedp, *errmsg @*/ - /*@requires maxSet(valp) >= 0 /\ maxSet(vallenp) >= 0 - /\ maxSet(allocedp) >= 0 /\ maxSet(errmsg) >= 0 @*/ +static char * formatValue(headerSprintfArgs hsa, sprintfTag tag, int element) + /*@modifies hsa @*/ { char * val = NULL; - int need = 0; + size_t need = 0; char * t, * te; char buf[20]; int_32 count, type; @@ -2803,7 +2807,7 @@ static char * formatValue(sprintfTag tag, Header h, memset(buf, 0, sizeof(buf)); if (tag->ext) { /*@-boundswrite -branchstate @*/ - if (getExtension(h, tag->ext, &type, &data, &count, ec + tag->extNum)) + if (getExtension(hsa, tag->ext, &type, &data, &count, hsa->ec + tag->extNum)) { count = 1; type = RPM_STRING_TYPE; @@ -2812,7 +2816,7 @@ static char * formatValue(sprintfTag tag, Header h, /*@=boundswrite =branchstate @*/ } else { /*@-boundswrite -branchstate @*/ - if (!headerGetEntry(h, tag->tag, &type, (void **)&data, &count)) { + if (!headerGetEntry(hsa->h, tag->tag, &type, (void **)&data, &count)) { count = 1; type = RPM_STRING_TYPE; data = "(none)"; @@ -2827,10 +2831,7 @@ static char * formatValue(sprintfTag tag, Header h, data = headerFreeData(data, type); /*@=modobserver =observertrans@*/ - /*@-observertrans -readonlytrans@*/ - if (errmsg) - *errmsg = _("(index out of range)"); - /*@=observertrans =readonlytrans@*/ + hsa->errmsg = _("(index out of range)"); return NULL; } break; @@ -2858,19 +2859,15 @@ static char * formatValue(sprintfTag tag, Header h, /*@=boundswrite@*/ if (tag->type) { - ext = extensions; - while (ext->type != HEADER_EXT_LAST) { - if (ext->name != NULL && ext->type == HEADER_EXT_FORMAT - && !strcmp(ext->name, tag->type)) - { + for (ext = hsa->exts; ext != NULL && ext->type != HEADER_EXT_LAST; + ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1)) + { + if (ext->name == NULL || ext->type != HEADER_EXT_FORMAT) + continue; + if (!strcmp(ext->name, tag->type)) { tagtype = ext->u.formatFunction; break; } - - if (ext->type == HEADER_EXT_MORE) - ext = ext->u.more; - else - ext++; } } @@ -2989,49 +2986,28 @@ static char * formatValue(sprintfTag tag, Header h, /*@-branchstate@*/ if (val && need > 0) { - if (((*vallenp) + need) >= (*allocedp)) { - if ((*allocedp) <= need) - (*allocedp) += need; -/*@-shiftimplementation@*/ - (*allocedp) <<= 1; -/*@=shiftimplementation@*/ -/*@-unqualifiedtrans@*/ /* FIX: double indirection */ - (*valp) = xrealloc((*valp), (*allocedp)+1); -/*@=unqualifiedtrans@*/ - } - t = (*valp) + (*vallenp); + t = hsaReserve(hsa, need); /*@-boundswrite@*/ te = stpcpy(t, val); /*@=boundswrite@*/ - (*vallenp) += (te - t); + hsa->vallen += (te - t); val = _free(val); } /*@=branchstate@*/ - return ((*valp) + (*vallenp)); + return (hsa->val + hsa->vallen); } /** - * @param h header + * @param hsa headerSprintf args * @param token - * @param extensions - * @param ec extension cache * @param element - * @retval *valp - * @retval *vallenp - * @retval *allocedp - * @retval *errmsg error message (if any) * @return end of formatted string (NULL on error) */ /*@observer@*/ -static char * singleSprintf(Header h, sprintfToken token, - const headerSprintfExtension extensions, - rpmec ec, int element, - char ** valp, int * vallenp, int * allocedp, - /*@null@*/ /*@out@*/ errmsg_t * errmsg) - /*@modifies h, ec, *valp, *vallenp, *allocedp, *errmsg @*/ - /*@requires maxSet(valp) >= 0 /\ maxSet(vallenp) >= 0 - /\ maxSet(allocedp) >= 0 /\ maxSet(errmsg) >= 0 @*/ +static char * singleSprintf(headerSprintfArgs hsa, sprintfToken token, + int element) + /*@modifies hsa @*/ { char * t, * te; int i, j; @@ -3040,7 +3016,7 @@ static char * singleSprintf(Header h, sprintfToken token, int_32 count; sprintfToken spft; int condNumFormats; - int need; + size_t need; /* we assume the token and header have been validated already! */ @@ -3050,35 +3026,24 @@ static char * singleSprintf(Header h, sprintfToken token, case PTOK_STRING: need = token->u.string.len; - if (need <= 0) break; - if (((*vallenp) + need) >= (*allocedp)) { - if ((*allocedp) <= need) - (*allocedp) += need; -/*@-shiftimplementation@*/ - (*allocedp) <<= 1; -/*@=shiftimplementation@*/ -/*@-unqualifiedtrans@*/ /* FIX: double indirection */ - (*valp) = xrealloc((*valp), (*allocedp)+1); -/*@=unqualifiedtrans@*/ - } - t = (*valp) + (*vallenp); + if (need == 0) break; + t = hsaReserve(hsa, need); /*@-boundswrite@*/ te = stpcpy(t, token->u.string.string); /*@=boundswrite@*/ - (*vallenp) += (te - t); + hsa->vallen += (te - t); break; case PTOK_TAG: - t = (*valp) + (*vallenp); - te = formatValue(&token->u.tag, h, extensions, ec, - (token->u.tag.justOne ? 0 : element), - valp, vallenp, allocedp, errmsg); + t = hsa->val + hsa->vallen; + te = formatValue(hsa, &token->u.tag, + (token->u.tag.justOne ? 0 : element)); if (te == NULL) return NULL; break; case PTOK_COND: - if (token->u.cond.tag.ext || headerIsEntry(h, token->u.cond.tag.tag)) { + if (token->u.cond.tag.ext || headerIsEntry(hsa->h, token->u.cond.tag.tag)) { spft = token->u.cond.ifFormat; condNumFormats = token->u.cond.numIfTokens; } else { @@ -3087,22 +3052,11 @@ static char * singleSprintf(Header h, sprintfToken token, } need = condNumFormats * 20; - if (spft == NULL || need <= 0) break; - if (((*vallenp) + need) >= (*allocedp)) { - if ((*allocedp) <= need) - (*allocedp) += need; -/*@-shiftimplementation@*/ - (*allocedp) <<= 1; -/*@=shiftimplementation@*/ -/*@-unqualifiedtrans@*/ /* FIX: double indirection */ - (*valp) = xrealloc((*valp), (*allocedp)+1); -/*@=unqualifiedtrans@*/ - } + if (spft == NULL || need == 0) break; - t = (*valp) + (*vallenp); + t = hsaReserve(hsa, need); for (i = 0; i < condNumFormats; i++, spft++) { - te = singleSprintf(h, spft, extensions, ec, - element, valp, vallenp, allocedp, errmsg); + te = singleSprintf(hsa, spft, element); if (te == NULL) return NULL; } @@ -3118,24 +3072,21 @@ static char * singleSprintf(Header h, sprintfToken token, if (spft->u.tag.ext) { /*@-boundswrite@*/ - if (getExtension(h, spft->u.tag.ext, &type, NULL, &count, - ec + spft->u.tag.extNum)) + if (getExtension(hsa, spft->u.tag.ext, &type, NULL, &count, + hsa->ec + spft->u.tag.extNum)) continue; /*@=boundswrite@*/ } else { /*@-boundswrite@*/ - if (!headerGetEntry(h, spft->u.tag.tag, &type, NULL, &count)) + if (!headerGetEntry(hsa->h, spft->u.tag.tag, &type, NULL, &count)) continue; /*@=boundswrite@*/ } if (numElements > 1 && count != numElements) switch (type) { default: - /*@-observertrans -readonlytrans@*/ - if (errmsg) - *errmsg = + hsa->errmsg = _("array iterator used with different sized arrays"); - /*@=observertrans =readonlytrans@*/ return NULL; /*@notreached@*/ /*@switchbreak@*/ break; case RPM_BIN_TYPE: @@ -3148,41 +3099,20 @@ static char * singleSprintf(Header h, sprintfToken token, if (numElements == -1) { need = sizeof("(none)") - 1; - if (((*vallenp) + need) >= (*allocedp)) { - if ((*allocedp) <= need) - (*allocedp) += need; -/*@-shiftimplementation@*/ - (*allocedp) <<= 1; -/*@=shiftimplementation@*/ -/*@-unqualifiedtrans@*/ /* FIX: double indirection */ - (*valp) = xrealloc((*valp), (*allocedp)+1); -/*@=unqualifiedtrans@*/ - } - t = (*valp) + (*vallenp); + t = hsaReserve(hsa, need); /*@-boundswrite@*/ te = stpcpy(t, "(none)"); /*@=boundswrite@*/ - (*vallenp) += (te - t); + hsa->vallen += (te - t); } else { need = numElements * token->u.array.numTokens * 10; - if (need <= 0) break; - if (((*vallenp) + need) >= (*allocedp)) { - if ((*allocedp) <= need) - (*allocedp) += need; -/*@-shiftimplementation@*/ - (*allocedp) <<= 1; -/*@=shiftimplementation@*/ -/*@-unqualifiedtrans@*/ /* FIX: double indirection */ - (*valp) = xrealloc((*valp), (*allocedp)+1); -/*@=unqualifiedtrans@*/ - } + if (need == 0) break; - t = (*valp) + (*vallenp); + t = hsaReserve(hsa, need); for (j = 0; j < numElements; j++) { spft = token->u.array.format; for (i = 0; i < token->u.array.numTokens; i++, spft++) { - te = singleSprintf(h, spft, extensions, ec, j, - valp, vallenp, allocedp, errmsg); + te = singleSprintf(hsa, spft, j); if (te == NULL) return NULL; } @@ -3191,7 +3121,7 @@ static char * singleSprintf(Header h, sprintfToken token, break; } - return ((*valp) + (*vallenp)); + return (hsa->val + hsa->vallen); } /** @@ -3203,17 +3133,16 @@ static /*@only@*/ rpmec rpmecNew(const headerSprintfExtension extensions) /*@*/ { - headerSprintfExtension ext = extensions; + headerSprintfExtension ext; rpmec ec; int i = 0; - while (ext->type != HEADER_EXT_LAST) { + for (ext = extensions; ext != NULL && ext->type != HEADER_EXT_LAST; + ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1)) + { i++; - if (ext->type == HEADER_EXT_MORE) - ext = ext->u.more; - else - ext++; } + ec = xcalloc(i, sizeof(*ec)); return ec; } @@ -3228,19 +3157,16 @@ static /*@null@*/ rpmec rpmecFree(const headerSprintfExtension extensions, /*@only@*/ rpmec ec) /*@modifies ec @*/ { - headerSprintfExtension ext = extensions; + headerSprintfExtension ext; int i = 0; - while (ext->type != HEADER_EXT_LAST) { + for (ext = extensions; ext != NULL && ext->type != HEADER_EXT_LAST; + ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1)) + { /*@-boundswrite@*/ if (ec[i].freeit) ec[i].data = _free(ec[i].data); /*@=boundswrite@*/ - i++; - if (ext->type == HEADER_EXT_MORE) - ext = ext->u.more; - else - ext++; } ec = _free(ec); @@ -3263,56 +3189,55 @@ char * headerSprintf(Header h, const char * fmt, const struct headerTagTableEntry_s * tbltags, const struct headerSprintfExtension_s * extensions, /*@null@*/ /*@out@*/ errmsg_t * errmsg) - /*@modifies *errmsg @*/ + /*@modifies h, *errmsg @*/ + /*@requires maxSet(errmsg) >= 0 @*/ { -/*@-castexpose@*/ /* FIX: legacy API shouldn't change. */ - headerSprintfExtension exts = (headerSprintfExtension) extensions; - headerTagTableEntry tags = (headerTagTableEntry) tbltags; -/*@=castexpose@*/ + headerSprintfArgs hsa = memset(alloca(sizeof(*hsa)), 0, sizeof(*hsa)); char * te; - char * fmtString; - sprintfToken format; - int numTokens; - char * val = NULL; - int vallen = 0; - int alloced = 0; int i; - rpmec ec; - /*fmtString = escapeString(fmt);*/ - fmtString = xstrdup(fmt); - + hsa->h = headerLink(h); + hsa->fmt = xstrdup(fmt); +/*@-castexpose@*/ /* FIX: legacy API shouldn't change. */ + hsa->exts = (headerSprintfExtension) extensions; + hsa->tags = (headerTagTableEntry) tbltags; +/*@=castexpose@*/ + hsa->errmsg = NULL; + /*@-boundswrite@*/ - if (parseFormat(fmtString, tags, exts, &format, &numTokens, - NULL, PARSER_BEGIN, errmsg)) + if (parseFormat(hsa, hsa->fmt, &hsa->format, &hsa->numTokens, NULL, PARSER_BEGIN)) goto exit; /*@=boundswrite@*/ - ec = rpmecNew(exts); + hsa->ec = rpmecNew(hsa->exts); - val = xstrdup(""); - for (i = 0; i < numTokens; i++) { + hsa->val = xstrdup(""); + for (i = 0; i < hsa->numTokens; i++) { /*@-boundswrite@*/ /*@-mods@*/ - te = singleSprintf(h, format + i, exts, ec, 0, - &val, &vallen, &alloced, errmsg); + te = singleSprintf(hsa, hsa->format + i, 0); /*@=mods@*/ if (te == NULL) { - val = _free(val); + hsa->val = _free(hsa->val); break; } /*@=boundswrite@*/ } - if (val != NULL && vallen < alloced) - val = xrealloc(val, vallen+1); + if (hsa->val != NULL && hsa->vallen < hsa->alloced) + hsa->val = xrealloc(hsa->val, hsa->vallen+1); - ec = rpmecFree(exts, ec); - format = freeFormat(format, numTokens); + hsa->ec = rpmecFree(hsa->exts, hsa->ec); + hsa->format = freeFormat(hsa->format, hsa->numTokens); exit: - fmtString = _free(fmtString); - return val; +/*@-dependenttrans -observertrans @*/ + if (errmsg) + *errmsg = hsa->errmsg; +/*@=dependenttrans =observertrans @*/ + hsa->h = headerFree(hsa->h); + hsa->fmt = _free(hsa->fmt); + return hsa->val; } /** -- 2.7.4