}
/**
- * Wrap tag data in simple header xml markup.
- * @param type tag type
- * @param data tag value
- * @param formatPrefix
- * @param padding
- * @param element (unused)
- * @return formatted string
- */
-static /*@only@*/ char * xmlFormat(int_32 type, const void * data,
- char * formatPrefix, int padding,
- /*@unused@*/ int element)
- /*@modifies formatPrefix @*/
-{
- const char * xtag;
- size_t nb;
- char * val;
- char * s = NULL;
- char * t, * te;
- long anint = 0;
-
- switch (type) {
- case RPM_I18NSTRING_TYPE:
- case RPM_STRING_TYPE:
- s = data;
- xtag = "string";
- break;
- case RPM_CHAR_TYPE:
- case RPM_INT8_TYPE:
- anint = *((int_8 *) data);
- break;
- case RPM_INT16_TYPE:
- anint = *((int_16 *) data);
- break;
- case RPM_INT32_TYPE:
- anint = *((int_32 *) data);
- break;
- case RPM_NULL_TYPE:
- case RPM_STRING_ARRAY_TYPE:
- case RPM_BIN_TYPE:
- default:
- return xstrdup(_("(invalid type)"));
- /*@notreached@*/ break;
- }
-
- if (s == NULL) {
- int slen = 32;
- s = memset(alloca(slen+1), 0, slen+1);
- snprintf(s, slen, "%ld", anint);
- xtag = "integer";
- }
-
- nb = 2 * strlen(xtag) + sizeof("<></>") + strlen(s);
-
- te = t = alloca(nb);
- te = stpcpy( stpcpy( stpcpy(te, "<"), xtag), ">");
- te = stpcpy(te, s);
- te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">");
-
- nb += padding;
- val = xmalloc(nb+1);
-/*@-boundswrite@*/
- strcat(formatPrefix, "s");
-/*@=boundswrite@*/
- snprintf(val, nb, formatPrefix, t);
- val[nb] = '\0';
-
- return val;
-}
-
-/**
* Wrap a pubkey in ascii armor for display.
* @todo Permit selectable display formats (i.e. binary).
* @param type tag type
}
/**
+ * Wrap tag data in simple header xml markup.
+ * @param type tag type
+ * @param data tag value
+ * @param formatPrefix
+ * @param padding
+ * @param element (unused)
+ * @return formatted string
+ */
+static /*@only@*/ char * xmlFormat(int_32 type, const void * data,
+ char * formatPrefix, int padding,
+ /*@unused@*/ int element)
+ /*@modifies formatPrefix @*/
+{
+ const char * xtag = NULL;
+ size_t nb;
+ char * val;
+ const char * s = NULL;
+ char * t, * te;
+ unsigned long anint = 0;
+
+ switch (type) {
+ case RPM_I18NSTRING_TYPE:
+ case RPM_STRING_TYPE:
+ s = data;
+ xtag = "string";
+ break;
+ case RPM_BIN_TYPE:
+ s = base64Format(type, data, formatPrefix, padding, element);
+ xtag = "base64";
+ break;
+ case RPM_CHAR_TYPE:
+ case RPM_INT8_TYPE:
+ anint = *((uint_8 *) data);
+ break;
+ case RPM_INT16_TYPE:
+ anint = *((uint_16 *) data);
+ break;
+ case RPM_INT32_TYPE:
+ anint = *((uint_32 *) data);
+ break;
+ case RPM_NULL_TYPE:
+ case RPM_STRING_ARRAY_TYPE:
+ default:
+ return xstrdup(_("(invalid xml type)"));
+ /*@notreached@*/ break;
+ }
+
+ if (s == NULL) {
+ int tlen = 32;
+ t = memset(alloca(tlen+1), 0, tlen+1);
+ snprintf(t, tlen, "%lu", anint);
+ s = t;
+ xtag = "integer";
+ }
+
+ nb = 2 * strlen(xtag) + sizeof("\t<></>") + strlen(s);
+ te = t = alloca(nb);
+ te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), ">");
+ te = stpcpy(te, s);
+ te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">");
+
+ /* XXX s was malloc'd */
+ if (!strcmp(xtag, "base64"))
+ s = _free(s);
+
+ nb += padding;
+ val = xmalloc(nb+1);
+/*@-boundswrite@*/
+ strcat(formatPrefix, "s");
+/*@=boundswrite@*/
+ snprintf(val, nb, formatPrefix, t);
+ val[nb] = '\0';
+
+ return val;
+}
+
+/**
* Display signature fingerprint and time.
* @param type tag type
* @param data tag value
#define PARSER_IN_ARRAY 1
#define PARSER_IN_EXPR 2
+/* XXX for xml support */
+/*@-redecl@*/
+/*@observer@*/ extern const char *const tagName(int tag)
+ /*@*/;
+/*@=redecl@*/
+
/** \ingroup header
*/
/*@observer@*/ /*@unchecked@*/
static headerSprintfArgs hsaInit(/*@returned@*/ headerSprintfArgs hsa)
/*@modifies hsa */
{
+ sprintfTag tag =
+ (hsa->format->type == PTOK_TAG
+ ? &hsa->format->u.tag :
+ (hsa->format->type == PTOK_ARRAY
+ ? &hsa->format->u.array.format->u.tag :
+ NULL));
+
if (hsa != NULL) {
+#if 0
+if (tag != NULL) {
+fprintf(stderr, "*** hsaInit(%d): fmt %p ext[%d] %p #%d 1? %d format \"%s\" type \"%s\" pad %d\n", hsa->format->type, tag->fmt, tag->extNum, tag->ext, tag->tag, tag->justOne, tag->format, tag->type, tag->pad);
+}
+#endif
hsa->i = 0;
+ if (tag != NULL && tag->tag == -2)
+ hsa->hi = headerInitIterator(hsa->h);
}
return hsa;
}
/*@modifies hsa */
{
sprintfToken fmt = NULL;
+ sprintfTag tag =
+ (hsa->format->type == PTOK_TAG
+ ? &hsa->format->u.tag :
+ (hsa->format->type == PTOK_ARRAY
+ ? &hsa->format->u.array.format->u.tag :
+ NULL));
if (hsa != NULL && hsa->i >= 0 && hsa->i < hsa->numTokens) {
- fmt = hsa->format + hsa->i++;
+ fmt = hsa->format + hsa->i;
+ if (hsa->hi == NULL) {
+ hsa->i++;
+ } else {
+ int_32 tagno;
+ int_32 type;
+ int_32 count;
+
+ if (!headerNextIterator(hsa->hi, &tagno, &type, NULL, &count))
+ fmt = NULL;
+ tag->tag = tagno;
+ }
}
+
+#if 0
+if (tag != NULL) {
+fprintf(stderr, "*** hsaNext(%d): fmt %p ext[%d] %p #%d 1? %d format \"%s\" type \"%s\" pad %d ret %p\n", hsa->format->type, tag->fmt, tag->extNum, tag->ext, tag->tag, tag->justOne, tag->format, tag->type, tag->pad, fmt);
+}
+#endif
+
return fmt;
}
static headerSprintfArgs hsaFini(/*@returned@*/ headerSprintfArgs hsa)
/*@modifies hsa */
{
+#if 0
+ sprintfTag tag =
+ (hsa->format->type == PTOK_TAG
+ ? &hsa->format->u.tag :
+ (hsa->format->type == PTOK_ARRAY
+ ? &hsa->format->u.array.format->u.tag :
+ NULL));
+
+if (tag != NULL) {
+fprintf(stderr, "*** hsaFini(%d): fmt %p ext[%d] %p #%d 1? %d format \"%s\" type \"%s\" pad %d\n", hsa->format->type, tag->fmt, tag->extNum, tag->ext, tag->tag, tag->justOne, tag->format, tag->type, tag->pad);
+}
+#endif
+
if (hsa != NULL) {
hsa->hi = headerFreeIterator(hsa->hi);
hsa->i = 0;
/**
* @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 @*/
+ * @param token parsed fields
+ * @param name name to find
+ * @return 0 on success, 1 on not found
+ */
+static int findTag(headerSprintfArgs hsa, sprintfToken token, const char * name)
+ /*@modifies token @*/
{
- headerTagTableEntry entry;
+ headerTagTableEntry tag;
headerSprintfExtension ext;
+ sprintfTag stag = (token->type == PTOK_COND
+ ? &token->u.cond.tag : &token->u.tag);
+
+ stag->fmt = NULL;
+ stag->ext = NULL;
+ stag->extNum = 0;
+ stag->tag = -1;
- *tagMatch = NULL;
- *extMatch = NULL;
+ if (!strcmp(name, "*")) {
+ stag->tag = -2;
+ goto bingo;
+ }
/*@-branchstate@*/
- if (strncmp("RPMTAG_", tagname, sizeof("RPMTAG_")-1)) {
+ if (strncmp("RPMTAG_", name, sizeof("RPMTAG_")-1)) {
/*@-boundswrite@*/
- char * t = alloca(strlen(tagname) + sizeof("RPMTAG_"));
- (void) stpcpy( stpcpy(t, "RPMTAG_"), tagname);
- tagname = t;
+ char * t = alloca(strlen(name) + sizeof("RPMTAG_"));
+ (void) stpcpy( stpcpy(t, "RPMTAG_"), name);
+ name = t;
/*@=boundswrite@*/
}
/*@=branchstate@*/
- /* Search extensions first to permit overriding header tags. */
+ /* Search extensions for specific tag override. */
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;
+ if (!xstrcasecmp(ext->name, name)) {
+ stag->ext = ext->u.tagFunction;
+ stag->extNum = ext - hsa->exts;
+ goto bingo;
}
}
- /* Search header tags. */
- for (entry = hsa->tags; entry->name != NULL; entry++) {
- if (!xstrcasecmp(entry->name, tagname)) {
- *tagMatch = entry;
- return;
+ /* Search tag names. */
+ for (tag = hsa->tags; tag->name != NULL; tag++) {
+ if (!xstrcasecmp(tag->name, name)) {
+ stag->tag = tag->val;
+ goto bingo;
+ }
+ }
+
+ return 1;
+
+bingo:
+ /* Search extensions for specific format. */
+ if (stag->type != NULL)
+ 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, stag->type)) {
+ stag->fmt = ext->u.formatFunction;
+ break;
}
}
+ return 0;
}
/* forward ref */
sprintfToken format;
sprintfToken token;
int numTokens;
- headerTagTableEntry tag;
- headerSprintfExtension ext;
int i;
int done = 0;
}
i = 0;
-/*@-boundswrite@*/
- findTag(hsa, start, &tag, &ext);
-/*@=boundswrite@*/
+ token->type = PTOK_TAG;
- if (tag) {
- token->u.tag.ext = NULL;
- token->u.tag.tag = tag->val;
- } else if (ext) {
- token->u.tag.ext = ext->u.tagFunction;
- token->u.tag.extNum = ext - hsa->exts;
- } else {
+ if (findTag(hsa, token, start)) {
hsa->errmsg = _("unknown tag");
format = freeFormat(format, numTokens);
return 1;
}
- token->type = PTOK_TAG;
-
start = next;
-
/*@switchbreak@*/ break;
case '[':
static int parseExpression(headerSprintfArgs hsa, sprintfToken token,
char * str, /*@out@*/ char ** endPtr)
{
- headerTagTableEntry tag;
- headerSprintfExtension ext;
char * chptr;
char * end;
*endPtr = chptr;
- 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 - hsa->exts;
- } else {
- token->u.cond.tag.ext = NULL;
- token->u.cond.tag.tag = -1;
- }
-
token->type = PTOK_COND;
+ (void) findTag(hsa, token, str);
+
return 0;
}
/*@=boundswrite@*/
const char ** strarray;
int datafree = 0;
int countBuf;
- headerTagFormatFunction tagtype = NULL;
- headerSprintfExtension ext;
memset(buf, 0, sizeof(buf));
if (tag->ext) {
(void) stpcpy( stpcpy(buf, "%"), tag->format);
/*@=boundswrite@*/
- if (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;
- }
- }
- }
-
/*@-branchstate@*/
if (data)
switch (type) {
case RPM_STRING_ARRAY_TYPE:
strarray = (const char **)data;
- if (tagtype)
- val = tagtype(RPM_STRING_TYPE, strarray[element], buf, tag->pad, 0);
+ if (tag->fmt)
+ val = tag->fmt(RPM_STRING_TYPE, strarray[element], buf, tag->pad, element);
if (val) {
need = strlen(val);
break;
case RPM_STRING_TYPE:
- if (tagtype)
- val = tagtype(RPM_STRING_TYPE, data, buf, tag->pad, 0);
+ if (tag->fmt)
+ val = tag->fmt(RPM_STRING_TYPE, data, buf, tag->pad, 0);
if (val) {
need = strlen(val);
/*@innerbreak@*/ break;
}
- if (tagtype)
- val = tagtype(RPM_INT32_TYPE, &intVal, buf, tag->pad, element);
+ if (tag->fmt)
+ val = tag->fmt(RPM_INT32_TYPE, &intVal, buf, tag->pad, element);
if (val) {
need = strlen(val);
case RPM_BIN_TYPE:
/* XXX HACK ALERT: element field abused as no. bytes of binary data. */
- if (tagtype)
- val = tagtype(RPM_BIN_TYPE, data, buf, tag->pad, count);
+ if (tag->fmt)
+ val = tag->fmt(RPM_BIN_TYPE, data, buf, tag->pad, count);
if (val) {
need = strlen(val);
case PTOK_ARRAY:
numElements = -1;
spft = token->u.array.format;
- for (i = 0; i < token->u.array.numTokens; i++, spft++) {
+ for (i = 0; i < token->u.array.numTokens; i++, spft++)
+ {
if (spft->type != PTOK_TAG ||
spft->u.tag.arrayCount ||
spft->u.tag.justOne) continue;
continue;
/*@=boundswrite@*/
}
+
+ if (type == RPM_BIN_TYPE)
+ count = 1; /* XXX count abused as no. of bytes. */
+
if (numElements > 1 && count != numElements)
switch (type) {
default:
/*@=boundswrite@*/
hsa->vallen += (te - t);
} else {
+ int isxml;
+
need = numElements * token->u.array.numTokens * 10;
if (need == 0) break;
+ spft = token->u.array.format;
+ isxml =
+ (spft->type == PTOK_TAG && !strcmp(spft->u.tag.type, "xml"));
+
+ if (isxml) {
+ const char * tagN = tagName(spft->u.tag.tag);
+
+ need = strlen(tagN) + sizeof("<rpmTag name=>\n") - 1;
+ t = hsaReserve(hsa, need);
+/*@-boundswrite@*/
+ te = stpcpy(t, "<rpmTag name=");
+ te = stpcpy(te, tagN);
+ te = stpcpy(te, ">\n");
+/*@=boundswrite@*/
+ hsa->vallen += (te - t);
+ }
+
t = hsaReserve(hsa, need);
for (j = 0; j < numElements; j++) {
spft = token->u.array.format;
return NULL;
}
}
+
+ if (isxml) {
+ need = sizeof("<rpmTag/>\n") - 1;
+ t = hsaReserve(hsa, need);
+/*@-boundswrite@*/
+ te = stpcpy(t, "<rpmTag/>\n");
+/*@=boundswrite@*/
+ hsa->vallen += (te - t);
+ }
+
}
break;
}
/**
* Create an extension cache.
- * @param extensions
+ * @param exts
* @return new extension cache
*/
static /*@only@*/ rpmec
-rpmecNew(const headerSprintfExtension extensions)
+rpmecNew(const headerSprintfExtension exts)
/*@*/
{
headerSprintfExtension ext;
rpmec ec;
int i = 0;
- for (ext = extensions; ext != NULL && ext->type != HEADER_EXT_LAST;
+ for (ext = exts; ext != NULL && ext->type != HEADER_EXT_LAST;
ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1))
{
i++;
* @return NULL always
*/
static /*@null@*/ rpmec
-rpmecFree(const headerSprintfExtension extensions, /*@only@*/ rpmec ec)
+rpmecFree(const headerSprintfExtension exts, /*@only@*/ rpmec ec)
/*@modifies ec @*/
{
headerSprintfExtension ext;
int i = 0;
- for (ext = extensions; ext != NULL && ext->type != HEADER_EXT_LAST;
+ for (ext = exts; ext != NULL && ext->type != HEADER_EXT_LAST;
ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1))
{
/*@-boundswrite@*/