1 //===-- Options.cpp -------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Interpreter/Options.h"
16 #include "lldb/Host/OptionParser.h"
17 #include "lldb/Interpreter/CommandCompletions.h"
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Interpreter/CommandObject.h"
20 #include "lldb/Interpreter/CommandReturnObject.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Utility/StreamString.h"
23 #include "llvm/ADT/STLExtras.h"
26 using namespace lldb_private
;
29 Options::Options() { BuildValidOptionSets(); }
31 Options::~Options() = default;
33 void Options::NotifyOptionParsingStarting(ExecutionContext
*execution_context
) {
34 m_seen_options
.clear();
35 // Let the subclass reset its option values
36 OptionParsingStarting(execution_context
);
40 Options::NotifyOptionParsingFinished(ExecutionContext
*execution_context
) {
41 return OptionParsingFinished(execution_context
);
44 void Options::OptionSeen(int option_idx
) { m_seen_options
.insert(option_idx
); }
46 // Returns true is set_a is a subset of set_b; Otherwise returns false.
48 bool Options::IsASubset(const OptionSet
&set_a
, const OptionSet
&set_b
) {
49 bool is_a_subset
= true;
50 OptionSet::const_iterator pos_a
;
51 OptionSet::const_iterator pos_b
;
53 // set_a is a subset of set_b if every member of set_a is also a member of
56 for (pos_a
= set_a
.begin(); pos_a
!= set_a
.end() && is_a_subset
; ++pos_a
) {
57 pos_b
= set_b
.find(*pos_a
);
58 if (pos_b
== set_b
.end())
65 // Returns the set difference set_a - set_b, i.e. { x | ElementOf (x, set_a) &&
66 // !ElementOf (x, set_b) }
68 size_t Options::OptionsSetDiff(const OptionSet
&set_a
, const OptionSet
&set_b
,
71 OptionSet::const_iterator pos_a
;
72 OptionSet::const_iterator pos_b
;
74 for (pos_a
= set_a
.begin(); pos_a
!= set_a
.end(); ++pos_a
) {
75 pos_b
= set_b
.find(*pos_a
);
76 if (pos_b
== set_b
.end()) {
85 // Returns the union of set_a and set_b. Does not put duplicate members into
88 void Options::OptionsSetUnion(const OptionSet
&set_a
, const OptionSet
&set_b
,
89 OptionSet
&union_set
) {
90 OptionSet::const_iterator pos
;
91 OptionSet::iterator pos_union
;
93 // Put all the elements of set_a into the union.
95 for (pos
= set_a
.begin(); pos
!= set_a
.end(); ++pos
)
96 union_set
.insert(*pos
);
98 // Put all the elements of set_b that are not already there into the union.
99 for (pos
= set_b
.begin(); pos
!= set_b
.end(); ++pos
) {
100 pos_union
= union_set
.find(*pos
);
101 if (pos_union
== union_set
.end())
102 union_set
.insert(*pos
);
106 bool Options::VerifyOptions(CommandReturnObject
&result
) {
107 bool options_are_valid
= false;
109 int num_levels
= GetRequiredOptions().size();
111 for (int i
= 0; i
< num_levels
&& !options_are_valid
; ++i
) {
112 // This is the correct set of options if: 1). m_seen_options contains
113 // all of m_required_options[i] (i.e. all the required options at this
114 // level are a subset of m_seen_options); AND 2). { m_seen_options -
115 // m_required_options[i] is a subset of m_options_options[i] (i.e. all
116 // the rest of m_seen_options are in the set of optional options at this
119 // Check to see if all of m_required_options[i] are a subset of
121 if (IsASubset(GetRequiredOptions()[i
], m_seen_options
)) {
122 // Construct the set difference: remaining_options = {m_seen_options} -
123 // {m_required_options[i]}
124 OptionSet remaining_options
;
125 OptionsSetDiff(m_seen_options
, GetRequiredOptions()[i
],
127 // Check to see if remaining_options is a subset of
128 // m_optional_options[i]
129 if (IsASubset(remaining_options
, GetOptionalOptions()[i
]))
130 options_are_valid
= true;
134 options_are_valid
= true;
137 if (options_are_valid
) {
138 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
140 result
.AppendError("invalid combination of options for the given command");
143 return options_are_valid
;
146 // This is called in the Options constructor, though we could call it lazily if
147 // that ends up being a performance problem.
149 void Options::BuildValidOptionSets() {
150 // Check to see if we already did this.
151 if (m_required_options
.size() != 0)
154 // Check to see if there are any options.
155 int num_options
= NumCommandOptions();
156 if (num_options
== 0)
159 auto opt_defs
= GetDefinitions();
160 m_required_options
.resize(1);
161 m_optional_options
.resize(1);
163 // First count the number of option sets we've got. Ignore
164 // LLDB_ALL_OPTION_SETS...
166 uint32_t num_option_sets
= 0;
168 for (const auto &def
: opt_defs
) {
169 uint32_t this_usage_mask
= def
.usage_mask
;
170 if (this_usage_mask
== LLDB_OPT_SET_ALL
) {
171 if (num_option_sets
== 0)
174 for (uint32_t j
= 0; j
< LLDB_MAX_NUM_OPTION_SETS
; j
++) {
175 if (this_usage_mask
& (1 << j
)) {
176 if (num_option_sets
<= j
)
177 num_option_sets
= j
+ 1;
183 if (num_option_sets
> 0) {
184 m_required_options
.resize(num_option_sets
);
185 m_optional_options
.resize(num_option_sets
);
187 for (const auto &def
: opt_defs
) {
188 for (uint32_t j
= 0; j
< num_option_sets
; j
++) {
189 if (def
.usage_mask
& 1 << j
) {
191 m_required_options
[j
].insert(def
.short_option
);
193 m_optional_options
[j
].insert(def
.short_option
);
200 uint32_t Options::NumCommandOptions() { return GetDefinitions().size(); }
202 Option
*Options::GetLongOptions() {
203 // Check to see if this has already been done.
204 if (m_getopt_table
.empty()) {
205 auto defs
= GetDefinitions();
209 std::map
<int, uint32_t> option_seen
;
211 m_getopt_table
.resize(defs
.size() + 1);
212 for (size_t i
= 0; i
< defs
.size(); ++i
) {
213 const int short_opt
= defs
[i
].short_option
;
215 m_getopt_table
[i
].definition
= &defs
[i
];
216 m_getopt_table
[i
].flag
= nullptr;
217 m_getopt_table
[i
].val
= short_opt
;
219 if (option_seen
.find(short_opt
) == option_seen
.end()) {
220 option_seen
[short_opt
] = i
;
221 } else if (short_opt
) {
222 m_getopt_table
[i
].val
= 0;
223 std::map
<int, uint32_t>::const_iterator pos
=
224 option_seen
.find(short_opt
);
226 if (defs
[i
].HasShortOption())
227 Debugger::ReportError(
229 "option[{0}] --{1} has a short option -{2} that "
230 "conflicts with option[{3}] --{4}, short option won't "
232 i
, defs
[i
].long_option
, short_opt
, pos
->second
,
233 m_getopt_table
[pos
->second
].definition
->long_option
,
237 Debugger::ReportError(
239 "option[{0}] --{1} has a short option {2:x} that "
240 "conflicts with option[{3}] --{4}, short option won't "
242 (int)i
, defs
[i
].long_option
, short_opt
, pos
->second
,
243 m_getopt_table
[pos
->second
].definition
->long_option
,
249 // getopt_long_only requires a NULL final entry in the table:
251 m_getopt_table
.back().definition
= nullptr;
252 m_getopt_table
.back().flag
= nullptr;
253 m_getopt_table
.back().val
= 0;
256 if (m_getopt_table
.empty())
259 return &m_getopt_table
.front();
262 // This function takes INDENT, which tells how many spaces to output at the
263 // front of each line; SPACES, which is a string containing 80 spaces; and
264 // TEXT, which is the text that is to be output. It outputs the text, on
265 // multiple lines if necessary, to RESULT, with INDENT spaces at the front of
266 // each line. It breaks lines on spaces, tabs or newlines, shortening the line
267 // if necessary to not break in the middle of a word. It assumes that each
268 // output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
270 void Options::OutputFormattedUsageText(Stream
&strm
,
271 const OptionDefinition
&option_def
,
272 uint32_t output_max_columns
) {
273 std::string actual_text
;
274 if (option_def
.validator
) {
275 const char *condition
= option_def
.validator
->ShortConditionString();
278 actual_text
.append(condition
);
279 actual_text
.append("] ");
282 actual_text
.append(option_def
.usage_text
);
284 // Will it all fit on one line?
286 if (static_cast<uint32_t>(actual_text
.length() + strm
.GetIndentLevel()) <
287 output_max_columns
) {
288 // Output it as a single line.
289 strm
.Indent(actual_text
);
292 // We need to break it up into multiple lines.
294 int text_width
= output_max_columns
- strm
.GetIndentLevel() - 1;
297 int final_end
= actual_text
.length();
300 while (end
< final_end
) {
301 // Don't start the 'text' on a space, since we're already outputting the
303 while ((start
< final_end
) && (actual_text
[start
] == ' '))
306 end
= start
+ text_width
;
310 // If we're not at the end of the text, make sure we break the line on
312 while (end
> start
&& actual_text
[end
] != ' ' &&
313 actual_text
[end
] != '\t' && actual_text
[end
] != '\n')
317 sub_len
= end
- start
;
321 assert(start
< final_end
);
322 assert(start
+ sub_len
<= final_end
);
323 strm
.Write(actual_text
.c_str() + start
, sub_len
);
330 bool Options::SupportsLongOption(const char *long_option
) {
331 if (!long_option
|| !long_option
[0])
334 auto opt_defs
= GetDefinitions();
335 if (opt_defs
.empty())
338 const char *long_option_name
= long_option
;
339 if (long_option
[0] == '-' && long_option
[1] == '-')
340 long_option_name
+= 2;
342 for (auto &def
: opt_defs
) {
343 if (!def
.long_option
)
346 if (strcmp(def
.long_option
, long_option_name
) == 0)
353 enum OptionDisplayType
{
359 static bool PrintOption(const OptionDefinition
&opt_def
,
360 OptionDisplayType display_type
, const char *header
,
361 const char *footer
, bool show_optional
, Stream
&strm
) {
362 if (display_type
== eDisplayShortOption
&& !opt_def
.HasShortOption())
365 if (header
&& header
[0])
366 strm
.PutCString(header
);
368 if (show_optional
&& !opt_def
.required
)
370 const bool show_short_option
=
371 opt_def
.HasShortOption() && display_type
!= eDisplayLongOption
;
372 if (show_short_option
)
373 strm
.Printf("-%c", opt_def
.short_option
);
375 strm
.Printf("--%s", opt_def
.long_option
);
376 switch (opt_def
.option_has_arg
) {
377 case OptionParser::eNoArgument
:
379 case OptionParser::eRequiredArgument
:
380 strm
.Printf(" <%s>", CommandObject::GetArgumentName(opt_def
.argument_type
));
383 case OptionParser::eOptionalArgument
:
384 strm
.Printf("%s[<%s>]", show_short_option
? "" : "=",
385 CommandObject::GetArgumentName(opt_def
.argument_type
));
388 if (show_optional
&& !opt_def
.required
)
390 if (footer
&& footer
[0])
391 strm
.PutCString(footer
);
395 void Options::GenerateOptionUsage(Stream
&strm
, CommandObject
&cmd
,
396 uint32_t screen_width
) {
397 auto opt_defs
= GetDefinitions();
398 const uint32_t save_indent_level
= strm
.GetIndentLevel();
399 llvm::StringRef name
= cmd
.GetCommandName();
400 StreamString arguments_str
;
401 cmd
.GetFormattedCommandArguments(arguments_str
);
403 const uint32_t num_options
= NumCommandOptions();
404 if (num_options
== 0)
407 const bool only_print_args
= cmd
.IsDashDashCommand();
408 if (!only_print_args
)
409 strm
.PutCString("\nCommand Options Usage:\n");
413 // First, show each usage level set of options, e.g. <cmd> [options-for-
416 // [options-for-level-1]
419 if (!only_print_args
) {
420 uint32_t num_option_sets
= GetRequiredOptions().size();
421 for (uint32_t opt_set
= 0; opt_set
< num_option_sets
; ++opt_set
) {
426 // Different option sets may require different args.
427 StreamString args_str
;
428 uint32_t opt_set_mask
= 1 << opt_set
;
429 cmd
.GetFormattedCommandArguments(args_str
, opt_set_mask
);
431 // First go through and print all options that take no arguments as a
432 // single string. If a command has "-a" "-b" and "-c", this will show up
435 // We use a set here so that they will be sorted.
436 std::set
<int> required_options
;
437 std::set
<int> optional_options
;
439 for (auto &def
: opt_defs
) {
440 if (def
.usage_mask
& opt_set_mask
&& def
.HasShortOption() &&
441 def
.option_has_arg
== OptionParser::eNoArgument
) {
443 required_options
.insert(def
.short_option
);
445 optional_options
.insert(def
.short_option
);
450 if (!required_options
.empty()) {
451 strm
.PutCString(" -");
452 for (int short_option
: required_options
)
453 strm
.PutChar(short_option
);
456 if (!optional_options
.empty()) {
457 strm
.PutCString(" [-");
458 for (int short_option
: optional_options
)
459 strm
.PutChar(short_option
);
463 // First go through and print the required options (list them up front).
464 for (auto &def
: opt_defs
) {
465 if (def
.usage_mask
& opt_set_mask
&& def
.HasShortOption() &&
466 def
.required
&& def
.option_has_arg
!= OptionParser::eNoArgument
)
467 PrintOption(def
, eDisplayBestOption
, " ", nullptr, true, strm
);
470 // Now go through again, and this time only print the optional options.
471 for (auto &def
: opt_defs
) {
472 if (def
.usage_mask
& opt_set_mask
&& !def
.required
&&
473 def
.option_has_arg
!= OptionParser::eNoArgument
)
474 PrintOption(def
, eDisplayBestOption
, " ", nullptr, true, strm
);
477 if (args_str
.GetSize() > 0) {
478 if (cmd
.WantsRawCommandString())
480 strm
<< " " << args_str
.GetString();
485 if ((only_print_args
|| cmd
.WantsRawCommandString()) &&
486 arguments_str
.GetSize() > 0) {
487 if (!only_print_args
)
490 strm
<< " " << arguments_str
.GetString();
493 if (!only_print_args
) {
496 // Now print out all the detailed information about the various options:
497 // long form, short form and help text:
498 // -short <argument> ( --long_name <argument> )
503 // Put the command options in a sorted container, so we can output
504 // them alphabetically by short_option.
505 std::multimap
<int, uint32_t> options_ordered
;
506 for (auto def
: llvm::enumerate(opt_defs
))
507 options_ordered
.insert(
508 std::make_pair(def
.value().short_option
, def
.index()));
510 // Go through each option, find the table entry and write out the detailed
511 // help information for that option.
513 bool first_option_printed
= false;
515 for (auto pos
: options_ordered
) {
516 // Put a newline separation between arguments
517 if (first_option_printed
)
520 first_option_printed
= true;
522 OptionDefinition opt_def
= opt_defs
[pos
.second
];
525 if (opt_def
.short_option
&& opt_def
.HasShortOption()) {
526 PrintOption(opt_def
, eDisplayShortOption
, nullptr, nullptr, false,
528 PrintOption(opt_def
, eDisplayLongOption
, " ( ", " )", false, strm
);
530 // Short option is not printable, just print long option
531 PrintOption(opt_def
, eDisplayLongOption
, nullptr, nullptr, false, strm
);
537 if (opt_def
.usage_text
)
538 OutputFormattedUsageText(strm
, opt_def
, screen_width
);
539 if (!opt_def
.enum_values
.empty()) {
541 strm
.Printf("Values: ");
542 bool is_first
= true;
543 for (const auto &enum_value
: opt_def
.enum_values
) {
545 strm
.Printf("%s", enum_value
.string_value
);
549 strm
.Printf(" | %s", enum_value
.string_value
);
557 // Restore the indent level
558 strm
.SetIndentLevel(save_indent_level
);
561 // This function is called when we have been given a potentially incomplete set
562 // of options, such as when an alias has been defined (more options might be
563 // added at at the time the alias is invoked). We need to verify that the
564 // options in the set m_seen_options are all part of a set that may be used
565 // together, but m_seen_options may be missing some of the "required" options.
567 bool Options::VerifyPartialOptions(CommandReturnObject
&result
) {
568 bool options_are_valid
= false;
570 int num_levels
= GetRequiredOptions().size();
572 for (int i
= 0; i
< num_levels
&& !options_are_valid
; ++i
) {
573 // In this case we are treating all options as optional rather than
574 // required. Therefore a set of options is correct if m_seen_options is a
575 // subset of the union of m_required_options and m_optional_options.
577 OptionsSetUnion(GetRequiredOptions()[i
], GetOptionalOptions()[i
],
579 if (IsASubset(m_seen_options
, union_set
))
580 options_are_valid
= true;
584 return options_are_valid
;
587 bool Options::HandleOptionCompletion(CompletionRequest
&request
,
588 OptionElementVector
&opt_element_vector
,
589 CommandInterpreter
&interpreter
) {
590 // For now we just scan the completions to see if the cursor position is in
591 // an option or its argument. Otherwise we'll call HandleArgumentCompletion.
592 // In the future we can use completion to validate options as well if we
595 auto opt_defs
= GetDefinitions();
597 llvm::StringRef cur_opt_str
= request
.GetCursorArgumentPrefix();
599 for (size_t i
= 0; i
< opt_element_vector
.size(); i
++) {
600 size_t opt_pos
= static_cast<size_t>(opt_element_vector
[i
].opt_pos
);
601 size_t opt_arg_pos
= static_cast<size_t>(opt_element_vector
[i
].opt_arg_pos
);
602 int opt_defs_index
= opt_element_vector
[i
].opt_defs_index
;
603 if (opt_pos
== request
.GetCursorIndex()) {
604 // We're completing the option itself.
606 if (opt_defs_index
== OptionArgElement::eBareDash
) {
607 // We're completing a bare dash. That means all options are open.
608 // FIXME: We should scan the other options provided and only complete
610 // within the option group they belong to.
611 std::string opt_str
= "-a";
613 for (auto &def
: opt_defs
) {
614 if (!def
.short_option
)
616 opt_str
[1] = def
.short_option
;
617 request
.AddCompletion(opt_str
, def
.usage_text
);
621 } else if (opt_defs_index
== OptionArgElement::eBareDoubleDash
) {
622 std::string
full_name("--");
623 for (auto &def
: opt_defs
) {
624 if (!def
.short_option
)
627 full_name
.erase(full_name
.begin() + 2, full_name
.end());
628 full_name
.append(def
.long_option
);
629 request
.AddCompletion(full_name
, def
.usage_text
);
632 } else if (opt_defs_index
!= OptionArgElement::eUnrecognizedArg
) {
633 // We recognized it, if it an incomplete long option, complete it
634 // anyway (getopt_long_only is happy with shortest unique string, but
635 // it's still a nice thing to do.) Otherwise return The string so the
636 // upper level code will know this is a full match and add the " ".
637 const OptionDefinition
&opt
= opt_defs
[opt_defs_index
];
638 llvm::StringRef long_option
= opt
.long_option
;
639 if (cur_opt_str
.startswith("--") && cur_opt_str
!= long_option
) {
640 request
.AddCompletion("--" + long_option
.str(), opt
.usage_text
);
643 request
.AddCompletion(request
.GetCursorArgumentPrefix());
646 // FIXME - not handling wrong options yet:
647 // Check to see if they are writing a long option & complete it.
648 // I think we will only get in here if the long option table has two
650 // that are not unique up to this point. getopt_long_only does
651 // shortest unique match for long options already.
652 if (cur_opt_str
.consume_front("--")) {
653 for (auto &def
: opt_defs
) {
654 llvm::StringRef
long_option(def
.long_option
);
655 if (long_option
.startswith(cur_opt_str
))
656 request
.AddCompletion("--" + long_option
.str(), def
.usage_text
);
662 } else if (opt_arg_pos
== request
.GetCursorIndex()) {
663 // Okay the cursor is on the completion of an argument. See if it has a
664 // completion, otherwise return no matches.
665 if (opt_defs_index
!= -1) {
666 HandleOptionArgumentCompletion(request
, opt_element_vector
, i
,
670 // No completion callback means no completions...
675 // Not the last element, keep going.
682 void Options::HandleOptionArgumentCompletion(
683 CompletionRequest
&request
, OptionElementVector
&opt_element_vector
,
684 int opt_element_index
, CommandInterpreter
&interpreter
) {
685 auto opt_defs
= GetDefinitions();
686 std::unique_ptr
<SearchFilter
> filter_up
;
688 int opt_defs_index
= opt_element_vector
[opt_element_index
].opt_defs_index
;
690 // See if this is an enumeration type option, and if so complete it here:
692 const auto &enum_values
= opt_defs
[opt_defs_index
].enum_values
;
693 if (!enum_values
.empty())
694 for (const auto &enum_value
: enum_values
)
695 request
.TryCompleteCurrentArg(enum_value
.string_value
);
697 // If this is a source file or symbol type completion, and there is a -shlib
698 // option somewhere in the supplied arguments, then make a search filter for
699 // that shared library.
700 // FIXME: Do we want to also have an "OptionType" so we don't have to match
703 uint32_t completion_mask
= opt_defs
[opt_defs_index
].completion_type
;
705 if (completion_mask
== 0) {
706 lldb::CommandArgumentType option_arg_type
=
707 opt_defs
[opt_defs_index
].argument_type
;
708 if (option_arg_type
!= eArgTypeNone
) {
709 const CommandObject::ArgumentTableEntry
*arg_entry
=
710 CommandObject::FindArgumentDataByType(
711 opt_defs
[opt_defs_index
].argument_type
);
713 completion_mask
= arg_entry
->completion_type
;
717 if (completion_mask
& lldb::eSourceFileCompletion
||
718 completion_mask
& lldb::eSymbolCompletion
) {
719 for (size_t i
= 0; i
< opt_element_vector
.size(); i
++) {
720 int cur_defs_index
= opt_element_vector
[i
].opt_defs_index
;
722 // trying to use <0 indices will definitely cause problems
723 if (cur_defs_index
== OptionArgElement::eUnrecognizedArg
||
724 cur_defs_index
== OptionArgElement::eBareDash
||
725 cur_defs_index
== OptionArgElement::eBareDoubleDash
)
728 int cur_arg_pos
= opt_element_vector
[i
].opt_arg_pos
;
729 const char *cur_opt_name
= opt_defs
[cur_defs_index
].long_option
;
731 // If this is the "shlib" option and there was an argument provided,
732 // restrict it to that shared library.
733 if (cur_opt_name
&& strcmp(cur_opt_name
, "shlib") == 0 &&
735 const char *module_name
=
736 request
.GetParsedLine().GetArgumentAtIndex(cur_arg_pos
);
738 FileSpec
module_spec(module_name
);
739 lldb::TargetSP target_sp
=
740 interpreter
.GetDebugger().GetSelectedTarget();
741 // Search filters require a target...
744 std::make_unique
<SearchFilterByModule
>(target_sp
, module_spec
);
751 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
752 interpreter
, completion_mask
, request
, filter_up
.get());
755 void OptionGroupOptions::Append(OptionGroup
*group
) {
756 auto group_option_defs
= group
->GetDefinitions();
757 for (uint32_t i
= 0; i
< group_option_defs
.size(); ++i
) {
758 m_option_infos
.push_back(OptionInfo(group
, i
));
759 m_option_defs
.push_back(group_option_defs
[i
]);
763 const OptionGroup
*OptionGroupOptions::GetGroupWithOption(char short_opt
) {
764 for (uint32_t i
= 0; i
< m_option_defs
.size(); i
++) {
765 OptionDefinition opt_def
= m_option_defs
[i
];
766 if (opt_def
.short_option
== short_opt
)
767 return m_option_infos
[i
].option_group
;
772 void OptionGroupOptions::Append(OptionGroup
*group
, uint32_t src_mask
,
774 auto group_option_defs
= group
->GetDefinitions();
775 for (uint32_t i
= 0; i
< group_option_defs
.size(); ++i
) {
776 if (group_option_defs
[i
].usage_mask
& src_mask
) {
777 m_option_infos
.push_back(OptionInfo(group
, i
));
778 m_option_defs
.push_back(group_option_defs
[i
]);
779 m_option_defs
.back().usage_mask
= dst_mask
;
784 void OptionGroupOptions::Append(
785 OptionGroup
*group
, llvm::ArrayRef
<llvm::StringRef
> exclude_long_options
) {
786 auto group_option_defs
= group
->GetDefinitions();
787 for (uint32_t i
= 0; i
< group_option_defs
.size(); ++i
) {
788 const auto &definition
= group_option_defs
[i
];
789 if (llvm::is_contained(exclude_long_options
, definition
.long_option
))
792 m_option_infos
.push_back(OptionInfo(group
, i
));
793 m_option_defs
.push_back(definition
);
797 void OptionGroupOptions::Finalize() {
798 m_did_finalize
= true;
801 Status
OptionGroupOptions::SetOptionValue(uint32_t option_idx
,
802 llvm::StringRef option_value
,
803 ExecutionContext
*execution_context
) {
804 // After calling OptionGroupOptions::Append(...), you must finalize the
805 // groups by calling OptionGroupOptions::Finlize()
806 assert(m_did_finalize
);
808 if (option_idx
< m_option_infos
.size()) {
809 error
= m_option_infos
[option_idx
].option_group
->SetOptionValue(
810 m_option_infos
[option_idx
].option_index
, option_value
,
814 error
.SetErrorString("invalid option index"); // Shouldn't happen...
819 void OptionGroupOptions::OptionParsingStarting(
820 ExecutionContext
*execution_context
) {
821 std::set
<OptionGroup
*> group_set
;
822 OptionInfos::iterator pos
, end
= m_option_infos
.end();
823 for (pos
= m_option_infos
.begin(); pos
!= end
; ++pos
) {
824 OptionGroup
*group
= pos
->option_group
;
825 if (group_set
.find(group
) == group_set
.end()) {
826 group
->OptionParsingStarting(execution_context
);
827 group_set
.insert(group
);
832 OptionGroupOptions::OptionParsingFinished(ExecutionContext
*execution_context
) {
833 std::set
<OptionGroup
*> group_set
;
835 OptionInfos::iterator pos
, end
= m_option_infos
.end();
836 for (pos
= m_option_infos
.begin(); pos
!= end
; ++pos
) {
837 OptionGroup
*group
= pos
->option_group
;
838 if (group_set
.find(group
) == group_set
.end()) {
839 error
= group
->OptionParsingFinished(execution_context
);
840 group_set
.insert(group
);
848 // OptionParser permutes the arguments while processing them, so we create a
849 // temporary array holding to avoid modification of the input arguments. The
850 // options themselves are never modified, but the API expects a char * anyway,
851 // hence the const_cast.
852 static std::vector
<char *> GetArgvForParsing(const Args
&args
) {
853 std::vector
<char *> result
;
854 // OptionParser always skips the first argument as it is based on getopt().
855 result
.push_back(const_cast<char *>("<FAKE-ARG0>"));
856 for (const Args::ArgEntry
&entry
: args
)
857 result
.push_back(const_cast<char *>(entry
.c_str()));
858 result
.push_back(nullptr);
862 // Given a permuted argument, find it's position in the original Args vector.
863 static Args::const_iterator
FindOriginalIter(const char *arg
,
864 const Args
&original
) {
865 return llvm::find_if(
866 original
, [arg
](const Args::ArgEntry
&D
) { return D
.c_str() == arg
; });
869 // Given a permuted argument, find it's index in the original Args vector.
870 static size_t FindOriginalIndex(const char *arg
, const Args
&original
) {
871 return std::distance(original
.begin(), FindOriginalIter(arg
, original
));
874 // Construct a new Args object, consisting of the entries from the original
875 // arguments, but in the permuted order.
876 static Args
ReconstituteArgsAfterParsing(llvm::ArrayRef
<char *> parsed
,
877 const Args
&original
) {
879 for (const char *arg
: parsed
) {
880 auto pos
= FindOriginalIter(arg
, original
);
881 assert(pos
!= original
.end());
882 result
.AppendArgument(pos
->ref(), pos
->GetQuoteChar());
887 static size_t FindArgumentIndexForOption(const Args
&args
,
888 const Option
&long_option
) {
889 std::string short_opt
= llvm::formatv("-{0}", char(long_option
.val
)).str();
890 std::string long_opt
=
891 std::string(llvm::formatv("--{0}", long_option
.definition
->long_option
));
892 for (const auto &entry
: llvm::enumerate(args
)) {
893 if (entry
.value().ref().startswith(short_opt
) ||
894 entry
.value().ref().startswith(long_opt
))
895 return entry
.index();
901 static std::string
BuildShortOptions(const Option
*long_options
) {
903 llvm::raw_string_ostream
sstr(storage
);
905 // Leading : tells getopt to return a : for a missing option argument AND to
906 // suppress error messages.
909 for (size_t i
= 0; long_options
[i
].definition
!= nullptr; ++i
) {
910 if (long_options
[i
].flag
== nullptr) {
911 sstr
<< (char)long_options
[i
].val
;
912 switch (long_options
[i
].definition
->option_has_arg
) {
914 case OptionParser::eNoArgument
:
916 case OptionParser::eRequiredArgument
:
919 case OptionParser::eOptionalArgument
:
925 return std::move(sstr
.str());
928 llvm::Expected
<Args
> Options::ParseAlias(const Args
&args
,
929 OptionArgVector
*option_arg_vector
,
930 std::string
&input_line
) {
931 Option
*long_options
= GetLongOptions();
933 if (long_options
== nullptr) {
934 return llvm::make_error
<llvm::StringError
>("Invalid long options",
935 llvm::inconvertibleErrorCode());
938 std::string short_options
= BuildShortOptions(long_options
);
940 Args args_copy
= args
;
941 std::vector
<char *> argv
= GetArgvForParsing(args
);
943 std::unique_lock
<std::mutex
> lock
;
944 OptionParser::Prepare(lock
);
947 int long_options_index
= -1;
948 val
= OptionParser::Parse(argv
, short_options
, long_options
,
949 &long_options_index
);
952 return llvm::createStringError(llvm::inconvertibleErrorCode(),
953 "last option requires an argument");
960 return llvm::make_error
<llvm::StringError
>(
961 "Unknown or ambiguous option", llvm::inconvertibleErrorCode());
969 // Look up the long option index
970 if (long_options_index
== -1) {
971 for (int j
= 0; long_options
[j
].definition
|| long_options
[j
].flag
||
974 if (long_options
[j
].val
== val
) {
975 long_options_index
= j
;
981 // See if the option takes an argument, and see if one was supplied.
982 if (long_options_index
== -1) {
983 return llvm::make_error
<llvm::StringError
>(
984 llvm::formatv("Invalid option with value '{0}'.", char(val
)).str(),
985 llvm::inconvertibleErrorCode());
988 StreamString option_str
;
989 option_str
.Printf("-%c", val
);
990 const OptionDefinition
*def
= long_options
[long_options_index
].definition
;
992 (def
== nullptr) ? OptionParser::eNoArgument
: def
->option_has_arg
;
994 const char *option_arg
= nullptr;
996 case OptionParser::eRequiredArgument
:
997 if (OptionParser::GetOptionArgument() == nullptr) {
998 return llvm::make_error
<llvm::StringError
>(
999 llvm::formatv("Option '{0}' is missing argument specifier.",
1000 option_str
.GetString())
1002 llvm::inconvertibleErrorCode());
1005 case OptionParser::eOptionalArgument
:
1006 option_arg
= OptionParser::GetOptionArgument();
1008 case OptionParser::eNoArgument
:
1011 return llvm::make_error
<llvm::StringError
>(
1012 llvm::formatv("error with options table; invalid value in has_arg "
1013 "field for option '{0}'.",
1016 llvm::inconvertibleErrorCode());
1018 // Find option in the argument list; also see if it was supposed to take an
1019 // argument and if one was supplied. Remove option (and argument, if
1020 // given) from the argument list. Also remove them from the
1021 // raw_input_string, if one was passed in.
1022 // Note: We also need to preserve any option argument values that were
1023 // surrounded by backticks, as we lose track of them in the
1024 // option_args_vector.
1026 FindArgumentIndexForOption(args_copy
, long_options
[long_options_index
]);
1027 std::string option_to_insert
;
1029 if (idx
!= size_t(-1) && has_arg
) {
1030 bool arg_has_backtick
= args_copy
[idx
+ 1].GetQuoteChar() == '`';
1031 if (arg_has_backtick
)
1032 option_to_insert
= "`";
1033 option_to_insert
+= option_arg
;
1034 if (arg_has_backtick
)
1035 option_to_insert
+= "`";
1037 option_to_insert
= option_arg
;
1039 option_to_insert
= CommandInterpreter::g_no_argument
;
1041 option_arg_vector
->emplace_back(std::string(option_str
.GetString()),
1042 has_arg
, option_to_insert
);
1044 if (idx
== size_t(-1))
1047 if (!input_line
.empty()) {
1048 llvm::StringRef tmp_arg
= args_copy
[idx
].ref();
1049 size_t pos
= input_line
.find(std::string(tmp_arg
));
1050 if (pos
!= std::string::npos
)
1051 input_line
.erase(pos
, tmp_arg
.size());
1053 args_copy
.DeleteArgumentAtIndex(idx
);
1054 if ((option_to_insert
!= CommandInterpreter::g_no_argument
) &&
1055 (OptionParser::GetOptionArgument() != nullptr) &&
1056 (idx
< args_copy
.GetArgumentCount()) &&
1057 (args_copy
[idx
].ref() == OptionParser::GetOptionArgument())) {
1058 if (input_line
.size() > 0) {
1059 size_t pos
= input_line
.find(option_to_insert
);
1060 if (pos
!= std::string::npos
)
1061 input_line
.erase(pos
, option_to_insert
.size());
1063 args_copy
.DeleteArgumentAtIndex(idx
);
1067 return std::move(args_copy
);
1070 OptionElementVector
Options::ParseForCompletion(const Args
&args
,
1071 uint32_t cursor_index
) {
1072 OptionElementVector option_element_vector
;
1073 Option
*long_options
= GetLongOptions();
1074 option_element_vector
.clear();
1076 if (long_options
== nullptr)
1077 return option_element_vector
;
1079 std::string short_options
= BuildShortOptions(long_options
);
1081 std::unique_lock
<std::mutex
> lock
;
1082 OptionParser::Prepare(lock
);
1083 OptionParser::EnableError(false);
1086 auto opt_defs
= GetDefinitions();
1088 std::vector
<char *> dummy_vec
= GetArgvForParsing(args
);
1090 bool failed_once
= false;
1091 uint32_t dash_dash_pos
= -1;
1094 bool missing_argument
= false;
1095 int long_options_index
= -1;
1097 val
= OptionParser::Parse(dummy_vec
, short_options
, long_options
,
1098 &long_options_index
);
1101 // When we're completing a "--" which is the last option on line,
1107 // If this is a bare "--" we mark it as such so we can complete it
1108 // successfully later. Handling the "--" is a little tricky, since that
1109 // may mean end of options or arguments, or the user might want to
1110 // complete options by long name. I make this work by checking whether
1111 // the cursor is in the "--" argument, and if so I assume we're
1112 // completing the long option, otherwise I let it pass to
1113 // OptionParser::Parse which will terminate the option parsing. Note, in
1114 // either case we continue parsing the line so we can figure out what
1115 // other options were passed. This will be useful when we come to
1116 // restricting completions based on what other options we've seen on the
1119 if (static_cast<size_t>(OptionParser::GetOptionIndex()) <
1121 (strcmp(dummy_vec
[OptionParser::GetOptionIndex() - 1], "--") == 0)) {
1122 dash_dash_pos
= FindOriginalIndex(
1123 dummy_vec
[OptionParser::GetOptionIndex() - 1], args
);
1124 if (dash_dash_pos
== cursor_index
) {
1125 option_element_vector
.push_back(
1126 OptionArgElement(OptionArgElement::eBareDoubleDash
, dash_dash_pos
,
1127 OptionArgElement::eBareDoubleDash
));
1133 } else if (val
== '?') {
1134 option_element_vector
.push_back(OptionArgElement(
1135 OptionArgElement::eUnrecognizedArg
,
1136 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1138 OptionArgElement::eUnrecognizedArg
));
1140 } else if (val
== 0) {
1142 } else if (val
== ':') {
1143 // This is a missing argument.
1144 val
= OptionParser::GetOptionErrorCause();
1145 missing_argument
= true;
1150 // Look up the long option index
1151 if (long_options_index
== -1) {
1152 for (int j
= 0; long_options
[j
].definition
|| long_options
[j
].flag
||
1153 long_options
[j
].val
;
1155 if (long_options
[j
].val
== val
) {
1156 long_options_index
= j
;
1162 // See if the option takes an argument, and see if one was supplied.
1163 if (long_options_index
>= 0) {
1164 int opt_defs_index
= -1;
1165 for (size_t i
= 0; i
< opt_defs
.size(); i
++) {
1166 if (opt_defs
[i
].short_option
!= val
)
1172 const OptionDefinition
*def
= long_options
[long_options_index
].definition
;
1174 (def
== nullptr) ? OptionParser::eNoArgument
: def
->option_has_arg
;
1176 case OptionParser::eNoArgument
:
1177 option_element_vector
.push_back(OptionArgElement(
1179 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1183 case OptionParser::eRequiredArgument
:
1184 if (OptionParser::GetOptionArgument() != nullptr) {
1186 if (missing_argument
)
1189 arg_index
= OptionParser::GetOptionIndex() - 2;
1191 option_element_vector
.push_back(OptionArgElement(
1193 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 2],
1197 option_element_vector
.push_back(OptionArgElement(
1199 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1204 case OptionParser::eOptionalArgument
:
1205 if (OptionParser::GetOptionArgument() != nullptr) {
1206 option_element_vector
.push_back(OptionArgElement(
1208 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 2],
1210 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1213 option_element_vector
.push_back(OptionArgElement(
1215 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 2],
1217 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1222 // The options table is messed up. Here we'll just continue
1223 option_element_vector
.push_back(OptionArgElement(
1224 OptionArgElement::eUnrecognizedArg
,
1225 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1227 OptionArgElement::eUnrecognizedArg
));
1231 option_element_vector
.push_back(OptionArgElement(
1232 OptionArgElement::eUnrecognizedArg
,
1233 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1235 OptionArgElement::eUnrecognizedArg
));
1239 // Finally we have to handle the case where the cursor index points at a
1240 // single "-". We want to mark that in the option_element_vector, but only
1241 // if it is not after the "--". But it turns out that OptionParser::Parse
1242 // just ignores an isolated "-". So we have to look it up by hand here. We
1243 // only care if it is AT the cursor position. Note, a single quoted dash is
1244 // not the same as a single dash...
1246 const Args::ArgEntry
&cursor
= args
[cursor_index
];
1247 if ((static_cast<int32_t>(dash_dash_pos
) == -1 ||
1248 cursor_index
< dash_dash_pos
) &&
1249 !cursor
.IsQuoted() && cursor
.ref() == "-") {
1250 option_element_vector
.push_back(
1251 OptionArgElement(OptionArgElement::eBareDash
, cursor_index
,
1252 OptionArgElement::eBareDash
));
1254 return option_element_vector
;
1257 llvm::Expected
<Args
> Options::Parse(const Args
&args
,
1258 ExecutionContext
*execution_context
,
1259 lldb::PlatformSP platform_sp
,
1260 bool require_validation
) {
1262 Option
*long_options
= GetLongOptions();
1263 if (long_options
== nullptr) {
1264 return llvm::make_error
<llvm::StringError
>("Invalid long options.",
1265 llvm::inconvertibleErrorCode());
1268 std::string short_options
= BuildShortOptions(long_options
);
1269 std::vector
<char *> argv
= GetArgvForParsing(args
);
1270 std::unique_lock
<std::mutex
> lock
;
1271 OptionParser::Prepare(lock
);
1274 int long_options_index
= -1;
1275 val
= OptionParser::Parse(argv
, short_options
, long_options
,
1276 &long_options_index
);
1279 error
.SetErrorString("last option requires an argument");
1286 // Did we get an error?
1288 error
.SetErrorString("unknown or ambiguous option");
1291 // The option auto-set itself
1297 // Lookup the long option index
1298 if (long_options_index
== -1) {
1299 for (int i
= 0; long_options
[i
].definition
|| long_options
[i
].flag
||
1300 long_options
[i
].val
;
1302 if (long_options
[i
].val
== val
) {
1303 long_options_index
= i
;
1308 // Call the callback with the option
1309 if (long_options_index
>= 0 &&
1310 long_options
[long_options_index
].definition
) {
1311 const OptionDefinition
*def
= long_options
[long_options_index
].definition
;
1314 // User did not pass in an explicit platform. Try to grab from the
1315 // execution context.
1316 TargetSP target_sp
=
1317 execution_context
? execution_context
->GetTargetSP() : TargetSP();
1318 platform_sp
= target_sp
? target_sp
->GetPlatform() : PlatformSP();
1320 OptionValidator
*validator
= def
->validator
;
1322 if (!platform_sp
&& require_validation
) {
1323 // Caller requires validation but we cannot validate as we don't have
1324 // the mandatory platform against which to validate.
1325 return llvm::make_error
<llvm::StringError
>(
1326 "cannot validate options: no platform available",
1327 llvm::inconvertibleErrorCode());
1330 bool validation_failed
= false;
1332 // Ensure we have an execution context, empty or not.
1333 ExecutionContext dummy_context
;
1334 ExecutionContext
*exe_ctx_p
=
1335 execution_context
? execution_context
: &dummy_context
;
1336 if (validator
&& !validator
->IsValid(*platform_sp
, *exe_ctx_p
)) {
1337 validation_failed
= true;
1338 error
.SetErrorStringWithFormat("Option \"%s\" invalid. %s",
1340 def
->validator
->LongConditionString());
1344 // As long as validation didn't fail, we set the option value.
1345 if (!validation_failed
)
1347 SetOptionValue(long_options_index
,
1348 (def
->option_has_arg
== OptionParser::eNoArgument
)
1350 : OptionParser::GetOptionArgument(),
1352 // If the Option setting returned an error, we should stop parsing
1353 // and return the error.
1357 error
.SetErrorStringWithFormat("invalid option with value '%i'", val
);
1362 return error
.ToError();
1365 argv
.erase(argv
.begin(), argv
.begin() + OptionParser::GetOptionIndex());
1366 return ReconstituteArgsAfterParsing(argv
, args
);