From c56b4bcbf3d92d6c1a5079cce9668c53e646e220 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Tue, 24 Feb 2009 14:53:30 +0000 Subject: [PATCH] Add virXPathLongHex() and virXPathULongHex() Add new functions to allow parsing integers with base 16 This will be used to e.g. parse PCI vendor IDs. --- ChangeLog | 4 ++ src/xml.c | 138 +++++++++++++++++++++++++++++++++++++++--------------- src/xml.h | 8 ++++ 3 files changed, 113 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index f06e987226..f1bc649965 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Tue Feb 24 14:52:44 GMT 2009 Mark McLoughlin + + * src/xml.[ch]: Add virXPathLongHex() and virXPathULongHex() + Tue Feb 24 14:51:32 GMT 2009 Mark McLoughlin * docs/formatdomain.html: fix a typo in hostdev docs diff --git a/src/xml.c b/src/xml.c index 9c27a106d7..edfdc178f7 100644 --- a/src/xml.c +++ b/src/xml.c @@ -116,6 +116,50 @@ virXPathNumber(virConnectPtr conn, return (0); } +static int +virXPathLongBase(virConnectPtr conn, + const char *xpath, + xmlXPathContextPtr ctxt, + int base, + long *value) +{ + xmlXPathObjectPtr obj; + xmlNodePtr relnode; + int ret = 0; + + if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) { + virXMLError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("Invalid parameter to virXPathLong()")); + return (-1); + } + relnode = ctxt->node; + obj = xmlXPathEval(BAD_CAST xpath, ctxt); + if ((obj != NULL) && (obj->type == XPATH_STRING) && + (obj->stringval != NULL) && (obj->stringval[0] != 0)) { + char *conv = NULL; + long val; + + val = strtol((const char *) obj->stringval, &conv, base); + if (conv == (const char *) obj->stringval) { + ret = -2; + } else { + *value = val; + } + } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) && + (!(isnan(obj->floatval)))) { + *value = (long) obj->floatval; + if (*value != obj->floatval) { + ret = -2; + } + } else { + ret = -1; + } + + xmlXPathFreeObject(obj); + ctxt->node = relnode; + return (ret); +} + /** * virXPathLong: * @xpath: the XPath string to evaluate @@ -133,6 +177,38 @@ virXPathLong(virConnectPtr conn, const char *xpath, xmlXPathContextPtr ctxt, long *value) +{ + return virXPathLongBase(conn, xpath, ctxt, 10, value); +} + +/** + * virXPathLongHex: + * @xpath: the XPath string to evaluate + * @ctxt: an XPath context + * @value: the returned long value + * + * Convenience function to evaluate an XPath number + * according to a base of 16 + * + * Returns 0 in case of success in which case @value is set, + * or -1 if the XPath evaluation failed or -2 if the + * value doesn't have a long format. + */ +int +virXPathLongHex(virConnectPtr conn, + const char *xpath, + xmlXPathContextPtr ctxt, + long *value) +{ + return virXPathLongBase(conn, xpath, ctxt, 16, value); +} + +static int +virXPathULongBase(virConnectPtr conn, + const char *xpath, + xmlXPathContextPtr ctxt, + int base, + unsigned long *value) { xmlXPathObjectPtr obj; xmlNodePtr relnode; @@ -140,7 +216,7 @@ virXPathLong(virConnectPtr conn, if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) { virXMLError(conn, VIR_ERR_INTERNAL_ERROR, - "%s", _("Invalid parameter to virXPathLong()")); + "%s", _("Invalid parameter to virXPathULong()")); return (-1); } relnode = ctxt->node; @@ -150,7 +226,7 @@ virXPathLong(virConnectPtr conn, char *conv = NULL; long val; - val = strtol((const char *) obj->stringval, &conv, 10); + val = strtoul((const char *) obj->stringval, &conv, base); if (conv == (const char *) obj->stringval) { ret = -2; } else { @@ -158,7 +234,7 @@ virXPathLong(virConnectPtr conn, } } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) && (!(isnan(obj->floatval)))) { - *value = (long) obj->floatval; + *value = (unsigned long) obj->floatval; if (*value != obj->floatval) { ret = -2; } @@ -189,41 +265,29 @@ virXPathULong(virConnectPtr conn, xmlXPathContextPtr ctxt, unsigned long *value) { - xmlXPathObjectPtr obj; - xmlNodePtr relnode; - int ret = 0; + return virXPathULongBase(conn, xpath, ctxt, 10, value); +} - if ((ctxt == NULL) || (xpath == NULL) || (value == NULL)) { - virXMLError(conn, VIR_ERR_INTERNAL_ERROR, - "%s", _("Invalid parameter to virXPathULong()")); - return (-1); - } - relnode = ctxt->node; - obj = xmlXPathEval(BAD_CAST xpath, ctxt); - if ((obj != NULL) && (obj->type == XPATH_STRING) && - (obj->stringval != NULL) && (obj->stringval[0] != 0)) { - char *conv = NULL; - long val; - - val = strtoul((const char *) obj->stringval, &conv, 10); - if (conv == (const char *) obj->stringval) { - ret = -2; - } else { - *value = val; - } - } else if ((obj != NULL) && (obj->type == XPATH_NUMBER) && - (!(isnan(obj->floatval)))) { - *value = (unsigned long) obj->floatval; - if (*value != obj->floatval) { - ret = -2; - } - } else { - ret = -1; - } - - xmlXPathFreeObject(obj); - ctxt->node = relnode; - return (ret); +/** + * virXPathUHex: + * @xpath: the XPath string to evaluate + * @ctxt: an XPath context + * @value: the returned long value + * + * Convenience function to evaluate an XPath number + * according to base of 16 + * + * Returns 0 in case of success in which case @value is set, + * or -1 if the XPath evaluation failed or -2 if the + * value doesn't have a long format. + */ +int +virXPathULongHex(virConnectPtr conn, + const char *xpath, + xmlXPathContextPtr ctxt, + unsigned long *value) +{ + return virXPathULongBase(conn, xpath, ctxt, 16, value); } char * diff --git a/src/xml.h b/src/xml.h index da9d3b5930..3754af293a 100644 --- a/src/xml.h +++ b/src/xml.h @@ -29,6 +29,14 @@ int virXPathULong (virConnectPtr conn, const char *xpath, xmlXPathContextPtr ctxt, unsigned long *value); +int virXPathLongHex (virConnectPtr conn, + const char *xpath, + xmlXPathContextPtr ctxt, + long *value); +int virXPathULongHex(virConnectPtr conn, + const char *xpath, + xmlXPathContextPtr ctxt, + unsigned long *value); xmlNodePtr virXPathNode (virConnectPtr conn, const char *xpath, xmlXPathContextPtr ctxt);