#define ELEM_STR(_offset) (*((fr_table_elem_t const *)(_offset))).str
#define ELEM_LEN(_offset) (*((fr_table_elem_t const *)(_offset))).len
+/** Brute force search a sorted or ordered ptr table, assuming the pointers are strings
+ *
+ * @param[in] table to search in.
+ * @param[in] str_val to compare against the ptr field.
+ * @param[in] def default value.
+ */
+char const *_fr_table_ptr_by_str_value(fr_table_ptr_sorted_t const *table, size_t table_len, char const *str_val, char const *def)
+{
+ size_t i;
+
+ if (!str_val) return NULL;
+
+ for (i = 0; i < table_len; i++) if (strcasecmp(str_val, table[i].value) == 0) return table[i].name.str;
+
+ return def;
+}
+
/** Create type specific string to value functions
*
* @param[in] _func used for searching.
*/
#define NAME_NUMBER_NOT_FOUND INT32_MIN
+char const *_fr_table_ptr_by_str_value(fr_table_ptr_sorted_t const *table, size_t table_len, char const *str_val, char const *def);
+
+/** Brute force search a sorted or ordered ptr table, assuming the pointers are strings
+ *
+ * @param[in] _table to search in.
+ * @param[in] _str_value to compare against the ptr field.
+ * @param[in] _def default value.
+ */
+#define fr_table_str_by_str_value(_table, _str_value, _def) \
+_Generic((_table), \
+ fr_table_ptr_sorted_t const * : _fr_table_ptr_by_str_value((fr_table_ptr_sorted_t const *)_table, _table ## _len, _str_value, _def), \
+ fr_table_ptr_ordered_t const * : _fr_table_ptr_by_str_value((fr_table_ptr_sorted_t const *)_table, _table ## _len, _str_value, _def), \
+ fr_table_ptr_sorted_t * : _fr_table_ptr_by_str_value((fr_table_ptr_sorted_t const *)_table, _table ## _len, _str_value, _def), \
+ fr_table_ptr_ordered_t * : _fr_table_ptr_by_str_value((fr_table_ptr_sorted_t const *)_table, _table ## _len, _str_value, _def))
int fr_table_sorted_num_by_str(fr_table_num_sorted_t const *table, size_t table_len,
char const *name, int def);