Adding a validation callback mechanism to OptionValueString (such a feature might theoretically be added to the general OptionValue base class should the need arise)
Using this mechanism, making sure that the options to pass a summary string or a named summary to frame variable do not have invalid values

<rdar://problem/11576143>



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@169927 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Interpreter/OptionGroupVariable.cpp b/source/Interpreter/OptionGroupVariable.cpp
index 5f1c271..e98ff56 100644
--- a/source/Interpreter/OptionGroupVariable.cpp
+++ b/source/Interpreter/OptionGroupVariable.cpp
@@ -15,6 +15,8 @@
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
+#include "lldb/Core/DataVisualization.h"
+#include "lldb/Core/Error.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Utility/Utils.h"
@@ -39,7 +41,22 @@
 
 OptionGroupVariable::OptionGroupVariable (bool show_frame_options) :
     OptionGroup(),
-    include_frame_options (show_frame_options)
+    include_frame_options (show_frame_options),
+    summary([] (const char* str,void*)->Error
+            {
+                if (!str || !str[0])
+                    return Error("must specify a valid named summary");
+                TypeSummaryImplSP summary_sp;
+                if (DataVisualization::NamedSummaryFormats::GetSummaryFormat(ConstString(str), summary_sp) == false)
+                    return Error("must specify a valid named summary");
+                return Error();
+            }),
+    summary_string([] (const char* str, void*)->Error
+           {
+               if (!str || !str[0])
+                   return Error("must specify a non-empty summary string");
+               return Error();
+           })
 {
 }
 
@@ -67,10 +84,10 @@
             show_scope = true;
             break;
         case 'y':
-            summary.SetCurrentValue(option_arg);
+            error = summary.SetCurrentValue(option_arg);
             break;
         case 'z':
-            summary_string.SetCurrentValue(option_arg);
+            error = summary_string.SetCurrentValue(option_arg);
             break;
         default:
             error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
diff --git a/source/Interpreter/OptionValueString.cpp b/source/Interpreter/OptionValueString.cpp
index 696e62b..91a9803 100644
--- a/source/Interpreter/OptionValueString.cpp
+++ b/source/Interpreter/OptionValueString.cpp
@@ -61,20 +61,36 @@
     case eVarSetOperationInsertBefore:
     case eVarSetOperationInsertAfter:
     case eVarSetOperationRemove:
+        if (m_validator)
+        {
+            error = m_validator(value_cstr,m_validator_baton);
+            if (error.Fail())
+                return error;
+        }
         error = OptionValue::SetValueFromCString (value_cstr, op);
         break;
 
     case eVarSetOperationAppend:
+        {
+        std::string new_value(m_current_value);
         if (value_cstr && value_cstr[0])
         {
             if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
             {
                 std::string str;
                 Args::EncodeEscapeSequences (value_cstr, str);
-                m_current_value += str;
+                new_value.append(str);
             }
             else
-                m_current_value += value_cstr;
+                new_value.append(value_cstr);
+        }
+        if (m_validator)
+        {
+            error = m_validator(new_value.c_str(),m_validator_baton);
+            if (error.Fail())
+                return error;
+        }
+        m_current_value.assign(new_value);
         }
         break;
 
@@ -84,6 +100,12 @@
 
     case eVarSetOperationReplace:
     case eVarSetOperationAssign:
+        if (m_validator)
+        {
+            error = m_validator(value_cstr,m_validator_baton);
+            if (error.Fail())
+                return error;
+        }
         m_value_was_set = true;
         if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
         {
@@ -104,3 +126,39 @@
 {
     return OptionValueSP(new OptionValueString(*this));
 }
+
+Error
+OptionValueString::SetCurrentValue (const char *value)
+{
+    if (m_validator)
+    {
+        Error error(m_validator(value,m_validator_baton));
+        if (error.Fail())
+            return error;
+    }
+    if (value && value[0])
+        m_current_value.assign (value);
+    else
+        m_current_value.clear();
+    return Error();
+}
+
+Error
+OptionValueString::AppendToCurrentValue (const char *value)
+{
+    if (value && value[0])
+    {
+        if (m_validator)
+        {
+            std::string new_value(m_current_value);
+            new_value.append(value);
+            Error error(m_validator(value,m_validator_baton));
+            if (error.Fail())
+                return error;
+            m_current_value.assign(new_value);
+        }
+        else
+            m_current_value.append (value);
+    }
+    return Error();
+}