Generalize xml header formatting to support other formats too

Refactor the xml specific output parts into generic format and tag
level header and footer function pointers. No functional changes.
This commit is contained in:
Panu Matilainen 2024-02-15 17:18:14 +02:00
parent b1c59924f7
commit cefb0a182a
1 changed files with 73 additions and 33 deletions

View File

@ -70,9 +70,20 @@ struct sprintfToken_s {
#undef HTKEYTYPE #undef HTKEYTYPE
#undef HTDATATYPE #undef HTDATATYPE
typedef struct headerSprintfArgs_s *headerSprintfArgs;
struct xformat_s {
void (*xHeader)(headerSprintfArgs hsa);
void (*xFooter)(headerSprintfArgs hsa);
void (*xTagHeader)(headerSprintfArgs hsa, rpmTagVal tag, int nelem);
void (*xTagFooter)(headerSprintfArgs hsa, rpmTagVal tag, int nelem);
void (*xItemHeader)(headerSprintfArgs hsa, rpmTagVal tag, int n, int nelem);
void (*xItemFooter)(headerSprintfArgs hsa, rpmTagVal tag, int n, int nelem);
};
/** /**
*/ */
typedef struct headerSprintfArgs_s { struct headerSprintfArgs_s {
Header h; Header h;
char * fmt; char * fmt;
const char * errmsg; const char * errmsg;
@ -85,8 +96,8 @@ typedef struct headerSprintfArgs_s {
int numTokens; int numTokens;
int i; int i;
headerGetFlags hgflags; headerGetFlags hgflags;
} * headerSprintfArgs; struct xformat_s xfmt;
};
static char escapedChar(const char ch) static char escapedChar(const char ch)
{ {
@ -246,6 +257,45 @@ static void hsaError(headerSprintfArgs hsa, const char *fmt, ...)
} }
} }
static void xmlHeader(headerSprintfArgs hsa)
{
hsaAppend(hsa, "<rpmHeader>\n");
}
static void xmlFooter(headerSprintfArgs hsa)
{
hsaAppend(hsa, "</rpmHeader>\n");
}
static void xmlTagHeader(headerSprintfArgs hsa, rpmTagVal tag, int nelem)
{
const char * tagN = rpmTagGetName(tag);
char *tagval = NULL;
if (rstreq(tagN, "(unknown)")) {
rasprintf(&tagval, "[%u]", tag);
tagN = tagval;
}
hsaAppend(hsa, " <rpmTag name=\"");
if (tagN != NULL)
hsaAppend(hsa, tagN);
hsaAppend(hsa, "\">\n");
free(tagval);
}
static void xmlTagFooter(headerSprintfArgs hsa, rpmTagVal tag, int nelem)
{
hsaAppend(hsa, " </rpmTag>\n");
}
static struct xformat_s xformat_xml = {
.xHeader = xmlHeader,
.xFooter = xmlFooter,
.xTagHeader = xmlTagHeader,
.xTagFooter = xmlTagFooter,
};
/** /**
* Search tags for a name. * Search tags for a name.
* @param hsa headerSprintf args * @param hsa headerSprintf args
@ -760,43 +810,33 @@ static char * singleSprintf(headerSprintfArgs hsa, sprintfToken token,
} }
if (found) { if (found) {
int isxml;
need = numElements * token->u.array.numTokens * 10; need = numElements * token->u.array.numTokens * 10;
if (need == 0) break; if (need == 0) break;
spft = token->u.array.format; spft = token->u.array.format;
isxml = (spft->type == PTOK_TAG && spft->u.tag.type != NULL &&
rstreq(spft->u.tag.type, "xml"));
if (isxml) { if (hsa->xfmt.xTagHeader)
const char * tagN = rpmTagGetName(spft->u.tag.tag); hsa->xfmt.xTagHeader(hsa, spft->u.tag.tag, numElements);
char *tagval = NULL;
if (rstreq(tagN, "(unknown)")) {
rasprintf(&tagval, "[%u]", spft->u.tag.tag);
tagN = tagval;
}
hsaAppend(hsa, " <rpmTag name=\"");
if (tagN != NULL)
hsaAppend(hsa, tagN);
hsaAppend(hsa, "\">\n");
free(tagval);
}
for (j = 0; j < numElements; j++) { for (j = 0; j < numElements; j++) {
spft = token->u.array.format; 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 (hsa->xfmt.xItemHeader) {
hsa->xfmt.xItemHeader(hsa, spft->u.tag.tag,
j, numElements);
}
te = singleSprintf(hsa, spft, j); te = singleSprintf(hsa, spft, j);
if (hsa->xfmt.xItemFooter) {
hsa->xfmt.xItemFooter(hsa, spft->u.tag.tag,
j, numElements);
}
if (te == NULL) if (te == NULL)
return NULL; return NULL;
} }
} }
if (isxml) { if (hsa->xfmt.xTagFooter)
hsaAppend(hsa, " </rpmTag>\n"); hsa->xfmt.xTagFooter(hsa, spft->u.tag.tag, numElements);
}
} }
break; break;
@ -820,7 +860,6 @@ char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg)
struct headerSprintfArgs_s hsa; struct headerSprintfArgs_s hsa;
sprintfToken nextfmt; sprintfToken nextfmt;
sprintfTag tag; sprintfTag tag;
int isxml;
memset(&hsa, 0, sizeof(hsa)); memset(&hsa, 0, sizeof(hsa));
hsa.h = headerLink(h); hsa.h = headerLink(h);
@ -839,12 +878,14 @@ char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg)
(hsa.format->type == PTOK_ARRAY (hsa.format->type == PTOK_ARRAY
? &hsa.format->u.array.format->u.tag : ? &hsa.format->u.array.format->u.tag :
NULL)); NULL));
isxml = (tag != NULL && tag->tag == -2 && tag->type != NULL && rstreq(tag->type, "xml")); if (tag != NULL && tag->tag == -2 && tag->type != NULL) {
if (rstreq(tag->type, "xml"))
if (isxml) { hsa.xfmt = xformat_xml; /* struct assignment */
hsaAppend(&hsa, "<rpmHeader>\n");
} }
if (hsa.xfmt.xHeader)
hsa.xfmt.xHeader(&hsa);
hsaInit(&hsa); hsaInit(&hsa);
while ((nextfmt = hsaNext(&hsa)) != NULL) { while ((nextfmt = hsaNext(&hsa)) != NULL) {
if (singleSprintf(&hsa, nextfmt, 0) == NULL) { if (singleSprintf(&hsa, nextfmt, 0) == NULL) {
@ -854,9 +895,8 @@ char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg)
} }
hsaFini(&hsa); hsaFini(&hsa);
if (isxml) { if (hsa.xfmt.xFooter)
hsaAppend(&hsa, "</rpmHeader>\n"); hsa.xfmt.xFooter(&hsa);
}
if (hsa.val != NULL && hsa.vallen < hsa.alloced) if (hsa.val != NULL && hsa.vallen < hsa.alloced)
hsa.val = xrealloc(hsa.val, hsa.vallen+1); hsa.val = xrealloc(hsa.val, hsa.vallen+1);