namespace lldb_private {
-typedef struct Option
+struct OptionDefinition;
+
+struct Option
{
- // name of long option
- const char *name;
- // one of no_argument, required_argument, and optional_argument:
- // whether option takes an argument
- int has_arg;
+ // The definition of the option that this refers to.
+ const OptionDefinition *definition;
// if not NULL, set *flag to val when option found
int *flag;
// if flag not NULL, value to set *flag to; else return value
int val;
-} Option;
+};
class OptionParser
{
--- /dev/null
+//===-- CommandOptionValidators.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CommandOptionValidators_h_
+#define liblldb_CommandOptionValidators_h_
+
+#include "lldb/lldb-private-types.h"
+
+namespace lldb_private {
+
+class Platform;
+class ExecutionContext;
+
+class PosixPlatformCommandOptionValidator : public OptionValidator
+{
+ virtual bool IsValid(Platform &platform, ExecutionContext &target) const;
+ virtual const char* ShortConditionString() const;
+ virtual const char* LongConditionString() const;
+};
+
+} // namespace lldb_private
+
+
+#endif // liblldb_CommandOptionValidators_h_
void
OutputFormattedUsageText (Stream &strm,
- const char *text,
+ const OptionDefinition &option_def,
uint32_t output_max_columns);
void
int max_return_elements,
bool &word_complete,
StringList &matches);
+
+ CommandInterpreter&
+ GetInterpreter()
+ {
+ return m_interpreter;
+ }
protected:
// This is a set of options expressed as indexes into the options table for this Option.
namespace lldb_private
{
+ class Platform;
+ class ExecutionContext;
+
//----------------------------------------------------------------------
// Every register is described in detail including its name, alternate
// name (optional), encoding, size in bytes and the default display
struct OptionValidator
{
virtual ~OptionValidator() { }
- virtual bool IsValid() const = 0;
- virtual const char * ValidConditionString() const = 0;
+ virtual bool IsValid(Platform &platform, ExecutionContext &target) const = 0;
+ virtual const char * ShortConditionString() const = 0;
+ virtual const char * LongConditionString() const = 0;
};
- typedef struct
+ struct OptionDefinition
{
uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
// then this option belongs to option set n.
lldb::CommandArgumentType argument_type; // Type of argument this option takes
const char *usage_text; // Full text explaining what this options does and what (if any) argument to
// pass it.
- } OptionDefinition;
+ };
} // namespace lldb_private
#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"
CommandOptions m_options;
};
+namespace
+{
+ PosixPlatformCommandOptionValidator g_posix_validator;
+}
+
OptionDefinition
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." },
#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"
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;
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)
// 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
{
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)
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:
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)
{
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()),
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))
// 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:
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)
}
}
- 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));
CommandObject.cpp
CommandObjectRegexCommand.cpp
CommandObjectScript.cpp
+ CommandOptionValidators.cpp
CommandReturnObject.cpp
OptionGroupArchitecture.cpp
OptionGroupBoolean.cpp
--- /dev/null
+//===-- 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.";
+}
{
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;
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",
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())
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
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;
{
// 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--;
}
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();
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
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)
{