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