<rdar://problem/12798131>
Cleaned up the option parsing code to always pass around the short options as integers. Previously we cast this down to "char" and lost some information. I recently added an assert that would detect duplicate short character options which was firing during the test suite.
This fix does the following:
- make sure all short options are treated as "int"
- make sure that short options can be non-printable values when a short option is not required or when an option group is mixed into many commands and a short option is not desired
- fix the help printing to "do the right thing" in all cases. Previously if there were duplicate short character options, it would just not emit help for the duplicates
- fix option parsing when there are duplicates to parse options correctly. Previously the option parsing, when done for an OptionGroup, would just start parsing options incorrectly by omitting table entries and it would end up setting the wrong option value
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@169189 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp
index 1518968..dde546c 100644
--- a/source/Interpreter/Args.cpp
+++ b/source/Interpreter/Args.cpp
@@ -625,13 +625,16 @@
{
if (long_options[i].flag == NULL)
{
- sstr << (char)long_options[i].val;
- switch (long_options[i].has_arg)
+ if (isprint(long_options[i].val))
{
- default:
- case no_argument: break;
- case required_argument: sstr << ':'; break;
- case optional_argument: sstr << "::"; break;
+ sstr << (char)long_options[i].val;
+ switch (long_options[i].has_arg)
+ {
+ default:
+ case no_argument: break;
+ case required_argument: sstr << ':'; break;
+ case optional_argument: sstr << "::"; break;
+ }
}
}
}
@@ -645,7 +648,10 @@
while (1)
{
int long_options_index = -1;
- val = ::getopt_long(GetArgumentCount(), GetArgumentVector(), sstr.GetData(), long_options,
+ val = ::getopt_long(GetArgumentCount(),
+ GetArgumentVector(),
+ sstr.GetData(),
+ long_options,
&long_options_index);
if (val == -1)
break;
@@ -1092,7 +1098,7 @@
{
char short_buffer[3];
char long_buffer[255];
- ::snprintf (short_buffer, sizeof (short_buffer), "-%c", (char) long_options[long_options_index].val);
+ ::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);
size_t end = GetArgumentCount ();
size_t idx = 0;
@@ -1216,7 +1222,7 @@
if (long_options_index >= 0)
{
StreamString option_str;
- option_str.Printf ("-%c", (char) val);
+ option_str.Printf ("-%c", val);
switch (long_options[long_options_index].has_arg)
{
@@ -1256,16 +1262,14 @@
}
break;
default:
- result.AppendErrorWithFormat
- ("error with options table; invalid value in has_arg field for option '%c'.\n",
- (char) val);
+ result.AppendErrorWithFormat ("error with options table; invalid value in has_arg field for option '%c'.\n", val);
result.SetStatus (eReturnStatusFailed);
break;
}
}
else
{
- result.AppendErrorWithFormat ("Invalid option with value '%c'.\n", (char) val);
+ result.AppendErrorWithFormat ("Invalid option with value '%c'.\n", val);
result.SetStatus (eReturnStatusFailed);
}
diff --git a/source/Interpreter/OptionGroupArchitecture.cpp b/source/Interpreter/OptionGroupArchitecture.cpp
index 1756051..af103bb 100644
--- a/source/Interpreter/OptionGroupArchitecture.cpp
+++ b/source/Interpreter/OptionGroupArchitecture.cpp
@@ -62,7 +62,7 @@
const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
diff --git a/source/Interpreter/OptionGroupBoolean.cpp b/source/Interpreter/OptionGroupBoolean.cpp
index 58ac0f1..5b5b384 100644
--- a/source/Interpreter/OptionGroupBoolean.cpp
+++ b/source/Interpreter/OptionGroupBoolean.cpp
@@ -20,7 +20,7 @@
OptionGroupBoolean::OptionGroupBoolean (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
const char *usage_text,
bool default_value,
bool no_argument_toggle_default) :
diff --git a/source/Interpreter/OptionGroupFile.cpp b/source/Interpreter/OptionGroupFile.cpp
index 4749087..6867395 100644
--- a/source/Interpreter/OptionGroupFile.cpp
+++ b/source/Interpreter/OptionGroupFile.cpp
@@ -20,7 +20,7 @@
OptionGroupFile::OptionGroupFile (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text) :
@@ -60,7 +60,7 @@
OptionGroupFileList::OptionGroupFileList (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text) :
@@ -83,8 +83,8 @@
Error
OptionGroupFileList::SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg)
+ uint32_t option_idx,
+ const char *option_arg)
{
Error error (m_file_list.SetValueFromCString (option_arg));
return error;
diff --git a/source/Interpreter/OptionGroupFormat.cpp b/source/Interpreter/OptionGroupFormat.cpp
index 8af74ae..795fb03 100644
--- a/source/Interpreter/OptionGroupFormat.cpp
+++ b/source/Interpreter/OptionGroupFormat.cpp
@@ -67,7 +67,7 @@
const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
diff --git a/source/Interpreter/OptionGroupOutputFile.cpp b/source/Interpreter/OptionGroupOutputFile.cpp
index 1ec31da..aa01bf5 100644
--- a/source/Interpreter/OptionGroupOutputFile.cpp
+++ b/source/Interpreter/OptionGroupOutputFile.cpp
@@ -32,7 +32,7 @@
g_option_table[] =
{
{ LLDB_OPT_SET_1 , false, "outfile", 'o', required_argument, NULL, 0, eArgTypeFilename , "Specify a path for capturing command output."},
- { LLDB_OPT_SET_1 , false, "append-outfile" , 'A', no_argument, NULL, 0, eArgTypeNone , "Append to the the file specified with '--outfile <path>'."},
+ { LLDB_OPT_SET_1 , false, "append-outfile" , 'apnd', no_argument, NULL, 0, eArgTypeNone , "Append to the the file specified with '--outfile <path>'."},
};
uint32_t
@@ -49,11 +49,11 @@
Error
OptionGroupOutputFile::SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg)
+ uint32_t option_idx,
+ const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
@@ -61,7 +61,7 @@
error = m_file.SetValueFromCString (option_arg);
break;
- case 'A':
+ case 'apnd':
m_append.SetCurrentValue(true);
break;
diff --git a/source/Interpreter/OptionGroupPlatform.cpp b/source/Interpreter/OptionGroupPlatform.cpp
index 358dc01..152ab4d 100644
--- a/source/Interpreter/OptionGroupPlatform.cpp
+++ b/source/Interpreter/OptionGroupPlatform.cpp
@@ -113,7 +113,7 @@
if (!m_include_platform_option)
++option_idx;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
diff --git a/source/Interpreter/OptionGroupString.cpp b/source/Interpreter/OptionGroupString.cpp
index 7440fd4..ee96239 100644
--- a/source/Interpreter/OptionGroupString.cpp
+++ b/source/Interpreter/OptionGroupString.cpp
@@ -20,7 +20,7 @@
OptionGroupString::OptionGroupString (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text,
diff --git a/source/Interpreter/OptionGroupUInt64.cpp b/source/Interpreter/OptionGroupUInt64.cpp
index 76d0260..e6996f7 100644
--- a/source/Interpreter/OptionGroupUInt64.cpp
+++ b/source/Interpreter/OptionGroupUInt64.cpp
@@ -20,7 +20,7 @@
OptionGroupUInt64::OptionGroupUInt64 (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text,
diff --git a/source/Interpreter/OptionGroupUUID.cpp b/source/Interpreter/OptionGroupUUID.cpp
index 48b0edf..14bdc84 100644
--- a/source/Interpreter/OptionGroupUUID.cpp
+++ b/source/Interpreter/OptionGroupUUID.cpp
@@ -47,11 +47,11 @@
Error
OptionGroupUUID::SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg)
+ uint32_t option_idx,
+ const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
diff --git a/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
index 2d734a1..532ddc6 100644
--- a/source/Interpreter/OptionGroupValueObjectDisplay.cpp
+++ b/source/Interpreter/OptionGroupValueObjectDisplay.cpp
@@ -64,7 +64,7 @@
const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
bool success = false;
switch (short_option)
diff --git a/source/Interpreter/OptionGroupVariable.cpp b/source/Interpreter/OptionGroupVariable.cpp
index 9c1cf21..151bc89 100644
--- a/source/Interpreter/OptionGroupVariable.cpp
+++ b/source/Interpreter/OptionGroupVariable.cpp
@@ -24,14 +24,14 @@
static OptionDefinition
g_option_table[] =
{
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-args", 'a', no_argument, NULL, 0, eArgTypeNone, "Omit function arguments."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-locals", 'l', no_argument, NULL, 0, eArgTypeNone, "Omit local variables."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-globals", 'g', no_argument, NULL, 0, eArgTypeNone, "Show the current frame source file global and static variables."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-declaration",'c', no_argument, NULL, 0, eArgTypeNone, "Show variable declaration information (source file and line where the variable was declared)."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeRegularExpression, "The <variable-name> argument for name lookups are regular expressions."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "scope", 's', no_argument, NULL, 0, eArgTypeNone, "Show variable scope (argument, local, global, static)."},
- { LLDB_OPT_SET_1, false, "summary", 'y', required_argument, NULL, 0, eArgTypeName, "Specify the summary that the variable output should use."},
- { LLDB_OPT_SET_2, false, "summary-string", 'z', required_argument, NULL, 0, eArgTypeName, "Specify a summary string to use to format the variable output."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-args", 'a', no_argument, NULL, 0, eArgTypeNone, "Omit function arguments."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-locals", 'l', no_argument, NULL, 0, eArgTypeNone, "Omit local variables."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-globals", 'g', no_argument, NULL, 0, eArgTypeNone, "Show the current frame source file global and static variables."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-declaration",'c', no_argument, NULL, 0, eArgTypeNone, "Show variable declaration information (source file and line where the variable was declared)."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeRegularExpression, "The <variable-name> argument for name lookups are regular expressions."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "scope", 's', no_argument, NULL, 0, eArgTypeNone, "Show variable scope (argument, local, global, static)."},
+ { LLDB_OPT_SET_1, false, "summary", 'y', required_argument, NULL, 0, eArgTypeName, "Specify the summary that the variable output should use."},
+ { LLDB_OPT_SET_2, false, "summary-string", 'z', required_argument, NULL, 0, eArgTypeName, "Specify a summary string to use to format the variable output."},
};
@@ -53,7 +53,7 @@
Error error;
if (!include_frame_options)
option_idx += 3;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
case 'r': use_regex = true; break;
diff --git a/source/Interpreter/OptionGroupWatchpoint.cpp b/source/Interpreter/OptionGroupWatchpoint.cpp
index aa5b000..e352a0e 100644
--- a/source/Interpreter/OptionGroupWatchpoint.cpp
+++ b/source/Interpreter/OptionGroupWatchpoint.cpp
@@ -73,7 +73,7 @@
const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
case 'w':
diff --git a/source/Interpreter/Options.cpp b/source/Interpreter/Options.cpp
index 4a04a46..dfb0ab7 100644
--- a/source/Interpreter/Options.cpp
+++ b/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 @@
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 @@
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;
- if (option_seen.test(short_opt) == false)
+ 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.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 @@
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 @@
// 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_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_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 @@
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 @@
{
// 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 @@
// 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))
{
- if (opt_defs[i].short_option == option)
- {
- found = true;
- //Print out the help information for this option.
-
- // Put a newline separation between arguments
- if (first_option_printed)
- first_option_printed = 0;
- 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);
- }
+ PrintOption (opt_defs[i], eDisplayShortOption, NULL, NULL, false, strm);
+ PrintOption (opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
}
+ else
+ {
+ // 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++)
+ {
+ 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);
}
// Restore the indent level