blob: 9baa9d26d431c137d61f4366c21bf89f5391b9c2 [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
14#include <bitset>
15
16// Other libraries and framework includes
17// Project includes
18#include "lldb/Interpreter/CommandObject.h"
19#include "lldb/Interpreter/CommandReturnObject.h"
20#include "lldb/Interpreter/CommandCompletions.h"
21#include "lldb/Interpreter/CommandInterpreter.h"
22#include "lldb/Core/StreamString.h"
23#include "lldb/Target/Target.h"
24
25using namespace lldb;
26using namespace lldb_private;
27
28//-------------------------------------------------------------------------
29// Options
30//-------------------------------------------------------------------------
31Options::Options () :
32 m_getopt_table ()
33{
Jim Ingham86511212010-06-15 18:47:14 +000034 BuildValidOptionSets();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035}
36
37Options::~Options ()
38{
39}
40
41
42void
43Options::ResetOptionValues ()
44{
45 m_seen_options.clear();
46}
47
48void
49Options::OptionSeen (int option_idx)
50{
51 m_seen_options.insert ((char) option_idx);
52}
53
54// Returns true is set_a is a subset of set_b; Otherwise returns false.
55
56bool
57Options::IsASubset (const OptionSet& set_a, const OptionSet& set_b)
58{
59 bool is_a_subset = true;
60 OptionSet::const_iterator pos_a;
61 OptionSet::const_iterator pos_b;
62
63 // set_a is a subset of set_b if every member of set_a is also a member of set_b
64
65 for (pos_a = set_a.begin(); pos_a != set_a.end() && is_a_subset; ++pos_a)
66 {
67 pos_b = set_b.find(*pos_a);
68 if (pos_b == set_b.end())
69 is_a_subset = false;
70 }
71
72 return is_a_subset;
73}
74
75// Returns the set difference set_a - set_b, i.e. { x | ElementOf (x, set_a) && !ElementOf (x, set_b) }
76
77size_t
78Options::OptionsSetDiff (const OptionSet& set_a, const OptionSet& set_b, OptionSet& diffs)
79{
80 size_t num_diffs = 0;
81 OptionSet::const_iterator pos_a;
82 OptionSet::const_iterator pos_b;
83
84 for (pos_a = set_a.begin(); pos_a != set_a.end(); ++pos_a)
85 {
86 pos_b = set_b.find(*pos_a);
87 if (pos_b == set_b.end())
88 {
89 ++num_diffs;
90 diffs.insert(*pos_a);
91 }
92 }
93
94 return num_diffs;
95}
96
97// Returns the union of set_a and set_b. Does not put duplicate members into the union.
98
99void
100Options::OptionsSetUnion (const OptionSet &set_a, const OptionSet &set_b, OptionSet &union_set)
101{
102 OptionSet::const_iterator pos;
103 OptionSet::iterator pos_union;
104
105 // Put all the elements of set_a into the union.
106
107 for (pos = set_a.begin(); pos != set_a.end(); ++pos)
108 union_set.insert(*pos);
109
110 // Put all the elements of set_b that are not already there into the union.
111 for (pos = set_b.begin(); pos != set_b.end(); ++pos)
112 {
113 pos_union = union_set.find(*pos);
114 if (pos_union == union_set.end())
115 union_set.insert(*pos);
116 }
117}
118
119bool
120Options::VerifyOptions (CommandReturnObject &result)
121{
122 bool options_are_valid = false;
123
124 int num_levels = m_required_options.size();
125 if (num_levels)
126 {
127 for (int i = 0; i < num_levels && !options_are_valid; ++i)
128 {
129 // This is the correct set of options if: 1). m_seen_options contains all of m_required_options[i]
130 // (i.e. all the required options at this level are a subset of m_seen_options); AND
131 // 2). { m_seen_options - m_required_options[i] is a subset of m_options_options[i] (i.e. all the rest of
132 // m_seen_options are in the set of optional options at this level.
133
134 // Check to see if all of m_required_options[i] are a subset of m_seen_options
135 if (IsASubset (m_required_options[i], m_seen_options))
136 {
137 // Construct the set difference: remaining_options = {m_seen_options} - {m_required_options[i]}
138 OptionSet remaining_options;
139 OptionsSetDiff (m_seen_options, m_required_options[i], remaining_options);
140 // Check to see if remaining_options is a subset of m_optional_options[i]
141 if (IsASubset (remaining_options, m_optional_options[i]))
142 options_are_valid = true;
143 }
144 }
145 }
146 else
147 {
148 options_are_valid = true;
149 }
150
151 if (options_are_valid)
152 {
153 result.SetStatus (eReturnStatusSuccessFinishNoResult);
154 }
155 else
156 {
157 result.AppendError ("invalid combination of options for the given command");
158 result.SetStatus (eReturnStatusFailed);
159 }
160
161 return options_are_valid;
162}
163
Jim Ingham86511212010-06-15 18:47:14 +0000164// This is called in the Options constructor, though we could call it lazily if that ends up being
165// a performance problem.
166
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167void
168Options::BuildValidOptionSets ()
169{
170 // Check to see if we already did this.
171 if (m_required_options.size() != 0)
172 return;
173
174 // Check to see if there are any options.
175 int num_options = NumCommandOptions ();
176 if (num_options == 0)
177 return;
178
179 const lldb::OptionDefinition *full_options_table = GetDefinitions();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180 m_required_options.resize(1);
181 m_optional_options.resize(1);
Jim Ingham86511212010-06-15 18:47:14 +0000182
183 // First count the number of option sets we've got. Ignore LLDB_ALL_OPTION_SETS...
184
185 uint32_t num_option_sets = 0;
186
187 for (int i = 0; i < num_options; i++)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188 {
Jim Ingham86511212010-06-15 18:47:14 +0000189 uint32_t this_usage_mask = full_options_table[i].usage_mask;
190 if (this_usage_mask == LLDB_OPT_SET_ALL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191 {
Jim Ingham86511212010-06-15 18:47:14 +0000192 if (num_option_sets == 0)
193 num_option_sets = 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000194 }
195 else
196 {
Jim Ingham86511212010-06-15 18:47:14 +0000197 for (int j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
198 {
199 if (this_usage_mask & 1 << j)
200 {
201 if (num_option_sets <= j)
202 num_option_sets = j + 1;
203 }
204 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205 }
Jim Ingham86511212010-06-15 18:47:14 +0000206 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207
Jim Ingham86511212010-06-15 18:47:14 +0000208 if (num_option_sets > 0)
209 {
210 m_required_options.resize(num_option_sets);
211 m_optional_options.resize(num_option_sets);
212
213 for (int i = 0; i < num_options; ++i)
214 {
215 for (int j = 0; j < num_option_sets; j++)
216 {
217 if (full_options_table[i].usage_mask & 1 << j)
218 {
219 if (full_options_table[i].required)
220 m_required_options[j].insert(full_options_table[i].short_option);
221 else
222 m_optional_options[j].insert(full_options_table[i].short_option);
223 }
224 }
225 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 }
227}
228
229uint32_t
230Options::NumCommandOptions ()
231{
232 const lldb::OptionDefinition *full_options_table = GetDefinitions ();
Jim Ingham86511212010-06-15 18:47:14 +0000233 if (full_options_table == NULL)
234 return 0;
235
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236 int i = 0;
237
238 if (full_options_table != NULL)
239 {
240 while (full_options_table[i].long_option != NULL)
241 ++i;
242 }
243
244 return i;
245}
246
247struct option *
248Options::GetLongOptions ()
249{
250 // Check to see if this has already been done.
251 if (m_getopt_table.empty())
252 {
253 // Check to see if there are any options.
254 const uint32_t num_options = NumCommandOptions();
255 if (num_options == 0)
256 return NULL;
257
258 uint32_t i;
259 uint32_t j;
260 const lldb::OptionDefinition *full_options_table = GetDefinitions();
261
262 std::bitset<256> option_seen;
263
264 m_getopt_table.resize(num_options + 1);
265 for (i = 0, j = 0; i < num_options; ++i)
266 {
267 char short_opt = full_options_table[i].short_option;
268
269 if (option_seen.test(short_opt) == false)
270 {
271 m_getopt_table[j].name = full_options_table[i].long_option;
272 m_getopt_table[j].has_arg = full_options_table[i].option_has_arg;
273 m_getopt_table[j].flag = NULL;
274 m_getopt_table[j].val = full_options_table[i].short_option;
275 option_seen.set(short_opt);
276 ++j;
277 }
278 }
279
280 //getopt_long requires a NULL final entry in the table:
281
282 m_getopt_table[j].name = NULL;
283 m_getopt_table[j].has_arg = 0;
284 m_getopt_table[j].flag = NULL;
285 m_getopt_table[j].val = 0;
286 }
287
288 return m_getopt_table.data();
289}
290
291
292// This function takes INDENT, which tells how many spaces to output at the front of each line; SPACES, which is
293// a string containing 80 spaces; and TEXT, which is the text that is to be output. It outputs the text, on
294// multiple lines if necessary, to RESULT, with INDENT spaces at the front of each line. It breaks lines on spaces,
295// tabs or newlines, shortening the line if necessary to not break in the middle of a word. It assumes that each
296// output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
297
298
299void
300Options::OutputFormattedUsageText
301(
302 Stream &strm,
303 const char *text,
304 uint32_t output_max_columns
305)
306{
307 int len = strlen (text);
308
309 // Will it all fit on one line?
310
311 if ((len + strm.GetIndentLevel()) < output_max_columns)
312 {
313 // Output it as a single line.
314 strm.Indent (text);
315 strm.EOL();
316 }
317 else
318 {
319 // We need to break it up into multiple lines.
320
321 int text_width = output_max_columns - strm.GetIndentLevel() - 1;
322 int start = 0;
323 int end = start;
324 int final_end = strlen (text);
325 int sub_len;
326
327 while (end < final_end)
328 {
329 // Don't start the 'text' on a space, since we're already outputting the indentation.
330 while ((start < final_end) && (text[start] == ' '))
331 start++;
332
333 end = start + text_width;
334 if (end > final_end)
335 end = final_end;
336 else
337 {
338 // If we're not at the end of the text, make sure we break the line on white space.
339 while (end > start
340 && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
341 end--;
342 }
343
344 sub_len = end - start;
345 if (start != 0)
346 strm.EOL();
347 strm.Indent();
348 assert (start < final_end);
349 assert (start + sub_len <= final_end);
350 strm.Write(text + start, sub_len);
351 start = end + 1;
352 }
353 strm.EOL();
354 }
355}
356
357void
358Options::GenerateOptionUsage
359(
360 Stream &strm,
361 CommandObject *cmd,
362 const char *program_name)
363{
364 uint32_t screen_width = 80;
365 const lldb::OptionDefinition *full_options_table = GetDefinitions();
366 const uint32_t save_indent_level = strm.GetIndentLevel();
367 const char *name;
368
369 if (cmd)
370 name = cmd->GetCommandName();
371 else
372 name = program_name;
373
374 strm.PutCString ("\nCommand Options Usage:\n");
375
376 strm.IndentMore(2);
377
378 // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
379 // <cmd> [options-for-level-1]
380 // etc.
381
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382 const uint32_t num_options = NumCommandOptions();
Jim Ingham86511212010-06-15 18:47:14 +0000383 if (num_options == 0)
384 return;
385
386 BuildValidOptionSets ();
387 int num_option_sets = m_required_options.size();
388
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389 uint32_t i;
Jim Ingham86511212010-06-15 18:47:14 +0000390
391 for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392 {
Jim Ingham86511212010-06-15 18:47:14 +0000393 uint32_t opt_set_mask;
394
395 opt_set_mask = 1 << opt_set;
396 if (opt_set > 0)
397 strm.Printf ("\n");
398 strm.Indent (name);
399
400 for (i = 0; i < num_options; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000401 {
Jim Ingham86511212010-06-15 18:47:14 +0000402 if (full_options_table[i].usage_mask & opt_set_mask)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403 {
Jim Ingham86511212010-06-15 18:47:14 +0000404 // Add current option to the end of out_stream.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405
Jim Ingham86511212010-06-15 18:47:14 +0000406 if (full_options_table[i].required)
407 {
408 if (full_options_table[i].option_has_arg == required_argument)
409 {
410 strm.Printf (" -%c %s",
411 full_options_table[i].short_option,
412 full_options_table[i].argument_name);
413 }
414 else if (full_options_table[i].option_has_arg == optional_argument)
415 {
416 strm.Printf (" -%c [%s]",
417 full_options_table[i].short_option,
418 full_options_table[i].argument_name);
419 }
420 else
421 strm.Printf (" -%c", full_options_table[i].short_option);
422 }
423 else
424 {
425 if (full_options_table[i].option_has_arg == required_argument)
426 strm.Printf (" [-%c %s]", full_options_table[i].short_option,
427 full_options_table[i].argument_name);
428 else if (full_options_table[i].option_has_arg == optional_argument)
429 strm.Printf (" [-%c [%s]]", full_options_table[i].short_option,
430 full_options_table[i].argument_name);
431 else
432 strm.Printf (" [-%c]", full_options_table[i].short_option);
433 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000434 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435 }
436 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437 strm.Printf ("\n\n");
438
439 // Now print out all the detailed information about the various options: long form, short form and help text:
440 // -- long_name <argument>
441 // - short <argument>
442 // help text
443
444 // This variable is used to keep track of which options' info we've printed out, because some options can be in
445 // more than one usage level, but we only want to print the long form of its information once.
446
447 OptionSet options_seen;
448 OptionSet::iterator pos;
449 strm.IndentMore (5);
450
451 int first_option_printed = 1;
452 for (i = 0; i < num_options; ++i)
453 {
454 // Only print out this option if we haven't already seen it.
455 pos = options_seen.find (full_options_table[i].short_option);
456 if (pos == options_seen.end())
457 {
458 // Put a newline separation between arguments
459 if (first_option_printed)
460 first_option_printed = 0;
461 else
462 strm.EOL();
463
464 options_seen.insert (full_options_table[i].short_option);
465 strm.Indent ();
466 strm.Printf ("-%c ", full_options_table[i].short_option);
467 if (full_options_table[i].argument_name != NULL)
468 strm.PutCString(full_options_table[i].argument_name);
469 strm.EOL();
470 strm.Indent ();
471 strm.Printf ("--%s ", full_options_table[i].long_option);
472 if (full_options_table[i].argument_name != NULL)
473 strm.PutCString(full_options_table[i].argument_name);
474 strm.EOL();
475
476 strm.IndentMore (5);
477
478 if (full_options_table[i].usage_text)
479 OutputFormattedUsageText (strm,
480 full_options_table[i].usage_text,
481 screen_width);
482 if (full_options_table[i].enum_values != NULL)
483 {
484 strm.Indent ();
485 strm.Printf("Values: ");
486 for (int j = 0; full_options_table[i].enum_values[j].string_value != NULL; j++)
487 {
488 if (j == 0)
489 strm.Printf("%s", full_options_table[i].enum_values[j].string_value);
490 else
491 strm.Printf(" | %s", full_options_table[i].enum_values[j].string_value);
492 }
493 strm.EOL();
494 }
495 strm.IndentLess (5);
496 }
497 }
498
499 // Restore the indent level
500 strm.SetIndentLevel (save_indent_level);
501}
502
503// This function is called when we have been given a potentially incomplete set of
504// options, such as when an alias has been defined (more options might be added at
505// at the time the alias is invoked). We need to verify that the options in the set
506// m_seen_options are all part of a set that may be used together, but m_seen_options
507// may be missing some of the "required" options.
508
509bool
510Options::VerifyPartialOptions (CommandReturnObject &result)
511{
512 bool options_are_valid = false;
513
514 int num_levels = m_required_options.size();
515 if (num_levels)
516 {
517 for (int i = 0; i < num_levels && !options_are_valid; ++i)
518 {
519 // In this case we are treating all options as optional rather than required.
520 // Therefore a set of options is correct if m_seen_options is a subset of the
521 // union of m_required_options and m_optional_options.
522 OptionSet union_set;
523 OptionsSetUnion (m_required_options[i], m_optional_options[i], union_set);
524 if (IsASubset (m_seen_options, union_set))
525 options_are_valid = true;
526 }
527 }
528
529 return options_are_valid;
530}
531
532bool
533Options::HandleOptionCompletion
534(
Greg Clayton66111032010-06-23 01:19:29 +0000535 CommandInterpreter &interpreter,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536 Args &input,
537 OptionElementVector &opt_element_vector,
538 int cursor_index,
539 int char_pos,
540 int match_start_point,
541 int max_return_elements,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000542 lldb_private::StringList &matches
543)
544{
545 // For now we just scan the completions to see if the cursor position is in
546 // an option or its argument. Otherwise we'll call HandleArgumentCompletion.
547 // In the future we can use completion to validate options as well if we want.
548
549 const OptionDefinition *opt_defs = GetDefinitions();
550
551 std::string cur_opt_std_str (input.GetArgumentAtIndex(cursor_index));
552 cur_opt_std_str.erase(char_pos);
553 const char *cur_opt_str = cur_opt_std_str.c_str();
554
555 for (int i = 0; i < opt_element_vector.size(); i++)
556 {
557 int opt_pos = opt_element_vector[i].opt_pos;
558 int opt_arg_pos = opt_element_vector[i].opt_arg_pos;
559 int opt_defs_index = opt_element_vector[i].opt_defs_index;
560 if (opt_pos == cursor_index)
561 {
562 // We're completing the option itself.
563 if (opt_defs_index != -1)
564 {
565 // We recognized it, if it an incomplete long option, complete it anyway (getopt_long is
566 // happy with shortest unique string, but it's still a nice thing to do.) Otherwise return
567 // The string so the upper level code will know this is a full match and add the " ".
568 if (cur_opt_str && strlen (cur_opt_str) > 2
569 && cur_opt_str[0] == '-' && cur_opt_str[1] == '-'
570 && strcmp (opt_defs[opt_defs_index].long_option, cur_opt_str) != 0)
571 {
572 std::string full_name ("--");
573 full_name.append (opt_defs[opt_defs_index].long_option);
574 matches.AppendString(full_name.c_str());
575 return true;
576 }
577 else
578 {
579 matches.AppendString(input.GetArgumentAtIndex(cursor_index));
580 return true;
581 }
582 }
583 else
584 {
585 // FIXME - not handling wrong options yet:
586 // Check to see if they are writing a long option & complete it.
587 // I think we will only get in here if the long option table has two elements
588 // that are not unique up to this point. getopt_long does shortest unique match
589 // for long options already.
590
591 if (cur_opt_str && strlen (cur_opt_str) > 2
592 && cur_opt_str[0] == '-' && cur_opt_str[1] == '-')
593 {
594 for (int i = 0 ; opt_defs[i].short_option != 0 ; i++)
595 {
596 if (strstr(opt_defs[i].long_option, cur_opt_str + 2) == opt_defs[i].long_option)
597 {
598 std::string full_name ("--");
599 full_name.append (opt_defs[i].long_option);
600 // The options definitions table has duplicates because of the
601 // way the grouping information is stored, so only add once.
602 bool duplicate = false;
603 for (int j = 0; j < matches.GetSize(); j++)
604 {
605 if (matches.GetStringAtIndex(j) == full_name)
606 {
607 duplicate = true;
608 break;
609 }
610 }
611 if (!duplicate)
612 matches.AppendString(full_name.c_str());
613 }
614 }
615 }
616 return true;
617 }
618
619
620 }
621 else if (opt_arg_pos == cursor_index)
622 {
623 // Okay the cursor is on the completion of an argument.
624 // See if it has a completion, otherwise return no matches.
625
626 if (opt_defs_index != -1)
627 {
Greg Clayton66111032010-06-23 01:19:29 +0000628 HandleOptionArgumentCompletion (interpreter,
629 input,
630 cursor_index,
631 strlen (input.GetArgumentAtIndex(cursor_index)),
632 opt_element_vector,
633 i,
634 match_start_point,
635 max_return_elements,
636 matches);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000637 return true;
638 }
639 else
640 {
641 // No completion callback means no completions...
642 return true;
643 }
644
645 }
646 else
647 {
648 // Not the last element, keep going.
649 continue;
650 }
651 }
652 return false;
653}
654
655bool
656Options::HandleOptionArgumentCompletion
657(
Greg Clayton66111032010-06-23 01:19:29 +0000658 CommandInterpreter &interpreter,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000659 Args &input,
660 int cursor_index,
661 int char_pos,
662 OptionElementVector &opt_element_vector,
663 int opt_element_index,
664 int match_start_point,
665 int max_return_elements,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666 lldb_private::StringList &matches
667)
668{
669 const OptionDefinition *opt_defs = GetDefinitions();
670 std::auto_ptr<SearchFilter> filter_ap;
671
672 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
673 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
674
675 // See if this is an enumeration type option, and if so complete it here:
676
677 OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values;
678 if (enum_values != NULL)
679 {
680 bool return_value = false;
681 std::string match_string(input.GetArgumentAtIndex (opt_arg_pos), input.GetArgumentAtIndex (opt_arg_pos) + char_pos);
682 for (int i = 0; enum_values[i].string_value != NULL; i++)
683 {
684 if (strstr(enum_values[i].string_value, match_string.c_str()) == enum_values[i].string_value)
685 {
686 matches.AppendString (enum_values[i].string_value);
687 return_value = true;
688 }
689 }
690 return return_value;
691 }
692
693 // If this is a source file or symbol type completion, and there is a
694 // -shlib option somewhere in the supplied arguments, then make a search filter
695 // for that shared library.
696 // FIXME: Do we want to also have an "OptionType" so we don't have to match string names?
697
698 uint32_t completion_mask = opt_defs[opt_defs_index].completionType;
699 if (completion_mask & CommandCompletions::eSourceFileCompletion
700 || completion_mask & CommandCompletions::eSymbolCompletion)
701 {
702 for (int i = 0; i < opt_element_vector.size(); i++)
703 {
704 int cur_defs_index = opt_element_vector[i].opt_defs_index;
705 int cur_arg_pos = opt_element_vector[i].opt_arg_pos;
706 const char *cur_opt_name = opt_defs[cur_defs_index].long_option;
707
708 // If this is the "shlib" option and there was an argument provided,
709 // restrict it to that shared library.
710 if (strcmp(cur_opt_name, "shlib") == 0 && cur_arg_pos != -1)
711 {
712 const char *module_name = input.GetArgumentAtIndex(cur_arg_pos);
713 if (module_name)
714 {
715 FileSpec module_spec(module_name);
Greg Clayton66111032010-06-23 01:19:29 +0000716 lldb::TargetSP target_sp = interpreter.GetDebugger().GetCurrentTarget();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000717 // Search filters require a target...
718 if (target_sp != NULL)
719 filter_ap.reset (new SearchFilterByModule (target_sp, module_spec));
720 }
721 break;
722 }
723 }
724 }
725
Greg Clayton66111032010-06-23 01:19:29 +0000726 return CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
727 completion_mask,
728 input.GetArgumentAtIndex (opt_arg_pos),
729 match_start_point,
730 max_return_elements,
731 filter_ap.get(),
732 matches);
733
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734}