summaryrefslogtreecommitdiffstats
path: root/lldb/source/Interpreter/Options.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Interpreter/Options.cpp')
-rw-r--r--lldb/source/Interpreter/Options.cpp272
1 files changed, 149 insertions, 123 deletions
diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp
index 4a04a4639fb..dfb0ab7d284 100644
--- a/lldb/source/Interpreter/Options.cpp
+++ b/lldb/source/Interpreter/Options.cpp
@@ -13,7 +13,7 @@
// C++ Includes
#include <algorithm>
#include <bitset>
-#include <set>
+#include <map>
// Other libraries and framework includes
// Project includes
@@ -58,7 +58,7 @@ Options::NotifyOptionParsingFinished ()
void
Options::OptionSeen (int option_idx)
{
- m_seen_options.insert ((char) option_idx);
+ m_seen_options.insert (option_idx);
}
// Returns true is set_a is a subset of set_b; Otherwise returns false.
@@ -266,37 +266,54 @@ Options::GetLongOptions ()
return NULL;
uint32_t i;
- uint32_t j;
const OptionDefinition *opt_defs = GetDefinitions();
- std::bitset<256> option_seen;
+ std::map<int, uint32_t> option_seen;
m_getopt_table.resize(num_options + 1);
- for (i = 0, j = 0; i < num_options; ++i)
+ for (i = 0; i < num_options; ++i)
{
- const char short_opt = opt_defs[i].short_option;
+ 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].flag = NULL;
+ m_getopt_table[i].val = short_opt;
- if (option_seen.test(short_opt) == false)
+ if (option_seen.find(short_opt) == option_seen.end())
{
- m_getopt_table[j].name = opt_defs[i].long_option;
- m_getopt_table[j].has_arg = opt_defs[i].option_has_arg;
- m_getopt_table[j].flag = NULL;
- m_getopt_table[j].val = short_opt;
- option_seen.set(short_opt);
- ++j;
+ option_seen[short_opt] = i;
}
- else
+ else if (short_opt)
{
- assert (!"duplicate short option character");
+ m_getopt_table[i].val = 0;
+ std::map<int, uint32_t>::const_iterator pos = option_seen.find(short_opt);
+ StreamString strm;
+ if (isprint(short_opt))
+ Host::SystemLog (Host::eSystemLogError, "option[%u] --%s has a short option -%c that conflicts with option[%u] --%s, short option won't be used for --%s\n",
+ i,
+ opt_defs[i].long_option,
+ short_opt,
+ pos->second,
+ m_getopt_table[pos->second].name,
+ 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",
+ i,
+ opt_defs[i].long_option,
+ short_opt,
+ pos->second,
+ m_getopt_table[pos->second].name,
+ opt_defs[i].long_option);
}
}
//getopt_long requires a NULL final entry in the table:
- m_getopt_table[j].name = NULL;
- m_getopt_table[j].has_arg = 0;
- m_getopt_table[j].flag = NULL;
- m_getopt_table[j].val = 0;
+ m_getopt_table[i].name = NULL;
+ m_getopt_table[i].has_arg = 0;
+ m_getopt_table[i].flag = NULL;
+ m_getopt_table[i].val = 0;
}
if (m_getopt_table.empty())
@@ -393,6 +410,57 @@ Options::SupportsLongOption (const char *long_option)
return false;
}
+enum OptionDisplayType
+{
+ eDisplayBestOption,
+ eDisplayShortOption,
+ eDisplayLongOption
+};
+
+static bool
+PrintOption (const OptionDefinition &opt_def,
+ OptionDisplayType display_type,
+ const char *header,
+ const char *footer,
+ bool show_optional,
+ Stream &strm)
+{
+ const bool has_short_option = isprint(opt_def.short_option) != 0;
+
+ if (display_type == eDisplayShortOption && !has_short_option)
+ return false;
+
+ if (header && header[0])
+ strm.PutCString(header);
+
+ if (show_optional && !opt_def.required)
+ strm.PutChar('[');
+ const bool show_short_option = has_short_option && display_type != eDisplayLongOption;
+ if (show_short_option)
+ strm.Printf ("-%c", opt_def.short_option);
+ else
+ strm.Printf ("--%s", opt_def.long_option);
+ switch (opt_def.option_has_arg)
+ {
+ case no_argument:
+ break;
+ case required_argument:
+ strm.Printf (" <%s>", CommandObject::GetArgumentName (opt_def.argument_type));
+ break;
+
+ case optional_argument:
+ strm.Printf ("%s[<%s>]",
+ show_short_option ? "" : "=",
+ CommandObject::GetArgumentName (opt_def.argument_type));
+ break;
+ }
+ if (show_optional && !opt_def.required)
+ strm.PutChar(']');
+ if (footer && footer[0])
+ strm.PutCString(footer);
+ return true;
+}
+
void
Options::GenerateOptionUsage
(
@@ -450,12 +518,12 @@ Options::GenerateOptionUsage
// a single string. If a command has "-a" "-b" and "-c", this will show
// up as [-abc]
- std::set<char> options;
- std::set<char>::const_iterator options_pos, options_end;
+ std::set<int> options;
+ std::set<int>::const_iterator options_pos, options_end;
bool first;
for (i = 0, first = true; i < num_options; ++i)
{
- if (opt_defs[i].usage_mask & opt_set_mask)
+ if (opt_defs[i].usage_mask & opt_set_mask && isprint(opt_defs[i].short_option))
{
// Add current option to the end of out_stream.
@@ -476,17 +544,17 @@ Options::GenerateOptionUsage
options_pos != options_end;
++options_pos)
{
- if (i==0 && ::isupper (*options_pos))
+ if (i==0 && ::islower (*options_pos))
continue;
- if (i==1 && ::islower (*options_pos))
+ if (i==1 && ::isupper (*options_pos))
continue;
- strm << *options_pos;
+ strm << (char)*options_pos;
}
}
for (i = 0, options.clear(); i < num_options; ++i)
{
- if (opt_defs[i].usage_mask & opt_set_mask)
+ if (opt_defs[i].usage_mask & opt_set_mask && isprint(opt_defs[i].short_option))
{
// Add current option to the end of out_stream.
@@ -507,11 +575,11 @@ Options::GenerateOptionUsage
options_pos != options_end;
++options_pos)
{
- if (i==0 && ::isupper (*options_pos))
+ if (i==0 && ::islower (*options_pos))
continue;
- if (i==1 && ::islower (*options_pos))
+ if (i==1 && ::isupper (*options_pos))
continue;
- strm << *options_pos;
+ strm << (char)*options_pos;
}
strm.PutChar(']');
}
@@ -520,26 +588,10 @@ Options::GenerateOptionUsage
for (i = 0; i < num_options; ++i)
{
- if (opt_defs[i].usage_mask & opt_set_mask)
+ if (opt_defs[i].usage_mask & opt_set_mask && isprint(opt_defs[i].short_option))
{
- // Add current option to the end of out_stream.
- CommandArgumentType arg_type = opt_defs[i].argument_type;
-
- if (opt_defs[i].required)
- {
- if (opt_defs[i].option_has_arg == required_argument)
- {
- strm.Printf (" -%c <%s>",
- opt_defs[i].short_option,
- CommandObject::GetArgumentName (arg_type));
- }
- else if (opt_defs[i].option_has_arg == optional_argument)
- {
- strm.Printf (" -%c [<%s>]",
- opt_defs[i].short_option,
- CommandObject::GetArgumentName (arg_type));
- }
- }
+ if (opt_defs[i].required && opt_defs[i].option_has_arg != no_argument)
+ PrintOption (opt_defs[i], eDisplayBestOption, " ", NULL, true, strm);
}
}
@@ -551,17 +603,8 @@ Options::GenerateOptionUsage
{
// Add current option to the end of out_stream.
- CommandArgumentType arg_type = opt_defs[i].argument_type;
-
- if (! opt_defs[i].required)
- {
- if (opt_defs[i].option_has_arg == required_argument)
- strm.Printf (" [-%c <%s>]", opt_defs[i].short_option,
- CommandObject::GetArgumentName (arg_type));
- else if (opt_defs[i].option_has_arg == optional_argument)
- strm.Printf (" [-%c [<%s>]]", opt_defs[i].short_option,
- CommandObject::GetArgumentName (arg_type));
- }
+ if (!opt_defs[i].required && opt_defs[i].option_has_arg != no_argument)
+ PrintOption (opt_defs[i], eDisplayBestOption, " ", NULL, true, strm);
}
}
@@ -592,86 +635,69 @@ Options::GenerateOptionUsage
// This variable is used to keep track of which options' info we've printed out, because some options can be in
// more than one usage level, but we only want to print the long form of its information once.
- OptionSet options_seen;
- OptionSet::iterator pos;
+ std::multimap<int, uint32_t> options_seen;
strm.IndentMore (5);
- std::vector<char> sorted_options;
-
-
// Put the unique command options in a vector & sort it, so we can output them alphabetically (by short_option)
// when writing out detailed help for each option.
for (i = 0; i < num_options; ++i)
- {
- pos = options_seen.find (opt_defs[i].short_option);
- if (pos == options_seen.end())
- {
- options_seen.insert (opt_defs[i].short_option);
- sorted_options.push_back (opt_defs[i].short_option);
- }
- }
-
- std::sort (sorted_options.begin(), sorted_options.end());
+ options_seen.insert(std::make_pair(opt_defs[i].short_option, i));
// Go through the unique'd and alphabetically sorted vector of options, find the table entry for each option
// and write out the detailed help information for that option.
- int first_option_printed = 1;
- size_t end = sorted_options.size();
- for (size_t j = 0; j < end; ++j)
+ bool first_option_printed = false;;
+
+ for (auto pos : options_seen)
{
- char option = sorted_options[j];
- bool found = false;
- for (i = 0; i < num_options && !found; ++i)
+ i = pos.second;
+ //Print out the help information for this option.
+
+ // Put a newline separation between arguments
+ if (first_option_printed)
+ strm.EOL();
+ else
+ first_option_printed = true;
+
+ CommandArgumentType arg_type = opt_defs[i].argument_type;
+
+ StreamString arg_name_str;
+ arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type));
+
+ strm.Indent ();
+ if (opt_defs[i].short_option && isprint(opt_defs[i].short_option))
+ {
+ PrintOption (opt_defs[i], eDisplayShortOption, NULL, NULL, false, strm);
+ PrintOption (opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
+ }
+ else
{
- if (opt_defs[i].short_option == option)
+ // Short option is not printable, just print long option
+ PrintOption (opt_defs[i], eDisplayLongOption, NULL, NULL, false, strm);
+ }
+ strm.EOL();
+
+ strm.IndentMore (5);
+
+ if (opt_defs[i].usage_text)
+ OutputFormattedUsageText (strm,
+ opt_defs[i].usage_text,
+ screen_width);
+ if (opt_defs[i].enum_values != NULL)
+ {
+ strm.Indent ();
+ strm.Printf("Values: ");
+ for (int k = 0; opt_defs[i].enum_values[k].string_value != NULL; k++)
{
- found = true;
- //Print out the help information for this option.
-
- // Put a newline separation between arguments
- if (first_option_printed)
- first_option_printed = 0;
+ if (k == 0)
+ strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
else
- strm.EOL();
-
- CommandArgumentType arg_type = opt_defs[i].argument_type;
-
- StreamString arg_name_str;
- arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type));
-
- strm.Indent ();
- strm.Printf ("-%c", opt_defs[i].short_option);
- if (arg_type != eArgTypeNone)
- strm.Printf (" <%s>", CommandObject::GetArgumentName (arg_type));
- strm.Printf (" ( --%s", opt_defs[i].long_option);
- if (arg_type != eArgTypeNone)
- strm.Printf (" <%s>", CommandObject::GetArgumentName (arg_type));
- strm.PutCString(" )\n");
-
- strm.IndentMore (5);
-
- if (opt_defs[i].usage_text)
- OutputFormattedUsageText (strm,
- opt_defs[i].usage_text,
- screen_width);
- if (opt_defs[i].enum_values != NULL)
- {
- strm.Indent ();
- strm.Printf("Values: ");
- for (int k = 0; opt_defs[i].enum_values[k].string_value != NULL; k++)
- {
- if (k == 0)
- strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
- else
- strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
- }
- strm.EOL();
- }
- strm.IndentLess (5);
+ strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
}
+ strm.EOL();
}
+ strm.IndentLess (5);
}
// Restore the indent level
OpenPOWER on IntegriCloud