1 //===-- 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 
10 #include "lldb/Interpreter/Options.h"
11 
12 // C Includes
13 // C++ Includes
14 #include <bitset>
15 #include <algorithm>
16 
17 // Other libraries and framework includes
18 // Project includes
19 #include "lldb/Interpreter/CommandObject.h"
20 #include "lldb/Interpreter/CommandReturnObject.h"
21 #include "lldb/Interpreter/CommandCompletions.h"
22 #include "lldb/Interpreter/CommandInterpreter.h"
23 #include "lldb/Core/StreamString.h"
24 #include "lldb/Target/Target.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 //-------------------------------------------------------------------------
30 // Options
31 //-------------------------------------------------------------------------
32 Options::Options () :
33     m_getopt_table ()
34 {
35     BuildValidOptionSets();
36 }
37 
38 Options::~Options ()
39 {
40 }
41 
42 
43 void
44 Options::ResetOptionValues ()
45 {
46     m_seen_options.clear();
47 }
48 
49 void
50 Options::OptionSeen (int option_idx)
51 {
52     m_seen_options.insert ((char) option_idx);
53 }
54 
55 // Returns true is set_a is a subset of set_b;  Otherwise returns false.
56 
57 bool
58 Options::IsASubset (const OptionSet& set_a, const OptionSet& set_b)
59 {
60     bool is_a_subset = true;
61     OptionSet::const_iterator pos_a;
62     OptionSet::const_iterator pos_b;
63 
64     // set_a is a subset of set_b if every member of set_a is also a member of set_b
65 
66     for (pos_a = set_a.begin(); pos_a != set_a.end() && is_a_subset; ++pos_a)
67     {
68         pos_b = set_b.find(*pos_a);
69         if (pos_b == set_b.end())
70             is_a_subset = false;
71     }
72 
73     return is_a_subset;
74 }
75 
76 // Returns the set difference set_a - set_b, i.e. { x | ElementOf (x, set_a) && !ElementOf (x, set_b) }
77 
78 size_t
79 Options::OptionsSetDiff (const OptionSet& set_a, const OptionSet& set_b, OptionSet& diffs)
80 {
81     size_t num_diffs = 0;
82     OptionSet::const_iterator pos_a;
83     OptionSet::const_iterator pos_b;
84 
85     for (pos_a = set_a.begin(); pos_a != set_a.end(); ++pos_a)
86     {
87         pos_b = set_b.find(*pos_a);
88         if (pos_b == set_b.end())
89         {
90             ++num_diffs;
91             diffs.insert(*pos_a);
92         }
93     }
94 
95     return num_diffs;
96 }
97 
98 // Returns the union of set_a and set_b.  Does not put duplicate members into the union.
99 
100 void
101 Options::OptionsSetUnion (const OptionSet &set_a, const OptionSet &set_b, OptionSet &union_set)
102 {
103     OptionSet::const_iterator pos;
104     OptionSet::iterator pos_union;
105 
106     // Put all the elements of set_a into the union.
107 
108     for (pos = set_a.begin(); pos != set_a.end(); ++pos)
109         union_set.insert(*pos);
110 
111     // Put all the elements of set_b that are not already there into the union.
112     for (pos = set_b.begin(); pos != set_b.end(); ++pos)
113     {
114         pos_union = union_set.find(*pos);
115         if (pos_union == union_set.end())
116             union_set.insert(*pos);
117     }
118 }
119 
120 bool
121 Options::VerifyOptions (CommandReturnObject &result)
122 {
123     bool options_are_valid = false;
124 
125     int num_levels = GetRequiredOptions().size();
126     if (num_levels)
127     {
128         for (int i = 0; i < num_levels && !options_are_valid; ++i)
129         {
130             // This is the correct set of options if:  1). m_seen_options contains all of m_required_options[i]
131             // (i.e. all the required options at this level are a subset of m_seen_options); AND
132             // 2). { m_seen_options - m_required_options[i] is a subset of m_options_options[i] (i.e. all the rest of
133             // m_seen_options are in the set of optional options at this level.
134 
135             // Check to see if all of m_required_options[i] are a subset of m_seen_options
136             if (IsASubset (GetRequiredOptions()[i], m_seen_options))
137             {
138                 // Construct the set difference: remaining_options = {m_seen_options} - {m_required_options[i]}
139                 OptionSet remaining_options;
140                 OptionsSetDiff (m_seen_options, GetRequiredOptions()[i], remaining_options);
141                 // Check to see if remaining_options is a subset of m_optional_options[i]
142                 if (IsASubset (remaining_options, GetOptionalOptions()[i]))
143                     options_are_valid = true;
144             }
145         }
146     }
147     else
148     {
149         options_are_valid = true;
150     }
151 
152     if (options_are_valid)
153     {
154         result.SetStatus (eReturnStatusSuccessFinishNoResult);
155     }
156     else
157     {
158         result.AppendError ("invalid combination of options for the given command");
159         result.SetStatus (eReturnStatusFailed);
160     }
161 
162     return options_are_valid;
163 }
164 
165 // This is called in the Options constructor, though we could call it lazily if that ends up being
166 // a performance problem.
167 
168 void
169 Options::BuildValidOptionSets ()
170 {
171     // Check to see if we already did this.
172     if (m_required_options.size() != 0)
173         return;
174 
175     // Check to see if there are any options.
176     int num_options = NumCommandOptions ();
177     if (num_options == 0)
178         return;
179 
180     const lldb::OptionDefinition *full_options_table = GetDefinitions();
181     m_required_options.resize(1);
182     m_optional_options.resize(1);
183 
184     // First count the number of option sets we've got.  Ignore LLDB_ALL_OPTION_SETS...
185 
186     uint32_t num_option_sets = 0;
187 
188     for (int i = 0; i < num_options; i++)
189     {
190         uint32_t this_usage_mask = full_options_table[i].usage_mask;
191         if (this_usage_mask == LLDB_OPT_SET_ALL)
192         {
193             if (num_option_sets == 0)
194                 num_option_sets = 1;
195         }
196         else
197         {
198             for (int j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
199             {
200                 if (this_usage_mask & (1 << j))
201                 {
202                     if (num_option_sets <= j)
203                         num_option_sets = j + 1;
204                 }
205             }
206         }
207     }
208 
209     if (num_option_sets > 0)
210     {
211         m_required_options.resize(num_option_sets);
212         m_optional_options.resize(num_option_sets);
213 
214         for (int i = 0; i < num_options; ++i)
215         {
216             for (int j = 0; j < num_option_sets; j++)
217             {
218                 if (full_options_table[i].usage_mask & 1 << j)
219                 {
220                     if (full_options_table[i].required)
221                         m_required_options[j].insert(full_options_table[i].short_option);
222                     else
223                         m_optional_options[j].insert(full_options_table[i].short_option);
224                 }
225             }
226         }
227     }
228 }
229 
230 uint32_t
231 Options::NumCommandOptions ()
232 {
233     const lldb::OptionDefinition *full_options_table = GetDefinitions ();
234     if (full_options_table == NULL)
235         return 0;
236 
237     int i = 0;
238 
239     if (full_options_table != NULL)
240     {
241         while (full_options_table[i].long_option != NULL)
242             ++i;
243     }
244 
245     return i;
246 }
247 
248 struct option *
249 Options::GetLongOptions ()
250 {
251     // Check to see if this has already been done.
252     if (m_getopt_table.empty())
253     {
254         // Check to see if there are any options.
255         const uint32_t num_options = NumCommandOptions();
256         if (num_options == 0)
257             return NULL;
258 
259         uint32_t i;
260         uint32_t j;
261         const lldb::OptionDefinition *full_options_table = GetDefinitions();
262 
263         std::bitset<256> option_seen;
264 
265         m_getopt_table.resize(num_options + 1);
266         for (i = 0, j = 0; i < num_options; ++i)
267         {
268             char short_opt = full_options_table[i].short_option;
269 
270             if (option_seen.test(short_opt) == false)
271             {
272                 m_getopt_table[j].name    = full_options_table[i].long_option;
273                 m_getopt_table[j].has_arg = full_options_table[i].option_has_arg;
274                 m_getopt_table[j].flag    = NULL;
275                 m_getopt_table[j].val     = full_options_table[i].short_option;
276                 option_seen.set(short_opt);
277                 ++j;
278             }
279         }
280 
281         //getopt_long requires a NULL final entry in the table:
282 
283         m_getopt_table[j].name    = NULL;
284         m_getopt_table[j].has_arg = 0;
285         m_getopt_table[j].flag    = NULL;
286         m_getopt_table[j].val     = 0;
287     }
288 
289     if (m_getopt_table.empty())
290         return NULL;
291 
292     return &m_getopt_table.front();
293 }
294 
295 
296 // This function takes INDENT, which tells how many spaces to output at the front of each line; SPACES, which is
297 // a string containing 80 spaces; and TEXT, which is the text that is to be output.   It outputs the text, on
298 // multiple lines if necessary, to RESULT, with INDENT spaces at the front of each line.  It breaks lines on spaces,
299 // tabs or newlines, shortening the line if necessary to not break in the middle of a word.  It assumes that each
300 // output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
301 
302 
303 void
304 Options::OutputFormattedUsageText
305 (
306     Stream &strm,
307     const char *text,
308     uint32_t output_max_columns
309 )
310 {
311     int len = strlen (text);
312 
313     // Will it all fit on one line?
314 
315     if ((len + strm.GetIndentLevel()) < output_max_columns)
316     {
317         // Output it as a single line.
318         strm.Indent (text);
319         strm.EOL();
320     }
321     else
322     {
323         // We need to break it up into multiple lines.
324 
325         int text_width = output_max_columns - strm.GetIndentLevel() - 1;
326         int start = 0;
327         int end = start;
328         int final_end = strlen (text);
329         int sub_len;
330 
331         while (end < final_end)
332         {
333             // Don't start the 'text' on a space, since we're already outputting the indentation.
334             while ((start < final_end) && (text[start] == ' '))
335                 start++;
336 
337             end = start + text_width;
338             if (end > final_end)
339                 end = final_end;
340             else
341             {
342                 // If we're not at the end of the text, make sure we break the line on white space.
343                 while (end > start
344                        && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
345                     end--;
346             }
347 
348             sub_len = end - start;
349             if (start != 0)
350                 strm.EOL();
351             strm.Indent();
352             assert (start < final_end);
353             assert (start + sub_len <= final_end);
354             strm.Write(text + start, sub_len);
355             start = end + 1;
356         }
357         strm.EOL();
358     }
359 }
360 
361 void
362 Options::GenerateOptionUsage
363 (
364     CommandInterpreter &interpreter,
365     Stream &strm,
366     CommandObject *cmd
367 )
368 {
369     const uint32_t screen_width = interpreter.GetDebugger().GetTerminalWidth();
370 
371     const lldb::OptionDefinition *full_options_table = GetDefinitions();
372     const uint32_t save_indent_level = strm.GetIndentLevel();
373     const char *name;
374 
375     StreamString arguments_str;
376 
377     if (cmd)
378     {
379         name = cmd->GetCommandName();
380         cmd->GetFormattedCommandArguments (arguments_str);
381     }
382     else
383         name = "";
384 
385     strm.PutCString ("\nCommand Options Usage:\n");
386 
387     strm.IndentMore(2);
388 
389     // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
390     //                                                   <cmd> [options-for-level-1]
391     //                                                   etc.
392 
393     const uint32_t num_options = NumCommandOptions();
394     if (num_options == 0)
395         return;
396 
397     int num_option_sets = GetRequiredOptions().size();
398 
399     uint32_t i;
400 
401     for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set)
402     {
403         uint32_t opt_set_mask;
404 
405         opt_set_mask = 1 << opt_set;
406         if (opt_set > 0)
407             strm.Printf ("\n");
408         strm.Indent (name);
409 
410         // First go through and print all options that take no arguments as
411         // a single string. If a command has "-a" "-b" and "-c", this will show
412         // up as [-abc]
413 
414         std::set<char> options;
415         std::set<char>::const_iterator options_pos, options_end;
416         bool first;
417         for (i = 0, first = true; i < num_options; ++i)
418         {
419             if (full_options_table[i].usage_mask & opt_set_mask)
420             {
421                 // Add current option to the end of out_stream.
422 
423                 if (full_options_table[i].required == true &&
424                     full_options_table[i].option_has_arg == no_argument)
425                 {
426                     options.insert (full_options_table[i].short_option);
427                 }
428             }
429         }
430 
431         if (options.empty() == false)
432         {
433             // We have some required options with no arguments
434             strm.PutCString(" -");
435             for (i=0; i<2; ++i)
436                 for (options_pos = options.begin(), options_end = options.end();
437                      options_pos != options_end;
438                      ++options_pos)
439                 {
440                     if (i==0 && ::isupper (*options_pos))
441                         continue;
442                     if (i==1 && ::islower (*options_pos))
443                         continue;
444                     strm << *options_pos;
445                 }
446         }
447 
448         for (i = 0, options.clear(); i < num_options; ++i)
449         {
450             if (full_options_table[i].usage_mask & opt_set_mask)
451             {
452                 // Add current option to the end of out_stream.
453 
454                 if (full_options_table[i].required == false &&
455                     full_options_table[i].option_has_arg == no_argument)
456                 {
457                     options.insert (full_options_table[i].short_option);
458                 }
459             }
460         }
461 
462         if (options.empty() == false)
463         {
464             // We have some required options with no arguments
465             strm.PutCString(" [-");
466             for (i=0; i<2; ++i)
467                 for (options_pos = options.begin(), options_end = options.end();
468                      options_pos != options_end;
469                      ++options_pos)
470                 {
471                     if (i==0 && ::isupper (*options_pos))
472                         continue;
473                     if (i==1 && ::islower (*options_pos))
474                         continue;
475                     strm << *options_pos;
476                 }
477             strm.PutChar(']');
478         }
479 
480         // First go through and print the required options (list them up front).
481 
482         for (i = 0; i < num_options; ++i)
483         {
484             if (full_options_table[i].usage_mask & opt_set_mask)
485             {
486                 // Add current option to the end of out_stream.
487                 CommandArgumentType arg_type = full_options_table[i].argument_type;
488 
489                 if (full_options_table[i].required)
490                 {
491                     if (full_options_table[i].option_has_arg == required_argument)
492                     {
493                         strm.Printf (" -%c <%s>",
494                                      full_options_table[i].short_option,
495                                      CommandObject::GetArgumentName (arg_type));
496                     }
497                     else if (full_options_table[i].option_has_arg == optional_argument)
498                     {
499                         strm.Printf (" -%c [<%s>]",
500                                      full_options_table[i].short_option,
501                                      CommandObject::GetArgumentName (arg_type));
502                     }
503                 }
504             }
505         }
506 
507         // Now go through again, and this time only print the optional options.
508 
509         for (i = 0; i < num_options; ++i)
510         {
511             if (full_options_table[i].usage_mask & opt_set_mask)
512             {
513                 // Add current option to the end of out_stream.
514 
515                 CommandArgumentType arg_type = full_options_table[i].argument_type;
516 
517                 if (! full_options_table[i].required)
518                 {
519                     if (full_options_table[i].option_has_arg == required_argument)
520                         strm.Printf (" [-%c <%s>]", full_options_table[i].short_option,
521                                      CommandObject::GetArgumentName (arg_type));
522                     else if (full_options_table[i].option_has_arg == optional_argument)
523                         strm.Printf (" [-%c [<%s>]]", full_options_table[i].short_option,
524                                      CommandObject::GetArgumentName (arg_type));
525                 }
526             }
527         }
528         if (arguments_str.GetSize() > 0)
529             strm.Printf (" %s", arguments_str.GetData());
530     }
531     strm.Printf ("\n\n");
532 
533     // Now print out all the detailed information about the various options:  long form, short form and help text:
534     //   --long_name <argument>  ( -short <argument> )
535     //   help text
536 
537     // This variable is used to keep track of which options' info we've printed out, because some options can be in
538     // more than one usage level, but we only want to print the long form of its information once.
539 
540     OptionSet options_seen;
541     OptionSet::iterator pos;
542     strm.IndentMore (5);
543 
544     std::vector<char> sorted_options;
545 
546 
547     // Put the unique command options in a vector & sort it, so we can output them alphabetically (by short_option)
548     // when writing out detailed help for each option.
549 
550     for (i = 0; i < num_options; ++i)
551     {
552         pos = options_seen.find (full_options_table[i].short_option);
553         if (pos == options_seen.end())
554         {
555             options_seen.insert (full_options_table[i].short_option);
556             sorted_options.push_back (full_options_table[i].short_option);
557         }
558     }
559 
560     std::sort (sorted_options.begin(), sorted_options.end());
561 
562     // Go through the unique'd and alphabetically sorted vector of options, find the table entry for each option
563     // and write out the detailed help information for that option.
564 
565     int first_option_printed = 1;
566     size_t end = sorted_options.size();
567     for (size_t j = 0; j < end; ++j)
568     {
569         char option = sorted_options[j];
570         bool found = false;
571         for (i = 0; i < num_options && !found; ++i)
572         {
573             if (full_options_table[i].short_option == option)
574             {
575                 found = true;
576                 //Print out the help information for this option.
577 
578                 // Put a newline separation between arguments
579                 if (first_option_printed)
580                     first_option_printed = 0;
581                 else
582                     strm.EOL();
583 
584                 CommandArgumentType arg_type = full_options_table[i].argument_type;
585 
586                 StreamString arg_name_str;
587                 arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type));
588 
589                 strm.Indent ();
590                 strm.Printf ("-%c", full_options_table[i].short_option);
591                 if (arg_type != eArgTypeNone)
592                     strm.Printf (" <%s>",  CommandObject::GetArgumentName (arg_type));
593                 strm.Printf ("  ( --%s", full_options_table[i].long_option);
594                 if (arg_type != eArgTypeNone)
595                     strm.Printf (" <%s>", CommandObject::GetArgumentName (arg_type));
596                 strm.PutCString(" )\n");
597 
598                 strm.IndentMore (5);
599 
600                 if (full_options_table[i].usage_text)
601                     OutputFormattedUsageText (strm,
602                                               full_options_table[i].usage_text,
603                                               screen_width);
604                 if (full_options_table[i].enum_values != NULL)
605                 {
606                     strm.Indent ();
607                     strm.Printf("Values: ");
608                     for (int k = 0; full_options_table[i].enum_values[k].string_value != NULL; k++)
609                     {
610                         if (k == 0)
611                             strm.Printf("%s", full_options_table[i].enum_values[k].string_value);
612                         else
613                             strm.Printf(" | %s", full_options_table[i].enum_values[k].string_value);
614                     }
615                     strm.EOL();
616                 }
617                 strm.IndentLess (5);
618             }
619         }
620     }
621 
622     // Restore the indent level
623     strm.SetIndentLevel (save_indent_level);
624 }
625 
626 // This function is called when we have been given a potentially incomplete set of
627 // options, such as when an alias has been defined (more options might be added at
628 // at the time the alias is invoked).  We need to verify that the options in the set
629 // m_seen_options are all part of a set that may be used together, but m_seen_options
630 // may be missing some of the "required" options.
631 
632 bool
633 Options::VerifyPartialOptions (CommandReturnObject &result)
634 {
635     bool options_are_valid = false;
636 
637     int num_levels = GetRequiredOptions().size();
638     if (num_levels)
639       {
640         for (int i = 0; i < num_levels && !options_are_valid; ++i)
641           {
642             // In this case we are treating all options as optional rather than required.
643             // Therefore a set of options is correct if m_seen_options is a subset of the
644             // union of m_required_options and m_optional_options.
645             OptionSet union_set;
646             OptionsSetUnion (GetRequiredOptions()[i], GetOptionalOptions()[i], union_set);
647             if (IsASubset (m_seen_options, union_set))
648                 options_are_valid = true;
649           }
650       }
651 
652     return options_are_valid;
653 }
654 
655 bool
656 Options::HandleOptionCompletion
657 (
658     CommandInterpreter &interpreter,
659     Args &input,
660     OptionElementVector &opt_element_vector,
661     int cursor_index,
662     int char_pos,
663     int match_start_point,
664     int max_return_elements,
665     bool &word_complete,
666     lldb_private::StringList &matches
667 )
668 {
669     word_complete = true;
670 
671     // For now we just scan the completions to see if the cursor position is in
672     // an option or its argument.  Otherwise we'll call HandleArgumentCompletion.
673     // In the future we can use completion to validate options as well if we want.
674 
675     const OptionDefinition *opt_defs = GetDefinitions();
676 
677     std::string cur_opt_std_str (input.GetArgumentAtIndex(cursor_index));
678     cur_opt_std_str.erase(char_pos);
679     const char *cur_opt_str = cur_opt_std_str.c_str();
680 
681     for (int i = 0; i < opt_element_vector.size(); i++)
682     {
683         int opt_pos = opt_element_vector[i].opt_pos;
684         int opt_arg_pos = opt_element_vector[i].opt_arg_pos;
685         int opt_defs_index = opt_element_vector[i].opt_defs_index;
686         if (opt_pos == cursor_index)
687         {
688             // We're completing the option itself.
689 
690             if (opt_defs_index == OptionArgElement::eBareDash)
691             {
692                 // We're completing a bare dash.  That means all options are open.
693                 // FIXME: We should scan the other options provided and only complete options
694                 // within the option group they belong to.
695                 char opt_str[3] = {'-', 'a', '\0'};
696 
697                 for (int j = 0 ; opt_defs[j].short_option != 0 ; j++)
698                 {
699                     opt_str[1] = opt_defs[j].short_option;
700                     matches.AppendString (opt_str);
701                 }
702                 return true;
703             }
704             else if (opt_defs_index == OptionArgElement::eBareDoubleDash)
705             {
706                 std::string full_name ("--");
707                 for (int j = 0 ; opt_defs[j].short_option != 0 ; j++)
708                 {
709                     full_name.erase(full_name.begin() + 2, full_name.end());
710                     full_name.append (opt_defs[j].long_option);
711                     matches.AppendString (full_name.c_str());
712                 }
713                 return true;
714             }
715             else if (opt_defs_index != OptionArgElement::eUnrecognizedArg)
716             {
717                 // We recognized it, if it an incomplete long option, complete it anyway (getopt_long is
718                 // happy with shortest unique string, but it's still a nice thing to do.)  Otherwise return
719                 // The string so the upper level code will know this is a full match and add the " ".
720                 if (cur_opt_str && strlen (cur_opt_str) > 2
721                     && cur_opt_str[0] == '-' && cur_opt_str[1] == '-'
722                     && strcmp (opt_defs[opt_defs_index].long_option, cur_opt_str) != 0)
723                 {
724                         std::string full_name ("--");
725                         full_name.append (opt_defs[opt_defs_index].long_option);
726                         matches.AppendString(full_name.c_str());
727                         return true;
728                 }
729                 else
730                 {
731                     matches.AppendString(input.GetArgumentAtIndex(cursor_index));
732                     return true;
733                 }
734             }
735             else
736             {
737                 // FIXME - not handling wrong options yet:
738                 // Check to see if they are writing a long option & complete it.
739                 // I think we will only get in here if the long option table has two elements
740                 // that are not unique up to this point.  getopt_long does shortest unique match
741                 // for long options already.
742 
743                 if (cur_opt_str && strlen (cur_opt_str) > 2
744                     && cur_opt_str[0] == '-' && cur_opt_str[1] == '-')
745                 {
746                     for (int j = 0 ; opt_defs[j].short_option != 0 ; j++)
747                     {
748                         if (strstr(opt_defs[j].long_option, cur_opt_str + 2) == opt_defs[j].long_option)
749                         {
750                             std::string full_name ("--");
751                             full_name.append (opt_defs[j].long_option);
752                             // The options definitions table has duplicates because of the
753                             // way the grouping information is stored, so only add once.
754                             bool duplicate = false;
755                             for (int k = 0; k < matches.GetSize(); k++)
756                             {
757                                 if (matches.GetStringAtIndex(k) == full_name)
758                                 {
759                                     duplicate = true;
760                                     break;
761                                 }
762                             }
763                             if (!duplicate)
764                                 matches.AppendString(full_name.c_str());
765                         }
766                     }
767                 }
768                 return true;
769             }
770 
771 
772         }
773         else if (opt_arg_pos == cursor_index)
774         {
775             // Okay the cursor is on the completion of an argument.
776             // See if it has a completion, otherwise return no matches.
777 
778             if (opt_defs_index != -1)
779             {
780                 HandleOptionArgumentCompletion (interpreter,
781                                                 input,
782                                                 cursor_index,
783                                                 strlen (input.GetArgumentAtIndex(cursor_index)),
784                                                 opt_element_vector,
785                                                 i,
786                                                 match_start_point,
787                                                 max_return_elements,
788                                                 word_complete,
789                                                 matches);
790                 return true;
791             }
792             else
793             {
794                 // No completion callback means no completions...
795                 return true;
796             }
797 
798         }
799         else
800         {
801             // Not the last element, keep going.
802             continue;
803         }
804     }
805     return false;
806 }
807 
808 bool
809 Options::HandleOptionArgumentCompletion
810 (
811     CommandInterpreter &interpreter,
812     Args &input,
813     int cursor_index,
814     int char_pos,
815     OptionElementVector &opt_element_vector,
816     int opt_element_index,
817     int match_start_point,
818     int max_return_elements,
819     bool &word_complete,
820     lldb_private::StringList &matches
821 )
822 {
823     const OptionDefinition *opt_defs = GetDefinitions();
824     std::auto_ptr<SearchFilter> filter_ap;
825 
826     int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
827     int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
828 
829     // See if this is an enumeration type option, and if so complete it here:
830 
831     OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values;
832     if (enum_values != NULL)
833     {
834         bool return_value = false;
835         std::string match_string(input.GetArgumentAtIndex (opt_arg_pos), input.GetArgumentAtIndex (opt_arg_pos) + char_pos);
836         for (int i = 0; enum_values[i].string_value != NULL; i++)
837         {
838             if (strstr(enum_values[i].string_value, match_string.c_str()) == enum_values[i].string_value)
839             {
840                 matches.AppendString (enum_values[i].string_value);
841                 return_value = true;
842             }
843         }
844         return return_value;
845     }
846 
847     // If this is a source file or symbol type completion, and  there is a
848     // -shlib option somewhere in the supplied arguments, then make a search filter
849     // for that shared library.
850     // FIXME: Do we want to also have an "OptionType" so we don't have to match string names?
851 
852     uint32_t completion_mask = opt_defs[opt_defs_index].completionType;
853     if (completion_mask & CommandCompletions::eSourceFileCompletion
854         || completion_mask & CommandCompletions::eSymbolCompletion)
855     {
856         for (int i = 0; i < opt_element_vector.size(); i++)
857         {
858             int cur_defs_index = opt_element_vector[i].opt_defs_index;
859             int cur_arg_pos    = opt_element_vector[i].opt_arg_pos;
860             const char *cur_opt_name = opt_defs[cur_defs_index].long_option;
861 
862             // If this is the "shlib" option and there was an argument provided,
863             // restrict it to that shared library.
864             if (strcmp(cur_opt_name, "shlib") == 0 && cur_arg_pos != -1)
865             {
866                 const char *module_name = input.GetArgumentAtIndex(cur_arg_pos);
867                 if (module_name)
868                 {
869                     FileSpec module_spec(module_name, false);
870                     lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
871                     // Search filters require a target...
872                     if (target_sp != NULL)
873                         filter_ap.reset (new SearchFilterByModule (target_sp, module_spec));
874                 }
875                 break;
876             }
877         }
878     }
879 
880     return CommandCompletions::InvokeCommonCompletionCallbacks (interpreter,
881                                                                 completion_mask,
882                                                                 input.GetArgumentAtIndex (opt_arg_pos),
883                                                                 match_start_point,
884                                                                 max_return_elements,
885                                                                 filter_ap.get(),
886                                                                 word_complete,
887                                                                 matches);
888 
889 }
890