On 22 April 2015 at 19:03, Frank Henigman <fjhenig...@google.com> wrote: > From: Frank Henigman <fjhenig...@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 <fjhenig...@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> Very nicely written.
> + </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); How would waffle handle cases where one feeds in a non-null terminated character array ? I'm assuming that strncasecmp might help although surely there is a better way. > +} > + > +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 }, What inspired you to add these aliases - was it wflinfo ? No objections here (actually I think it's a very nice idea) just curios. > +}; > + > 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); Same comment as in patch 2 applies here. Let's not do the sorting at runtime. > 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); Ditto. > + 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 Thank you for this one. -Emil _______________________________________________ waffle mailing list waffle@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/waffle