On Fri, 2011-06-03 at 13:03 +0100, Ian Campbell wrote:
> On Fri, 2011-06-03 at 12:10 +0100, Ian Jackson wrote:
> > This is a bit mad, isn't it ? I mean, we could have a
> > non-autogenerated "lookup string from table" function and only
> > autogenerate the tables. I think that's a nicer interface for
> > callers, too - for example, they can print a list of options if they
> > want to, etc.
>
> Yes, I agree.
I ended up providing the table and a lookup function (a wrapper around a
common private implementation).
I even tested this version ;-) (skanky testprog generator attached,
patch not for application, avoid contact with eyes, etc)
8<--------------------------------------------------------------------
# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1307109900 -3600
# Node ID d033fc8122931d13e4921b9a299f4c90f1146757
# Parent bd110eb1481a650db3406bf2da80c76b1bfd7e7d
libxl: autogenerate to_string and from_string functions for Enumerations.
The generated strings are the lower case enum value names, with underscores.
Accepted string for parsing are the same but are case insensitive.
We provide a table of strings->value for each Enumeration as well as a
convenience function to perform a lookup.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
diff -r bd110eb1481a -r d033fc812293 tools/libxl/gentypes.py
--- a/tools/libxl/gentypes.py Fri Jun 03 10:22:22 2011 +0100
+++ b/tools/libxl/gentypes.py Fri Jun 03 15:05:00 2011 +0100
@@ -113,6 +113,43 @@ def libxl_C_type_destroy(ty, v, indent =
s = indent + s
return s.replace("\n", "\n%s" % indent).rstrip(indent)
+def libxl_C_enum_to_string(ty, e, indent = " "):
+ s = ""
+ s += "switch(%s) {\n" % e
+ for v in ty.values:
+ s += " case %s:\n" % (v.name)
+ s += " return \"%s\";\n" % (v.valuename.lower())
+ s += " default:\n "
+ s += " return NULL;\n"
+ s += "}\n"
+
+ if s != "":
+ s = indent + s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
+def libxl_C_enum_strings(ty, indent=""):
+ s = ""
+ s += "libxl_enum_string_table %s_string_table[] = {\n" % (ty.typename)
+ for v in ty.values:
+ s += " { .s = \"%s\", .v = %s },\n" % (v.valuename.lower(), v.name)
+ s += " { NULL, -1 },\n"
+ s += "};\n"
+ s += "\n"
+
+ if s != "":
+ s = indent + s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
+def libxl_C_enum_from_string(ty, str, e, indent = " "):
+ s = ""
+ s += "return libxl__enum_from_string(%s_string_table,\n" % ty.typename
+ s += " %s, (int *)%s);\n" % (str, e)
+
+ if s != "":
+ s = indent + s
+ return s.replace("\n", "\n%s" % indent).rstrip(indent)
+
+
if __name__ == '__main__':
if len(sys.argv) < 4:
print >>sys.stderr, "Usage: gentypes.py <idl> <header>
<implementation>"
@@ -142,6 +179,10 @@ if __name__ == '__main__':
f.write(libxl_C_type_define(ty) + ";\n")
if ty.destructor_fn is not None:
f.write("void %s(%s *p);\n" % (ty.destructor_fn, ty.typename))
+ if isinstance(ty, libxltypes.Enumeration):
+ f.write("const char *%s_to_string(%s e);\n" % (ty.typename,
ty.typename))
+ f.write("int %s_from_string(const char *s, %s *e);\n" %
(ty.typename, ty.typename))
+ f.write("extern libxl_enum_string_table %s_string_table[];\n" %
(ty.typename))
f.write("\n")
f.write("""#endif /* __LIBXL_TYPES_H */\n""")
@@ -165,6 +206,7 @@ if __name__ == '__main__':
#include <string.h>
#include "libxl.h"
+#include "libxl_internal.h"
#define LIBXL_DTOR_POISON 0xa5
@@ -177,4 +219,21 @@ if __name__ == '__main__':
f.write(" memset(p, LIBXL_DTOR_POISON, sizeof(*p));\n")
f.write("}\n")
f.write("\n")
+
+ for ty in [t for t in types if isinstance(t,libxltypes.Enumeration)]:
+ f.write("const char *%s_to_string(%s e)\n" % (ty.typename,
ty.typename))
+ f.write("{\n")
+ f.write(libxl_C_enum_to_string(ty, "e"))
+ f.write("}\n")
+ f.write("\n")
+
+ f.write(libxl_C_enum_strings(ty))
+
+ f.write("int %s_from_string(const char *s, %s *e)\n" % (ty.typename,
ty.typename))
+ f.write("{\n")
+ f.write(libxl_C_enum_from_string(ty, "s", "e"))
+ f.write("}\n")
+ f.write("\n")
+
+
f.close()
diff -r bd110eb1481a -r d033fc812293 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h Fri Jun 03 10:22:22 2011 +0100
+++ b/tools/libxl/libxl.h Fri Jun 03 15:05:00 2011 +0100
@@ -185,6 +185,17 @@ void libxl_cpuid_destroy(libxl_cpuid_pol
typedef uint32_t libxl_domid;
+/*
+ * Formatting Enumerations.
+ *
+ * Each enumeration type libxl_E declares an associated lookup table
+ * libxl_E_string_table and a lookup function libxl_E_from_string.
+ */
+typedef struct {
+ const char *s;
+ int v;
+} libxl_enum_string_table;
+
#include "_libxl_types.h"
typedef struct libxl__ctx libxl_ctx;
diff -r bd110eb1481a -r d033fc812293 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h Fri Jun 03 10:22:22 2011 +0100
+++ b/tools/libxl/libxl_internal.h Fri Jun 03 15:05:00 2011 +0100
@@ -323,6 +323,8 @@ _hidden char *libxl__abs_path(libxl__gc
_hidden char *libxl__domid_to_name(libxl__gc *gc, uint32_t domid);
_hidden char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid);
+_hidden int libxl__enum_from_string(const libxl_enum_string_table *t,
+ const char *s, int *e);
/* holds the CPUID response for a single CPUID leaf
* input contains the value of the EAX and ECX register,
diff -r bd110eb1481a -r d033fc812293 tools/libxl/libxl_utils.c
--- a/tools/libxl/libxl_utils.c Fri Jun 03 10:22:22 2011 +0100
+++ b/tools/libxl/libxl_utils.c Fri Jun 03 15:05:00 2011 +0100
@@ -639,3 +639,17 @@ int libxl_get_max_cpus(libxl_ctx *ctx)
{
return xc_get_max_cpus(ctx->xch);
}
+
+int libxl__enum_from_string(const libxl_enum_string_table *t,
+ const char *s, int *e)
+{
+ if (!t) return ERROR_INVAL;
+
+ for( ; t->s; t++) {
+ if (!strcasecmp(t->s, s)) {
+ *e = t->v;
+ return 0;
+ }
+ }
+ return ERROR_FAIL;
+}
enumtest.patch
Description: Text Data
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|