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/DiagnosticsRendering.h"
23 #include "lldb/Utility/StreamString.h"
24 #include "llvm/ADT/STLExtras.h"
27 using namespace lldb_private
;
29 namespace lldb_private
{
31 /// An llvm::Error that represents an option parsing diagnostic.
32 class OptionParseError
33 : public llvm::ErrorInfo
<OptionParseError
, DiagnosticError
> {
34 std::vector
<DiagnosticDetail
> m_details
;
37 using llvm::ErrorInfo
<OptionParseError
, DiagnosticError
>::ErrorInfo
;
38 OptionParseError(DiagnosticDetail detail
)
39 : ErrorInfo(std::error_code(EINVAL
, std::generic_category())),
40 m_details({detail
}) {}
41 OptionParseError(const Args::ArgEntry
&arg
, std::string msg
)
42 : ErrorInfo(std::error_code(EINVAL
, std::generic_category())) {
43 DiagnosticDetail::SourceLocation sloc
;
44 if (auto pos
= arg
.GetPos()) {
45 uint16_t len
= arg
.GetLength();
46 sloc
= {FileSpec
{}, 1, *pos
, len
, false, true};
48 m_details
.push_back(DiagnosticDetail
{sloc
, lldb::eSeverityError
, msg
, msg
});
50 std::unique_ptr
<CloneableError
> Clone() const override
{
51 return std::make_unique
<OptionParseError
>(m_details
[0]);
53 llvm::ArrayRef
<DiagnosticDetail
> GetDetails() const override
{
59 char OptionParseError::ID
;
61 } // namespace lldb_private
64 Options::Options() { BuildValidOptionSets(); }
66 Options::~Options() = default;
68 void Options::NotifyOptionParsingStarting(ExecutionContext
*execution_context
) {
69 m_seen_options
.clear();
70 // Let the subclass reset its option values
71 OptionParsingStarting(execution_context
);
75 Options::NotifyOptionParsingFinished(ExecutionContext
*execution_context
) {
76 return OptionParsingFinished(execution_context
);
79 void Options::OptionSeen(int option_idx
) { m_seen_options
.insert(option_idx
); }
81 // Returns true is set_a is a subset of set_b; Otherwise returns false.
83 bool Options::IsASubset(const OptionSet
&set_a
, const OptionSet
&set_b
) {
84 bool is_a_subset
= true;
85 OptionSet::const_iterator pos_a
;
86 OptionSet::const_iterator pos_b
;
88 // set_a is a subset of set_b if every member of set_a is also a member of
91 for (pos_a
= set_a
.begin(); pos_a
!= set_a
.end() && is_a_subset
; ++pos_a
) {
92 pos_b
= set_b
.find(*pos_a
);
93 if (pos_b
== set_b
.end())
100 // Returns the set difference set_a - set_b, i.e. { x | ElementOf (x, set_a) &&
101 // !ElementOf (x, set_b) }
103 size_t Options::OptionsSetDiff(const OptionSet
&set_a
, const OptionSet
&set_b
,
105 size_t num_diffs
= 0;
106 OptionSet::const_iterator pos_a
;
107 OptionSet::const_iterator pos_b
;
109 for (pos_a
= set_a
.begin(); pos_a
!= set_a
.end(); ++pos_a
) {
110 pos_b
= set_b
.find(*pos_a
);
111 if (pos_b
== set_b
.end()) {
113 diffs
.insert(*pos_a
);
120 // Returns the union of set_a and set_b. Does not put duplicate members into
123 void Options::OptionsSetUnion(const OptionSet
&set_a
, const OptionSet
&set_b
,
124 OptionSet
&union_set
) {
125 OptionSet::const_iterator pos
;
126 OptionSet::iterator pos_union
;
128 // Put all the elements of set_a into the union.
130 for (pos
= set_a
.begin(); pos
!= set_a
.end(); ++pos
)
131 union_set
.insert(*pos
);
133 // Put all the elements of set_b that are not already there into the union.
134 for (pos
= set_b
.begin(); pos
!= set_b
.end(); ++pos
) {
135 pos_union
= union_set
.find(*pos
);
136 if (pos_union
== union_set
.end())
137 union_set
.insert(*pos
);
141 bool Options::VerifyOptions(CommandReturnObject
&result
) {
142 bool options_are_valid
= false;
144 int num_levels
= GetRequiredOptions().size();
146 for (int i
= 0; i
< num_levels
&& !options_are_valid
; ++i
) {
147 // This is the correct set of options if: 1). m_seen_options contains
148 // all of m_required_options[i] (i.e. all the required options at this
149 // level are a subset of m_seen_options); AND 2). { m_seen_options -
150 // m_required_options[i] is a subset of m_options_options[i] (i.e. all
151 // the rest of m_seen_options are in the set of optional options at this
154 // Check to see if all of m_required_options[i] are a subset of
156 if (IsASubset(GetRequiredOptions()[i
], m_seen_options
)) {
157 // Construct the set difference: remaining_options = {m_seen_options} -
158 // {m_required_options[i]}
159 OptionSet remaining_options
;
160 OptionsSetDiff(m_seen_options
, GetRequiredOptions()[i
],
162 // Check to see if remaining_options is a subset of
163 // m_optional_options[i]
164 if (IsASubset(remaining_options
, GetOptionalOptions()[i
]))
165 options_are_valid
= true;
169 options_are_valid
= true;
172 if (options_are_valid
) {
173 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
175 result
.AppendError("invalid combination of options for the given command");
178 return options_are_valid
;
181 // This is called in the Options constructor, though we could call it lazily if
182 // that ends up being a performance problem.
184 void Options::BuildValidOptionSets() {
185 // Check to see if we already did this.
186 if (m_required_options
.size() != 0)
189 // Check to see if there are any options.
190 int num_options
= NumCommandOptions();
191 if (num_options
== 0)
194 auto opt_defs
= GetDefinitions();
195 m_required_options
.resize(1);
196 m_optional_options
.resize(1);
198 // First count the number of option sets we've got. Ignore
199 // LLDB_ALL_OPTION_SETS...
201 uint32_t num_option_sets
= 0;
203 for (const auto &def
: opt_defs
) {
204 uint32_t this_usage_mask
= def
.usage_mask
;
205 if (this_usage_mask
== LLDB_OPT_SET_ALL
) {
206 if (num_option_sets
== 0)
209 for (uint32_t j
= 0; j
< LLDB_MAX_NUM_OPTION_SETS
; j
++) {
210 if (this_usage_mask
& (1 << j
)) {
211 if (num_option_sets
<= j
)
212 num_option_sets
= j
+ 1;
218 if (num_option_sets
> 0) {
219 m_required_options
.resize(num_option_sets
);
220 m_optional_options
.resize(num_option_sets
);
222 for (const auto &def
: opt_defs
) {
223 for (uint32_t j
= 0; j
< num_option_sets
; j
++) {
224 if (def
.usage_mask
& 1 << j
) {
226 m_required_options
[j
].insert(def
.short_option
);
228 m_optional_options
[j
].insert(def
.short_option
);
235 uint32_t Options::NumCommandOptions() { return GetDefinitions().size(); }
237 Option
*Options::GetLongOptions() {
238 // Check to see if this has already been done.
239 if (m_getopt_table
.empty()) {
240 auto defs
= GetDefinitions();
244 std::map
<int, uint32_t> option_seen
;
246 m_getopt_table
.resize(defs
.size() + 1);
247 for (size_t i
= 0; i
< defs
.size(); ++i
) {
248 const int short_opt
= defs
[i
].short_option
;
250 m_getopt_table
[i
].definition
= &defs
[i
];
251 m_getopt_table
[i
].flag
= nullptr;
252 m_getopt_table
[i
].val
= short_opt
;
254 auto [pos
, inserted
] = option_seen
.try_emplace(short_opt
, i
);
255 if (!inserted
&& short_opt
) {
256 m_getopt_table
[i
].val
= 0;
258 if (defs
[i
].HasShortOption())
259 Debugger::ReportError(
261 "option[{0}] --{1} has a short option -{2} that "
262 "conflicts with option[{3}] --{4}, short option won't "
264 i
, defs
[i
].long_option
, short_opt
, pos
->second
,
265 m_getopt_table
[pos
->second
].definition
->long_option
,
269 Debugger::ReportError(
271 "option[{0}] --{1} has a short option {2:x} that "
272 "conflicts with option[{3}] --{4}, short option won't "
274 (int)i
, defs
[i
].long_option
, short_opt
, pos
->second
,
275 m_getopt_table
[pos
->second
].definition
->long_option
,
281 // getopt_long_only requires a NULL final entry in the table:
283 m_getopt_table
.back().definition
= nullptr;
284 m_getopt_table
.back().flag
= nullptr;
285 m_getopt_table
.back().val
= 0;
288 if (m_getopt_table
.empty())
291 return &m_getopt_table
.front();
294 // This function takes INDENT, which tells how many spaces to output at the
295 // front of each line; SPACES, which is a string containing 80 spaces; and
296 // TEXT, which is the text that is to be output. It outputs the text, on
297 // multiple lines if necessary, to RESULT, with INDENT spaces at the front of
298 // each line. It breaks lines on spaces, tabs or newlines, shortening the line
299 // if necessary to not break in the middle of a word. It assumes that each
300 // output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
302 void Options::OutputFormattedUsageText(Stream
&strm
,
303 const OptionDefinition
&option_def
,
304 uint32_t output_max_columns
) {
305 std::string actual_text
;
306 if (option_def
.validator
) {
307 const char *condition
= option_def
.validator
->ShortConditionString();
310 actual_text
.append(condition
);
311 actual_text
.append("] ");
314 actual_text
.append(option_def
.usage_text
);
316 // Will it all fit on one line?
318 if (static_cast<uint32_t>(actual_text
.length() + strm
.GetIndentLevel()) <
319 output_max_columns
) {
320 // Output it as a single line.
321 strm
.Indent(actual_text
);
324 // We need to break it up into multiple lines.
326 int text_width
= output_max_columns
- strm
.GetIndentLevel() - 1;
329 int final_end
= actual_text
.length();
332 while (end
< final_end
) {
333 // Don't start the 'text' on a space, since we're already outputting the
335 while ((start
< final_end
) && (actual_text
[start
] == ' '))
338 end
= start
+ text_width
;
342 // If we're not at the end of the text, make sure we break the line on
344 while (end
> start
&& actual_text
[end
] != ' ' &&
345 actual_text
[end
] != '\t' && actual_text
[end
] != '\n')
349 sub_len
= end
- start
;
353 assert(start
< final_end
);
354 assert(start
+ sub_len
<= final_end
);
355 strm
.Write(actual_text
.c_str() + start
, sub_len
);
362 bool Options::SupportsLongOption(const char *long_option
) {
363 if (!long_option
|| !long_option
[0])
366 auto opt_defs
= GetDefinitions();
367 if (opt_defs
.empty())
370 const char *long_option_name
= long_option
;
371 if (long_option
[0] == '-' && long_option
[1] == '-')
372 long_option_name
+= 2;
374 for (auto &def
: opt_defs
) {
375 if (!def
.long_option
)
378 if (strcmp(def
.long_option
, long_option_name
) == 0)
385 enum OptionDisplayType
{
391 static bool PrintOption(const OptionDefinition
&opt_def
,
392 OptionDisplayType display_type
, const char *header
,
393 const char *footer
, bool show_optional
, Stream
&strm
) {
394 if (display_type
== eDisplayShortOption
&& !opt_def
.HasShortOption())
397 if (header
&& header
[0])
398 strm
.PutCString(header
);
400 if (show_optional
&& !opt_def
.required
)
402 const bool show_short_option
=
403 opt_def
.HasShortOption() && display_type
!= eDisplayLongOption
;
404 if (show_short_option
)
405 strm
.Printf("-%c", opt_def
.short_option
);
407 strm
.Printf("--%s", opt_def
.long_option
);
408 switch (opt_def
.option_has_arg
) {
409 case OptionParser::eNoArgument
:
411 case OptionParser::eRequiredArgument
:
412 strm
.Printf(" <%s>", CommandObject::GetArgumentName(opt_def
.argument_type
));
415 case OptionParser::eOptionalArgument
:
416 strm
.Printf("%s[<%s>]", show_short_option
? "" : "=",
417 CommandObject::GetArgumentName(opt_def
.argument_type
));
420 if (show_optional
&& !opt_def
.required
)
422 if (footer
&& footer
[0])
423 strm
.PutCString(footer
);
427 void Options::GenerateOptionUsage(Stream
&strm
, CommandObject
&cmd
,
428 uint32_t screen_width
) {
429 auto opt_defs
= GetDefinitions();
430 const uint32_t save_indent_level
= strm
.GetIndentLevel();
431 llvm::StringRef name
= cmd
.GetCommandName();
432 StreamString arguments_str
;
433 cmd
.GetFormattedCommandArguments(arguments_str
);
435 const uint32_t num_options
= NumCommandOptions();
436 if (num_options
== 0)
439 const bool only_print_args
= cmd
.IsDashDashCommand();
440 if (!only_print_args
)
441 strm
.PutCString("\nCommand Options Usage:\n");
445 // First, show each usage level set of options, e.g. <cmd> [options-for-
448 // [options-for-level-1]
451 if (!only_print_args
) {
452 uint32_t num_option_sets
= GetRequiredOptions().size();
453 for (uint32_t opt_set
= 0; opt_set
< num_option_sets
; ++opt_set
) {
458 // Different option sets may require different args.
459 StreamString args_str
;
460 uint32_t opt_set_mask
= 1 << opt_set
;
461 cmd
.GetFormattedCommandArguments(args_str
, opt_set_mask
);
463 // First go through and print all options that take no arguments as a
464 // single string. If a command has "-a" "-b" and "-c", this will show up
467 // We use a set here so that they will be sorted.
468 std::set
<int> required_options
;
469 std::set
<int> optional_options
;
471 for (auto &def
: opt_defs
) {
472 if (def
.usage_mask
& opt_set_mask
&& def
.HasShortOption() &&
473 def
.option_has_arg
== OptionParser::eNoArgument
) {
475 required_options
.insert(def
.short_option
);
477 optional_options
.insert(def
.short_option
);
482 if (!required_options
.empty()) {
483 strm
.PutCString(" -");
484 for (int short_option
: required_options
)
485 strm
.PutChar(short_option
);
488 if (!optional_options
.empty()) {
489 strm
.PutCString(" [-");
490 for (int short_option
: optional_options
)
491 strm
.PutChar(short_option
);
495 // First go through and print the required options (list them up front).
496 for (auto &def
: opt_defs
) {
497 if (def
.usage_mask
& opt_set_mask
&& def
.HasShortOption() &&
498 def
.required
&& def
.option_has_arg
!= OptionParser::eNoArgument
)
499 PrintOption(def
, eDisplayBestOption
, " ", nullptr, true, strm
);
502 // Now go through again, and this time only print the optional options.
503 for (auto &def
: opt_defs
) {
504 if (def
.usage_mask
& opt_set_mask
&& !def
.required
&&
505 def
.option_has_arg
!= OptionParser::eNoArgument
)
506 PrintOption(def
, eDisplayBestOption
, " ", nullptr, true, strm
);
509 if (args_str
.GetSize() > 0) {
510 if (cmd
.WantsRawCommandString())
512 strm
<< " " << args_str
.GetString();
517 if ((only_print_args
|| cmd
.WantsRawCommandString()) &&
518 arguments_str
.GetSize() > 0) {
519 if (!only_print_args
)
522 strm
<< " " << arguments_str
.GetString();
525 if (!only_print_args
) {
528 // Now print out all the detailed information about the various options:
529 // long form, short form and help text:
530 // -short <argument> ( --long_name <argument> )
535 // Put the command options in a sorted container, so we can output
536 // them alphabetically by short_option.
537 std::multimap
<int, uint32_t> options_ordered
;
538 for (auto def
: llvm::enumerate(opt_defs
))
539 options_ordered
.insert(
540 std::make_pair(def
.value().short_option
, def
.index()));
542 // Go through each option, find the table entry and write out the detailed
543 // help information for that option.
545 bool first_option_printed
= false;
547 for (auto pos
: options_ordered
) {
548 // Put a newline separation between arguments
549 if (first_option_printed
)
552 first_option_printed
= true;
554 OptionDefinition opt_def
= opt_defs
[pos
.second
];
557 if (opt_def
.short_option
&& opt_def
.HasShortOption()) {
558 PrintOption(opt_def
, eDisplayShortOption
, nullptr, nullptr, false,
560 PrintOption(opt_def
, eDisplayLongOption
, " ( ", " )", false, strm
);
562 // Short option is not printable, just print long option
563 PrintOption(opt_def
, eDisplayLongOption
, nullptr, nullptr, false, strm
);
569 if (opt_def
.usage_text
)
570 OutputFormattedUsageText(strm
, opt_def
, screen_width
);
571 if (!opt_def
.enum_values
.empty()) {
573 strm
.Printf("Values: ");
574 bool is_first
= true;
575 for (const auto &enum_value
: opt_def
.enum_values
) {
577 strm
.Printf("%s", enum_value
.string_value
);
581 strm
.Printf(" | %s", enum_value
.string_value
);
589 // Restore the indent level
590 strm
.SetIndentLevel(save_indent_level
);
593 // This function is called when we have been given a potentially incomplete set
594 // of options, such as when an alias has been defined (more options might be
595 // added at at the time the alias is invoked). We need to verify that the
596 // options in the set m_seen_options are all part of a set that may be used
597 // together, but m_seen_options may be missing some of the "required" options.
599 bool Options::VerifyPartialOptions(CommandReturnObject
&result
) {
600 bool options_are_valid
= false;
602 int num_levels
= GetRequiredOptions().size();
604 for (int i
= 0; i
< num_levels
&& !options_are_valid
; ++i
) {
605 // In this case we are treating all options as optional rather than
606 // required. Therefore a set of options is correct if m_seen_options is a
607 // subset of the union of m_required_options and m_optional_options.
609 OptionsSetUnion(GetRequiredOptions()[i
], GetOptionalOptions()[i
],
611 if (IsASubset(m_seen_options
, union_set
))
612 options_are_valid
= true;
616 return options_are_valid
;
619 bool Options::HandleOptionCompletion(CompletionRequest
&request
,
620 OptionElementVector
&opt_element_vector
,
621 CommandInterpreter
&interpreter
) {
622 // For now we just scan the completions to see if the cursor position is in
623 // an option or its argument. Otherwise we'll call HandleArgumentCompletion.
624 // In the future we can use completion to validate options as well if we
627 auto opt_defs
= GetDefinitions();
629 llvm::StringRef cur_opt_str
= request
.GetCursorArgumentPrefix();
631 for (size_t i
= 0; i
< opt_element_vector
.size(); i
++) {
632 size_t opt_pos
= static_cast<size_t>(opt_element_vector
[i
].opt_pos
);
633 size_t opt_arg_pos
= static_cast<size_t>(opt_element_vector
[i
].opt_arg_pos
);
634 int opt_defs_index
= opt_element_vector
[i
].opt_defs_index
;
635 if (opt_pos
== request
.GetCursorIndex()) {
636 // We're completing the option itself.
638 if (opt_defs_index
== OptionArgElement::eBareDash
) {
639 // We're completing a bare dash. That means all options are open.
640 // FIXME: We should scan the other options provided and only complete
642 // within the option group they belong to.
643 std::string opt_str
= "-a";
645 for (auto &def
: opt_defs
) {
646 if (!def
.short_option
)
648 opt_str
[1] = def
.short_option
;
649 request
.AddCompletion(opt_str
, def
.usage_text
);
653 } else if (opt_defs_index
== OptionArgElement::eBareDoubleDash
) {
654 std::string
full_name("--");
655 for (auto &def
: opt_defs
) {
656 if (!def
.short_option
)
659 full_name
.erase(full_name
.begin() + 2, full_name
.end());
660 full_name
.append(def
.long_option
);
661 request
.AddCompletion(full_name
, def
.usage_text
);
664 } else if (opt_defs_index
!= OptionArgElement::eUnrecognizedArg
) {
665 // We recognized it, if it an incomplete long option, complete it
666 // anyway (getopt_long_only is happy with shortest unique string, but
667 // it's still a nice thing to do.) Otherwise return The string so the
668 // upper level code will know this is a full match and add the " ".
669 const OptionDefinition
&opt
= opt_defs
[opt_defs_index
];
670 llvm::StringRef long_option
= opt
.long_option
;
671 if (cur_opt_str
.starts_with("--") && cur_opt_str
!= long_option
) {
672 request
.AddCompletion("--" + long_option
.str(), opt
.usage_text
);
675 request
.AddCompletion(request
.GetCursorArgumentPrefix());
678 // FIXME - not handling wrong options yet:
679 // Check to see if they are writing a long option & complete it.
680 // I think we will only get in here if the long option table has two
682 // that are not unique up to this point. getopt_long_only does
683 // shortest unique match for long options already.
684 if (cur_opt_str
.consume_front("--")) {
685 for (auto &def
: opt_defs
) {
686 llvm::StringRef
long_option(def
.long_option
);
687 if (long_option
.starts_with(cur_opt_str
))
688 request
.AddCompletion("--" + long_option
.str(), def
.usage_text
);
694 } else if (opt_arg_pos
== request
.GetCursorIndex()) {
695 // Okay the cursor is on the completion of an argument. See if it has a
696 // completion, otherwise return no matches. Note, opt_defs_index == -1
697 // means we're after an option, but that option doesn't exist. We'll
698 // end up treating that as an argument. Not sure we can do much better.
699 if (opt_defs_index
!= -1) {
700 HandleOptionArgumentCompletion(request
, opt_element_vector
, i
,
704 // No completion callback means no completions...
709 // Not the last element, keep going.
716 void Options::HandleOptionArgumentCompletion(
717 CompletionRequest
&request
, OptionElementVector
&opt_element_vector
,
718 int opt_element_index
, CommandInterpreter
&interpreter
) {
719 auto opt_defs
= GetDefinitions();
720 std::unique_ptr
<SearchFilter
> filter_up
;
722 int opt_defs_index
= opt_element_vector
[opt_element_index
].opt_defs_index
;
724 // See if this is an enumeration type option, and if so complete it here:
725 const auto &enum_values
= opt_defs
[opt_defs_index
].enum_values
;
726 if (!enum_values
.empty())
727 for (const auto &enum_value
: enum_values
)
728 request
.TryCompleteCurrentArg(enum_value
.string_value
);
730 // If this is a source file or symbol type completion, and there is a -shlib
731 // option somewhere in the supplied arguments, then make a search filter for
732 // that shared library.
733 // FIXME: Do we want to also have an "OptionType" so we don't have to match
736 uint32_t completion_mask
= opt_defs
[opt_defs_index
].completion_type
;
738 if (completion_mask
== 0) {
739 lldb::CommandArgumentType option_arg_type
=
740 opt_defs
[opt_defs_index
].argument_type
;
741 if (option_arg_type
!= eArgTypeNone
) {
742 const CommandObject::ArgumentTableEntry
*arg_entry
=
743 CommandObject::FindArgumentDataByType(
744 opt_defs
[opt_defs_index
].argument_type
);
746 completion_mask
= arg_entry
->completion_type
;
750 if (completion_mask
& lldb::eSourceFileCompletion
||
751 completion_mask
& lldb::eSymbolCompletion
) {
752 for (size_t i
= 0; i
< opt_element_vector
.size(); i
++) {
753 int cur_defs_index
= opt_element_vector
[i
].opt_defs_index
;
755 // trying to use <0 indices will definitely cause problems
756 if (cur_defs_index
== OptionArgElement::eUnrecognizedArg
||
757 cur_defs_index
== OptionArgElement::eBareDash
||
758 cur_defs_index
== OptionArgElement::eBareDoubleDash
)
761 int cur_arg_pos
= opt_element_vector
[i
].opt_arg_pos
;
762 const char *cur_opt_name
= opt_defs
[cur_defs_index
].long_option
;
764 // If this is the "shlib" option and there was an argument provided,
765 // restrict it to that shared library.
766 if (cur_opt_name
&& strcmp(cur_opt_name
, "shlib") == 0 &&
768 const char *module_name
=
769 request
.GetParsedLine().GetArgumentAtIndex(cur_arg_pos
);
771 FileSpec
module_spec(module_name
);
772 lldb::TargetSP target_sp
=
773 interpreter
.GetDebugger().GetSelectedTarget();
774 // Search filters require a target...
777 std::make_unique
<SearchFilterByModule
>(target_sp
, module_spec
);
784 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
785 interpreter
, completion_mask
, request
, filter_up
.get());
788 void OptionGroupOptions::Append(OptionGroup
*group
) {
789 auto group_option_defs
= group
->GetDefinitions();
790 for (uint32_t i
= 0; i
< group_option_defs
.size(); ++i
) {
791 m_option_infos
.push_back(OptionInfo(group
, i
));
792 m_option_defs
.push_back(group_option_defs
[i
]);
796 const OptionGroup
*OptionGroupOptions::GetGroupWithOption(char short_opt
) {
797 for (uint32_t i
= 0; i
< m_option_defs
.size(); i
++) {
798 OptionDefinition opt_def
= m_option_defs
[i
];
799 if (opt_def
.short_option
== short_opt
)
800 return m_option_infos
[i
].option_group
;
805 void OptionGroupOptions::Append(OptionGroup
*group
, uint32_t src_mask
,
807 auto group_option_defs
= group
->GetDefinitions();
808 for (uint32_t i
= 0; i
< group_option_defs
.size(); ++i
) {
809 if (group_option_defs
[i
].usage_mask
& src_mask
) {
810 m_option_infos
.push_back(OptionInfo(group
, i
));
811 m_option_defs
.push_back(group_option_defs
[i
]);
812 m_option_defs
.back().usage_mask
= dst_mask
;
817 void OptionGroupOptions::Append(
818 OptionGroup
*group
, llvm::ArrayRef
<llvm::StringRef
> exclude_long_options
) {
819 auto group_option_defs
= group
->GetDefinitions();
820 for (uint32_t i
= 0; i
< group_option_defs
.size(); ++i
) {
821 const auto &definition
= group_option_defs
[i
];
822 if (llvm::is_contained(exclude_long_options
, definition
.long_option
))
825 m_option_infos
.push_back(OptionInfo(group
, i
));
826 m_option_defs
.push_back(definition
);
830 void OptionGroupOptions::Finalize() {
831 m_did_finalize
= true;
834 Status
OptionGroupOptions::SetOptionValue(uint32_t option_idx
,
835 llvm::StringRef option_value
,
836 ExecutionContext
*execution_context
) {
837 // After calling OptionGroupOptions::Append(...), you must finalize the
838 // groups by calling OptionGroupOptions::Finlize()
839 assert(m_did_finalize
);
841 if (option_idx
< m_option_infos
.size()) {
842 error
= m_option_infos
[option_idx
].option_group
->SetOptionValue(
843 m_option_infos
[option_idx
].option_index
, option_value
,
848 Status::FromErrorString("invalid option index"); // Shouldn't happen...
853 void OptionGroupOptions::OptionParsingStarting(
854 ExecutionContext
*execution_context
) {
855 std::set
<OptionGroup
*> group_set
;
856 OptionInfos::iterator pos
, end
= m_option_infos
.end();
857 for (pos
= m_option_infos
.begin(); pos
!= end
; ++pos
) {
858 OptionGroup
*group
= pos
->option_group
;
859 if (group_set
.find(group
) == group_set
.end()) {
860 group
->OptionParsingStarting(execution_context
);
861 group_set
.insert(group
);
866 OptionGroupOptions::OptionParsingFinished(ExecutionContext
*execution_context
) {
867 std::set
<OptionGroup
*> group_set
;
869 OptionInfos::iterator pos
, end
= m_option_infos
.end();
870 for (pos
= m_option_infos
.begin(); pos
!= end
; ++pos
) {
871 OptionGroup
*group
= pos
->option_group
;
872 if (group_set
.find(group
) == group_set
.end()) {
873 error
= group
->OptionParsingFinished(execution_context
);
874 group_set
.insert(group
);
882 // OptionParser permutes the arguments while processing them, so we create a
883 // temporary array holding to avoid modification of the input arguments. The
884 // options themselves are never modified, but the API expects a char * anyway,
885 // hence the const_cast.
886 static std::vector
<char *> GetArgvForParsing(const Args
&args
) {
887 std::vector
<char *> result
;
888 // OptionParser always skips the first argument as it is based on getopt().
889 result
.push_back(const_cast<char *>("<FAKE-ARG0>"));
890 for (const Args::ArgEntry
&entry
: args
)
891 result
.push_back(const_cast<char *>(entry
.c_str()));
892 result
.push_back(nullptr);
896 // Given a permuted argument, find it's position in the original Args vector.
897 static Args::const_iterator
FindOriginalIter(const char *arg
,
898 const Args
&original
) {
899 return llvm::find_if(
900 original
, [arg
](const Args::ArgEntry
&D
) { return D
.c_str() == arg
; });
903 // Given a permuted argument, find it's index in the original Args vector.
904 static size_t FindOriginalIndex(const char *arg
, const Args
&original
) {
905 return std::distance(original
.begin(), FindOriginalIter(arg
, original
));
908 // Construct a new Args object, consisting of the entries from the original
909 // arguments, but in the permuted order.
910 static Args
ReconstituteArgsAfterParsing(llvm::ArrayRef
<char *> parsed
,
911 const Args
&original
) {
913 for (const char *arg
: parsed
) {
914 auto pos
= FindOriginalIter(arg
, original
);
915 assert(pos
!= original
.end());
916 result
.AppendArgument(pos
->ref(), pos
->GetQuoteChar());
921 static size_t FindArgumentIndexForOption(const Args
&args
,
922 const Option
&long_option
) {
923 std::string short_opt
= llvm::formatv("-{0}", char(long_option
.val
)).str();
924 std::string long_opt
=
925 std::string(llvm::formatv("--{0}", long_option
.definition
->long_option
));
926 for (const auto &entry
: llvm::enumerate(args
)) {
927 if (entry
.value().ref().starts_with(short_opt
) ||
928 entry
.value().ref().starts_with(long_opt
))
929 return entry
.index();
935 static std::string
BuildShortOptions(const Option
*long_options
) {
937 llvm::raw_string_ostream
sstr(storage
);
939 // Leading : tells getopt to return a : for a missing option argument AND to
940 // suppress error messages.
943 for (size_t i
= 0; long_options
[i
].definition
!= nullptr; ++i
) {
944 if (long_options
[i
].flag
== nullptr) {
945 sstr
<< (char)long_options
[i
].val
;
946 switch (long_options
[i
].definition
->option_has_arg
) {
948 case OptionParser::eNoArgument
:
950 case OptionParser::eRequiredArgument
:
953 case OptionParser::eOptionalArgument
:
962 llvm::Expected
<Args
> Options::ParseAlias(const Args
&args
,
963 OptionArgVector
*option_arg_vector
,
964 std::string
&input_line
) {
965 Option
*long_options
= GetLongOptions();
967 if (long_options
== nullptr) {
968 return llvm::createStringError("Invalid long options");
971 std::string short_options
= BuildShortOptions(long_options
);
973 Args args_copy
= args
;
974 std::vector
<char *> argv
= GetArgvForParsing(args
);
976 std::unique_lock
<std::mutex
> lock
;
977 OptionParser::Prepare(lock
);
980 int long_options_index
= -1;
981 val
= OptionParser::Parse(argv
, short_options
, long_options
,
982 &long_options_index
);
985 return llvm::createStringError(llvm::inconvertibleErrorCode(),
986 "last option requires an argument");
993 return llvm::createStringError("Unknown or ambiguous option");
1001 // Look up the long option index
1002 if (long_options_index
== -1) {
1003 for (int j
= 0; long_options
[j
].definition
|| long_options
[j
].flag
||
1004 long_options
[j
].val
;
1006 if (long_options
[j
].val
== val
) {
1007 long_options_index
= j
;
1013 // See if the option takes an argument, and see if one was supplied.
1014 if (long_options_index
== -1) {
1015 return llvm::createStringError(
1016 llvm::formatv("Invalid option with value '{0}'.", char(val
)).str());
1019 StreamString option_str
;
1020 option_str
.Printf("-%c", val
);
1021 const OptionDefinition
*def
= long_options
[long_options_index
].definition
;
1023 (def
== nullptr) ? OptionParser::eNoArgument
: def
->option_has_arg
;
1025 const char *option_arg
= nullptr;
1027 case OptionParser::eRequiredArgument
:
1028 if (OptionParser::GetOptionArgument() == nullptr) {
1029 return llvm::createStringError(
1030 llvm::formatv("Option '{0}' is missing argument specifier.",
1031 option_str
.GetString())
1035 case OptionParser::eOptionalArgument
:
1036 option_arg
= OptionParser::GetOptionArgument();
1038 case OptionParser::eNoArgument
:
1041 return llvm::createStringError(
1042 llvm::formatv("error with options table; invalid value in has_arg "
1043 "field for option '{0}'.",
1047 // Find option in the argument list; also see if it was supposed to take an
1048 // argument and if one was supplied. Remove option (and argument, if
1049 // given) from the argument list. Also remove them from the
1050 // raw_input_string, if one was passed in.
1051 // Note: We also need to preserve any option argument values that were
1052 // surrounded by backticks, as we lose track of them in the
1053 // option_args_vector.
1055 FindArgumentIndexForOption(args_copy
, long_options
[long_options_index
]);
1056 std::string option_to_insert
;
1058 if (idx
!= size_t(-1) && has_arg
) {
1059 bool arg_has_backtick
= args_copy
[idx
+ 1].GetQuoteChar() == '`';
1060 if (arg_has_backtick
)
1061 option_to_insert
= "`";
1062 option_to_insert
+= option_arg
;
1063 if (arg_has_backtick
)
1064 option_to_insert
+= "`";
1066 option_to_insert
= option_arg
;
1068 option_to_insert
= CommandInterpreter::g_no_argument
;
1070 option_arg_vector
->emplace_back(std::string(option_str
.GetString()),
1071 has_arg
, option_to_insert
);
1073 if (idx
== size_t(-1))
1076 if (!input_line
.empty()) {
1077 llvm::StringRef tmp_arg
= args_copy
[idx
].ref();
1078 size_t pos
= input_line
.find(std::string(tmp_arg
));
1079 if (pos
!= std::string::npos
)
1080 input_line
.erase(pos
, tmp_arg
.size());
1082 args_copy
.DeleteArgumentAtIndex(idx
);
1083 if ((option_to_insert
!= CommandInterpreter::g_no_argument
) &&
1084 (OptionParser::GetOptionArgument() != nullptr) &&
1085 (idx
< args_copy
.GetArgumentCount()) &&
1086 (args_copy
[idx
].ref() == OptionParser::GetOptionArgument())) {
1087 if (input_line
.size() > 0) {
1088 size_t pos
= input_line
.find(option_to_insert
);
1089 if (pos
!= std::string::npos
)
1090 input_line
.erase(pos
, option_to_insert
.size());
1092 args_copy
.DeleteArgumentAtIndex(idx
);
1096 return std::move(args_copy
);
1099 OptionElementVector
Options::ParseForCompletion(const Args
&args
,
1100 uint32_t cursor_index
) {
1101 OptionElementVector option_element_vector
;
1102 Option
*long_options
= GetLongOptions();
1103 option_element_vector
.clear();
1105 if (long_options
== nullptr)
1106 return option_element_vector
;
1108 std::string short_options
= BuildShortOptions(long_options
);
1110 std::unique_lock
<std::mutex
> lock
;
1111 OptionParser::Prepare(lock
);
1112 OptionParser::EnableError(false);
1115 auto opt_defs
= GetDefinitions();
1117 std::vector
<char *> dummy_vec
= GetArgvForParsing(args
);
1119 bool failed_once
= false;
1120 uint32_t dash_dash_pos
= -1;
1123 bool missing_argument
= false;
1124 int long_options_index
= -1;
1126 val
= OptionParser::Parse(dummy_vec
, short_options
, long_options
,
1127 &long_options_index
);
1130 // When we're completing a "--" which is the last option on line,
1136 // If this is a bare "--" we mark it as such so we can complete it
1137 // successfully later. Handling the "--" is a little tricky, since that
1138 // may mean end of options or arguments, or the user might want to
1139 // complete options by long name. I make this work by checking whether
1140 // the cursor is in the "--" argument, and if so I assume we're
1141 // completing the long option, otherwise I let it pass to
1142 // OptionParser::Parse which will terminate the option parsing. Note, in
1143 // either case we continue parsing the line so we can figure out what
1144 // other options were passed. This will be useful when we come to
1145 // restricting completions based on what other options we've seen on the
1148 if (static_cast<size_t>(OptionParser::GetOptionIndex()) <
1150 (strcmp(dummy_vec
[OptionParser::GetOptionIndex() - 1], "--") == 0)) {
1151 dash_dash_pos
= FindOriginalIndex(
1152 dummy_vec
[OptionParser::GetOptionIndex() - 1], args
);
1153 if (dash_dash_pos
== cursor_index
) {
1154 option_element_vector
.push_back(
1155 OptionArgElement(OptionArgElement::eBareDoubleDash
, dash_dash_pos
,
1156 OptionArgElement::eBareDoubleDash
));
1162 } else if (val
== '?') {
1163 option_element_vector
.push_back(OptionArgElement(
1164 OptionArgElement::eUnrecognizedArg
,
1165 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1167 OptionArgElement::eUnrecognizedArg
));
1169 } else if (val
== 0) {
1171 } else if (val
== ':') {
1172 // This is a missing argument.
1173 val
= OptionParser::GetOptionErrorCause();
1174 missing_argument
= true;
1179 // Look up the long option index
1180 if (long_options_index
== -1) {
1181 for (int j
= 0; long_options
[j
].definition
|| long_options
[j
].flag
||
1182 long_options
[j
].val
;
1184 if (long_options
[j
].val
== val
) {
1185 long_options_index
= j
;
1191 // See if the option takes an argument, and see if one was supplied.
1192 if (long_options_index
>= 0) {
1193 int opt_defs_index
= -1;
1194 for (size_t i
= 0; i
< opt_defs
.size(); i
++) {
1195 if (opt_defs
[i
].short_option
!= val
)
1201 const OptionDefinition
*def
= long_options
[long_options_index
].definition
;
1203 (def
== nullptr) ? OptionParser::eNoArgument
: def
->option_has_arg
;
1205 case OptionParser::eNoArgument
:
1206 option_element_vector
.push_back(OptionArgElement(
1208 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1212 case OptionParser::eRequiredArgument
:
1213 if (OptionParser::GetOptionArgument() != nullptr) {
1215 if (missing_argument
)
1218 arg_index
= OptionParser::GetOptionIndex() - 2;
1220 option_element_vector
.push_back(OptionArgElement(
1222 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 2],
1226 option_element_vector
.push_back(OptionArgElement(
1228 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1233 case OptionParser::eOptionalArgument
:
1234 option_element_vector
.push_back(OptionArgElement(
1236 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 2],
1238 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1242 // The options table is messed up. Here we'll just continue
1243 option_element_vector
.push_back(OptionArgElement(
1244 OptionArgElement::eUnrecognizedArg
,
1245 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1247 OptionArgElement::eUnrecognizedArg
));
1251 option_element_vector
.push_back(OptionArgElement(
1252 OptionArgElement::eUnrecognizedArg
,
1253 FindOriginalIndex(dummy_vec
[OptionParser::GetOptionIndex() - 1],
1255 OptionArgElement::eUnrecognizedArg
));
1259 // Finally we have to handle the case where the cursor index points at a
1260 // single "-". We want to mark that in the option_element_vector, but only
1261 // if it is not after the "--". But it turns out that OptionParser::Parse
1262 // just ignores an isolated "-". So we have to look it up by hand here. We
1263 // only care if it is AT the cursor position. Note, a single quoted dash is
1264 // not the same as a single dash...
1266 const Args::ArgEntry
&cursor
= args
[cursor_index
];
1267 if ((static_cast<int32_t>(dash_dash_pos
) == -1 ||
1268 cursor_index
< dash_dash_pos
) &&
1269 !cursor
.IsQuoted() && cursor
.ref() == "-") {
1270 option_element_vector
.push_back(
1271 OptionArgElement(OptionArgElement::eBareDash
, cursor_index
,
1272 OptionArgElement::eBareDash
));
1274 return option_element_vector
;
1277 llvm::Expected
<Args
> Options::Parse(const Args
&args
,
1278 ExecutionContext
*execution_context
,
1279 lldb::PlatformSP platform_sp
,
1280 bool require_validation
) {
1282 Option
*long_options
= GetLongOptions();
1283 if (long_options
== nullptr) {
1284 return llvm::createStringError("Invalid long options.");
1287 std::string short_options
= BuildShortOptions(long_options
);
1288 std::vector
<char *> argv
= GetArgvForParsing(args
);
1290 std::unique_lock
<std::mutex
> lock
;
1291 OptionParser::Prepare(lock
);
1293 int long_options_index
= -1;
1294 int val
= OptionParser::Parse(argv
, short_options
, long_options
,
1295 &long_options_index
);
1298 error
= Status::FromErrorString("last option requires an argument");
1305 // Did we get an error?
1307 // Account for "argv[0]" and that it points to the next option.
1308 int idx
= OptionParser::GetOptionIndex() - 2;
1309 if (idx
>= 0 && (size_t)idx
< args
.GetArgumentCount())
1310 error
= Status::FromError(llvm::make_error
<OptionParseError
>(
1311 args
[idx
], "unknown or ambiguous option"));
1313 error
= Status("unknown or ambiguous option");
1317 // The option auto-set itself
1323 // Lookup the long option index
1324 if (long_options_index
== -1) {
1325 for (int i
= 0; long_options
[i
].definition
|| long_options
[i
].flag
||
1326 long_options
[i
].val
;
1328 if (long_options
[i
].val
== val
) {
1329 long_options_index
= i
;
1334 // Call the callback with the option
1335 if (long_options_index
>= 0 &&
1336 long_options
[long_options_index
].definition
) {
1337 const OptionDefinition
*def
= long_options
[long_options_index
].definition
;
1340 // User did not pass in an explicit platform. Try to grab from the
1341 // execution context.
1342 TargetSP target_sp
=
1343 execution_context
? execution_context
->GetTargetSP() : TargetSP();
1344 platform_sp
= target_sp
? target_sp
->GetPlatform() : PlatformSP();
1346 OptionValidator
*validator
= def
->validator
;
1348 if (!platform_sp
&& require_validation
) {
1349 // Caller requires validation but we cannot validate as we don't have
1350 // the mandatory platform against which to validate.
1351 return llvm::createStringError(
1352 "cannot validate options: no platform available");
1355 bool validation_failed
= false;
1357 // Ensure we have an execution context, empty or not.
1358 ExecutionContext dummy_context
;
1359 ExecutionContext
*exe_ctx_p
=
1360 execution_context
? execution_context
: &dummy_context
;
1361 if (validator
&& !validator
->IsValid(*platform_sp
, *exe_ctx_p
)) {
1362 validation_failed
= true;
1363 error
= Status::FromErrorStringWithFormat(
1364 "Option \"%s\" invalid. %s", def
->long_option
,
1365 def
->validator
->LongConditionString());
1369 // As long as validation didn't fail, we set the option value.
1370 if (!validation_failed
)
1372 SetOptionValue(long_options_index
,
1373 (def
->option_has_arg
== OptionParser::eNoArgument
)
1375 : OptionParser::GetOptionArgument(),
1377 // If the Option setting returned an error, we should stop parsing
1378 // and return the error.
1382 error
= Status::FromErrorStringWithFormat(
1383 "invalid option with value '%i'", val
);
1388 return error
.ToError();
1391 argv
.erase(argv
.begin(), argv
.begin() + OptionParser::GetOptionIndex());
1392 return ReconstituteArgsAfterParsing(argv
, args
);
1395 llvm::Error
lldb_private::CreateOptionParsingError(
1396 llvm::StringRef option_arg
, const char short_option
,
1397 llvm::StringRef long_option
, llvm::StringRef additional_context
) {
1399 llvm::raw_string_ostream
stream(buffer
);
1400 stream
<< "Invalid value ('" << option_arg
<< "') for -" << short_option
;
1401 if (!long_option
.empty())
1402 stream
<< " (" << long_option
<< ")";
1403 if (!additional_context
.empty())
1404 stream
<< ": " << additional_context
;
1405 return llvm::createStringError(llvm::inconvertibleErrorCode(), buffer
);