summaryrefslogtreecommitdiff
path: root/rpmdb/header.c
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2003-03-10 14:39:07 +0000
committerjbj <devnull@localhost>2003-03-10 14:39:07 +0000
commitb58ca441e66148fa7f206729898943551c6c4c19 (patch)
tree1b645d72650a9d5e2ac674a46c8c8ffe4c4f0fec /rpmdb/header.c
parent57ba0c77a23c2f040d152ee5c0ff49262fbf8f26 (diff)
downloadlibrpm-tizen-b58ca441e66148fa7f206729898943551c6c4c19.tar.gz
librpm-tizen-b58ca441e66148fa7f206729898943551c6c4c19.tar.bz2
librpm-tizen-b58ca441e66148fa7f206729898943551c6c4c19.zip
Minimize ars passed throuch headerSprintf call chain.
CVS patchset: 6670 CVS date: 2003/03/10 14:39:07
Diffstat (limited to 'rpmdb/header.c')
-rw-r--r--rpmdb/header.c575
1 files changed, 250 insertions, 325 deletions
diff --git a/rpmdb/header.c b/rpmdb/header.c
index cdad7c0f7..c7eef80ef 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;
}
/**