summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Commands/CommandObjectPlatform.cpp14
-rw-r--r--lldb/source/Interpreter/Args.cpp45
-rw-r--r--lldb/source/Interpreter/CMakeLists.txt1
-rw-r--r--lldb/source/Interpreter/CommandOptionValidators.cpp39
-rw-r--r--lldb/source/Interpreter/Options.cpp45
5 files changed, 107 insertions, 37 deletions
diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp
index 96ebd51758e..9998dbdccda 100644
--- a/lldb/source/Commands/CommandObjectPlatform.cpp
+++ b/lldb/source/Commands/CommandObjectPlatform.cpp
@@ -21,6 +21,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandOptionValidators.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionGroupFile.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
@@ -1644,6 +1645,11 @@ protected:
CommandOptions m_options;
};
+namespace
+{
+ PosixPlatformCommandOptionValidator g_posix_validator;
+}
+
OptionDefinition
CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
{
@@ -1654,10 +1660,10 @@ CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_5 , true , "contains" , 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that contain a string." },
{ LLDB_OPT_SET_6 , true , "regex" , 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." },
{ LLDB_OPT_SET_FROM_TO(2, 6), false, "parent" , 'P', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "uid" , 'u', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching user ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "euid" , 'U', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective user ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "gid" , 'g', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching group ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "egid" , 'G', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective group ID." },
+{ LLDB_OPT_SET_FROM_TO(2, 6), false, "uid" , 'u', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching user ID." },
+{ LLDB_OPT_SET_FROM_TO(2, 6), false, "euid" , 'U', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective user ID." },
+{ LLDB_OPT_SET_FROM_TO(2, 6), false, "gid" , 'g', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching group ID." },
+{ LLDB_OPT_SET_FROM_TO(2, 6), false, "egid" , 'G', OptionParser::eRequiredArgument, &g_posix_validator, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective group ID." },
{ LLDB_OPT_SET_FROM_TO(2, 6), false, "arch" , 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
{ LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args" , 'A', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
{ LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose" , 'v', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Enable verbose output." },
diff --git a/lldb/source/Interpreter/Args.cpp b/lldb/source/Interpreter/Args.cpp
index facddcd94c4..0b8f3e1a917 100644
--- a/lldb/source/Interpreter/Args.cpp
+++ b/lldb/source/Interpreter/Args.cpp
@@ -20,6 +20,7 @@
#include "lldb/Core/StreamString.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Process.h"
//#include "lldb/Target/RegisterContext.h"
@@ -627,14 +628,14 @@ Args::ParseOptions (Options &options)
return error;
}
- for (int i=0; long_options[i].name != nullptr; ++i)
+ for (int i=0; long_options[i].definition != nullptr; ++i)
{
if (long_options[i].flag == nullptr)
{
if (isprint8(long_options[i].val))
{
sstr << (char)long_options[i].val;
- switch (long_options[i].has_arg)
+ switch (long_options[i].definition->option_has_arg)
{
default:
case OptionParser::eNoArgument: break;
@@ -673,7 +674,7 @@ Args::ParseOptions (Options &options)
if (long_options_index == -1)
{
for (int i=0;
- long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
+ long_options[i].definition || long_options[i].flag || long_options[i].val;
++i)
{
if (long_options[i].val == val)
@@ -686,8 +687,18 @@ Args::ParseOptions (Options &options)
// Call the callback with the option
if (long_options_index >= 0)
{
- error = options.SetOptionValue(long_options_index,
- long_options[long_options_index].has_arg == OptionParser::eNoArgument ? nullptr : OptionParser::GetOptionArgument());
+ const OptionDefinition *def = long_options[long_options_index].definition;
+ CommandInterpreter &interpreter = options.GetInterpreter();
+ OptionValidator *validator = def->validator;
+ if (validator && !validator->IsValid(*interpreter.GetPlatform(true), interpreter.GetExecutionContext()))
+ {
+ error.SetErrorStringWithFormat("Option \"%s\" invalid. %s", def->long_option, def->validator->LongConditionString());
+ }
+ else
+ {
+ error = options.SetOptionValue(long_options_index,
+ (def->option_has_arg == OptionParser::eNoArgument) ? nullptr : OptionParser::GetOptionArgument());
+ }
}
else
{
@@ -1222,7 +1233,7 @@ Args::FindArgumentIndexForOption (Option *long_options, int long_options_index)
char short_buffer[3];
char long_buffer[255];
::snprintf (short_buffer, sizeof (short_buffer), "-%c", long_options[long_options_index].val);
- ::snprintf (long_buffer, sizeof (long_buffer), "--%s", long_options[long_options_index].name);
+ ::snprintf (long_buffer, sizeof (long_buffer), "--%s", long_options[long_options_index].definition->long_option);
size_t end = GetArgumentCount ();
size_t idx = 0;
while (idx < end)
@@ -1278,12 +1289,12 @@ Args::ParseAliasOptions (Options &options,
return;
}
- for (i = 0; long_options[i].name != nullptr; ++i)
+ for (i = 0; long_options[i].definition != nullptr; ++i)
{
if (long_options[i].flag == nullptr)
{
sstr << (char) long_options[i].val;
- switch (long_options[i].has_arg)
+ switch (long_options[i].definition->option_has_arg)
{
default:
case OptionParser::eNoArgument:
@@ -1328,7 +1339,7 @@ Args::ParseAliasOptions (Options &options,
if (long_options_index == -1)
{
for (int j = 0;
- long_options[j].name || long_options[j].has_arg || long_options[j].flag || long_options[j].val;
+ long_options[j].definition || long_options[j].flag || long_options[j].val;
++j)
{
if (long_options[j].val == val)
@@ -1344,8 +1355,10 @@ Args::ParseAliasOptions (Options &options,
{
StreamString option_str;
option_str.Printf ("-%c", val);
+ const OptionDefinition *def = long_options[long_options_index].definition;
+ int has_arg = (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
- switch (long_options[long_options_index].has_arg)
+ switch (has_arg)
{
case OptionParser::eNoArgument:
option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()),
@@ -1410,7 +1423,7 @@ Args::ParseAliasOptions (Options &options,
raw_input_string.erase (pos, strlen (tmp_arg));
}
ReplaceArgumentAtIndex (idx, "");
- if ((long_options[long_options_index].has_arg != OptionParser::eNoArgument)
+ if ((long_options[long_options_index].definition->option_has_arg != OptionParser::eNoArgument)
&& (OptionParser::GetOptionArgument() != nullptr)
&& (idx+1 < GetArgumentCount())
&& (strcmp (OptionParser::GetOptionArgument(), GetArgumentAtIndex(idx+1)) == 0))
@@ -1453,12 +1466,12 @@ Args::ParseArgsForCompletion
// to suppress error messages.
sstr << ":";
- for (int i = 0; long_options[i].name != nullptr; ++i)
+ for (int i = 0; long_options[i].definition != nullptr; ++i)
{
if (long_options[i].flag == nullptr)
{
sstr << (char) long_options[i].val;
- switch (long_options[i].has_arg)
+ switch (long_options[i].definition->option_has_arg)
{
default:
case OptionParser::eNoArgument:
@@ -1555,7 +1568,7 @@ Args::ParseArgsForCompletion
if (long_options_index == -1)
{
for (int j = 0;
- long_options[j].name || long_options[j].has_arg || long_options[j].flag || long_options[j].val;
+ long_options[j].definition || long_options[j].flag || long_options[j].val;
++j)
{
if (long_options[j].val == val)
@@ -1581,7 +1594,9 @@ Args::ParseArgsForCompletion
}
}
- switch (long_options[long_options_index].has_arg)
+ const OptionDefinition *def = long_options[long_options_index].definition;
+ int has_arg = (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
+ switch (has_arg)
{
case OptionParser::eNoArgument:
option_element_vector.push_back (OptionArgElement (opt_defs_index, OptionParser::GetOptionIndex() - 1, 0));
diff --git a/lldb/source/Interpreter/CMakeLists.txt b/lldb/source/Interpreter/CMakeLists.txt
index 27597fc3c3e..52f89bb3e9b 100644
--- a/lldb/source/Interpreter/CMakeLists.txt
+++ b/lldb/source/Interpreter/CMakeLists.txt
@@ -7,6 +7,7 @@ add_lldb_library(lldbInterpreter
CommandObject.cpp
CommandObjectRegexCommand.cpp
CommandObjectScript.cpp
+ CommandOptionValidators.cpp
CommandReturnObject.cpp
OptionGroupArchitecture.cpp
OptionGroupBoolean.cpp
diff --git a/lldb/source/Interpreter/CommandOptionValidators.cpp b/lldb/source/Interpreter/CommandOptionValidators.cpp
new file mode 100644
index 00000000000..c9f3e3b4635
--- /dev/null
+++ b/lldb/source/Interpreter/CommandOptionValidators.cpp
@@ -0,0 +1,39 @@
+//===-- CommandOptionValidators.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Interpreter/CommandOptionValidators.h"
+
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Target/Platform.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+bool PosixPlatformCommandOptionValidator::IsValid(Platform &platform, ExecutionContext &target) const
+{
+ llvm::Triple::OSType os = platform.GetSystemArchitecture().GetTriple().getOS();
+ switch (os)
+ {
+ // Are there any other platforms that are not POSIX-compatible?
+ case llvm::Triple::Win32:
+ return false;
+ default:
+ return true;
+ }
+}
+
+const char* PosixPlatformCommandOptionValidator::ShortConditionString() const
+{
+ return "POSIX";
+}
+
+const char* PosixPlatformCommandOptionValidator::LongConditionString() const
+{
+ return "Option only valid for POSIX-compliant hosts.";
+}
diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp
index 0aa8aae2dd2..a8766f5f861 100644
--- a/lldb/source/Interpreter/Options.cpp
+++ b/lldb/source/Interpreter/Options.cpp
@@ -277,8 +277,7 @@ Options::GetLongOptions ()
{
const int short_opt = opt_defs[i].short_option;
- m_getopt_table[i].name = opt_defs[i].long_option;
- m_getopt_table[i].has_arg = opt_defs[i].option_has_arg;
+ m_getopt_table[i].definition = &opt_defs[i];
m_getopt_table[i].flag = nullptr;
m_getopt_table[i].val = short_opt;
@@ -297,7 +296,7 @@ Options::GetLongOptions ()
opt_defs[i].long_option,
short_opt,
pos->second,
- m_getopt_table[pos->second].name,
+ m_getopt_table[pos->second].definition->long_option,
opt_defs[i].long_option);
else
Host::SystemLog (Host::eSystemLogError, "option[%u] --%s has a short option 0x%x that conflicts with option[%u] --%s, short option won't be used for --%s\n",
@@ -305,17 +304,16 @@ Options::GetLongOptions ()
opt_defs[i].long_option,
short_opt,
pos->second,
- m_getopt_table[pos->second].name,
+ m_getopt_table[pos->second].definition->long_option,
opt_defs[i].long_option);
}
}
//getopt_long_only requires a NULL final entry in the table:
- m_getopt_table[i].name = nullptr;
- m_getopt_table[i].has_arg = 0;
- m_getopt_table[i].flag = nullptr;
- m_getopt_table[i].val = 0;
+ m_getopt_table[i].definition = nullptr;
+ m_getopt_table[i].flag = nullptr;
+ m_getopt_table[i].val = 0;
}
if (m_getopt_table.empty())
@@ -336,18 +334,29 @@ void
Options::OutputFormattedUsageText
(
Stream &strm,
- const char *text,
+ const OptionDefinition &option_def,
uint32_t output_max_columns
)
{
- int len = strlen (text);
+ std::string actual_text;
+ if (option_def.validator)
+ {
+ const char *condition = option_def.validator->ShortConditionString();
+ if (condition)
+ {
+ actual_text = "[";
+ actual_text.append(condition);
+ actual_text.append("] ");
+ }
+ }
+ actual_text.append(option_def.usage_text);
// Will it all fit on one line?
- if (static_cast<uint32_t>(len + strm.GetIndentLevel()) < output_max_columns)
+ if (static_cast<uint32_t>(actual_text.length() + strm.GetIndentLevel()) < output_max_columns)
{
// Output it as a single line.
- strm.Indent (text);
+ strm.Indent (actual_text.c_str());
strm.EOL();
}
else
@@ -357,13 +366,13 @@ Options::OutputFormattedUsageText
int text_width = output_max_columns - strm.GetIndentLevel() - 1;
int start = 0;
int end = start;
- int final_end = strlen (text);
+ int final_end = actual_text.length();
int sub_len;
while (end < final_end)
{
// Don't start the 'text' on a space, since we're already outputting the indentation.
- while ((start < final_end) && (text[start] == ' '))
+ while ((start < final_end) && (actual_text[start] == ' '))
start++;
end = start + text_width;
@@ -373,7 +382,7 @@ Options::OutputFormattedUsageText
{
// If we're not at the end of the text, make sure we break the line on white space.
while (end > start
- && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
+ && actual_text[end] != ' ' && actual_text[end] != '\t' && actual_text[end] != '\n')
end--;
}
@@ -383,7 +392,7 @@ Options::OutputFormattedUsageText
strm.Indent();
assert (start < final_end);
assert (start + sub_len <= final_end);
- strm.Write(text + start, sub_len);
+ strm.Write(actual_text.c_str() + start, sub_len);
start = end + 1;
}
strm.EOL();
@@ -630,7 +639,7 @@ Options::GenerateOptionUsage
strm.Printf ("\n\n");
// Now print out all the detailed information about the various options: long form, short form and help text:
- // --long_name <argument> ( -short <argument> )
+ // -short <argument> ( --long_name <argument> )
// help text
// This variable is used to keep track of which options' info we've printed out, because some options can be in
@@ -683,7 +692,7 @@ Options::GenerateOptionUsage
if (opt_defs[i].usage_text)
OutputFormattedUsageText (strm,
- opt_defs[i].usage_text,
+ opt_defs[i],
screen_width);
if (opt_defs[i].enum_values != nullptr)
{
OpenPOWER on IntegriCloud