1 //===-- Options.cpp -------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Interpreter/Options.h"
10 
11 #include <algorithm>
12 #include <bitset>
13 #include <map>
14 #include <set>
15 
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 
24 using namespace lldb;
25 using namespace lldb_private;
26 
27 // Options
28 Options::Options() { BuildValidOptionSets(); }
29 
30 Options::~Options() = default;
31 
32 void Options::NotifyOptionParsingStarting(ExecutionContext *execution_context) {
33   m_seen_options.clear();
34   // Let the subclass reset its option values
35   OptionParsingStarting(execution_context);
36 }
37 
38 Status
39 Options::NotifyOptionParsingFinished(ExecutionContext *execution_context) {
40   return OptionParsingFinished(execution_context);
41 }
42 
43 void Options::OptionSeen(int option_idx) { m_seen_options.insert(option_idx); }
44 
45 // Returns true is set_a is a subset of set_b;  Otherwise returns false.
46 
47 bool Options::IsASubset(const OptionSet &set_a, const OptionSet &set_b) {
48   bool is_a_subset = true;
49   OptionSet::const_iterator pos_a;
50   OptionSet::const_iterator pos_b;
51 
52   // set_a is a subset of set_b if every member of set_a is also a member of
53   // set_b
54 
55   for (pos_a = set_a.begin(); pos_a != set_a.end() && is_a_subset; ++pos_a) {
56     pos_b = set_b.find(*pos_a);
57     if (pos_b == set_b.end())
58       is_a_subset = false;
59   }
60 
61   return is_a_subset;
62 }
63 
64 // Returns the set difference set_a - set_b, i.e. { x | ElementOf (x, set_a) &&
65 // !ElementOf (x, set_b) }
66 
67 size_t Options::OptionsSetDiff(const OptionSet &set_a, const OptionSet &set_b,
68                                OptionSet &diffs) {
69   size_t num_diffs = 0;
70   OptionSet::const_iterator pos_a;
71   OptionSet::const_iterator pos_b;
72 
73   for (pos_a = set_a.begin(); pos_a != set_a.end(); ++pos_a) {
74     pos_b = set_b.find(*pos_a);
75     if (pos_b == set_b.end()) {
76       ++num_diffs;
77       diffs.insert(*pos_a);
78     }
79   }
80 
81   return num_diffs;
82 }
83 
84 // Returns the union of set_a and set_b.  Does not put duplicate members into
85 // the union.
86 
87 void Options::OptionsSetUnion(const OptionSet &set_a, const OptionSet &set_b,
88                               OptionSet &union_set) {
89   OptionSet::const_iterator pos;
90   OptionSet::iterator pos_union;
91 
92   // Put all the elements of set_a into the union.
93 
94   for (pos = set_a.begin(); pos != set_a.end(); ++pos)
95     union_set.insert(*pos);
96 
97   // Put all the elements of set_b that are not already there into the union.
98   for (pos = set_b.begin(); pos != set_b.end(); ++pos) {
99     pos_union = union_set.find(*pos);
100     if (pos_union == union_set.end())
101       union_set.insert(*pos);
102   }
103 }
104 
105 bool Options::VerifyOptions(CommandReturnObject &result) {
106   bool options_are_valid = false;
107 
108   int num_levels = GetRequiredOptions().size();
109   if (num_levels) {
110     for (int i = 0; i < num_levels && !options_are_valid; ++i) {
111       // This is the correct set of options if:  1). m_seen_options contains
112       // all of m_required_options[i] (i.e. all the required options at this
113       // level are a subset of m_seen_options); AND 2). { m_seen_options -
114       // m_required_options[i] is a subset of m_options_options[i] (i.e. all
115       // the rest of m_seen_options are in the set of optional options at this
116       // level.
117 
118       // Check to see if all of m_required_options[i] are a subset of
119       // m_seen_options
120       if (IsASubset(GetRequiredOptions()[i], m_seen_options)) {
121         // Construct the set difference: remaining_options = {m_seen_options} -
122         // {m_required_options[i]}
123         OptionSet remaining_options;
124         OptionsSetDiff(m_seen_options, GetRequiredOptions()[i],
125                        remaining_options);
126         // Check to see if remaining_options is a subset of
127         // m_optional_options[i]
128         if (IsASubset(remaining_options, GetOptionalOptions()[i]))
129           options_are_valid = true;
130       }
131     }
132   } else {
133     options_are_valid = true;
134   }
135 
136   if (options_are_valid) {
137     result.SetStatus(eReturnStatusSuccessFinishNoResult);
138   } else {
139     result.AppendError("invalid combination of options for the given command");
140   }
141 
142   return options_are_valid;
143 }
144 
145 // This is called in the Options constructor, though we could call it lazily if
146 // that ends up being a performance problem.
147 
148 void Options::BuildValidOptionSets() {
149   // Check to see if we already did this.
150   if (m_required_options.size() != 0)
151     return;
152 
153   // Check to see if there are any options.
154   int num_options = NumCommandOptions();
155   if (num_options == 0)
156     return;
157 
158   auto opt_defs = GetDefinitions();
159   m_required_options.resize(1);
160   m_optional_options.resize(1);
161 
162   // First count the number of option sets we've got.  Ignore
163   // LLDB_ALL_OPTION_SETS...
164 
165   uint32_t num_option_sets = 0;
166 
167   for (const auto &def : opt_defs) {
168     uint32_t this_usage_mask = def.usage_mask;
169     if (this_usage_mask == LLDB_OPT_SET_ALL) {
170       if (num_option_sets == 0)
171         num_option_sets = 1;
172     } else {
173       for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++) {
174         if (this_usage_mask & (1 << j)) {
175           if (num_option_sets <= j)
176             num_option_sets = j + 1;
177         }
178       }
179     }
180   }
181 
182   if (num_option_sets > 0) {
183     m_required_options.resize(num_option_sets);
184     m_optional_options.resize(num_option_sets);
185 
186     for (const auto &def : opt_defs) {
187       for (uint32_t j = 0; j < num_option_sets; j++) {
188         if (def.usage_mask & 1 << j) {
189           if (def.required)
190             m_required_options[j].insert(def.short_option);
191           else
192             m_optional_options[j].insert(def.short_option);
193         }
194       }
195     }
196   }
197 }
198 
199 uint32_t Options::NumCommandOptions() { return GetDefinitions().size(); }
200 
201 Option *Options::GetLongOptions() {
202   // Check to see if this has already been done.
203   if (m_getopt_table.empty()) {
204     auto defs = GetDefinitions();
205     if (defs.empty())
206       return nullptr;
207 
208     std::map<int, uint32_t> option_seen;
209 
210     m_getopt_table.resize(defs.size() + 1);
211     for (size_t i = 0; i < defs.size(); ++i) {
212       const int short_opt = defs[i].short_option;
213 
214       m_getopt_table[i].definition = &defs[i];
215       m_getopt_table[i].flag = nullptr;
216       m_getopt_table[i].val = short_opt;
217 
218       if (option_seen.find(short_opt) == option_seen.end()) {
219         option_seen[short_opt] = i;
220       } else if (short_opt) {
221         m_getopt_table[i].val = 0;
222         std::map<int, uint32_t>::const_iterator pos =
223             option_seen.find(short_opt);
224         StreamString strm;
225         if (defs[i].HasShortOption())
226           Host::SystemLog(Host::eSystemLogError,
227                           "option[%u] --%s has a short option -%c that "
228                           "conflicts with option[%u] --%s, short option won't "
229                           "be used for --%s\n",
230                           (int)i, defs[i].long_option, short_opt, pos->second,
231                           m_getopt_table[pos->second].definition->long_option,
232                           defs[i].long_option);
233         else
234           Host::SystemLog(Host::eSystemLogError,
235                           "option[%u] --%s has a short option 0x%x that "
236                           "conflicts with option[%u] --%s, short option won't "
237                           "be used for --%s\n",
238                           (int)i, defs[i].long_option, short_opt, pos->second,
239                           m_getopt_table[pos->second].definition->long_option,
240                           defs[i].long_option);
241       }
242     }
243 
244     // getopt_long_only requires a NULL final entry in the table:
245 
246     m_getopt_table.back().definition = nullptr;
247     m_getopt_table.back().flag = nullptr;
248     m_getopt_table.back().val = 0;
249   }
250 
251   if (m_getopt_table.empty())
252     return nullptr;
253 
254   return &m_getopt_table.front();
255 }
256 
257 // This function takes INDENT, which tells how many spaces to output at the
258 // front of each line; SPACES, which is a string containing 80 spaces; and
259 // TEXT, which is the text that is to be output.   It outputs the text, on
260 // multiple lines if necessary, to RESULT, with INDENT spaces at the front of
261 // each line.  It breaks lines on spaces, tabs or newlines, shortening the line
262 // if necessary to not break in the middle of a word.  It assumes that each
263 // output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
264 
265 void Options::OutputFormattedUsageText(Stream &strm,
266                                        const OptionDefinition &option_def,
267                                        uint32_t output_max_columns) {
268   std::string actual_text;
269   if (option_def.validator) {
270     const char *condition = option_def.validator->ShortConditionString();
271     if (condition) {
272       actual_text = "[";
273       actual_text.append(condition);
274       actual_text.append("] ");
275     }
276   }
277   actual_text.append(option_def.usage_text);
278 
279   // Will it all fit on one line?
280 
281   if (static_cast<uint32_t>(actual_text.length() + strm.GetIndentLevel()) <
282       output_max_columns) {
283     // Output it as a single line.
284     strm.Indent(actual_text);
285     strm.EOL();
286   } else {
287     // We need to break it up into multiple lines.
288 
289     int text_width = output_max_columns - strm.GetIndentLevel() - 1;
290     int start = 0;
291     int end = start;
292     int final_end = actual_text.length();
293     int sub_len;
294 
295     while (end < final_end) {
296       // Don't start the 'text' on a space, since we're already outputting the
297       // indentation.
298       while ((start < final_end) && (actual_text[start] == ' '))
299         start++;
300 
301       end = start + text_width;
302       if (end > final_end)
303         end = final_end;
304       else {
305         // If we're not at the end of the text, make sure we break the line on
306         // white space.
307         while (end > start && actual_text[end] != ' ' &&
308                actual_text[end] != '\t' && actual_text[end] != '\n')
309           end--;
310       }
311 
312       sub_len = end - start;
313       if (start != 0)
314         strm.EOL();
315       strm.Indent();
316       assert(start < final_end);
317       assert(start + sub_len <= final_end);
318       strm.Write(actual_text.c_str() + start, sub_len);
319       start = end + 1;
320     }
321     strm.EOL();
322   }
323 }
324 
325 bool Options::SupportsLongOption(const char *long_option) {
326   if (!long_option || !long_option[0])
327     return false;
328 
329   auto opt_defs = GetDefinitions();
330   if (opt_defs.empty())
331     return false;
332 
333   const char *long_option_name = long_option;
334   if (long_option[0] == '-' && long_option[1] == '-')
335     long_option_name += 2;
336 
337   for (auto &def : opt_defs) {
338     if (!def.long_option)
339       continue;
340 
341     if (strcmp(def.long_option, long_option_name) == 0)
342       return true;
343   }
344 
345   return false;
346 }
347 
348 enum OptionDisplayType {
349   eDisplayBestOption,
350   eDisplayShortOption,
351   eDisplayLongOption
352 };
353 
354 static bool PrintOption(const OptionDefinition &opt_def,
355                         OptionDisplayType display_type, const char *header,
356                         const char *footer, bool show_optional, Stream &strm) {
357   if (display_type == eDisplayShortOption && !opt_def.HasShortOption())
358     return false;
359 
360   if (header && header[0])
361     strm.PutCString(header);
362 
363   if (show_optional && !opt_def.required)
364     strm.PutChar('[');
365   const bool show_short_option =
366       opt_def.HasShortOption() && display_type != eDisplayLongOption;
367   if (show_short_option)
368     strm.Printf("-%c", opt_def.short_option);
369   else
370     strm.Printf("--%s", opt_def.long_option);
371   switch (opt_def.option_has_arg) {
372   case OptionParser::eNoArgument:
373     break;
374   case OptionParser::eRequiredArgument:
375     strm.Printf(" <%s>", CommandObject::GetArgumentName(opt_def.argument_type));
376     break;
377 
378   case OptionParser::eOptionalArgument:
379     strm.Printf("%s[<%s>]", show_short_option ? "" : "=",
380                 CommandObject::GetArgumentName(opt_def.argument_type));
381     break;
382   }
383   if (show_optional && !opt_def.required)
384     strm.PutChar(']');
385   if (footer && footer[0])
386     strm.PutCString(footer);
387   return true;
388 }
389 
390 void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
391                                   uint32_t screen_width) {
392   const bool only_print_args = cmd->IsDashDashCommand();
393 
394   auto opt_defs = GetDefinitions();
395   const uint32_t save_indent_level = strm.GetIndentLevel();
396   llvm::StringRef name;
397 
398   StreamString arguments_str;
399 
400   if (cmd) {
401     name = cmd->GetCommandName();
402     cmd->GetFormattedCommandArguments(arguments_str);
403   } else
404     name = "";
405 
406   strm.PutCString("\nCommand Options Usage:\n");
407 
408   strm.IndentMore(2);
409 
410   // First, show each usage level set of options, e.g. <cmd> [options-for-
411   // level-0]
412   //                                                   <cmd>
413   //                                                   [options-for-level-1]
414   //                                                   etc.
415 
416   const uint32_t num_options = NumCommandOptions();
417   if (num_options == 0)
418     return;
419 
420   uint32_t num_option_sets = GetRequiredOptions().size();
421 
422   uint32_t i;
423 
424   if (!only_print_args) {
425     for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set) {
426       uint32_t opt_set_mask;
427 
428       opt_set_mask = 1 << opt_set;
429       if (opt_set > 0)
430         strm.Printf("\n");
431       strm.Indent(name);
432 
433       // Different option sets may require different args.
434       StreamString args_str;
435       if (cmd)
436         cmd->GetFormattedCommandArguments(args_str, opt_set_mask);
437 
438       // First go through and print all options that take no arguments as a
439       // single string. If a command has "-a" "-b" and "-c", this will show up
440       // as [-abc]
441 
442       std::set<int> options;
443       std::set<int>::const_iterator options_pos, options_end;
444       for (auto &def : opt_defs) {
445         if (def.usage_mask & opt_set_mask && def.HasShortOption()) {
446           // Add current option to the end of out_stream.
447 
448           if (def.required && def.option_has_arg == OptionParser::eNoArgument) {
449             options.insert(def.short_option);
450           }
451         }
452       }
453 
454       if (!options.empty()) {
455         // We have some required options with no arguments
456         strm.PutCString(" -");
457         for (i = 0; i < 2; ++i)
458           for (options_pos = options.begin(), options_end = options.end();
459                options_pos != options_end; ++options_pos) {
460             if (i == 0 && ::islower(*options_pos))
461               continue;
462             if (i == 1 && ::isupper(*options_pos))
463               continue;
464             strm << (char)*options_pos;
465           }
466       }
467 
468       options.clear();
469       for (auto &def : opt_defs) {
470         if (def.usage_mask & opt_set_mask && def.HasShortOption()) {
471           // Add current option to the end of out_stream.
472 
473           if (!def.required &&
474               def.option_has_arg == OptionParser::eNoArgument) {
475             options.insert(def.short_option);
476           }
477         }
478       }
479 
480       if (!options.empty()) {
481         // We have some required options with no arguments
482         strm.PutCString(" [-");
483         for (i = 0; i < 2; ++i)
484           for (options_pos = options.begin(), options_end = options.end();
485                options_pos != options_end; ++options_pos) {
486             if (i == 0 && ::islower(*options_pos))
487               continue;
488             if (i == 1 && ::isupper(*options_pos))
489               continue;
490             strm << (char)*options_pos;
491           }
492         strm.PutChar(']');
493       }
494 
495       // First go through and print the required options (list them up front).
496 
497       for (auto &def : opt_defs) {
498         if (def.usage_mask & opt_set_mask && def.HasShortOption()) {
499           if (def.required && def.option_has_arg != OptionParser::eNoArgument)
500             PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm);
501         }
502       }
503 
504       // Now go through again, and this time only print the optional options.
505 
506       for (auto &def : opt_defs) {
507         if (def.usage_mask & opt_set_mask) {
508           // Add current option to the end of out_stream.
509 
510           if (!def.required && def.option_has_arg != OptionParser::eNoArgument)
511             PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm);
512         }
513       }
514 
515       if (args_str.GetSize() > 0) {
516         if (cmd->WantsRawCommandString() && !only_print_args)
517           strm.Printf(" --");
518 
519         strm << " " << args_str.GetString();
520         if (only_print_args)
521           break;
522       }
523     }
524   }
525 
526   if (cmd && (only_print_args || cmd->WantsRawCommandString()) &&
527       arguments_str.GetSize() > 0) {
528     if (!only_print_args)
529       strm.PutChar('\n');
530     strm.Indent(name);
531     strm << " " << arguments_str.GetString();
532   }
533 
534   strm.Printf("\n\n");
535 
536   if (!only_print_args) {
537     // Now print out all the detailed information about the various options:
538     // long form, short form and help text:
539     //   -short <argument> ( --long_name <argument> )
540     //   help text
541 
542     // This variable is used to keep track of which options' info we've printed
543     // out, because some options can be in more than one usage level, but we
544     // only want to print the long form of its information once.
545 
546     std::multimap<int, uint32_t> options_seen;
547     strm.IndentMore(5);
548 
549     // Put the unique command options in a vector & sort it, so we can output
550     // them alphabetically (by short_option) when writing out detailed help for
551     // each option.
552 
553     i = 0;
554     for (auto &def : opt_defs)
555       options_seen.insert(std::make_pair(def.short_option, i++));
556 
557     // Go through the unique'd and alphabetically sorted vector of options,
558     // find the table entry for each option and write out the detailed help
559     // information for that option.
560 
561     bool first_option_printed = false;
562 
563     for (auto pos : options_seen) {
564       i = pos.second;
565       // Print out the help information for this option.
566 
567       // Put a newline separation between arguments
568       if (first_option_printed)
569         strm.EOL();
570       else
571         first_option_printed = true;
572 
573       CommandArgumentType arg_type = opt_defs[i].argument_type;
574 
575       StreamString arg_name_str;
576       arg_name_str.Printf("<%s>", CommandObject::GetArgumentName(arg_type));
577 
578       strm.Indent();
579       if (opt_defs[i].short_option && opt_defs[i].HasShortOption()) {
580         PrintOption(opt_defs[i], eDisplayShortOption, nullptr, nullptr, false,
581                     strm);
582         PrintOption(opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
583       } else {
584         // Short option is not printable, just print long option
585         PrintOption(opt_defs[i], eDisplayLongOption, nullptr, nullptr, false,
586                     strm);
587       }
588       strm.EOL();
589 
590       strm.IndentMore(5);
591 
592       if (opt_defs[i].usage_text)
593         OutputFormattedUsageText(strm, opt_defs[i], screen_width);
594       if (!opt_defs[i].enum_values.empty()) {
595         strm.Indent();
596         strm.Printf("Values: ");
597         bool is_first = true;
598         for (const auto &enum_value : opt_defs[i].enum_values) {
599           if (is_first) {
600             strm.Printf("%s", enum_value.string_value);
601             is_first = false;
602           }
603           else
604             strm.Printf(" | %s", enum_value.string_value);
605         }
606         strm.EOL();
607       }
608       strm.IndentLess(5);
609     }
610   }
611 
612   // Restore the indent level
613   strm.SetIndentLevel(save_indent_level);
614 }
615 
616 // This function is called when we have been given a potentially incomplete set
617 // of options, such as when an alias has been defined (more options might be
618 // added at at the time the alias is invoked).  We need to verify that the
619 // options in the set m_seen_options are all part of a set that may be used
620 // together, but m_seen_options may be missing some of the "required" options.
621 
622 bool Options::VerifyPartialOptions(CommandReturnObject &result) {
623   bool options_are_valid = false;
624 
625   int num_levels = GetRequiredOptions().size();
626   if (num_levels) {
627     for (int i = 0; i < num_levels && !options_are_valid; ++i) {
628       // In this case we are treating all options as optional rather than
629       // required. Therefore a set of options is correct if m_seen_options is a
630       // subset of the union of m_required_options and m_optional_options.
631       OptionSet union_set;
632       OptionsSetUnion(GetRequiredOptions()[i], GetOptionalOptions()[i],
633                       union_set);
634       if (IsASubset(m_seen_options, union_set))
635         options_are_valid = true;
636     }
637   }
638 
639   return options_are_valid;
640 }
641 
642 bool Options::HandleOptionCompletion(CompletionRequest &request,
643                                      OptionElementVector &opt_element_vector,
644                                      CommandInterpreter &interpreter) {
645   // For now we just scan the completions to see if the cursor position is in
646   // an option or its argument.  Otherwise we'll call HandleArgumentCompletion.
647   // In the future we can use completion to validate options as well if we
648   // want.
649 
650   auto opt_defs = GetDefinitions();
651 
652   llvm::StringRef cur_opt_str = request.GetCursorArgumentPrefix();
653 
654   for (size_t i = 0; i < opt_element_vector.size(); i++) {
655     size_t opt_pos = static_cast<size_t>(opt_element_vector[i].opt_pos);
656     size_t opt_arg_pos = static_cast<size_t>(opt_element_vector[i].opt_arg_pos);
657     int opt_defs_index = opt_element_vector[i].opt_defs_index;
658     if (opt_pos == request.GetCursorIndex()) {
659       // We're completing the option itself.
660 
661       if (opt_defs_index == OptionArgElement::eBareDash) {
662         // We're completing a bare dash.  That means all options are open.
663         // FIXME: We should scan the other options provided and only complete
664         // options
665         // within the option group they belong to.
666         std::string opt_str = "-a";
667 
668         for (auto &def : opt_defs) {
669           if (!def.short_option)
670             continue;
671           opt_str[1] = def.short_option;
672           request.AddCompletion(opt_str, def.usage_text);
673         }
674 
675         return true;
676       } else if (opt_defs_index == OptionArgElement::eBareDoubleDash) {
677         std::string full_name("--");
678         for (auto &def : opt_defs) {
679           if (!def.short_option)
680             continue;
681 
682           full_name.erase(full_name.begin() + 2, full_name.end());
683           full_name.append(def.long_option);
684           request.AddCompletion(full_name, def.usage_text);
685         }
686         return true;
687       } else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) {
688         // We recognized it, if it an incomplete long option, complete it
689         // anyway (getopt_long_only is happy with shortest unique string, but
690         // it's still a nice thing to do.)  Otherwise return The string so the
691         // upper level code will know this is a full match and add the " ".
692         const OptionDefinition &opt = opt_defs[opt_defs_index];
693         llvm::StringRef long_option = opt.long_option;
694         if (cur_opt_str.startswith("--") && cur_opt_str != long_option) {
695           request.AddCompletion("--" + long_option.str(), opt.usage_text);
696           return true;
697         } else
698           request.AddCompletion(request.GetCursorArgumentPrefix());
699         return true;
700       } else {
701         // FIXME - not handling wrong options yet:
702         // Check to see if they are writing a long option & complete it.
703         // I think we will only get in here if the long option table has two
704         // elements
705         // that are not unique up to this point.  getopt_long_only does
706         // shortest unique match for long options already.
707         if (cur_opt_str.consume_front("--")) {
708           for (auto &def : opt_defs) {
709             llvm::StringRef long_option(def.long_option);
710             if (long_option.startswith(cur_opt_str))
711               request.AddCompletion("--" + long_option.str(), def.usage_text);
712           }
713         }
714         return true;
715       }
716 
717     } else if (opt_arg_pos == request.GetCursorIndex()) {
718       // Okay the cursor is on the completion of an argument. See if it has a
719       // completion, otherwise return no matches.
720       if (opt_defs_index != -1) {
721         HandleOptionArgumentCompletion(request, opt_element_vector, i,
722                                        interpreter);
723         return true;
724       } else {
725         // No completion callback means no completions...
726         return true;
727       }
728 
729     } else {
730       // Not the last element, keep going.
731       continue;
732     }
733   }
734   return false;
735 }
736 
737 void Options::HandleOptionArgumentCompletion(
738     CompletionRequest &request, OptionElementVector &opt_element_vector,
739     int opt_element_index, CommandInterpreter &interpreter) {
740   auto opt_defs = GetDefinitions();
741   std::unique_ptr<SearchFilter> filter_up;
742 
743   int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
744 
745   // See if this is an enumeration type option, and if so complete it here:
746 
747   const auto &enum_values = opt_defs[opt_defs_index].enum_values;
748   if (!enum_values.empty())
749     for (const auto &enum_value : enum_values)
750       request.TryCompleteCurrentArg(enum_value.string_value);
751 
752   // If this is a source file or symbol type completion, and  there is a -shlib
753   // option somewhere in the supplied arguments, then make a search filter for
754   // that shared library.
755   // FIXME: Do we want to also have an "OptionType" so we don't have to match
756   // string names?
757 
758   uint32_t completion_mask = opt_defs[opt_defs_index].completion_type;
759 
760   if (completion_mask == 0) {
761     lldb::CommandArgumentType option_arg_type =
762         opt_defs[opt_defs_index].argument_type;
763     if (option_arg_type != eArgTypeNone) {
764       const CommandObject::ArgumentTableEntry *arg_entry =
765           CommandObject::FindArgumentDataByType(
766               opt_defs[opt_defs_index].argument_type);
767       if (arg_entry)
768         completion_mask = arg_entry->completion_type;
769     }
770   }
771 
772   if (completion_mask & CommandCompletions::eSourceFileCompletion ||
773       completion_mask & CommandCompletions::eSymbolCompletion) {
774     for (size_t i = 0; i < opt_element_vector.size(); i++) {
775       int cur_defs_index = opt_element_vector[i].opt_defs_index;
776 
777       // trying to use <0 indices will definitely cause problems
778       if (cur_defs_index == OptionArgElement::eUnrecognizedArg ||
779           cur_defs_index == OptionArgElement::eBareDash ||
780           cur_defs_index == OptionArgElement::eBareDoubleDash)
781         continue;
782 
783       int cur_arg_pos = opt_element_vector[i].opt_arg_pos;
784       const char *cur_opt_name = opt_defs[cur_defs_index].long_option;
785 
786       // If this is the "shlib" option and there was an argument provided,
787       // restrict it to that shared library.
788       if (cur_opt_name && strcmp(cur_opt_name, "shlib") == 0 &&
789           cur_arg_pos != -1) {
790         const char *module_name =
791             request.GetParsedLine().GetArgumentAtIndex(cur_arg_pos);
792         if (module_name) {
793           FileSpec module_spec(module_name);
794           lldb::TargetSP target_sp =
795               interpreter.GetDebugger().GetSelectedTarget();
796           // Search filters require a target...
797           if (target_sp)
798             filter_up =
799                 std::make_unique<SearchFilterByModule>(target_sp, module_spec);
800         }
801         break;
802       }
803     }
804   }
805 
806   CommandCompletions::InvokeCommonCompletionCallbacks(
807       interpreter, completion_mask, request, filter_up.get());
808 }
809 
810 void OptionGroupOptions::Append(OptionGroup *group) {
811   auto group_option_defs = group->GetDefinitions();
812   for (uint32_t i = 0; i < group_option_defs.size(); ++i) {
813     m_option_infos.push_back(OptionInfo(group, i));
814     m_option_defs.push_back(group_option_defs[i]);
815   }
816 }
817 
818 const OptionGroup *OptionGroupOptions::GetGroupWithOption(char short_opt) {
819   for (uint32_t i = 0; i < m_option_defs.size(); i++) {
820     OptionDefinition opt_def = m_option_defs[i];
821     if (opt_def.short_option == short_opt)
822       return m_option_infos[i].option_group;
823   }
824   return nullptr;
825 }
826 
827 void OptionGroupOptions::Append(OptionGroup *group, uint32_t src_mask,
828                                 uint32_t dst_mask) {
829   auto group_option_defs = group->GetDefinitions();
830   for (uint32_t i = 0; i < group_option_defs.size(); ++i) {
831     if (group_option_defs[i].usage_mask & src_mask) {
832       m_option_infos.push_back(OptionInfo(group, i));
833       m_option_defs.push_back(group_option_defs[i]);
834       m_option_defs.back().usage_mask = dst_mask;
835     }
836   }
837 }
838 
839 void OptionGroupOptions::Finalize() {
840   m_did_finalize = true;
841 }
842 
843 Status OptionGroupOptions::SetOptionValue(uint32_t option_idx,
844                                           llvm::StringRef option_value,
845                                           ExecutionContext *execution_context) {
846   // After calling OptionGroupOptions::Append(...), you must finalize the
847   // groups by calling OptionGroupOptions::Finlize()
848   assert(m_did_finalize);
849   Status error;
850   if (option_idx < m_option_infos.size()) {
851     error = m_option_infos[option_idx].option_group->SetOptionValue(
852         m_option_infos[option_idx].option_index, option_value,
853         execution_context);
854 
855   } else {
856     error.SetErrorString("invalid option index"); // Shouldn't happen...
857   }
858   return error;
859 }
860 
861 void OptionGroupOptions::OptionParsingStarting(
862     ExecutionContext *execution_context) {
863   std::set<OptionGroup *> group_set;
864   OptionInfos::iterator pos, end = m_option_infos.end();
865   for (pos = m_option_infos.begin(); pos != end; ++pos) {
866     OptionGroup *group = pos->option_group;
867     if (group_set.find(group) == group_set.end()) {
868       group->OptionParsingStarting(execution_context);
869       group_set.insert(group);
870     }
871   }
872 }
873 Status
874 OptionGroupOptions::OptionParsingFinished(ExecutionContext *execution_context) {
875   std::set<OptionGroup *> group_set;
876   Status error;
877   OptionInfos::iterator pos, end = m_option_infos.end();
878   for (pos = m_option_infos.begin(); pos != end; ++pos) {
879     OptionGroup *group = pos->option_group;
880     if (group_set.find(group) == group_set.end()) {
881       error = group->OptionParsingFinished(execution_context);
882       group_set.insert(group);
883       if (error.Fail())
884         return error;
885     }
886   }
887   return error;
888 }
889 
890 // OptionParser permutes the arguments while processing them, so we create a
891 // temporary array holding to avoid modification of the input arguments. The
892 // options themselves are never modified, but the API expects a char * anyway,
893 // hence the const_cast.
894 static std::vector<char *> GetArgvForParsing(const Args &args) {
895   std::vector<char *> result;
896   // OptionParser always skips the first argument as it is based on getopt().
897   result.push_back(const_cast<char *>("<FAKE-ARG0>"));
898   for (const Args::ArgEntry &entry : args)
899     result.push_back(const_cast<char *>(entry.c_str()));
900   result.push_back(nullptr);
901   return result;
902 }
903 
904 // Given a permuted argument, find it's position in the original Args vector.
905 static Args::const_iterator FindOriginalIter(const char *arg,
906                                              const Args &original) {
907   return llvm::find_if(
908       original, [arg](const Args::ArgEntry &D) { return D.c_str() == arg; });
909 }
910 
911 // Given a permuted argument, find it's index in the original Args vector.
912 static size_t FindOriginalIndex(const char *arg, const Args &original) {
913   return std::distance(original.begin(), FindOriginalIter(arg, original));
914 }
915 
916 // Construct a new Args object, consisting of the entries from the original
917 // arguments, but in the permuted order.
918 static Args ReconstituteArgsAfterParsing(llvm::ArrayRef<char *> parsed,
919                                          const Args &original) {
920   Args result;
921   for (const char *arg : parsed) {
922     auto pos = FindOriginalIter(arg, original);
923     assert(pos != original.end());
924     result.AppendArgument(pos->ref(), pos->GetQuoteChar());
925   }
926   return result;
927 }
928 
929 static size_t FindArgumentIndexForOption(const Args &args,
930                                          const Option &long_option) {
931   std::string short_opt = llvm::formatv("-{0}", char(long_option.val)).str();
932   std::string long_opt =
933       std::string(llvm::formatv("--{0}", long_option.definition->long_option));
934   for (const auto &entry : llvm::enumerate(args)) {
935     if (entry.value().ref().startswith(short_opt) ||
936         entry.value().ref().startswith(long_opt))
937       return entry.index();
938   }
939 
940   return size_t(-1);
941 }
942 
943 static std::string BuildShortOptions(const Option *long_options) {
944   std::string storage;
945   llvm::raw_string_ostream sstr(storage);
946 
947   // Leading : tells getopt to return a : for a missing option argument AND to
948   // suppress error messages.
949   sstr << ":";
950 
951   for (size_t i = 0; long_options[i].definition != nullptr; ++i) {
952     if (long_options[i].flag == nullptr) {
953       sstr << (char)long_options[i].val;
954       switch (long_options[i].definition->option_has_arg) {
955       default:
956       case OptionParser::eNoArgument:
957         break;
958       case OptionParser::eRequiredArgument:
959         sstr << ":";
960         break;
961       case OptionParser::eOptionalArgument:
962         sstr << "::";
963         break;
964       }
965     }
966   }
967   return std::move(sstr.str());
968 }
969 
970 llvm::Expected<Args> Options::ParseAlias(const Args &args,
971                                          OptionArgVector *option_arg_vector,
972                                          std::string &input_line) {
973   Option *long_options = GetLongOptions();
974 
975   if (long_options == nullptr) {
976     return llvm::make_error<llvm::StringError>("Invalid long options",
977                                                llvm::inconvertibleErrorCode());
978   }
979 
980   std::string short_options = BuildShortOptions(long_options);
981 
982   Args args_copy = args;
983   std::vector<char *> argv = GetArgvForParsing(args);
984 
985   std::unique_lock<std::mutex> lock;
986   OptionParser::Prepare(lock);
987   int val;
988   while (true) {
989     int long_options_index = -1;
990     val = OptionParser::Parse(argv, short_options, long_options,
991                               &long_options_index);
992 
993     if (val == ':') {
994       return llvm::createStringError(llvm::inconvertibleErrorCode(),
995                                      "last option requires an argument");
996     }
997 
998     if (val == -1)
999       break;
1000 
1001     if (val == '?') {
1002       return llvm::make_error<llvm::StringError>(
1003           "Unknown or ambiguous option", llvm::inconvertibleErrorCode());
1004     }
1005 
1006     if (val == 0)
1007       continue;
1008 
1009     OptionSeen(val);
1010 
1011     // Look up the long option index
1012     if (long_options_index == -1) {
1013       for (int j = 0; long_options[j].definition || long_options[j].flag ||
1014                       long_options[j].val;
1015            ++j) {
1016         if (long_options[j].val == val) {
1017           long_options_index = j;
1018           break;
1019         }
1020       }
1021     }
1022 
1023     // See if the option takes an argument, and see if one was supplied.
1024     if (long_options_index == -1) {
1025       return llvm::make_error<llvm::StringError>(
1026           llvm::formatv("Invalid option with value '{0}'.", char(val)).str(),
1027           llvm::inconvertibleErrorCode());
1028     }
1029 
1030     StreamString option_str;
1031     option_str.Printf("-%c", val);
1032     const OptionDefinition *def = long_options[long_options_index].definition;
1033     int has_arg =
1034         (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
1035 
1036     const char *option_arg = nullptr;
1037     switch (has_arg) {
1038     case OptionParser::eRequiredArgument:
1039       if (OptionParser::GetOptionArgument() == nullptr) {
1040         return llvm::make_error<llvm::StringError>(
1041             llvm::formatv("Option '{0}' is missing argument specifier.",
1042                           option_str.GetString())
1043                 .str(),
1044             llvm::inconvertibleErrorCode());
1045       }
1046       LLVM_FALLTHROUGH;
1047     case OptionParser::eOptionalArgument:
1048       option_arg = OptionParser::GetOptionArgument();
1049       LLVM_FALLTHROUGH;
1050     case OptionParser::eNoArgument:
1051       break;
1052     default:
1053       return llvm::make_error<llvm::StringError>(
1054           llvm::formatv("error with options table; invalid value in has_arg "
1055                         "field for option '{0}'.",
1056                         char(val))
1057               .str(),
1058           llvm::inconvertibleErrorCode());
1059     }
1060     if (!option_arg)
1061       option_arg = "<no-argument>";
1062     option_arg_vector->emplace_back(std::string(option_str.GetString()),
1063                                     has_arg, std::string(option_arg));
1064 
1065     // Find option in the argument list; also see if it was supposed to take an
1066     // argument and if one was supplied.  Remove option (and argument, if
1067     // given) from the argument list.  Also remove them from the
1068     // raw_input_string, if one was passed in.
1069     size_t idx =
1070         FindArgumentIndexForOption(args_copy, long_options[long_options_index]);
1071     if (idx == size_t(-1))
1072       continue;
1073 
1074     if (!input_line.empty()) {
1075       auto tmp_arg = args_copy[idx].ref();
1076       size_t pos = input_line.find(std::string(tmp_arg));
1077       if (pos != std::string::npos)
1078         input_line.erase(pos, tmp_arg.size());
1079     }
1080     args_copy.DeleteArgumentAtIndex(idx);
1081     if ((long_options[long_options_index].definition->option_has_arg !=
1082          OptionParser::eNoArgument) &&
1083         (OptionParser::GetOptionArgument() != nullptr) &&
1084         (idx < args_copy.GetArgumentCount()) &&
1085         (args_copy[idx].ref() == OptionParser::GetOptionArgument())) {
1086       if (input_line.size() > 0) {
1087         auto tmp_arg = args_copy[idx].ref();
1088         size_t pos = input_line.find(std::string(tmp_arg));
1089         if (pos != std::string::npos)
1090           input_line.erase(pos, tmp_arg.size());
1091       }
1092       args_copy.DeleteArgumentAtIndex(idx);
1093     }
1094   }
1095 
1096   return std::move(args_copy);
1097 }
1098 
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();
1104 
1105   if (long_options == nullptr)
1106     return option_element_vector;
1107 
1108   std::string short_options = BuildShortOptions(long_options);
1109 
1110   std::unique_lock<std::mutex> lock;
1111   OptionParser::Prepare(lock);
1112   OptionParser::EnableError(false);
1113 
1114   int val;
1115   auto opt_defs = GetDefinitions();
1116 
1117   std::vector<char *> dummy_vec = GetArgvForParsing(args);
1118 
1119   bool failed_once = false;
1120   uint32_t dash_dash_pos = -1;
1121 
1122   while (true) {
1123     bool missing_argument = false;
1124     int long_options_index = -1;
1125 
1126     val = OptionParser::Parse(dummy_vec, short_options, long_options,
1127                               &long_options_index);
1128 
1129     if (val == -1) {
1130       // When we're completing a "--" which is the last option on line,
1131       if (failed_once)
1132         break;
1133 
1134       failed_once = true;
1135 
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
1146       // line.
1147 
1148       if (static_cast<size_t>(OptionParser::GetOptionIndex()) <
1149               dummy_vec.size() &&
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));
1157           continue;
1158         } else
1159           break;
1160       } else
1161         break;
1162     } else if (val == '?') {
1163       option_element_vector.push_back(OptionArgElement(
1164           OptionArgElement::eUnrecognizedArg,
1165           FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1166                             args),
1167           OptionArgElement::eUnrecognizedArg));
1168       continue;
1169     } else if (val == 0) {
1170       continue;
1171     } else if (val == ':') {
1172       // This is a missing argument.
1173       val = OptionParser::GetOptionErrorCause();
1174       missing_argument = true;
1175     }
1176 
1177     OptionSeen(val);
1178 
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;
1183            ++j) {
1184         if (long_options[j].val == val) {
1185           long_options_index = j;
1186           break;
1187         }
1188       }
1189     }
1190 
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)
1196           continue;
1197         opt_defs_index = i;
1198         break;
1199       }
1200 
1201       const OptionDefinition *def = long_options[long_options_index].definition;
1202       int has_arg =
1203           (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
1204       switch (has_arg) {
1205       case OptionParser::eNoArgument:
1206         option_element_vector.push_back(OptionArgElement(
1207             opt_defs_index,
1208             FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1209                               args),
1210             0));
1211         break;
1212       case OptionParser::eRequiredArgument:
1213         if (OptionParser::GetOptionArgument() != nullptr) {
1214           int arg_index;
1215           if (missing_argument)
1216             arg_index = -1;
1217           else
1218             arg_index = OptionParser::GetOptionIndex() - 2;
1219 
1220           option_element_vector.push_back(OptionArgElement(
1221               opt_defs_index,
1222               FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 2],
1223                                 args),
1224               arg_index));
1225         } else {
1226           option_element_vector.push_back(OptionArgElement(
1227               opt_defs_index,
1228               FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1229                                 args),
1230               -1));
1231         }
1232         break;
1233       case OptionParser::eOptionalArgument:
1234         if (OptionParser::GetOptionArgument() != nullptr) {
1235           option_element_vector.push_back(OptionArgElement(
1236               opt_defs_index,
1237               FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 2],
1238                                 args),
1239               FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1240                                 args)));
1241         } else {
1242           option_element_vector.push_back(OptionArgElement(
1243               opt_defs_index,
1244               FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 2],
1245                                 args),
1246               FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1247                                 args)));
1248         }
1249         break;
1250       default:
1251         // The options table is messed up.  Here we'll just continue
1252         option_element_vector.push_back(OptionArgElement(
1253             OptionArgElement::eUnrecognizedArg,
1254             FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1255                               args),
1256             OptionArgElement::eUnrecognizedArg));
1257         break;
1258       }
1259     } else {
1260       option_element_vector.push_back(OptionArgElement(
1261           OptionArgElement::eUnrecognizedArg,
1262           FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1263                             args),
1264           OptionArgElement::eUnrecognizedArg));
1265     }
1266   }
1267 
1268   // Finally we have to handle the case where the cursor index points at a
1269   // single "-".  We want to mark that in the option_element_vector, but only
1270   // if it is not after the "--".  But it turns out that OptionParser::Parse
1271   // just ignores an isolated "-".  So we have to look it up by hand here.  We
1272   // only care if it is AT the cursor position. Note, a single quoted dash is
1273   // not the same as a single dash...
1274 
1275   const Args::ArgEntry &cursor = args[cursor_index];
1276   if ((static_cast<int32_t>(dash_dash_pos) == -1 ||
1277        cursor_index < dash_dash_pos) &&
1278       !cursor.IsQuoted() && cursor.ref() == "-") {
1279     option_element_vector.push_back(
1280         OptionArgElement(OptionArgElement::eBareDash, cursor_index,
1281                          OptionArgElement::eBareDash));
1282   }
1283   return option_element_vector;
1284 }
1285 
1286 llvm::Expected<Args> Options::Parse(const Args &args,
1287                                     ExecutionContext *execution_context,
1288                                     lldb::PlatformSP platform_sp,
1289                                     bool require_validation) {
1290   Status error;
1291   Option *long_options = GetLongOptions();
1292   if (long_options == nullptr) {
1293     return llvm::make_error<llvm::StringError>("Invalid long options.",
1294                                                llvm::inconvertibleErrorCode());
1295   }
1296 
1297   std::string short_options = BuildShortOptions(long_options);
1298   std::vector<char *> argv = GetArgvForParsing(args);
1299   std::unique_lock<std::mutex> lock;
1300   OptionParser::Prepare(lock);
1301   int val;
1302   while (true) {
1303     int long_options_index = -1;
1304     val = OptionParser::Parse(argv, short_options, long_options,
1305                               &long_options_index);
1306 
1307     if (val == ':') {
1308       error.SetErrorString("last option requires an argument");
1309       break;
1310     }
1311 
1312     if (val == -1)
1313       break;
1314 
1315     // Did we get an error?
1316     if (val == '?') {
1317       error.SetErrorString("unknown or ambiguous option");
1318       break;
1319     }
1320     // The option auto-set itself
1321     if (val == 0)
1322       continue;
1323 
1324     OptionSeen(val);
1325 
1326     // Lookup the long option index
1327     if (long_options_index == -1) {
1328       for (int i = 0; long_options[i].definition || long_options[i].flag ||
1329                       long_options[i].val;
1330            ++i) {
1331         if (long_options[i].val == val) {
1332           long_options_index = i;
1333           break;
1334         }
1335       }
1336     }
1337     // Call the callback with the option
1338     if (long_options_index >= 0 &&
1339         long_options[long_options_index].definition) {
1340       const OptionDefinition *def = long_options[long_options_index].definition;
1341 
1342       if (!platform_sp) {
1343         // User did not pass in an explicit platform.  Try to grab from the
1344         // execution context.
1345         TargetSP target_sp =
1346             execution_context ? execution_context->GetTargetSP() : TargetSP();
1347         platform_sp = target_sp ? target_sp->GetPlatform() : PlatformSP();
1348       }
1349       OptionValidator *validator = def->validator;
1350 
1351       if (!platform_sp && require_validation) {
1352         // Caller requires validation but we cannot validate as we don't have
1353         // the mandatory platform against which to validate.
1354         return llvm::make_error<llvm::StringError>(
1355             "cannot validate options: no platform available",
1356             llvm::inconvertibleErrorCode());
1357       }
1358 
1359       bool validation_failed = false;
1360       if (platform_sp) {
1361         // Ensure we have an execution context, empty or not.
1362         ExecutionContext dummy_context;
1363         ExecutionContext *exe_ctx_p =
1364             execution_context ? execution_context : &dummy_context;
1365         if (validator && !validator->IsValid(*platform_sp, *exe_ctx_p)) {
1366           validation_failed = true;
1367           error.SetErrorStringWithFormat("Option \"%s\" invalid.  %s",
1368                                          def->long_option,
1369                                          def->validator->LongConditionString());
1370         }
1371       }
1372 
1373       // As long as validation didn't fail, we set the option value.
1374       if (!validation_failed)
1375         error =
1376             SetOptionValue(long_options_index,
1377                            (def->option_has_arg == OptionParser::eNoArgument)
1378                                ? nullptr
1379                                : OptionParser::GetOptionArgument(),
1380                            execution_context);
1381       // If the Option setting returned an error, we should stop parsing
1382       // and return the error.
1383       if (error.Fail())
1384         break;
1385     } else {
1386       error.SetErrorStringWithFormat("invalid option with value '%i'", val);
1387     }
1388   }
1389 
1390   if (error.Fail())
1391     return error.ToError();
1392 
1393   argv.pop_back();
1394   argv.erase(argv.begin(), argv.begin() + OptionParser::GetOptionIndex());
1395   return ReconstituteArgsAfterParsing(argv, args);
1396 }
1397