blob: 6f27abd4eeb5cd8d0041f6ce4d17a02f255c75be [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Options.cpp ---------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Jim Ingham40af72e2010-06-15 19:49:27 +000010#include "lldb/Interpreter/Options.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
Caroline Ticef362c452010-09-09 16:44:14 +000014#include <algorithm>
Greg Claytonab65b342011-04-13 22:47:15 +000015#include <bitset>
Greg Clayton3bcdfc02012-12-04 00:32:51 +000016#include <map>
Enrico Granatabef55ac2016-03-14 22:17:04 +000017#include <set>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018
19// Other libraries and framework includes
20// Project includes
Zachary Turner3eb2b442017-03-22 23:33:16 +000021#include "lldb/Host/OptionParser.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Interpreter/CommandCompletions.h"
23#include "lldb/Interpreter/CommandInterpreter.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000024#include "lldb/Interpreter/CommandObject.h"
25#include "lldb/Interpreter/CommandReturnObject.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Target/Target.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000027#include "lldb/Utility/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028
29using namespace lldb;
30using namespace lldb_private;
31
32//-------------------------------------------------------------------------
33// Options
34//-------------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000035Options::Options() : m_getopt_table() { BuildValidOptionSets(); }
36
37Options::~Options() {}
38
39void Options::NotifyOptionParsingStarting(ExecutionContext *execution_context) {
40 m_seen_options.clear();
41 // Let the subclass reset its option values
42 OptionParsingStarting(execution_context);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043}
44
Zachary Turner97206d52017-05-12 04:51:55 +000045Status
46Options::NotifyOptionParsingFinished(ExecutionContext *execution_context) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000047 return OptionParsingFinished(execution_context);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048}
49
Kate Stoneb9c1b512016-09-06 20:57:50 +000050void Options::OptionSeen(int option_idx) { m_seen_options.insert(option_idx); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051
52// Returns true is set_a is a subset of set_b; Otherwise returns false.
53
Kate Stoneb9c1b512016-09-06 20:57:50 +000054bool Options::IsASubset(const OptionSet &set_a, const OptionSet &set_b) {
55 bool is_a_subset = true;
56 OptionSet::const_iterator pos_a;
57 OptionSet::const_iterator pos_b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058
Kate Stoneb9c1b512016-09-06 20:57:50 +000059 // set_a is a subset of set_b if every member of set_a is also a member of
60 // set_b
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 for (pos_a = set_a.begin(); pos_a != set_a.end() && is_a_subset; ++pos_a) {
63 pos_b = set_b.find(*pos_a);
64 if (pos_b == set_b.end())
65 is_a_subset = false;
66 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067
Kate Stoneb9c1b512016-09-06 20:57:50 +000068 return is_a_subset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069}
70
Kate Stoneb9c1b512016-09-06 20:57:50 +000071// Returns the set difference set_a - set_b, i.e. { x | ElementOf (x, set_a) &&
72// !ElementOf (x, set_b) }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073
Kate Stoneb9c1b512016-09-06 20:57:50 +000074size_t Options::OptionsSetDiff(const OptionSet &set_a, const OptionSet &set_b,
75 OptionSet &diffs) {
76 size_t num_diffs = 0;
77 OptionSet::const_iterator pos_a;
78 OptionSet::const_iterator pos_b;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 for (pos_a = set_a.begin(); pos_a != set_a.end(); ++pos_a) {
81 pos_b = set_b.find(*pos_a);
82 if (pos_b == set_b.end()) {
83 ++num_diffs;
84 diffs.insert(*pos_a);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000085 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000086 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 return num_diffs;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000089}
90
Kate Stoneb9c1b512016-09-06 20:57:50 +000091// Returns the union of set_a and set_b. Does not put duplicate members into
92// the union.
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093
Kate Stoneb9c1b512016-09-06 20:57:50 +000094void Options::OptionsSetUnion(const OptionSet &set_a, const OptionSet &set_b,
95 OptionSet &union_set) {
96 OptionSet::const_iterator pos;
97 OptionSet::iterator pos_union;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000098
Kate Stoneb9c1b512016-09-06 20:57:50 +000099 // Put all the elements of set_a into the union.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101 for (pos = set_a.begin(); pos != set_a.end(); ++pos)
102 union_set.insert(*pos);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104 // Put all the elements of set_b that are not already there into the union.
105 for (pos = set_b.begin(); pos != set_b.end(); ++pos) {
106 pos_union = union_set.find(*pos);
107 if (pos_union == union_set.end())
108 union_set.insert(*pos);
109 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110}
111
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112bool Options::VerifyOptions(CommandReturnObject &result) {
113 bool options_are_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 int num_levels = GetRequiredOptions().size();
116 if (num_levels) {
117 for (int i = 0; i < num_levels && !options_are_valid; ++i) {
118 // This is the correct set of options if: 1). m_seen_options contains all
119 // of m_required_options[i]
120 // (i.e. all the required options at this level are a subset of
121 // m_seen_options); AND
122 // 2). { m_seen_options - m_required_options[i] is a subset of
123 // m_options_options[i] (i.e. all the rest of
124 // m_seen_options are in the set of optional options at this level.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000125
Kate Stoneb9c1b512016-09-06 20:57:50 +0000126 // Check to see if all of m_required_options[i] are a subset of
127 // m_seen_options
128 if (IsASubset(GetRequiredOptions()[i], m_seen_options)) {
129 // Construct the set difference: remaining_options = {m_seen_options} -
130 // {m_required_options[i]}
131 OptionSet remaining_options;
132 OptionsSetDiff(m_seen_options, GetRequiredOptions()[i],
133 remaining_options);
134 // Check to see if remaining_options is a subset of
135 // m_optional_options[i]
136 if (IsASubset(remaining_options, GetOptionalOptions()[i]))
137 options_are_valid = true;
138 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 } else {
141 options_are_valid = true;
142 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 if (options_are_valid) {
145 result.SetStatus(eReturnStatusSuccessFinishNoResult);
146 } else {
147 result.AppendError("invalid combination of options for the given command");
148 result.SetStatus(eReturnStatusFailed);
149 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 return options_are_valid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152}
153
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154// This is called in the Options constructor, though we could call it lazily if
155// that ends up being
Jim Ingham86511212010-06-15 18:47:14 +0000156// a performance problem.
157
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158void Options::BuildValidOptionSets() {
159 // Check to see if we already did this.
160 if (m_required_options.size() != 0)
161 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 // Check to see if there are any options.
164 int num_options = NumCommandOptions();
165 if (num_options == 0)
166 return;
167
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000168 auto opt_defs = GetDefinitions();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169 m_required_options.resize(1);
170 m_optional_options.resize(1);
171
172 // First count the number of option sets we've got. Ignore
173 // LLDB_ALL_OPTION_SETS...
174
175 uint32_t num_option_sets = 0;
176
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000177 for (const auto &def : opt_defs) {
178 uint32_t this_usage_mask = def.usage_mask;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179 if (this_usage_mask == LLDB_OPT_SET_ALL) {
180 if (num_option_sets == 0)
181 num_option_sets = 1;
182 } else {
183 for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++) {
184 if (this_usage_mask & (1 << j)) {
185 if (num_option_sets <= j)
186 num_option_sets = j + 1;
187 }
188 }
189 }
190 }
191
192 if (num_option_sets > 0) {
193 m_required_options.resize(num_option_sets);
194 m_optional_options.resize(num_option_sets);
195
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000196 for (const auto &def : opt_defs) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 for (uint32_t j = 0; j < num_option_sets; j++) {
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000198 if (def.usage_mask & 1 << j) {
199 if (def.required)
200 m_required_options[j].insert(def.short_option);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201 else
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000202 m_optional_options[j].insert(def.short_option);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000203 }
204 }
205 }
206 }
207}
208
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000209uint32_t Options::NumCommandOptions() { return GetDefinitions().size(); }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210
211Option *Options::GetLongOptions() {
212 // Check to see if this has already been done.
213 if (m_getopt_table.empty()) {
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000214 auto defs = GetDefinitions();
215 if (defs.empty())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000216 return nullptr;
217
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218 std::map<int, uint32_t> option_seen;
Enrico Granata4ebb8a42016-03-15 01:17:32 +0000219
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000220 m_getopt_table.resize(defs.size() + 1);
221 for (size_t i = 0; i < defs.size(); ++i) {
222 const int short_opt = defs[i].short_option;
Greg Claytoned8a7052010-09-18 03:37:20 +0000223
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000224 m_getopt_table[i].definition = &defs[i];
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225 m_getopt_table[i].flag = nullptr;
226 m_getopt_table[i].val = short_opt;
Enrico Granatabef55ac2016-03-14 22:17:04 +0000227
Kate Stoneb9c1b512016-09-06 20:57:50 +0000228 if (option_seen.find(short_opt) == option_seen.end()) {
229 option_seen[short_opt] = i;
230 } else if (short_opt) {
231 m_getopt_table[i].val = 0;
232 std::map<int, uint32_t>::const_iterator pos =
233 option_seen.find(short_opt);
234 StreamString strm;
235 if (isprint8(short_opt))
236 Host::SystemLog(Host::eSystemLogError,
237 "option[%u] --%s has a short option -%c that "
238 "conflicts with option[%u] --%s, short option won't "
239 "be used for --%s\n",
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000240 (int)i, defs[i].long_option, short_opt, pos->second,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241 m_getopt_table[pos->second].definition->long_option,
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000242 defs[i].long_option);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000243 else
244 Host::SystemLog(Host::eSystemLogError,
245 "option[%u] --%s has a short option 0x%x that "
246 "conflicts with option[%u] --%s, short option won't "
247 "be used for --%s\n",
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000248 (int)i, defs[i].long_option, short_opt, pos->second,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249 m_getopt_table[pos->second].definition->long_option,
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000250 defs[i].long_option);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000251 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252 }
253
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 // getopt_long_only requires a NULL final entry in the table:
255
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000256 m_getopt_table.back().definition = nullptr;
257 m_getopt_table.back().flag = nullptr;
258 m_getopt_table.back().val = 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259 }
260
261 if (m_getopt_table.empty())
262 return nullptr;
263
264 return &m_getopt_table.front();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265}
266
Kate Stoneb9c1b512016-09-06 20:57:50 +0000267// This function takes INDENT, which tells how many spaces to output at the
268// front of each line; SPACES, which is
269// a string containing 80 spaces; and TEXT, which is the text that is to be
270// output. It outputs the text, on
271// multiple lines if necessary, to RESULT, with INDENT spaces at the front of
272// each line. It breaks lines on spaces,
273// tabs or newlines, shortening the line if necessary to not break in the middle
274// of a word. It assumes that each
275// output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277void Options::OutputFormattedUsageText(Stream &strm,
278 const OptionDefinition &option_def,
279 uint32_t output_max_columns) {
280 std::string actual_text;
281 if (option_def.validator) {
282 const char *condition = option_def.validator->ShortConditionString();
283 if (condition) {
284 actual_text = "[";
285 actual_text.append(condition);
286 actual_text.append("] ");
287 }
288 }
289 actual_text.append(option_def.usage_text);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290
Kate Stoneb9c1b512016-09-06 20:57:50 +0000291 // Will it all fit on one line?
292
293 if (static_cast<uint32_t>(actual_text.length() + strm.GetIndentLevel()) <
294 output_max_columns) {
295 // Output it as a single line.
296 strm.Indent(actual_text.c_str());
297 strm.EOL();
298 } else {
299 // We need to break it up into multiple lines.
300
301 int text_width = output_max_columns - strm.GetIndentLevel() - 1;
302 int start = 0;
303 int end = start;
304 int final_end = actual_text.length();
305 int sub_len;
306
307 while (end < final_end) {
308 // Don't start the 'text' on a space, since we're already outputting the
309 // indentation.
310 while ((start < final_end) && (actual_text[start] == ' '))
311 start++;
312
313 end = start + text_width;
314 if (end > final_end)
315 end = final_end;
316 else {
317 // If we're not at the end of the text, make sure we break the line on
318 // white space.
319 while (end > start && actual_text[end] != ' ' &&
320 actual_text[end] != '\t' && actual_text[end] != '\n')
321 end--;
322 }
323
324 sub_len = end - start;
325 if (start != 0)
326 strm.EOL();
327 strm.Indent();
328 assert(start < final_end);
329 assert(start + sub_len <= final_end);
330 strm.Write(actual_text.c_str() + start, sub_len);
331 start = end + 1;
332 }
333 strm.EOL();
334 }
335}
336
337bool Options::SupportsLongOption(const char *long_option) {
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000338 if (!long_option || !long_option[0])
339 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000340
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000341 auto opt_defs = GetDefinitions();
342 if (opt_defs.empty())
343 return false;
344
345 const char *long_option_name = long_option;
346 if (long_option[0] == '-' && long_option[1] == '-')
347 long_option_name += 2;
348
349 for (auto &def : opt_defs) {
350 if (!def.long_option)
351 continue;
352
353 if (strcmp(def.long_option, long_option_name) == 0)
354 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355 }
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000356
Kate Stoneb9c1b512016-09-06 20:57:50 +0000357 return false;
358}
359
360enum OptionDisplayType {
361 eDisplayBestOption,
362 eDisplayShortOption,
363 eDisplayLongOption
364};
365
366static bool PrintOption(const OptionDefinition &opt_def,
367 OptionDisplayType display_type, const char *header,
368 const char *footer, bool show_optional, Stream &strm) {
369 const bool has_short_option = isprint8(opt_def.short_option) != 0;
370
371 if (display_type == eDisplayShortOption && !has_short_option)
372 return false;
373
374 if (header && header[0])
375 strm.PutCString(header);
376
377 if (show_optional && !opt_def.required)
378 strm.PutChar('[');
379 const bool show_short_option =
380 has_short_option && display_type != eDisplayLongOption;
381 if (show_short_option)
382 strm.Printf("-%c", opt_def.short_option);
383 else
384 strm.Printf("--%s", opt_def.long_option);
385 switch (opt_def.option_has_arg) {
386 case OptionParser::eNoArgument:
387 break;
388 case OptionParser::eRequiredArgument:
389 strm.Printf(" <%s>", CommandObject::GetArgumentName(opt_def.argument_type));
390 break;
391
392 case OptionParser::eOptionalArgument:
393 strm.Printf("%s[<%s>]", show_short_option ? "" : "=",
394 CommandObject::GetArgumentName(opt_def.argument_type));
395 break;
396 }
397 if (show_optional && !opt_def.required)
398 strm.PutChar(']');
399 if (footer && footer[0])
400 strm.PutCString(footer);
401 return true;
402}
403
404void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd,
405 uint32_t screen_width) {
406 const bool only_print_args = cmd->IsDashDashCommand();
407
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000408 auto opt_defs = GetDefinitions();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000409 const uint32_t save_indent_level = strm.GetIndentLevel();
Zachary Turnera4496982016-10-05 21:14:38 +0000410 llvm::StringRef name;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000411
412 StreamString arguments_str;
413
414 if (cmd) {
415 name = cmd->GetCommandName();
416 cmd->GetFormattedCommandArguments(arguments_str);
417 } else
418 name = "";
419
420 strm.PutCString("\nCommand Options Usage:\n");
421
422 strm.IndentMore(2);
423
424 // First, show each usage level set of options, e.g. <cmd>
425 // [options-for-level-0]
426 // <cmd>
427 // [options-for-level-1]
428 // etc.
429
430 const uint32_t num_options = NumCommandOptions();
431 if (num_options == 0)
432 return;
433
434 uint32_t num_option_sets = GetRequiredOptions().size();
435
436 uint32_t i;
437
438 if (!only_print_args) {
439 for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set) {
440 uint32_t opt_set_mask;
441
442 opt_set_mask = 1 << opt_set;
443 if (opt_set > 0)
444 strm.Printf("\n");
445 strm.Indent(name);
446
447 // Different option sets may require different args.
448 StreamString args_str;
449 if (cmd)
450 cmd->GetFormattedCommandArguments(args_str, opt_set_mask);
451
452 // First go through and print all options that take no arguments as
453 // a single string. If a command has "-a" "-b" and "-c", this will show
454 // up as [-abc]
455
456 std::set<int> options;
457 std::set<int>::const_iterator options_pos, options_end;
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000458 for (auto &def : opt_defs) {
459 if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000460 // Add current option to the end of out_stream.
461
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000462 if (def.required && def.option_has_arg == OptionParser::eNoArgument) {
463 options.insert(def.short_option);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464 }
465 }
466 }
467
468 if (options.empty() == false) {
469 // We have some required options with no arguments
470 strm.PutCString(" -");
471 for (i = 0; i < 2; ++i)
472 for (options_pos = options.begin(), options_end = options.end();
473 options_pos != options_end; ++options_pos) {
474 if (i == 0 && ::islower(*options_pos))
475 continue;
476 if (i == 1 && ::isupper(*options_pos))
477 continue;
478 strm << (char)*options_pos;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000479 }
480 }
481
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000482 options.clear();
483 for (auto &def : opt_defs) {
484 if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000485 // Add current option to the end of out_stream.
486
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000487 if (def.required == false &&
488 def.option_has_arg == OptionParser::eNoArgument) {
489 options.insert(def.short_option);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000490 }
491 }
492 }
493
494 if (options.empty() == false) {
495 // We have some required options with no arguments
496 strm.PutCString(" [-");
497 for (i = 0; i < 2; ++i)
498 for (options_pos = options.begin(), options_end = options.end();
499 options_pos != options_end; ++options_pos) {
500 if (i == 0 && ::islower(*options_pos))
501 continue;
502 if (i == 1 && ::isupper(*options_pos))
503 continue;
504 strm << (char)*options_pos;
505 }
506 strm.PutChar(']');
507 }
508
509 // First go through and print the required options (list them up front).
510
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000511 for (auto &def : opt_defs) {
512 if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) {
513 if (def.required && def.option_has_arg != OptionParser::eNoArgument)
514 PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515 }
516 }
517
518 // Now go through again, and this time only print the optional options.
519
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000520 for (auto &def : opt_defs) {
521 if (def.usage_mask & opt_set_mask) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522 // Add current option to the end of out_stream.
523
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000524 if (!def.required && def.option_has_arg != OptionParser::eNoArgument)
525 PrintOption(def, eDisplayBestOption, " ", nullptr, true, strm);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000526 }
527 }
528
529 if (args_str.GetSize() > 0) {
530 if (cmd->WantsRawCommandString() && !only_print_args)
531 strm.Printf(" --");
532
Zachary Turnerc1564272016-11-16 21:15:24 +0000533 strm << " " << args_str.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534 if (only_print_args)
535 break;
536 }
537 }
538 }
539
540 if (cmd && (only_print_args || cmd->WantsRawCommandString()) &&
541 arguments_str.GetSize() > 0) {
542 if (!only_print_args)
543 strm.PutChar('\n');
544 strm.Indent(name);
Zachary Turnerc1564272016-11-16 21:15:24 +0000545 strm << " " << arguments_str.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000546 }
547
548 strm.Printf("\n\n");
549
550 if (!only_print_args) {
551 // Now print out all the detailed information about the various options:
552 // long form, short form and help text:
553 // -short <argument> ( --long_name <argument> )
554 // help text
555
556 // This variable is used to keep track of which options' info we've printed
557 // out, because some options can be in
558 // more than one usage level, but we only want to print the long form of its
559 // information once.
560
561 std::multimap<int, uint32_t> options_seen;
562 strm.IndentMore(5);
563
564 // Put the unique command options in a vector & sort it, so we can output
565 // them alphabetically (by short_option)
566 // when writing out detailed help for each option.
567
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000568 i = 0;
569 for (auto &def : opt_defs)
570 options_seen.insert(std::make_pair(def.short_option, i++));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000571
572 // Go through the unique'd and alphabetically sorted vector of options, find
573 // the table entry for each option
574 // and write out the detailed help information for that option.
575
576 bool first_option_printed = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000577
578 for (auto pos : options_seen) {
579 i = pos.second;
580 // Print out the help information for this option.
581
582 // Put a newline separation between arguments
583 if (first_option_printed)
584 strm.EOL();
585 else
586 first_option_printed = true;
587
588 CommandArgumentType arg_type = opt_defs[i].argument_type;
589
590 StreamString arg_name_str;
591 arg_name_str.Printf("<%s>", CommandObject::GetArgumentName(arg_type));
592
593 strm.Indent();
594 if (opt_defs[i].short_option && isprint8(opt_defs[i].short_option)) {
595 PrintOption(opt_defs[i], eDisplayShortOption, nullptr, nullptr, false,
596 strm);
597 PrintOption(opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
598 } else {
599 // Short option is not printable, just print long option
600 PrintOption(opt_defs[i], eDisplayLongOption, nullptr, nullptr, false,
601 strm);
602 }
603 strm.EOL();
604
605 strm.IndentMore(5);
606
607 if (opt_defs[i].usage_text)
608 OutputFormattedUsageText(strm, opt_defs[i], screen_width);
609 if (opt_defs[i].enum_values != nullptr) {
610 strm.Indent();
611 strm.Printf("Values: ");
612 for (int k = 0; opt_defs[i].enum_values[k].string_value != nullptr;
613 k++) {
614 if (k == 0)
615 strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
616 else
617 strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
618 }
619 strm.EOL();
620 }
621 strm.IndentLess(5);
622 }
623 }
624
625 // Restore the indent level
626 strm.SetIndentLevel(save_indent_level);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000627}
628
Kate Stoneb9c1b512016-09-06 20:57:50 +0000629// This function is called when we have been given a potentially incomplete set
630// of
631// options, such as when an alias has been defined (more options might be added
632// at
633// at the time the alias is invoked). We need to verify that the options in the
634// set
635// m_seen_options are all part of a set that may be used together, but
636// m_seen_options
637// may be missing some of the "required" options.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000638
Kate Stoneb9c1b512016-09-06 20:57:50 +0000639bool Options::VerifyPartialOptions(CommandReturnObject &result) {
640 bool options_are_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641
Kate Stoneb9c1b512016-09-06 20:57:50 +0000642 int num_levels = GetRequiredOptions().size();
643 if (num_levels) {
644 for (int i = 0; i < num_levels && !options_are_valid; ++i) {
645 // In this case we are treating all options as optional rather than
646 // required.
647 // Therefore a set of options is correct if m_seen_options is a subset of
648 // the
649 // union of m_required_options and m_optional_options.
650 OptionSet union_set;
651 OptionsSetUnion(GetRequiredOptions()[i], GetOptionalOptions()[i],
652 union_set);
653 if (IsASubset(m_seen_options, union_set))
654 options_are_valid = true;
655 }
656 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000657
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658 return options_are_valid;
659}
Jim Inghamd6ccc602010-06-24 20:30:15 +0000660
Kate Stoneb9c1b512016-09-06 20:57:50 +0000661bool Options::HandleOptionCompletion(
662 Args &input, OptionElementVector &opt_element_vector, int cursor_index,
663 int char_pos, int match_start_point, int max_return_elements,
664 CommandInterpreter &interpreter, bool &word_complete,
665 lldb_private::StringList &matches) {
666 word_complete = true;
667
668 // For now we just scan the completions to see if the cursor position is in
669 // an option or its argument. Otherwise we'll call HandleArgumentCompletion.
670 // In the future we can use completion to validate options as well if we want.
671
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000672 auto opt_defs = GetDefinitions();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000673
674 std::string cur_opt_std_str(input.GetArgumentAtIndex(cursor_index));
675 cur_opt_std_str.erase(char_pos);
676 const char *cur_opt_str = cur_opt_std_str.c_str();
677
678 for (size_t i = 0; i < opt_element_vector.size(); i++) {
679 int opt_pos = opt_element_vector[i].opt_pos;
680 int opt_arg_pos = opt_element_vector[i].opt_arg_pos;
681 int opt_defs_index = opt_element_vector[i].opt_defs_index;
682 if (opt_pos == cursor_index) {
683 // We're completing the option itself.
684
685 if (opt_defs_index == OptionArgElement::eBareDash) {
686 // We're completing a bare dash. That means all options are open.
687 // FIXME: We should scan the other options provided and only complete
688 // options
689 // within the option group they belong to.
690 char opt_str[3] = {'-', 'a', '\0'};
691
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000692 for (auto &def : opt_defs) {
693 if (!def.short_option)
694 continue;
695 opt_str[1] = def.short_option;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000696 matches.AppendString(opt_str);
697 }
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000698
Kate Stoneb9c1b512016-09-06 20:57:50 +0000699 return true;
700 } else if (opt_defs_index == OptionArgElement::eBareDoubleDash) {
701 std::string full_name("--");
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000702 for (auto &def : opt_defs) {
703 if (!def.short_option)
704 continue;
705
Kate Stoneb9c1b512016-09-06 20:57:50 +0000706 full_name.erase(full_name.begin() + 2, full_name.end());
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000707 full_name.append(def.long_option);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000708 matches.AppendString(full_name.c_str());
709 }
710 return true;
711 } else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) {
712 // We recognized it, if it an incomplete long option, complete it anyway
713 // (getopt_long_only is
714 // happy with shortest unique string, but it's still a nice thing to
715 // do.) Otherwise return
716 // The string so the upper level code will know this is a full match and
717 // add the " ".
718 if (cur_opt_str && strlen(cur_opt_str) > 2 && cur_opt_str[0] == '-' &&
719 cur_opt_str[1] == '-' &&
720 strcmp(opt_defs[opt_defs_index].long_option, cur_opt_str) != 0) {
721 std::string full_name("--");
722 full_name.append(opt_defs[opt_defs_index].long_option);
723 matches.AppendString(full_name.c_str());
724 return true;
725 } else {
726 matches.AppendString(input.GetArgumentAtIndex(cursor_index));
727 return true;
728 }
729 } else {
730 // FIXME - not handling wrong options yet:
731 // Check to see if they are writing a long option & complete it.
732 // I think we will only get in here if the long option table has two
733 // elements
734 // that are not unique up to this point. getopt_long_only does shortest
735 // unique match
736 // for long options already.
737
738 if (cur_opt_str && strlen(cur_opt_str) > 2 && cur_opt_str[0] == '-' &&
739 cur_opt_str[1] == '-') {
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000740 for (auto &def : opt_defs) {
741 if (!def.long_option)
742 continue;
743
744 if (strstr(def.long_option, cur_opt_str + 2) == def.long_option) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000745 std::string full_name("--");
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000746 full_name.append(def.long_option);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000747 // The options definitions table has duplicates because of the
748 // way the grouping information is stored, so only add once.
749 bool duplicate = false;
750 for (size_t k = 0; k < matches.GetSize(); k++) {
751 if (matches.GetStringAtIndex(k) == full_name) {
752 duplicate = true;
753 break;
Jim Inghamd6ccc602010-06-24 20:30:15 +0000754 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000755 }
756 if (!duplicate)
757 matches.AppendString(full_name.c_str());
Jim Inghamd6ccc602010-06-24 20:30:15 +0000758 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000759 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000760 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000761 return true;
762 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000763
Kate Stoneb9c1b512016-09-06 20:57:50 +0000764 } else if (opt_arg_pos == cursor_index) {
765 // Okay the cursor is on the completion of an argument.
766 // See if it has a completion, otherwise return no matches.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000767
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768 if (opt_defs_index != -1) {
769 HandleOptionArgumentCompletion(
770 input, cursor_index, strlen(input.GetArgumentAtIndex(cursor_index)),
771 opt_element_vector, i, match_start_point, max_return_elements,
772 interpreter, word_complete, matches);
773 return true;
774 } else {
775 // No completion callback means no completions...
776 return true;
777 }
778
779 } else {
780 // Not the last element, keep going.
781 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000782 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000783 }
784 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785}
786
Kate Stoneb9c1b512016-09-06 20:57:50 +0000787bool Options::HandleOptionArgumentCompletion(
788 Args &input, int cursor_index, int char_pos,
789 OptionElementVector &opt_element_vector, int opt_element_index,
790 int match_start_point, int max_return_elements,
791 CommandInterpreter &interpreter, bool &word_complete,
792 lldb_private::StringList &matches) {
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000793 auto opt_defs = GetDefinitions();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000794 std::unique_ptr<SearchFilter> filter_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000795
Kate Stoneb9c1b512016-09-06 20:57:50 +0000796 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
797 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
798
799 // See if this is an enumeration type option, and if so complete it here:
800
801 OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values;
802 if (enum_values != nullptr) {
803 bool return_value = false;
804 std::string match_string(input.GetArgumentAtIndex(opt_arg_pos),
805 input.GetArgumentAtIndex(opt_arg_pos) + char_pos);
806 for (int i = 0; enum_values[i].string_value != nullptr; i++) {
807 if (strstr(enum_values[i].string_value, match_string.c_str()) ==
808 enum_values[i].string_value) {
809 matches.AppendString(enum_values[i].string_value);
810 return_value = true;
811 }
812 }
813 return return_value;
814 }
815
816 // If this is a source file or symbol type completion, and there is a
817 // -shlib option somewhere in the supplied arguments, then make a search
818 // filter
819 // for that shared library.
820 // FIXME: Do we want to also have an "OptionType" so we don't have to match
821 // string names?
822
823 uint32_t completion_mask = opt_defs[opt_defs_index].completion_type;
824
825 if (completion_mask == 0) {
826 lldb::CommandArgumentType option_arg_type =
827 opt_defs[opt_defs_index].argument_type;
828 if (option_arg_type != eArgTypeNone) {
829 const CommandObject::ArgumentTableEntry *arg_entry =
830 CommandObject::FindArgumentDataByType(
831 opt_defs[opt_defs_index].argument_type);
832 if (arg_entry)
833 completion_mask = arg_entry->completion_type;
834 }
835 }
836
837 if (completion_mask & CommandCompletions::eSourceFileCompletion ||
838 completion_mask & CommandCompletions::eSymbolCompletion) {
839 for (size_t i = 0; i < opt_element_vector.size(); i++) {
840 int cur_defs_index = opt_element_vector[i].opt_defs_index;
841
842 // trying to use <0 indices will definitely cause problems
843 if (cur_defs_index == OptionArgElement::eUnrecognizedArg ||
844 cur_defs_index == OptionArgElement::eBareDash ||
845 cur_defs_index == OptionArgElement::eBareDoubleDash)
846 continue;
847
848 int cur_arg_pos = opt_element_vector[i].opt_arg_pos;
849 const char *cur_opt_name = opt_defs[cur_defs_index].long_option;
850
851 // If this is the "shlib" option and there was an argument provided,
852 // restrict it to that shared library.
853 if (cur_opt_name && strcmp(cur_opt_name, "shlib") == 0 &&
854 cur_arg_pos != -1) {
855 const char *module_name = input.GetArgumentAtIndex(cur_arg_pos);
856 if (module_name) {
857 FileSpec module_spec(module_name, false);
858 lldb::TargetSP target_sp =
859 interpreter.GetDebugger().GetSelectedTarget();
860 // Search filters require a target...
861 if (target_sp)
862 filter_ap.reset(new SearchFilterByModule(target_sp, module_spec));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000863 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000864 break;
865 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000866 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000867 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000868
Kate Stoneb9c1b512016-09-06 20:57:50 +0000869 return CommandCompletions::InvokeCommonCompletionCallbacks(
870 interpreter, completion_mask, input.GetArgumentAtIndex(opt_arg_pos),
871 match_start_point, max_return_elements, filter_ap.get(), word_complete,
872 matches);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000873}
Greg Claytonf6b8b582011-04-13 00:18:08 +0000874
Kate Stoneb9c1b512016-09-06 20:57:50 +0000875void OptionGroupOptions::Append(OptionGroup *group) {
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000876 auto group_option_defs = group->GetDefinitions();
877 for (uint32_t i = 0; i < group_option_defs.size(); ++i) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000878 m_option_infos.push_back(OptionInfo(group, i));
879 m_option_defs.push_back(group_option_defs[i]);
880 }
Greg Clayton84c39662011-04-27 22:04:39 +0000881}
882
Kate Stoneb9c1b512016-09-06 20:57:50 +0000883const OptionGroup *OptionGroupOptions::GetGroupWithOption(char short_opt) {
884 for (uint32_t i = 0; i < m_option_defs.size(); i++) {
885 OptionDefinition opt_def = m_option_defs[i];
886 if (opt_def.short_option == short_opt)
887 return m_option_infos[i].option_group;
888 }
889 return nullptr;
Daniel Maleae0f8f572013-08-26 23:57:52 +0000890}
891
Kate Stoneb9c1b512016-09-06 20:57:50 +0000892void OptionGroupOptions::Append(OptionGroup *group, uint32_t src_mask,
893 uint32_t dst_mask) {
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000894 auto group_option_defs = group->GetDefinitions();
895 for (uint32_t i = 0; i < group_option_defs.size(); ++i) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000896 if (group_option_defs[i].usage_mask & src_mask) {
897 m_option_infos.push_back(OptionInfo(group, i));
898 m_option_defs.push_back(group_option_defs[i]);
899 m_option_defs.back().usage_mask = dst_mask;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000900 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000901 }
Greg Claytonf6b8b582011-04-13 00:18:08 +0000902}
903
Kate Stoneb9c1b512016-09-06 20:57:50 +0000904void OptionGroupOptions::Finalize() {
905 m_did_finalize = true;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000906}
907
Zachary Turner97206d52017-05-12 04:51:55 +0000908Status OptionGroupOptions::SetOptionValue(uint32_t option_idx,
909 llvm::StringRef option_value,
910 ExecutionContext *execution_context) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000911 // After calling OptionGroupOptions::Append(...), you must finalize the groups
912 // by calling OptionGroupOptions::Finlize()
913 assert(m_did_finalize);
Zachary Turner97206d52017-05-12 04:51:55 +0000914 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000915 if (option_idx < m_option_infos.size()) {
916 error = m_option_infos[option_idx].option_group->SetOptionValue(
Zachary Turnerfe114832016-11-12 16:56:47 +0000917 m_option_infos[option_idx].option_index, option_value,
918 execution_context);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919
920 } else {
921 error.SetErrorString("invalid option index"); // Shouldn't happen...
922 }
923 return error;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000924}
925
Kate Stoneb9c1b512016-09-06 20:57:50 +0000926void OptionGroupOptions::OptionParsingStarting(
927 ExecutionContext *execution_context) {
928 std::set<OptionGroup *> group_set;
929 OptionInfos::iterator pos, end = m_option_infos.end();
930 for (pos = m_option_infos.begin(); pos != end; ++pos) {
931 OptionGroup *group = pos->option_group;
932 if (group_set.find(group) == group_set.end()) {
933 group->OptionParsingStarting(execution_context);
934 group_set.insert(group);
Greg Claytonab65b342011-04-13 22:47:15 +0000935 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000936 }
Greg Claytonf6b8b582011-04-13 00:18:08 +0000937}
Zachary Turner97206d52017-05-12 04:51:55 +0000938Status
939OptionGroupOptions::OptionParsingFinished(ExecutionContext *execution_context) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940 std::set<OptionGroup *> group_set;
Zachary Turner97206d52017-05-12 04:51:55 +0000941 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000942 OptionInfos::iterator pos, end = m_option_infos.end();
943 for (pos = m_option_infos.begin(); pos != end; ++pos) {
944 OptionGroup *group = pos->option_group;
945 if (group_set.find(group) == group_set.end()) {
946 error = group->OptionParsingFinished(execution_context);
947 group_set.insert(group);
948 if (error.Fail())
949 return error;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000950 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000951 }
952 return error;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000953}
Pavel Labath5f56fca2018-03-09 10:39:40 +0000954
955// OptionParser permutes the arguments while processing them, so we create a
956// temporary array holding to avoid modification of the input arguments. The
957// options themselves are never modified, but the API expects a char * anyway,
958// hence the const_cast.
959static std::vector<char *> GetArgvForParsing(const Args &args) {
960 std::vector<char *> result;
961 // OptionParser always skips the first argument as it is based on getopt().
962 result.push_back(const_cast<char *>("<FAKE-ARG0>"));
963 for (const Args::ArgEntry &entry : args)
964 result.push_back(const_cast<char *>(entry.c_str()));
965 return result;
966}
967
968// Given a permuted argument, find it's position in the original Args vector.
969static Args::const_iterator FindOriginalIter(const char *arg,
970 const Args &original) {
971 return llvm::find_if(
972 original, [arg](const Args::ArgEntry &D) { return D.c_str() == arg; });
973}
974
975// Given a permuted argument, find it's index in the original Args vector.
976static size_t FindOriginalIndex(const char *arg, const Args &original) {
977 return std::distance(original.begin(), FindOriginalIter(arg, original));
978}
979
980// Construct a new Args object, consisting of the entries from the original
981// arguments, but in the permuted order.
982static Args ReconstituteArgsAfterParsing(llvm::ArrayRef<char *> parsed,
983 const Args &original) {
984 Args result;
985 for (const char *arg : parsed) {
986 auto pos = FindOriginalIter(arg, original);
987 assert(pos != original.end());
988 result.AppendArgument(pos->ref, pos->quote);
989 }
990 return result;
991}
992
993static size_t FindArgumentIndexForOption(const Args &args,
994 const Option &long_option) {
995 std::string short_opt = llvm::formatv("-{0}", char(long_option.val)).str();
996 std::string long_opt =
997 llvm::formatv("--{0}", long_option.definition->long_option);
998 for (const auto &entry : llvm::enumerate(args)) {
999 if (entry.value().ref.startswith(short_opt) ||
1000 entry.value().ref.startswith(long_opt))
1001 return entry.index();
1002 }
1003
1004 return size_t(-1);
1005}
1006
1007llvm::Expected<Args> Options::ParseAlias(const Args &args,
1008 OptionArgVector *option_arg_vector,
1009 std::string &input_line) {
1010 StreamString sstr;
1011 int i;
1012 Option *long_options = GetLongOptions();
1013
1014 if (long_options == nullptr) {
1015 return llvm::make_error<llvm::StringError>("Invalid long options",
1016 llvm::inconvertibleErrorCode());
1017 }
1018
1019 for (i = 0; long_options[i].definition != nullptr; ++i) {
1020 if (long_options[i].flag == nullptr) {
1021 sstr << (char)long_options[i].val;
1022 switch (long_options[i].definition->option_has_arg) {
1023 default:
1024 case OptionParser::eNoArgument:
1025 break;
1026 case OptionParser::eRequiredArgument:
1027 sstr << ":";
1028 break;
1029 case OptionParser::eOptionalArgument:
1030 sstr << "::";
1031 break;
1032 }
1033 }
1034 }
1035
1036 Args args_copy = args;
1037 std::vector<char *> argv = GetArgvForParsing(args);
1038
1039 std::unique_lock<std::mutex> lock;
1040 OptionParser::Prepare(lock);
1041 int val;
1042 while (1) {
1043 int long_options_index = -1;
1044 val = OptionParser::Parse(argv.size(), &*argv.begin(), sstr.GetString(),
1045 long_options, &long_options_index);
1046
1047 if (val == -1)
1048 break;
1049
1050 if (val == '?') {
1051 return llvm::make_error<llvm::StringError>(
1052 "Unknown or ambiguous option", llvm::inconvertibleErrorCode());
1053 }
1054
1055 if (val == 0)
1056 continue;
1057
1058 OptionSeen(val);
1059
1060 // Look up the long option index
1061 if (long_options_index == -1) {
1062 for (int j = 0; long_options[j].definition || long_options[j].flag ||
1063 long_options[j].val;
1064 ++j) {
1065 if (long_options[j].val == val) {
1066 long_options_index = j;
1067 break;
1068 }
1069 }
1070 }
1071
1072 // See if the option takes an argument, and see if one was supplied.
1073 if (long_options_index == -1) {
1074 return llvm::make_error<llvm::StringError>(
1075 llvm::formatv("Invalid option with value '{0}'.", char(val)).str(),
1076 llvm::inconvertibleErrorCode());
1077 }
1078
1079 StreamString option_str;
1080 option_str.Printf("-%c", val);
1081 const OptionDefinition *def = long_options[long_options_index].definition;
1082 int has_arg =
1083 (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
1084
1085 const char *option_arg = nullptr;
1086 switch (has_arg) {
1087 case OptionParser::eRequiredArgument:
1088 if (OptionParser::GetOptionArgument() == nullptr) {
1089 return llvm::make_error<llvm::StringError>(
1090 llvm::formatv("Option '{0}' is missing argument specifier.",
1091 option_str.GetString())
1092 .str(),
1093 llvm::inconvertibleErrorCode());
1094 }
1095 LLVM_FALLTHROUGH;
1096 case OptionParser::eOptionalArgument:
1097 option_arg = OptionParser::GetOptionArgument();
1098 LLVM_FALLTHROUGH;
1099 case OptionParser::eNoArgument:
1100 break;
1101 default:
1102 return llvm::make_error<llvm::StringError>(
1103 llvm::formatv("error with options table; invalid value in has_arg "
1104 "field for option '{0}'.",
1105 char(val))
1106 .str(),
1107 llvm::inconvertibleErrorCode());
1108 }
1109 if (!option_arg)
1110 option_arg = "<no-argument>";
1111 option_arg_vector->emplace_back(option_str.GetString(), has_arg,
1112 option_arg);
1113
1114 // Find option in the argument list; also see if it was supposed to take
1115 // an argument and if one was supplied. Remove option (and argument, if
1116 // given) from the argument list. Also remove them from the
1117 // raw_input_string, if one was passed in.
1118 size_t idx =
1119 FindArgumentIndexForOption(args_copy, long_options[long_options_index]);
1120 if (idx == size_t(-1))
1121 continue;
1122
1123 if (!input_line.empty()) {
1124 auto tmp_arg = args_copy[idx].ref;
1125 size_t pos = input_line.find(tmp_arg);
1126 if (pos != std::string::npos)
1127 input_line.erase(pos, tmp_arg.size());
1128 }
1129 args_copy.DeleteArgumentAtIndex(idx);
1130 if ((long_options[long_options_index].definition->option_has_arg !=
1131 OptionParser::eNoArgument) &&
1132 (OptionParser::GetOptionArgument() != nullptr) &&
1133 (idx < args_copy.GetArgumentCount()) &&
1134 (args_copy[idx].ref == OptionParser::GetOptionArgument())) {
1135 if (input_line.size() > 0) {
1136 auto tmp_arg = args_copy[idx].ref;
1137 size_t pos = input_line.find(tmp_arg);
1138 if (pos != std::string::npos)
1139 input_line.erase(pos, tmp_arg.size());
1140 }
1141 args_copy.DeleteArgumentAtIndex(idx);
1142 }
1143 }
1144
1145 return std::move(args_copy);
1146}
1147
1148OptionElementVector Options::ParseForCompletion(const Args &args,
1149 uint32_t cursor_index) {
1150 OptionElementVector option_element_vector;
1151 StreamString sstr;
1152 Option *long_options = GetLongOptions();
1153 option_element_vector.clear();
1154
1155 if (long_options == nullptr)
1156 return option_element_vector;
1157
1158 // Leading : tells getopt to return a : for a missing option argument AND
1159 // to suppress error messages.
1160
1161 sstr << ":";
1162 for (int i = 0; long_options[i].definition != nullptr; ++i) {
1163 if (long_options[i].flag == nullptr) {
1164 sstr << (char)long_options[i].val;
1165 switch (long_options[i].definition->option_has_arg) {
1166 default:
1167 case OptionParser::eNoArgument:
1168 break;
1169 case OptionParser::eRequiredArgument:
1170 sstr << ":";
1171 break;
1172 case OptionParser::eOptionalArgument:
1173 sstr << "::";
1174 break;
1175 }
1176 }
1177 }
1178
1179 std::unique_lock<std::mutex> lock;
1180 OptionParser::Prepare(lock);
1181 OptionParser::EnableError(false);
1182
1183 int val;
1184 auto opt_defs = GetDefinitions();
1185
1186 std::vector<char *> dummy_vec = GetArgvForParsing(args);
1187
1188 // I stick an element on the end of the input, because if the last element
1189 // is option that requires an argument, getopt_long_only will freak out.
1190 dummy_vec.push_back(const_cast<char *>("<FAKE-VALUE>"));
1191
1192 bool failed_once = false;
1193 uint32_t dash_dash_pos = -1;
1194
1195 while (1) {
1196 bool missing_argument = false;
1197 int long_options_index = -1;
1198
1199 val = OptionParser::Parse(dummy_vec.size(), &dummy_vec[0], sstr.GetString(),
1200 long_options, &long_options_index);
1201
1202 if (val == -1) {
1203 // When we're completing a "--" which is the last option on line,
1204 if (failed_once)
1205 break;
1206
1207 failed_once = true;
1208
1209 // If this is a bare "--" we mark it as such so we can complete it
1210 // successfully later. Handling the "--" is a little tricky, since that
1211 // may mean end of options or arguments, or the user might want to
1212 // complete options by long name. I make this work by checking whether
1213 // the cursor is in the "--" argument, and if so I assume we're
1214 // completing the long option, otherwise I let it pass to
1215 // OptionParser::Parse which will terminate the option parsing. Note, in
1216 // either case we continue parsing the line so we can figure out what
1217 // other options were passed. This will be useful when we come to
1218 // restricting completions based on what other options we've seen on the
1219 // line.
1220
1221 if (static_cast<size_t>(OptionParser::GetOptionIndex()) <
1222 dummy_vec.size() &&
1223 (strcmp(dummy_vec[OptionParser::GetOptionIndex() - 1], "--") == 0)) {
1224 dash_dash_pos = FindOriginalIndex(
1225 dummy_vec[OptionParser::GetOptionIndex() - 1], args);
1226 if (dash_dash_pos == cursor_index) {
1227 option_element_vector.push_back(
1228 OptionArgElement(OptionArgElement::eBareDoubleDash, dash_dash_pos,
1229 OptionArgElement::eBareDoubleDash));
1230 continue;
1231 } else
1232 break;
1233 } else
1234 break;
1235 } else if (val == '?') {
1236 option_element_vector.push_back(OptionArgElement(
1237 OptionArgElement::eUnrecognizedArg,
1238 FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1239 args),
1240 OptionArgElement::eUnrecognizedArg));
1241 continue;
1242 } else if (val == 0) {
1243 continue;
1244 } else if (val == ':') {
1245 // This is a missing argument.
1246 val = OptionParser::GetOptionErrorCause();
1247 missing_argument = true;
1248 }
1249
1250 OptionSeen(val);
1251
1252 // Look up the long option index
1253 if (long_options_index == -1) {
1254 for (int j = 0; long_options[j].definition || long_options[j].flag ||
1255 long_options[j].val;
1256 ++j) {
1257 if (long_options[j].val == val) {
1258 long_options_index = j;
1259 break;
1260 }
1261 }
1262 }
1263
1264 // See if the option takes an argument, and see if one was supplied.
1265 if (long_options_index >= 0) {
1266 int opt_defs_index = -1;
1267 for (size_t i = 0; i < opt_defs.size(); i++) {
1268 if (opt_defs[i].short_option != val)
1269 continue;
1270 opt_defs_index = i;
1271 break;
1272 }
1273
1274 const OptionDefinition *def = long_options[long_options_index].definition;
1275 int has_arg =
1276 (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
1277 switch (has_arg) {
1278 case OptionParser::eNoArgument:
1279 option_element_vector.push_back(OptionArgElement(
1280 opt_defs_index,
1281 FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1282 args),
1283 0));
1284 break;
1285 case OptionParser::eRequiredArgument:
1286 if (OptionParser::GetOptionArgument() != nullptr) {
1287 int arg_index;
1288 if (missing_argument)
1289 arg_index = -1;
1290 else
1291 arg_index = OptionParser::GetOptionIndex() - 2;
1292
1293 option_element_vector.push_back(OptionArgElement(
1294 opt_defs_index,
1295 FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 2],
1296 args),
1297 arg_index));
1298 } else {
1299 option_element_vector.push_back(OptionArgElement(
1300 opt_defs_index,
1301 FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1302 args),
1303 -1));
1304 }
1305 break;
1306 case OptionParser::eOptionalArgument:
1307 if (OptionParser::GetOptionArgument() != nullptr) {
1308 option_element_vector.push_back(OptionArgElement(
1309 opt_defs_index,
1310 FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 2],
1311 args),
1312 FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1313 args)));
1314 } else {
1315 option_element_vector.push_back(OptionArgElement(
1316 opt_defs_index,
1317 FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 2],
1318 args),
1319 FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1320 args)));
1321 }
1322 break;
1323 default:
1324 // The options table is messed up. Here we'll just continue
1325 option_element_vector.push_back(OptionArgElement(
1326 OptionArgElement::eUnrecognizedArg,
1327 FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1328 args),
1329 OptionArgElement::eUnrecognizedArg));
1330 break;
1331 }
1332 } else {
1333 option_element_vector.push_back(OptionArgElement(
1334 OptionArgElement::eUnrecognizedArg,
1335 FindOriginalIndex(dummy_vec[OptionParser::GetOptionIndex() - 1],
1336 args),
1337 OptionArgElement::eUnrecognizedArg));
1338 }
1339 }
1340
1341 // Finally we have to handle the case where the cursor index points at a
1342 // single "-". We want to mark that in
1343 // the option_element_vector, but only if it is not after the "--". But it
1344 // turns out that OptionParser::Parse just ignores
1345 // an isolated "-". So we have to look it up by hand here. We only care if
1346 // it is AT the cursor position.
1347 // Note, a single quoted dash is not the same as a single dash...
1348
1349 const Args::ArgEntry &cursor = args[cursor_index];
1350 if ((static_cast<int32_t>(dash_dash_pos) == -1 ||
1351 cursor_index < dash_dash_pos) &&
1352 cursor.quote == '\0' && cursor.ref == "-") {
1353 option_element_vector.push_back(
1354 OptionArgElement(OptionArgElement::eBareDash, cursor_index,
1355 OptionArgElement::eBareDash));
1356 }
1357 return option_element_vector;
1358}
1359
1360llvm::Expected<Args> Options::Parse(const Args &args,
1361 ExecutionContext *execution_context,
1362 lldb::PlatformSP platform_sp,
1363 bool require_validation) {
1364 StreamString sstr;
1365 Status error;
1366 Option *long_options = GetLongOptions();
1367 if (long_options == nullptr) {
1368 return llvm::make_error<llvm::StringError>("Invalid long options.",
1369 llvm::inconvertibleErrorCode());
1370 }
1371
1372 for (int i = 0; long_options[i].definition != nullptr; ++i) {
1373 if (long_options[i].flag == nullptr) {
1374 if (isprint8(long_options[i].val)) {
1375 sstr << (char)long_options[i].val;
1376 switch (long_options[i].definition->option_has_arg) {
1377 default:
1378 case OptionParser::eNoArgument:
1379 break;
1380 case OptionParser::eRequiredArgument:
1381 sstr << ':';
1382 break;
1383 case OptionParser::eOptionalArgument:
1384 sstr << "::";
1385 break;
1386 }
1387 }
1388 }
1389 }
1390 std::vector<char *> argv = GetArgvForParsing(args);
1391 std::unique_lock<std::mutex> lock;
1392 OptionParser::Prepare(lock);
1393 int val;
1394 while (1) {
1395 int long_options_index = -1;
1396 val = OptionParser::Parse(argv.size(), &*argv.begin(), sstr.GetString(),
1397 long_options, &long_options_index);
1398 if (val == -1)
1399 break;
1400
1401 // Did we get an error?
1402 if (val == '?') {
1403 error.SetErrorStringWithFormat("unknown or ambiguous option");
1404 break;
1405 }
1406 // The option auto-set itself
1407 if (val == 0)
1408 continue;
1409
1410 OptionSeen(val);
1411
1412 // Lookup the long option index
1413 if (long_options_index == -1) {
1414 for (int i = 0; long_options[i].definition || long_options[i].flag ||
1415 long_options[i].val;
1416 ++i) {
1417 if (long_options[i].val == val) {
1418 long_options_index = i;
1419 break;
1420 }
1421 }
1422 }
1423 // Call the callback with the option
1424 if (long_options_index >= 0 &&
1425 long_options[long_options_index].definition) {
1426 const OptionDefinition *def = long_options[long_options_index].definition;
1427
1428 if (!platform_sp) {
1429 // User did not pass in an explicit platform. Try to grab
1430 // from the execution context.
1431 TargetSP target_sp =
1432 execution_context ? execution_context->GetTargetSP() : TargetSP();
1433 platform_sp = target_sp ? target_sp->GetPlatform() : PlatformSP();
1434 }
1435 OptionValidator *validator = def->validator;
1436
1437 if (!platform_sp && require_validation) {
1438 // Caller requires validation but we cannot validate as we
1439 // don't have the mandatory platform against which to
1440 // validate.
1441 return llvm::make_error<llvm::StringError>(
1442 "cannot validate options: no platform available",
1443 llvm::inconvertibleErrorCode());
1444 }
1445
1446 bool validation_failed = false;
1447 if (platform_sp) {
1448 // Ensure we have an execution context, empty or not.
1449 ExecutionContext dummy_context;
1450 ExecutionContext *exe_ctx_p =
1451 execution_context ? execution_context : &dummy_context;
1452 if (validator && !validator->IsValid(*platform_sp, *exe_ctx_p)) {
1453 validation_failed = true;
1454 error.SetErrorStringWithFormat("Option \"%s\" invalid. %s",
1455 def->long_option,
1456 def->validator->LongConditionString());
1457 }
1458 }
1459
1460 // As long as validation didn't fail, we set the option value.
1461 if (!validation_failed)
1462 error =
1463 SetOptionValue(long_options_index,
1464 (def->option_has_arg == OptionParser::eNoArgument)
1465 ? nullptr
1466 : OptionParser::GetOptionArgument(),
1467 execution_context);
1468 } else {
1469 error.SetErrorStringWithFormat("invalid option with value '%i'", val);
1470 }
1471 if (error.Fail())
1472 return error.ToError();
1473 }
1474
1475 argv.erase(argv.begin(), argv.begin() + OptionParser::GetOptionIndex());
1476 return ReconstituteArgsAfterParsing(argv, args);
1477}