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.
This commit is contained in:
Mark McLoughlin 2009-02-24 14:53:30 +00:00
parent 14480f699d
commit c56b4bcbf3
3 changed files with 113 additions and 37 deletions

View File

@ -1,3 +1,7 @@
Tue Feb 24 14:52:44 GMT 2009 Mark McLoughlin <markmc@redhat.com>
* src/xml.[ch]: Add virXPathLongHex() and virXPathULongHex()
Tue Feb 24 14:51:32 GMT 2009 Mark McLoughlin <markmc@redhat.com>
* docs/formatdomain.html: fix a typo in hostdev docs

138
src/xml.c
View File

@ -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 *

View File

@ -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);