[waffle] [PATCH 3/4] waffle: add waffle_string_to_enum()
Emil Velikov
emil.l.velikov at gmail.com
Thu Apr 23 02:02:09 PDT 2015
On 22 April 2015 at 19:03, Frank Henigman <fjhenigman at google.com> wrote:
> 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>
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
More information about the waffle
mailing list