Add unit tests for a few string conversion functions in Args.
authorZachary Turner <zturner@google.com>
Fri, 16 Sep 2016 19:09:12 +0000 (19:09 +0000)
committerZachary Turner <zturner@google.com>
Fri, 16 Sep 2016 19:09:12 +0000 (19:09 +0000)
Also provided a StringRef overload for these functions and have
the const char* overloads delegate to the StringRef overload.

llvm-svn: 281764

lldb/include/lldb/Breakpoint/BreakpointID.h
lldb/include/lldb/Host/FileSpec.h
lldb/include/lldb/Interpreter/Args.h
lldb/include/lldb/Interpreter/Options.h
lldb/include/lldb/Target/Language.h
lldb/source/API/SBDebugger.cpp
lldb/source/Interpreter/Args.cpp
lldb/source/Interpreter/OptionValueChar.cpp
lldb/source/Interpreter/Property.cpp
lldb/unittests/Interpreter/TestArgs.cpp

index 08a7b5c..de44b2b 100644 (file)
@@ -87,6 +87,7 @@ public:
   ///     \b true if the name is a breakpoint name (as opposed to an ID or
   ///     range) false otherwise.
   //------------------------------------------------------------------
+  // TODO: Convert this function to use a StringRef.
   static bool StringIsBreakpointName(const char *name, Error &error);
 
   //------------------------------------------------------------------
index 86d487f..e65bed0 100644 (file)
@@ -80,6 +80,7 @@ public:
   ///
   /// @see FileSpec::SetFile (const char *path, bool resolve)
   //------------------------------------------------------------------
+  // TODO: Convert this constructor to use a StringRef.
   explicit FileSpec(const char *path, bool resolve_path,
                     PathSyntax syntax = ePathSyntaxHostNative);
 
index 0a6ea0b..a0e3d1e 100644 (file)
@@ -179,6 +179,7 @@ public:
   /// @return
   ///     The NULL terminated C string of the copy of \a arg_cstr.
   //------------------------------------------------------------------
+  // TODO: Convert this function to use a StringRef.
   const char *AppendArgument(const char *arg_cstr, char quote_char = '\0');
 
   void AppendArguments(const Args &rhs);
@@ -353,24 +354,26 @@ public:
     return min <= sval64 && sval64 <= max;
   }
 
+  // TODO: Make this function take a StringRef
   static lldb::addr_t StringToAddress(const ExecutionContext *exe_ctx,
                                       const char *s, lldb::addr_t fail_value,
                                       Error *error);
 
   static bool StringToBoolean(const char *s, bool fail_value,
-                              bool *success_ptr);
+    bool *success_ptr);
 
   static bool StringToBoolean(llvm::StringRef s, bool fail_value,
                               bool *success_ptr);
 
-  static char StringToChar(const char *s, char fail_value, bool *success_ptr);
+  static char StringToChar(llvm::StringRef s, char fail_value,
+                           bool *success_ptr);
 
   static int64_t StringToOptionEnum(const char *s,
                                     OptionEnumValueElement *enum_values,
                                     int32_t fail_value, Error &error);
 
   static lldb::ScriptLanguage
-  StringToScriptLanguage(const char *s, lldb::ScriptLanguage fail_value,
+  StringToScriptLanguage(llvm::StringRef s, lldb::ScriptLanguage fail_value,
                          bool *success_ptr);
 
   // TODO: Use StringRef
index fb854cd..f57dde5 100644 (file)
@@ -188,6 +188,7 @@ public:
   /// @see Args::ParseOptions (Options&)
   /// @see man getopt_long_only
   //------------------------------------------------------------------
+  // TODO: Make this function take a StringRef.
   virtual Error SetOptionValue(uint32_t option_idx, const char *option_arg,
                                ExecutionContext *execution_context) = 0;
 
index 8182483..f324ae1 100644 (file)
@@ -142,6 +142,7 @@ public:
   // These are accessors for general information about the Languages lldb knows
   // about:
 
+  // TODO: Convert this to using a StringRef.
   static lldb::LanguageType GetLanguageTypeFromString(const char *string);
 
   static const char *GetNameForLanguageType(lldb::LanguageType language);
index f7811f2..7641d78 100644 (file)
@@ -48,6 +48,7 @@
 #include "lldb/Target/TargetList.h"
 
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/ManagedStatic.h"
 
@@ -474,7 +475,8 @@ bool SBDebugger::SetDefaultArchitecture(const char *arch_name) {
 
 ScriptLanguage
 SBDebugger::GetScriptingLanguage(const char *script_language_name) {
-  return Args::StringToScriptLanguage(script_language_name,
+  if (!script_language_name) return eScriptLanguageDefault;
+  return Args::StringToScriptLanguage(llvm::StringRef(script_language_name),
                                       eScriptLanguageDefault, nullptr);
 }
 
index 997c0e1..0edb9bc 100644 (file)
@@ -732,24 +732,21 @@ const char *Args::StripSpaces(std::string &s, bool leading, bool trailing,
   return s.c_str();
 }
 
-bool Args::StringToBoolean(const char *s, bool fail_value, bool *success_ptr) {
-  if (!s)
-    return fail_value;
-  return Args::StringToBoolean(llvm::StringRef(s), fail_value, success_ptr);
+bool Args::StringToBoolean(const char *s, bool fail_value,
+  bool *success_ptr) {
+  return StringToBoolean(llvm::StringRef(s ? s : ""), fail_value, success_ptr);
 }
 
 bool Args::StringToBoolean(llvm::StringRef ref, bool fail_value,
                            bool *success_ptr) {
+  if (success_ptr)
+    *success_ptr = true;
   ref = ref.trim();
   if (ref.equals_lower("false") || ref.equals_lower("off") ||
       ref.equals_lower("no") || ref.equals_lower("0")) {
-    if (success_ptr)
-      *success_ptr = true;
     return false;
   } else if (ref.equals_lower("true") || ref.equals_lower("on") ||
              ref.equals_lower("yes") || ref.equals_lower("1")) {
-    if (success_ptr)
-      *success_ptr = true;
     return true;
   }
   if (success_ptr)
@@ -757,20 +754,15 @@ bool Args::StringToBoolean(llvm::StringRef ref, bool fail_value,
   return fail_value;
 }
 
-char Args::StringToChar(const char *s, char fail_value, bool *success_ptr) {
-  bool success = false;
-  char result = fail_value;
+char Args::StringToChar(llvm::StringRef s, char fail_value, bool *success_ptr) {
+  if (success_ptr)
+    *success_ptr = false;
+  if (s.size() != 1)
+    return fail_value;
 
-  if (s) {
-    size_t length = strlen(s);
-    if (length == 1) {
-      success = true;
-      result = s[0];
-    }
-  }
   if (success_ptr)
-    *success_ptr = success;
-  return result;
+    *success_ptr = true;
+  return s[0];
 }
 
 const char *Args::StringToVersion(const char *s, uint32_t &major,
@@ -870,23 +862,19 @@ int64_t Args::StringToOptionEnum(const char *s,
   return fail_value;
 }
 
-ScriptLanguage Args::StringToScriptLanguage(const char *s,
-                                            ScriptLanguage fail_value,
-                                            bool *success_ptr) {
-  if (s && s[0]) {
-    if ((::strcasecmp(s, "python") == 0) ||
-        (::strcasecmp(s, "default") == 0 &&
-         eScriptLanguagePython == eScriptLanguageDefault)) {
-      if (success_ptr)
-        *success_ptr = true;
-      return eScriptLanguagePython;
-    }
-    if (::strcasecmp(s, "none")) {
-      if (success_ptr)
-        *success_ptr = true;
-      return eScriptLanguageNone;
-    }
-  }
+lldb::ScriptLanguage
+Args::StringToScriptLanguage(llvm::StringRef s, lldb::ScriptLanguage fail_value,
+                             bool *success_ptr) {
+  if (success_ptr)
+    *success_ptr = true;
+
+  if (s.equals_lower("python"))
+    return eScriptLanguagePython;
+  if (s.equals_lower("default"))
+    return eScriptLanguageDefault;
+  if (s.equals_lower("none"))
+    return eScriptLanguageNone;
+
   if (success_ptr)
     *success_ptr = false;
   return fail_value;
index 3b4527c..bfc39ae 100644 (file)
@@ -47,7 +47,7 @@ Error OptionValueChar::SetValueFromString(llvm::StringRef value,
   case eVarSetOperationReplace:
   case eVarSetOperationAssign: {
     bool success = false;
-    char char_value = Args::StringToChar(value.str().c_str(), '\0', &success);
+    char char_value = Args::StringToChar(value, '\0', &success);
     if (success) {
       m_current_value = char_value;
       m_value_was_set = true;
index 1958949..0030d37 100644 (file)
@@ -51,8 +51,7 @@ Property::Property(const PropertyDefinition &definition)
     // "definition.default_uint_value" is the default boolean value if
     // "definition.default_cstr_value" is NULL, otherwise interpret
     // "definition.default_cstr_value" as a string value that represents the
-    // default
-    // value.
+    // default value.
     if (definition.default_cstr_value)
       m_value_sp.reset(new OptionValueBoolean(Args::StringToBoolean(
           definition.default_cstr_value, false, nullptr)));
@@ -61,11 +60,11 @@ Property::Property(const PropertyDefinition &definition)
           new OptionValueBoolean(definition.default_uint_value != 0));
     break;
 
-  case OptionValue::eTypeChar:
-    m_value_sp.reset(new OptionValueChar(
-        Args::StringToChar(definition.default_cstr_value, '\0', nullptr)));
+  case OptionValue::eTypeChar: {
+    llvm::StringRef s(definition.default_cstr_value ? definition.default_cstr_value : "");
+    m_value_sp = std::make_shared<OptionValueChar>(Args::StringToChar(s, '\0', nullptr));
     break;
-
+  }
   case OptionValue::eTypeDictionary:
     // "definition.default_uint_value" is always a OptionValue::Type
     m_value_sp.reset(new OptionValueDictionary(OptionValue::ConvertTypeToMask(
index a14b842..bec9340 100644 (file)
@@ -62,3 +62,92 @@ TEST(ArgsTest, TestAppendArg) {
   EXPECT_STREQ(args.GetArgumentAtIndex(0), "first_arg");
   EXPECT_STREQ(args.GetArgumentAtIndex(1), "second_arg");
 }
+
+TEST(ArgsTest, StringToBoolean) {
+  bool success = false;
+  EXPECT_TRUE(Args::StringToBoolean("true", false, nullptr));
+  EXPECT_TRUE(Args::StringToBoolean("on", false, nullptr));
+  EXPECT_TRUE(Args::StringToBoolean("yes", false, nullptr));
+  EXPECT_TRUE(Args::StringToBoolean("1", false, nullptr));
+
+  EXPECT_TRUE(Args::StringToBoolean("true", false, &success));
+  EXPECT_TRUE(success);
+  EXPECT_TRUE(Args::StringToBoolean("on", false, &success));
+  EXPECT_TRUE(success);
+  EXPECT_TRUE(Args::StringToBoolean("yes", false, &success));
+  EXPECT_TRUE(success);
+  EXPECT_TRUE(Args::StringToBoolean("1", false, &success));
+  EXPECT_TRUE(success);
+
+  EXPECT_FALSE(Args::StringToBoolean("false", true, nullptr));
+  EXPECT_FALSE(Args::StringToBoolean("off", true, nullptr));
+  EXPECT_FALSE(Args::StringToBoolean("no", true, nullptr));
+  EXPECT_FALSE(Args::StringToBoolean("0", true, nullptr));
+
+  EXPECT_FALSE(Args::StringToBoolean("false", true, &success));
+  EXPECT_TRUE(success);
+  EXPECT_FALSE(Args::StringToBoolean("off", true, &success));
+  EXPECT_TRUE(success);
+  EXPECT_FALSE(Args::StringToBoolean("no", true, &success));
+  EXPECT_TRUE(success);
+  EXPECT_FALSE(Args::StringToBoolean("0", true, &success));
+  EXPECT_TRUE(success);
+
+  EXPECT_FALSE(Args::StringToBoolean("10", false, &success));
+  EXPECT_FALSE(success);
+  EXPECT_TRUE(Args::StringToBoolean("10", true, &success));
+  EXPECT_FALSE(success);
+  EXPECT_TRUE(Args::StringToBoolean("", true, &success));
+  EXPECT_FALSE(success);
+  EXPECT_TRUE(Args::StringToBoolean(nullptr, true, &success));
+  EXPECT_FALSE(success);
+}
+
+TEST(ArgsTest, StringToChar) {
+  bool success = false;
+
+  EXPECT_EQ('A', Args::StringToChar("A", 'B', nullptr));
+  EXPECT_EQ('B', Args::StringToChar("B", 'A', nullptr));
+
+  EXPECT_EQ('A', Args::StringToChar("A", 'B', &success));
+  EXPECT_TRUE(success);
+  EXPECT_EQ('B', Args::StringToChar("B", 'A', &success));
+  EXPECT_TRUE(success);
+
+  EXPECT_EQ('A', Args::StringToChar("", 'A', &success));
+  EXPECT_FALSE(success);
+  EXPECT_EQ('A', Args::StringToChar("ABC", 'A', &success));
+  EXPECT_FALSE(success);
+}
+
+TEST(ArgsTest, StringToScriptLanguage) {
+  bool success = false;
+
+  EXPECT_EQ(lldb::eScriptLanguageDefault,
+            Args::StringToScriptLanguage("default", lldb::eScriptLanguageNone,
+                                         nullptr));
+  EXPECT_EQ(lldb::eScriptLanguagePython,
+            Args::StringToScriptLanguage("python", lldb::eScriptLanguageNone,
+                                         nullptr));
+  EXPECT_EQ(lldb::eScriptLanguageNone,
+            Args::StringToScriptLanguage("none", lldb::eScriptLanguagePython,
+                                         nullptr));
+
+  EXPECT_EQ(lldb::eScriptLanguageDefault,
+            Args::StringToScriptLanguage("default", lldb::eScriptLanguageNone,
+                                         &success));
+  EXPECT_TRUE(success);
+  EXPECT_EQ(lldb::eScriptLanguagePython,
+            Args::StringToScriptLanguage("python", lldb::eScriptLanguageNone,
+                                         &success));
+  EXPECT_TRUE(success);
+  EXPECT_EQ(lldb::eScriptLanguageNone,
+            Args::StringToScriptLanguage("none", lldb::eScriptLanguagePython,
+                                         &success));
+  EXPECT_TRUE(success);
+
+  EXPECT_EQ(lldb::eScriptLanguagePython,
+            Args::StringToScriptLanguage("invalid", lldb::eScriptLanguagePython,
+                                         &success));
+  EXPECT_FALSE(success);
+}
\ No newline at end of file