On Wed, Aug 01, 2018 at 18:02:30 +0100, Daniel P. Berrangé wrote: > The x86 and ppc impls both duplicate some logic when parsing CPU > features. Change the callback signature so that this duplication can be > pushed up a level to common code. > > Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> > --- > src/cpu/cpu_map.c | 106 +++++++++++++++--------- > src/cpu/cpu_map.h | 22 ++--- > src/cpu/cpu_ppc64.c | 112 ++++++------------------- > src/cpu/cpu_x86.c | 196 +++++++++++++------------------------------- > 4 files changed, 155 insertions(+), 281 deletions(-) > > diff --git a/src/cpu/cpu_map.c b/src/cpu/cpu_map.c > index 9e090919ed..17ed53fda6 100644 > --- a/src/cpu/cpu_map.c > +++ b/src/cpu/cpu_map.c > @@ -35,31 +35,51 @@ > > VIR_LOG_INIT("cpu.cpu_map"); > > -VIR_ENUM_IMPL(cpuMapElement, CPU_MAP_ELEMENT_LAST, > - "vendor", > - "feature", > - "model") > - > - > -static int load(xmlXPathContextPtr ctxt, > - cpuMapElement element, > - cpuMapLoadCallback callback, > - void *data) > +static int > +loadData(const char *mapfile, > + xmlXPathContextPtr ctxt, > + const char *xpath, Do you have any further plans with @xpath and actually pass something more fancy than just an element name in it? If not, I'd suggest renaming this parameter as "element" or something similar. Initially I was confused what XPath expression you'd be passing to loadData and whether including the expression in the error messages is a good idea. > + cpuMapLoadCallback callback, > + void *data) > { > int ret = -1; > xmlNodePtr ctxt_node; > xmlNodePtr *nodes = NULL; > int n; > + size_t i; > + int rv; > > ctxt_node = ctxt->node; > > - n = virXPathNodeSet(cpuMapElementTypeToString(element), ctxt, &nodes); > - if (n < 0) > + n = virXPathNodeSet(xpath, ctxt, &nodes); > + if (n < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("cannot find '%s' in CPU map '%s'"), xpath, mapfile); virXPathNodeSet already reports an appropriate error message before returning -1. Not to mention that the function would return 0 if the element was not found (in which case you don't want to report error anyway). Simply removing the call to virReportError will fix both issues. > goto cleanup; > + } > > - if (n > 0 && > - callback(element, ctxt, nodes, n, data) < 0) > + if (n > 0 && !callback) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("Unexpected %s in CPU map '%s'"), xpath, mapfile); > goto cleanup; > + } > + > + for (i = 0; i < n; i++) { > + xmlNodePtr old = ctxt->node; > + char *name = virXMLPropString(nodes[i], "name"); > + if (!name) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("cannot find %s name in CPU map '%s'"), xpath, mapfile); > + goto cleanup; > + } > + VIR_DEBUG("Load %s name %s", xpath, name); > + ctxt->node = nodes[i]; > + rv = callback(ctxt, name, data); > + ctxt->node = old; > + VIR_FREE(name); > + if (rv < 0) > + goto cleanup; > + } > > ret = 0; > > @@ -72,13 +92,14 @@ static int load(xmlXPathContextPtr ctxt, > > static int > cpuMapLoadInclude(const char *filename, > - cpuMapLoadCallback cb, > + cpuMapLoadCallback vendorCB, > + cpuMapLoadCallback featureCB, > + cpuMapLoadCallback modelCB, > void *data) > { > xmlDocPtr xml = NULL; > xmlXPathContextPtr ctxt = NULL; > int ret = -1; > - int element; > char *mapfile; > > if (!(mapfile = virFileFindResource(filename, > @@ -93,13 +114,14 @@ cpuMapLoadInclude(const char *filename, > > ctxt->node = xmlDocGetRootElement(xml); > > - for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) { > - if (load(ctxt, element, cb, data) < 0) { > - virReportError(VIR_ERR_INTERNAL_ERROR, > - _("cannot parse CPU map '%s'"), mapfile); > - goto cleanup; > - } > - } > + if (loadData(mapfile, ctxt, "vendor", vendorCB, data) < 0) > + goto cleanup; > + > + if (loadData(mapfile, ctxt, "feature", featureCB, data) < 0) > + goto cleanup; > + > + if (loadData(mapfile, ctxt, "model", modelCB, data) < 0) > + goto cleanup; > > ret = 0; > > @@ -113,7 +135,9 @@ cpuMapLoadInclude(const char *filename, > > > static int loadIncludes(xmlXPathContextPtr ctxt, > - cpuMapLoadCallback callback, > + cpuMapLoadCallback vendorCB, > + cpuMapLoadCallback featureCB, > + cpuMapLoadCallback modelCB, > void *data) > { > int ret = -1; > @@ -131,7 +155,7 @@ static int loadIncludes(xmlXPathContextPtr ctxt, > for (i = 0; i < n; i++) { > char *filename = virXMLPropString(nodes[i], "filename"); > VIR_DEBUG("Finding CPU map include '%s'", filename); > - if (cpuMapLoadInclude(filename, callback, data) < 0) { > + if (cpuMapLoadInclude(filename, vendorCB, featureCB, modelCB, data) < 0) { > VIR_FREE(filename); > goto cleanup; > } > @@ -149,7 +173,9 @@ static int loadIncludes(xmlXPathContextPtr ctxt, > > > int cpuMapLoad(const char *arch, > - cpuMapLoadCallback cb, > + cpuMapLoadCallback vendorCB, > + cpuMapLoadCallback featureCB, > + cpuMapLoadCallback modelCB, > void *data) > { > xmlDocPtr xml = NULL; > @@ -157,7 +183,6 @@ int cpuMapLoad(const char *arch, > virBuffer buf = VIR_BUFFER_INITIALIZER; > char *xpath = NULL; > int ret = -1; > - int element; > char *mapfile; > > if (!(mapfile = virFileFindResource("cpu_map.xml", > @@ -173,9 +198,15 @@ int cpuMapLoad(const char *arch, > goto cleanup; > } > > - if (cb == NULL) { > + if (vendorCB == NULL) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + "%s", _("no vendor callback provided")); > + goto cleanup; > + } > + > + if (modelCB == NULL) { > virReportError(VIR_ERR_INTERNAL_ERROR, > - "%s", _("no callback provided")); > + "%s", _("no model callback provided")); > goto cleanup; > } I'd remove both checks as suggested by John. ... Jirka -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list