[waffle] [PATCH 3/4] waffle: add waffle_string_to_enum()

Frank Henigman fjhenigman at google.com
Wed Apr 22 11:03:49 PDT 2015


From: Frank Henigman <fjhenigman at gmail.com>

Add waffle_string_to_enum() which, given a string, returns the
corresponding enum value.
Since the main use is expected to be parsing command lines,
the string case does not have to match, and some aliases exist.
For example "waffle_context_opengles2" will match WAFFLE_CONTEXT_OPENGL_ES2
(note additional underscore in the enum name).

Signed-off-by: Frank Henigman <fjhenigman at google.com>
---
 include/waffle/waffle.h      |  5 +++++
 man/waffle_enum.3.xml        | 24 ++++++++++++++++++++++++
 src/waffle/api/waffle_enum.c |  7 +++++++
 src/waffle/core/wcore_util.c | 36 ++++++++++++++++++++++++++++++++++++
 src/waffle/core/wcore_util.h |  3 +++
 src/waffle/waffle.def.in     |  1 +
 6 files changed, 76 insertions(+)

diff --git a/include/waffle/waffle.h b/include/waffle/waffle.h
index dd39f2c..8822e34 100644
--- a/include/waffle/waffle.h
+++ b/include/waffle/waffle.h
@@ -189,6 +189,11 @@ WAFFLE_ENUM_LIST(ENUM_ITEM)
 const char*
 waffle_enum_to_string(int32_t e);
 
+#if WAFFLE_API_VERSION >= 0x0106
+bool
+waffle_string_to_enum(const char *s, int32_t *e);
+#endif
+
 // ---------------------------------------------------------------------------
 
 bool
diff --git a/man/waffle_enum.3.xml b/man/waffle_enum.3.xml
index 4874fe7..4b08a04 100644
--- a/man/waffle_enum.3.xml
+++ b/man/waffle_enum.3.xml
@@ -23,6 +23,7 @@
   <refnamediv>
     <refname>waffle_enum</refname>
     <refname>waffle_enum_to_string</refname>
+    <refname>waffle_string_to_enum</refname>
     <refpurpose>Listing of non-error enums and associated utility functions</refpurpose>
   </refnamediv>
 
@@ -49,6 +50,12 @@ enum waffle_enum {...};
         <paramdef>int32_t <parameter>e</parameter></paramdef>
       </funcprototype>
 
+      <funcprototype>
+        <funcdef>bool <function>waffle_string_to_enum</function></funcdef>
+        <paramdef>const char* <parameter>s</parameter></paramdef>
+        <paramdef>int32_t* <parameter>e</parameter></paramdef>
+      </funcprototype>
+
     </funcsynopsis>
   </refsynopsisdiv>
 
@@ -74,6 +81,23 @@ enum waffle_enum {...};
       </varlistentry>
 
       <varlistentry>
+        <term><function>waffle_string_to_enum()</function></term>
+        <listitem>
+          <para>
+            Convert a string to a <type>waffle_enum</type> token in <code>*e</code>.
+            For example, convert <code>"WAFFLE_DONT_CARE"</code> to <constant>WAFFLE_DONT_CARE</constant>.
+            String matching is not case-sensitive, and aliases exist for some names.
+            Returns <constant>false</constant> and does not change <code>*e</code> if the string does not match any <type>waffle_enum</type> name.
+          </para>
+          <para>
+            This function always sets the error code to <constant>WAFFLE_NO_ERROR</constant>.
+            It can be called before waffle has been successfully initialized with
+            <citerefentry><refentrytitle><function>waffle_init</function></refentrytitle><manvolnum>3</manvolnum></citerefentry>
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><type>enum waffle_enum</type></term>
         <listitem>
           <para>
diff --git a/src/waffle/api/waffle_enum.c b/src/waffle/api/waffle_enum.c
index 1b8dfbb..d49ce5e 100644
--- a/src/waffle/api/waffle_enum.c
+++ b/src/waffle/api/waffle_enum.c
@@ -34,3 +34,10 @@ waffle_enum_to_string(int32_t e)
     wcore_error_reset();
     return wcore_enum_to_string(e);
 }
+
+WAFFLE_API bool
+waffle_string_to_enum(const char *s, int32_t *e)
+{
+    wcore_error_reset();
+    return wcore_string_to_enum(s, e);
+}
diff --git a/src/waffle/core/wcore_util.c b/src/waffle/core/wcore_util.c
index b912a30..80b66f9 100644
--- a/src/waffle/core/wcore_util.c
+++ b/src/waffle/core/wcore_util.c
@@ -24,6 +24,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <stdlib.h>
+#include <string.h>
 
 #include "wcore_error.h"
 #include "wcore_util.h"
@@ -74,6 +75,14 @@ struct enum_map_entry {
 };
 
 static int
+enum_cmp_name(const void *v1, const void *v2)
+{
+    const struct enum_map_entry *e1 = (const struct enum_map_entry *) v1;
+    const struct enum_map_entry *e2 = (const struct enum_map_entry *) v2;
+    return strcasecmp(e1->name, e2->name);
+}
+
+static int
 enum_cmp_value(const void *v1, const void *v2)
 {
     const struct enum_map_entry *e1 = (const struct enum_map_entry *) v1;
@@ -83,6 +92,14 @@ enum_cmp_value(const void *v1, const void *v2)
 
 #define NAME_VALUE(name, value) { #name, value },
 
+static struct enum_map_entry enum_map_name[] = {
+    WAFFLE_ENUM_LIST(NAME_VALUE)
+    // aliases
+    { "WAFFLE_CONTEXT_OPENGLES1", WAFFLE_CONTEXT_OPENGL_ES1 },
+    { "WAFFLE_CONTEXT_OPENGLES2", WAFFLE_CONTEXT_OPENGL_ES2 },
+    { "WAFFLE_CONTEXT_OPENGLES3", WAFFLE_CONTEXT_OPENGL_ES3 },
+};
+
 static struct enum_map_entry enum_map_value[] = {
     WAFFLE_ENUM_LIST(NAME_VALUE)
 };
@@ -97,6 +114,8 @@ enum_sort()
     static bool sorted = false;
     if (sorted)
         return;
+    qsort(enum_map_name, ARRAY_SIZE(enum_map_name), sizeof(enum_map_name[0]),
+          enum_cmp_name);
     qsort(enum_map_value, ARRAY_SIZE(enum_map_value), sizeof(enum_map_value[0]),
           enum_cmp_value);
     sorted = true;
@@ -118,4 +137,21 @@ wcore_enum_to_string(int32_t e)
     return found->name;
 }
 
+bool
+wcore_string_to_enum(const char *s, int32_t *e)
+{
+    enum_sort();
+    struct enum_map_entry key = { .name = s };
+    struct enum_map_entry *found = bsearch(&key,
+                                           enum_map_name,
+                                           ARRAY_SIZE(enum_map_name),
+                                           sizeof(enum_map_name[0]),
+                                           enum_cmp_name);
+    if (!found)
+        return false;
+
+    *e = found->value;
+    return true;
+}
+
 #undef ARRAY_SIZE
diff --git a/src/waffle/core/wcore_util.h b/src/waffle/core/wcore_util.h
index b823b21..21c2a88 100644
--- a/src/waffle/core/wcore_util.h
+++ b/src/waffle/core/wcore_util.h
@@ -112,6 +112,9 @@ wcore_calloc(size_t size);
 const char*
 wcore_enum_to_string(int32_t e);
 
+bool
+wcore_string_to_enum(const char *s, int32_t *e);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/waffle/waffle.def.in b/src/waffle/waffle.def.in
index 75a56c0..7726219 100644
--- a/src/waffle/waffle.def.in
+++ b/src/waffle/waffle.def.in
@@ -5,6 +5,7 @@ EXPORTS
     waffle_error_get_info
     waffle_error_to_string
     waffle_enum_to_string
+    waffle_string_to_enum
     waffle_init
     waffle_teardown
     waffle_make_current
-- 
2.2.0.rc0.207.ga3a616c



More information about the waffle mailing list