Add rpmtdFormat() method and enumeration of supported formats

- permits formatting any rpmtd data to our supported formats over
  iteration
This commit is contained in:
Panu Matilainen 2008-05-20 09:40:24 +03:00
parent d5381c16a7
commit 9b32e58e17
4 changed files with 98 additions and 23 deletions

View File

@ -21,6 +21,7 @@
*/
struct headerFormatFunc_s {
rpmtdFormats fmt; /*!< Value of extension */
const char *name; /*!< Name of extension. */
void *func; /*!< Pointer to formatter function. */
};
@ -34,7 +35,8 @@ struct headerTagFunc_s {
static const struct headerFormatFunc_s rpmHeaderFormats[];
static const struct headerTagFunc_s rpmHeaderTagExtensions[];
void *rpmHeaderFormatFunc(const char *fmt);
void *rpmHeaderFormatFuncByName(const char *fmt);
void *rpmHeaderFormatFuncByValue(rpmtdFormats fmt);
void *rpmHeaderTagFunc(rpmTag tag);
/**
@ -1059,7 +1061,7 @@ void *rpmHeaderTagFunc(rpmTag tag)
return func;
}
void *rpmHeaderFormatFunc(const char *fmt)
void *rpmHeaderFormatFuncByName(const char *fmt)
{
const struct headerFormatFunc_s * ext;
void *func = NULL;
@ -1073,6 +1075,19 @@ void *rpmHeaderFormatFunc(const char *fmt)
return func;
}
void *rpmHeaderFormatFuncByValue(rpmtdFormats fmt)
{
const struct headerFormatFunc_s * ext;
void *func = NULL;
for (ext = rpmHeaderFormats; ext->name != NULL; ext++) {
if (fmt == ext->fmt) {
func = ext->func;
break;
}
}
return func;
}
static const struct headerTagFunc_s rpmHeaderTagExtensions[] = {
{ RPMTAG_GROUP, groupTag },
{ RPMTAG_DESCRIPTION, descriptionTag },
@ -1090,20 +1105,20 @@ static const struct headerTagFunc_s rpmHeaderTagExtensions[] = {
};
static const struct headerFormatFunc_s rpmHeaderFormats[] = {
{ "string", stringFormat },
{ "armor", armorFormat },
{ "base64", base64Format },
{ "pgpsig", pgpsigFormat },
{ "depflags", depflagsFormat },
{ "fflags", fflagsFormat },
{ "perms", permsFormat },
{ "permissions", permsFormat },
{ "triggertype", triggertypeFormat },
{ "xml", xmlFormat },
{ "octal", octalFormat },
{ "hex", hexFormat },
{ "date", dateFormat },
{ "day", dayFormat },
{ "shescape", shescapeFormat },
{ NULL, NULL }
{ RPMTD_FORMAT_STRING, "string", stringFormat },
{ RPMTD_FORMAT_ARMOR, "armor", armorFormat },
{ RPMTD_FORMAT_BASE64, "base64", base64Format },
{ RPMTD_FORMAT_PGPSIG, "pgpsig", pgpsigFormat },
{ RPMTD_FORMAT_DEPFLAGS, "depflags", depflagsFormat },
{ RPMTD_FORMAT_FFLAGS, "fflags", fflagsFormat },
{ RPMTD_FORMAT_PERMS, "perms", permsFormat },
{ RPMTD_FORMAT_PERMS, "permissions", permsFormat },
{ RPMTD_FORMAT_TRIGGERTYPE, "triggertype", triggertypeFormat },
{ RPMTD_FORMAT_XML, "xml", xmlFormat },
{ RPMTD_FORMAT_OCTAL, "octal", octalFormat },
{ RPMTD_FORMAT_HEX, "hex", hexFormat },
{ RPMTD_FORMAT_DATE, "date", dateFormat },
{ RPMTD_FORMAT_DAY, "day", dayFormat },
{ RPMTD_FORMAT_SHESCAPE, "shescape", shescapeFormat },
{ -1, NULL, NULL }
};

View File

@ -28,7 +28,7 @@
typedef char * (*headerTagFormatFunction)
(rpmtd td, char * formatPrefix, size_t padding);
extern void *rpmHeaderFormatFunc(const char *fmt);
extern void *rpmHeaderFormatFuncByName(const char *fmt);
/** \ingroup header
*/
@ -258,7 +258,7 @@ static int findTag(headerSprintfArgs hsa, sprintfToken token, const char * name)
bingo:
/* Search extensions for specific format. */
if (stag->type != NULL)
stag->fmt = rpmHeaderFormatFunc(stag->type);
stag->fmt = rpmHeaderFormatFuncByName(stag->type);
return 0;
}

View File

@ -2,9 +2,15 @@
#include <rpm/rpmtd.h>
#include <rpm/rpmstring.h>
#include <rpm/rpmpgp.h>
#include "debug.h"
typedef char * (*headerTagFormatFunction)
(rpmtd td, char *formatPrefix, size_t padding);
extern void *rpmHeaderFormatFuncByValue(rpmtdFormats fmt);
rpmtd rpmtdNew(void)
{
rpmtd td = xmalloc(sizeof(*td));
@ -69,11 +75,14 @@ int rpmtdInit(rpmtd td)
int rpmtdNext(rpmtd td)
{
int i = -1;
assert(td != NULL);
int i = -1;
/* fix up for binary type abusing count as data length */
int count = (td->type == RPM_BIN_TYPE) ? 1 : td->count;
if (++td->ix >= 0) {
if (td->ix < td->count) {
if (td->ix < count) {
i = td->ix;
} else {
td->ix = i;
@ -136,6 +145,27 @@ const char * rpmtdGetString(rpmtd td)
return str;
}
char *rpmtdFormat(rpmtd td, rpmtdFormats fmt, const char *errmsg)
{
headerTagFormatFunction func = rpmHeaderFormatFuncByValue(fmt);
const char *err = NULL;
char *str = NULL;
if (func) {
char fmtbuf[50]; /* yuck, get rid of this */
strcpy(fmtbuf, "%");
str = func(td, fmtbuf, 0);
} else {
err = _("Unknown format");
}
if (err && errmsg) {
errmsg = err;
}
return str;
}
char *rpmtdToString(rpmtd td)
{
char *res = NULL;

View File

@ -119,6 +119,36 @@ uint32_t * rpmtdGetUint32(rpmtd td);
*/
const char * rpmtdGetString(rpmtd td);
typedef enum rpmtdFormats_e {
RPMTD_FORMAT_STRING = 0, /* plain string (any type) */
RPMTD_FORMAT_ARMOR = 1, /* ascii armor format (bin types) */
RPMTD_FORMAT_BASE64 = 2, /* base64 encoding (bin types) */
RPMTD_FORMAT_PGPSIG = 3, /* pgp/gpg signature (bin types) */
RPMTD_FORMAT_DEPFLAGS = 4, /* dependency flags (int32 types) */
RPMTD_FORMAT_FFLAGS = 5, /* file flags (int32 types) */
RPMTD_FORMAT_PERMS = 6, /* permission string (int32 types) */
RPMTD_FORMAT_TRIGGERTYPE = 7, /* trigger types */
RPMTD_FORMAT_XML = 8, /* xml format (any type) */
RPMTD_FORMAT_OCTAL = 9, /* octal format (int32 types) */
RPMTD_FORMAT_HEX = 10, /* hex format (int32 types) */
RPMTD_FORMAT_DATE = 11, /* date format (int32 types) */
RPMTD_FORMAT_DAY = 12, /* day format (int32 types) */
RPMTD_FORMAT_SHESCAPE = 13, /* shell escaped (any type) */
} rpmtdFormats;
/** \ingroup rpmtd
* Format data from tag container to string presentation of given format.
* Return malloced string presentation of current data in container,
* converting from integers etc as necessary. On array types, data from
* current iteration index is used for formatting.
* @param td Tag data container
* @param fmt Format to apply
* @param errmsg Error message from conversion (or NULL)
* @return String representation of current data (malloc'ed),
* NULL on error
*/
char *rpmtdFormat(rpmtd td, rpmtdFormats fmt, const char *errmsg);
/** \ingroup rpmtd
* Return data from tag container in string presentation.
* Return malloced string presentation of current data in container,