Parse XML from given buffer, select appropiate XPath node and return its
value as unsigned long.
---
tools/virsh.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 50d5e33..8804fc3 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2270,6 +2270,55 @@ static const vshCmdInfo info_freecell[] = {
{NULL, NULL}
};
+static int
+xPathULong(char *xml, char *xpath, unsigned long *value) {
+
+ xmlDocPtr doc = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ xmlXPathObjectPtr obj = NULL;
+ int ret = -1;
+
+ doc = xmlReadDoc((const xmlChar *) xml, "domain.xml", NULL,
+ XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOWARNING);
+ if (!doc)
+ goto cleanup;
+
+ ctxt = xmlXPathNewContext(doc);
+ if (!ctxt)
+ goto cleanup;
+
+ obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+ if (!obj)
+ goto cleanup;
+
+ if (!value)
+ goto cleanup;
+
+ *value = 0;
+ if ((obj->type == XPATH_STRING) &&
+ (obj->stringval != NULL) && (obj->stringval[0] != 0)) {
+ char *conv = NULL;
+ unsigned long val;
+
+ val = strtoul((const char *) obj->stringval, &conv, 10);
+ if (*conv =='\0') {
+ *value = val;
+ ret = 0;
+ }
+ } else if ((obj != NULL) && (obj->type == XPATH_NUMBER)) {
+ *value = (unsigned long) obj->floatval;
+ if (*value == obj->floatval) {
+ ret = 0;
+ }
+ }
+
+cleanup:
+ xmlXPathFreeObject(obj);
+ xmlXPathFreeContext(ctxt);
+ xmlFreeDoc(doc);
+ return ret;
+}
+
static const vshCmdOptDef opts_freecell[] = {
{"cellno", VSH_OT_INT, 0, N_("NUMA cell number")},
{"all", VSH_OT_BOOL, 0, N_("show free memory for all NUMA
cells")},
--
1.7.3.5