[beast: 3/15] SFI: add feature_toggle_find, feature_toggle_bool



commit 6e1cb4f628a2336ea7dc55b102d50b0e7861191f
Author: Tim Janik <timj gnu org>
Date:   Sat Jul 22 15:46:16 2017 +0200

    SFI: add feature_toggle_find, feature_toggle_bool
    
    Signed-off-by: Tim Janik <timj gnu org>

 sfi/bcore.cc           |   38 ++++++++++++++++++++++++++++++++++++++
 sfi/bcore.hh           |    2 ++
 sfi/tests/misctests.cc |   22 ++++++++++++++++++++++
 3 files changed, 62 insertions(+), 0 deletions(-)
---
diff --git a/sfi/bcore.cc b/sfi/bcore.cc
index 52fdc10..db6da7a 100644
--- a/sfi/bcore.cc
+++ b/sfi/bcore.cc
@@ -86,6 +86,44 @@ aligned_free (uint8 **free_pointer)
     }
 }
 
+/// Find @a feature in @a config, return its value or @a fallback.
+String
+feature_toggle_find (const String &config, const String &feature, const String &fallback)
+{
+  String haystack = ":" + config + ":";
+  String needle0 = ":no-" + feature + ":";
+  String needle1 = ":" + feature + ":";
+  String needle2 = ":" + feature + "=";
+  const char *n0 = g_strrstr (haystack.c_str(), needle0.c_str());
+  const char *n1 = g_strrstr (haystack.c_str(), needle1.c_str());
+  const char *n2 = g_strrstr (haystack.c_str(), needle2.c_str());
+  if (n0 && (!n1 || n0 > n1) && (!n2 || n0 > n2))
+    return "0";         // ":no-feature:" is the last toggle in config
+  if (n1 && (!n2 || n1 > n2))
+    return "1";         // ":feature:" is the last toggle in config
+  if (!n2)
+    return fallback;    // no "feature" variant found
+  const char *value = n2 + strlen (needle2.c_str());
+  const char *end = strchr (value, ':');
+  return end ? String (value, end - value) : String (value);
+}
+
+/// Check for @a feature in @a config, if @a feature is empty, checks for *any* feature.
+bool
+feature_toggle_bool (const char *config, const char *feature)
+{
+  if (feature && feature[0])
+    return string_to_bool (feature_toggle_find (config ? config : "", feature));
+  // check if *any* feature is enabled in config
+  if (!config || !config[0])
+    return false;
+  const size_t l = strlen (config);
+  for (size_t i = 0; i < l; i++)
+    if (config[i] && !strchr (": \t\n\r=", config[i]))
+      return true;      // found *some* non-space and non-separator config item
+  return false;         // just whitespace
+}
+
 // == Internal ==
 namespace Internal {
 
diff --git a/sfi/bcore.hh b/sfi/bcore.hh
index 2780179..6bfa8ff 100644
--- a/sfi/bcore.hh
+++ b/sfi/bcore.hh
@@ -51,6 +51,8 @@ template<class ...Args> void        info                 (const char *format, co
 template<class ...Args> inline void dump                 (const char *conditional, const char *format, const 
Args &...args) BSE_ALWAYS_INLINE;
 template<class ...Args> inline void debug                (const char *conditional, const char *format, const 
Args &...args) BSE_ALWAYS_INLINE;
 inline bool                         debug_enabled        (const char *conditional) BSE_ALWAYS_INLINE 
BSE_PURE;
+String                              feature_toggle_find  (const String &config, const String &feature, const 
String &fallback = "0");
+bool                                feature_toggle_bool  (const char *config, const char *feature);
 
 // == Binary Lookups ==
 template<typename RandIter, class Cmp, typename Arg, int case_lookup_or_sibling_or_insertion>
diff --git a/sfi/tests/misctests.cc b/sfi/tests/misctests.cc
index eb44c13..6e4bf4c 100644
--- a/sfi/tests/misctests.cc
+++ b/sfi/tests/misctests.cc
@@ -134,6 +134,28 @@ test_timestamps()
 }
 ADD_TEST (test_timestamps);
 
+static void
+test_feature_toggles()
+{
+  String r;
+  r = feature_toggle_find ("a:b", "a"); TCMP (r, ==, "1");
+  r = feature_toggle_find ("a:b", "b"); TCMP (r, ==, "1");
+  r = feature_toggle_find ("a:b", "c"); TCMP (r, ==, "0");
+  r = feature_toggle_find ("a:b", "c", "7"); TCMP (r, ==, "7");
+  r = feature_toggle_find ("a:no-b", "b"); TCMP (r, ==, "0");
+  r = feature_toggle_find ("no-a:b", "a"); TCMP (r, ==, "0");
+  r = feature_toggle_find ("no-a:b:a", "a"); TCMP (r, ==, "1");
+  r = feature_toggle_find ("no-a:b:a=5", "a"); TCMP (r, ==, "5");
+  r = feature_toggle_find ("no-a:b:a=5:c", "a"); TCMP (r, ==, "5");
+  bool b;
+  b = feature_toggle_bool ("", "a"); TCMP (b, ==, false);
+  b = feature_toggle_bool ("a:b:c", "a"); TCMP (b, ==, true);
+  b = feature_toggle_bool ("no-a:b:c", "a"); TCMP (b, ==, false);
+  b = feature_toggle_bool ("no-a:b:a=5:c", "b"); TCMP (b, ==, true);
+  b = feature_toggle_bool ("x", ""); TCMP (b, ==, true); // *any* feature?
+}
+ADD_TEST (test_feature_toggles);
+
 /* provide IDL type initializers */
 #define sfidl_pspec_Real(group, name, nick, blurb, dflt, min, max, step, hints)  \
   sfi_pspec_real (name, nick, blurb, dflt, min, max, step, hints)


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