[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 2/9] libxl: disks: new xlu_disk_parse function



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;
+}

Attachment: enumtest.patch
Description: Text Data

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.