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