[libvirt] [PATCH 1/2] util: add new file for virTypedParameter utils

Eric Blake eblake at redhat.com
Wed Jan 4 03:42:55 UTC 2012


Preparation for another patch that refactors common patterns
into the new file for fewer lines of code overall.

* src/util/util.h (virTypedParameterArrayClear): Move...
* src/util/virtypedparam.h: ...to new file.
(virTypedParameterArrayValidate, virTypedParameterAssign): New
prototypes.
* src/util/util.c (virTypedParameterArrayClear): Likewise.
* src/util/virtypedparam.c: New file.
* po/POTFILES.in: Mark file for translation.
* src/Makefile.am (UTIL_SOURCES): Build it.
* src/libvirt_private.syms (util.h): Split...
(virtypedparam.h): to new section.
(virkeycode.h): Sort.
* daemon/remote.c: Adjust callers.
* tools/virsh.c: Likewise.
---
 daemon/remote.c          |    1 +
 po/POTFILES.in           |    1 +
 src/Makefile.am          |    3 +-
 src/libvirt_private.syms |   20 +++--
 src/util/util.c          |   16 +----
 src/util/util.h          |    4 +-
 src/util/virtypedparam.c |  187 ++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virtypedparam.h |   37 +++++++++
 tools/virsh.c            |    3 +-
 9 files changed, 245 insertions(+), 27 deletions(-)
 create mode 100644 src/util/virtypedparam.c
 create mode 100644 src/util/virtypedparam.h

diff --git a/daemon/remote.c b/daemon/remote.c
index a28a754..4db8f91 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -44,6 +44,7 @@
 #include "virnetserverservice.h"
 #include "virnetserver.h"
 #include "virfile.h"
+#include "virtypedparam.h"

 #include "remote_protocol.h"
 #include "qemu_protocol.h"
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3e8359a..ca1db70 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -135,6 +135,7 @@ src/util/virpidfile.c
 src/util/virsocketaddr.c
 src/util/virterror.c
 src/util/virtime.c
+src/util/virtypedparam.c
 src/util/xml.c
 src/vbox/vbox_MSCOMGlue.c
 src/vbox/vbox_XPCOMCGlue.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 93bf54c..97a876d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in

-## Copyright (C) 2005-2011 Red Hat, Inc.
+## Copyright (C) 2005-2012 Red Hat, Inc.
 ## See COPYING.LIB for the License of this software

 # No libraries with the exception of LIBXML should be listed
@@ -87,6 +87,7 @@ UTIL_SOURCES =							\
 		util/virfile.c util/virfile.h			\
 		util/virnodesuspend.c util/virnodesuspend.h	\
 		util/virpidfile.c util/virpidfile.h		\
+		util/virtypedparam.c util/virtypedparam.h	\
 		util/xml.c util/xml.h				\
 		util/virterror.c util/virterror_internal.h	\
 		util/virkeycode.c util/virkeycode.h		\
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ac2c52e..c1760d0 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1134,7 +1134,6 @@ virStrToLong_ull;
 virStrcpy;
 virStrncpy;
 virTrimSpaces;
-virTypedParameterArrayClear;
 virVasprintf;


@@ -1165,6 +1164,13 @@ virFileFdopen;
 virFileRewrite;


+# virkeycode.h
+virKeycodeSetTypeFromString;
+virKeycodeSetTypeToString;
+virKeycodeValueFromString;
+virKeycodeValueTranslate;
+
+
 # virnetclient.h
 virNetClientHasPassFD;

@@ -1378,12 +1384,6 @@ virSetError;
 virSetErrorLogPriorityFunc;
 virStrerror;

-# virkeycode.h
-virKeycodeSetTypeToString;
-virKeycodeSetTypeFromString;
-virKeycodeValueFromString;
-virKeycodeValueTranslate;
-

 # virtime.h
 virTimeFieldsNow;
@@ -1398,6 +1398,12 @@ virTimeStringThen;
 virTimeStringThenRaw;


+# virtypedparam.h
+virTypedParameterArrayClear;
+virTypedParameterArrayValidate;
+virTypedParameterAssign;
+
+
 # xml.h
 virXMLChildElementCount;
 virXMLParseHelper;
diff --git a/src/util/util.c b/src/util/util.c
index 6f46d53..222a35d 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -1,7 +1,7 @@
 /*
  * utils.c: common, generic utility functions
  *
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  * Copyright (C) 2006, 2007 Binary Karma
  * Copyright (C) 2006 Shuveb Hussain
@@ -2554,17 +2554,3 @@ or other application using the libvirt API.\n\

     return 0;
 }
-
-void
-virTypedParameterArrayClear(virTypedParameterPtr params, int nparams)
-{
-    int i;
-
-    if (!params)
-        return;
-
-    for (i = 0; i < nparams; i++) {
-        if (params[i].type == VIR_TYPED_PARAM_STRING)
-            VIR_FREE(params[i].value.s);
-    }
-}
diff --git a/src/util/util.h b/src/util/util.h
index c9c785b..cb7e378 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -1,7 +1,7 @@
 /*
  * utils.h: common, generic utility functions
  *
- * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010-2012 Red Hat, Inc.
  * Copyright (C) 2006, 2007 Binary Karma
  * Copyright (C) 2006 Shuveb Hussain
  *
@@ -255,6 +255,4 @@ int virEmitXMLWarning(int fd,
                       const char *name,
                       const char *cmd) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);

-void virTypedParameterArrayClear(virTypedParameterPtr params, int nparams);
-
 #endif /* __VIR_UTIL_H__ */
diff --git a/src/util/virtypedparam.c b/src/util/virtypedparam.c
new file mode 100644
index 0000000..f71aa25
--- /dev/null
+++ b/src/util/virtypedparam.c
@@ -0,0 +1,187 @@
+/*
+ * virtypedparam.c: utility functions for dealing with virTypedParameters
+ *
+ * Copyright (C) 2011-2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <config.h>
+#include "virtypedparam.h"
+
+#include <stdarg.h>
+
+#include "memory.h"
+#include "util.h"
+#include "virterror_internal.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+#define virUtilError(code, ...)                                            \
+        virReportErrorHelper(VIR_FROM_NONE, code, __FILE__,                \
+                             __FUNCTION__, __LINE__, __VA_ARGS__)
+
+VIR_ENUM_DECL(virTypedParameter)
+VIR_ENUM_IMPL(virTypedParameter, VIR_TYPED_PARAM_STRING + 1,
+              "unknown",
+              "int",
+              "uint",
+              "llong",
+              "ullong",
+              "double",
+              "boolean",
+              "string")
+
+void
+virTypedParameterArrayClear(virTypedParameterPtr params, int nparams)
+{
+    int i;
+
+    if (!params)
+        return;
+
+    for (i = 0; i < nparams; i++) {
+        if (params[i].type == VIR_TYPED_PARAM_STRING)
+            VIR_FREE(params[i].value.s);
+    }
+}
+
+/* Validate that PARAMS contains only recognized parameter names with
+ * correct types, and with no duplicates.  Pass in as many name/type
+ * pairs as appropriate, and pass NULL to end the list of accepted
+ * parameters.  Return 0 on success, -1 on failure with error message
+ * already issued.  */
+int
+virTypedParameterArrayValidate(virTypedParameterPtr params, int nparams, ...)
+{
+    va_list ap;
+    int ret = -1;
+    int i, j;
+    const char *name;
+    int type;
+
+    va_start(ap, nparams);
+
+    /* Yes, this is quadratic, but since we reject duplicates and
+     * unknowns, it is constrained by the number of var-args passed
+     * in, which is expected to be small enough to not be
+     * noticeable.  */
+    for (i = 0; i < nparams; i++) {
+        va_end(ap);
+        va_start(ap, nparams);
+
+        name = va_arg(ap, const char *);
+        while (name) {
+            type = va_arg(ap, int);
+            if (STREQ(params[i].field, name)) {
+                if (params[i].type != type) {
+                    const char *badtype;
+
+                    badtype = virTypedParameterTypeToString(params[i].type);
+                    if (!badtype)
+                        badtype = virTypedParameterTypeToString(0);
+                    virUtilError(VIR_ERR_INVALID_ARG,
+                                 _("invalid type '%s' for parameter '%s', "
+                                   "expected '%s'"),
+                                 badtype, params[i].field,
+                                 virTypedParameterTypeToString(type));
+                }
+                break;
+            }
+            name = va_arg(ap, const char *);
+        }
+        if (!name) {
+            virUtilError(VIR_ERR_INVALID_ARG,
+                         _("parameter '%s' not supported"),
+                         params[i].field);
+            goto cleanup;
+        }
+        for (j = 0; j < i; j++) {
+            if (STREQ(params[i].field, params[j].field)) {
+                virUtilError(VIR_ERR_INVALID_ARG,
+                             _("parameter '%s' occurs multiple times"),
+                             params[i].field);
+                goto cleanup;
+            }
+        }
+    }
+
+    ret = 0;
+cleanup:
+    va_end(ap);
+    return ret;
+
+}
+
+/* Assign name, type, and the appropriately typed arg to param; in the
+ * case of a string, the caller is assumed to have malloc'd a string,
+ * or can pass NULL to have this function malloc an empty string.
+ * Return 0 on success, -1 after an error message on failure.  */
+int
+virTypedParameterAssign(virTypedParameterPtr param, const char *name,
+                        int type, ...)
+{
+    va_list ap;
+    int ret = -1;
+
+    va_start(ap, type);
+
+    if (virStrcpyStatic(param->field, name) == NULL) {
+        virUtilError(VIR_ERR_INTERNAL_ERROR, _("Field name '%s' too long"),
+                     name);
+        goto cleanup;
+    }
+    param->type = type;
+    switch (type)
+    {
+    case VIR_TYPED_PARAM_INT:
+        param->value.i = va_arg(ap, int);
+        break;
+    case VIR_TYPED_PARAM_UINT:
+        param->value.ui = va_arg(ap, unsigned int);
+        break;
+    case VIR_TYPED_PARAM_LLONG:
+        param->value.l = va_arg(ap, long long int);
+        break;
+    case VIR_TYPED_PARAM_ULLONG:
+        param->value.ul = va_arg(ap, unsigned long long int);
+        break;
+    case VIR_TYPED_PARAM_DOUBLE:
+        param->value.d = va_arg(ap, double);
+        break;
+    case VIR_TYPED_PARAM_BOOLEAN:
+        param->value.b = !!va_arg(ap, int);
+        break;
+    case VIR_TYPED_PARAM_STRING:
+        param->value.s = va_arg(ap, char *);
+        if (!param->value.s)
+            param->value.s = strdup("");
+        if (!param->value.s) {
+            virReportOOMError();
+            goto cleanup;
+        }
+        break;
+    default:
+        virUtilError(VIR_ERR_INTERNAL_ERROR,
+                     _("unexpected type %d for field %s"), type, name);
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    va_end(ap);
+    return ret;
+}
diff --git a/src/util/virtypedparam.h b/src/util/virtypedparam.h
new file mode 100644
index 0000000..52cbe78
--- /dev/null
+++ b/src/util/virtypedparam.h
@@ -0,0 +1,37 @@
+/*
+ * virtypedparam.h: managing typed parameters
+ *
+ * Copyright (C) 2011-2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+
+#ifndef __VIR_TYPED_PARAM_H_
+# define __VIR_TYPED_PARAM_H_
+
+# include "internal.h"
+
+void virTypedParameterArrayClear(virTypedParameterPtr params, int nparams);
+
+int virTypedParameterArrayValidate(virTypedParameterPtr params, int nparams,
+                                   /* const char *name, int type ... */ ...)
+    ATTRIBUTE_SENTINEL;
+
+int virTypedParameterAssign(virTypedParameterPtr param, const char *name,
+                            int type, /* TYPE arg */ ...);
+
+#endif /* __VIR_TYPED_PARAM_H */
diff --git a/tools/virsh.c b/tools/virsh.c
index e4b812e..46a77d8 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1,7 +1,7 @@
 /*
  * virsh.c: a shell to exercise the libvirt API
  *
- * Copyright (C) 2005, 2007-2011 Red Hat, Inc.
+ * Copyright (C) 2005, 2007-2012 Red Hat, Inc.
  *
  * See COPYING.LIB for the License of this software
  *
@@ -62,6 +62,7 @@
 #include "virnetdevbandwidth.h"
 #include "util/bitmap.h"
 #include "conf/domain_conf.h"
+#include "virtypedparam.h"

 static char *progname;

-- 
1.7.7.5




More information about the libvir-list mailing list