124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Options.cpp ---------------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea#include "lldb/lldb-python.h"
11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea
1284cdc15005983e5244d665fa779e33c2b6fac95fJim Ingham#include "lldb/Interpreter/Options.h"
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes
16e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice#include <algorithm>
175e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton#include <bitset>
186475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton#include <map>
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Interpreter/CommandObject.h"
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Interpreter/CommandReturnObject.h"
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Interpreter/CommandCompletions.h"
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Interpreter/CommandInterpreter.h"
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/StreamString.h"
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Target.h"
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//-------------------------------------------------------------------------
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Options
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//-------------------------------------------------------------------------
35f15996eea072cdaa8a092f22d3a1212b3d95f0ecGreg ClaytonOptions::Options (CommandInterpreter &interpreter) :
36f15996eea072cdaa8a092f22d3a1212b3d95f0ecGreg Clayton    m_interpreter (interpreter),
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_getopt_table ()
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    BuildValidOptionSets();
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::~Options ()
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
47143fcc3a15425659b381502ed4e1e50a3e726f36Greg ClaytonOptions::NotifyOptionParsingStarting ()
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_seen_options.clear();
5024bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton    // Let the subclass reset its option values
51143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    OptionParsingStarting ();
52143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton}
53143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton
54143fcc3a15425659b381502ed4e1e50a3e726f36Greg ClaytonError
55143fcc3a15425659b381502ed4e1e50a3e726f36Greg ClaytonOptions::NotifyOptionParsingFinished ()
56143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton{
57143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    return OptionParsingFinished ();
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::OptionSeen (int option_idx)
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
636475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    m_seen_options.insert (option_idx);
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Returns true is set_a is a subset of set_b;  Otherwise returns false.
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::IsASubset (const OptionSet& set_a, const OptionSet& set_b)
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool is_a_subset = true;
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    OptionSet::const_iterator pos_a;
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    OptionSet::const_iterator pos_b;
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // set_a is a subset of set_b if every member of set_a is also a member of set_b
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (pos_a = set_a.begin(); pos_a != set_a.end() && is_a_subset; ++pos_a)
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        pos_b = set_b.find(*pos_a);
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (pos_b == set_b.end())
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            is_a_subset = false;
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return is_a_subset;
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Returns the set difference set_a - set_b, i.e. { x | ElementOf (x, set_a) && !ElementOf (x, set_b) }
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::OptionsSetDiff (const OptionSet& set_a, const OptionSet& set_b, OptionSet& diffs)
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    size_t num_diffs = 0;
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    OptionSet::const_iterator pos_a;
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    OptionSet::const_iterator pos_b;
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (pos_a = set_a.begin(); pos_a != set_a.end(); ++pos_a)
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        pos_b = set_b.find(*pos_a);
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (pos_b == set_b.end())
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            ++num_diffs;
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            diffs.insert(*pos_a);
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return num_diffs;
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Returns the union of set_a and set_b.  Does not put duplicate members into the union.
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::OptionsSetUnion (const OptionSet &set_a, const OptionSet &set_b, OptionSet &union_set)
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    OptionSet::const_iterator pos;
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    OptionSet::iterator pos_union;
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Put all the elements of set_a into the union.
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (pos = set_a.begin(); pos != set_a.end(); ++pos)
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        union_set.insert(*pos);
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Put all the elements of set_b that are not already there into the union.
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (pos = set_b.begin(); pos != set_b.end(); ++pos)
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        pos_union = union_set.find(*pos);
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (pos_union == union_set.end())
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            union_set.insert(*pos);
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::VerifyOptions (CommandReturnObject &result)
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool options_are_valid = false;
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1368b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham    int num_levels = GetRequiredOptions().size();
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (num_levels)
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for (int i = 0; i < num_levels && !options_are_valid; ++i)
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // This is the correct set of options if:  1). m_seen_options contains all of m_required_options[i]
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // (i.e. all the required options at this level are a subset of m_seen_options); AND
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // 2). { m_seen_options - m_required_options[i] is a subset of m_options_options[i] (i.e. all the rest of
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // m_seen_options are in the set of optional options at this level.
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Check to see if all of m_required_options[i] are a subset of m_seen_options
1478b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham            if (IsASubset (GetRequiredOptions()[i], m_seen_options))
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // Construct the set difference: remaining_options = {m_seen_options} - {m_required_options[i]}
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                OptionSet remaining_options;
1518b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                OptionsSetDiff (m_seen_options, GetRequiredOptions()[i], remaining_options);
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // Check to see if remaining_options is a subset of m_optional_options[i]
1538b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                if (IsASubset (remaining_options, GetOptionalOptions()[i]))
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    options_are_valid = true;
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        options_are_valid = true;
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (options_are_valid)
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        result.SetStatus (eReturnStatusSuccessFinishNoResult);
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        result.AppendError ("invalid combination of options for the given command");
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        result.SetStatus (eReturnStatusFailed);
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return options_are_valid;
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham// This is called in the Options constructor, though we could call it lazily if that ends up being
17734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham// a performance problem.
17834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::BuildValidOptionSets ()
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Check to see if we already did this.
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_required_options.size() != 0)
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Check to see if there are any options.
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int num_options = NumCommandOptions ();
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (num_options == 0)
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
191d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton    const OptionDefinition *opt_defs = GetDefinitions();
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_required_options.resize(1);
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_optional_options.resize(1);
19434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
19534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    // First count the number of option sets we've got.  Ignore LLDB_ALL_OPTION_SETS...
19634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
19734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    uint32_t num_option_sets = 0;
19834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
19934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    for (int i = 0; i < num_options; i++)
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
201d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton        uint32_t this_usage_mask = opt_defs[i].usage_mask;
20234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        if (this_usage_mask == LLDB_OPT_SET_ALL)
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
20434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            if (num_option_sets == 0)
20534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                num_option_sets = 1;
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
2093e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs            for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
21034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            {
2118b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                if (this_usage_mask & (1 << j))
21234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                {
21334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                    if (num_option_sets <= j)
21434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                        num_option_sets = j + 1;
21534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                }
21634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            }
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
21834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    }
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    if (num_option_sets > 0)
22134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    {
22234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        m_required_options.resize(num_option_sets);
22334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        m_optional_options.resize(num_option_sets);
22434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
22534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        for (int i = 0; i < num_options; ++i)
22634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        {
2273e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs            for (uint32_t j = 0; j < num_option_sets; j++)
22834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            {
229d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                if (opt_defs[i].usage_mask & 1 << j)
23034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                {
231d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                    if (opt_defs[i].required)
232d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                        m_required_options[j].insert(opt_defs[i].short_option);
23334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                    else
234d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                        m_optional_options[j].insert(opt_defs[i].short_option);
23534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                }
23634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            }
23734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        }
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::NumCommandOptions ()
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
244d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton    const OptionDefinition *opt_defs = GetDefinitions ();
245d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton    if (opt_defs == NULL)
24634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        return 0;
24734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int i = 0;
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
250d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton    if (opt_defs != NULL)
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
252d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton        while (opt_defs[i].long_option != NULL)
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            ++i;
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return i;
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstruct option *
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::GetLongOptions ()
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Check to see if this has already been done.
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_getopt_table.empty())
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Check to see if there are any options.
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint32_t num_options = NumCommandOptions();
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (num_options == 0)
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return NULL;
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t i;
271d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton        const OptionDefinition *opt_defs = GetDefinitions();
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2736475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        std::map<int, uint32_t> option_seen;
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_getopt_table.resize(num_options + 1);
2766475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        for (i = 0; i < num_options; ++i)
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
2786475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            const int short_opt = opt_defs[i].short_option;
2796475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
2806475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            m_getopt_table[i].name    = opt_defs[i].long_option;
2816475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            m_getopt_table[i].has_arg = opt_defs[i].option_has_arg;
2826475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            m_getopt_table[i].flag    = NULL;
2836475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            m_getopt_table[i].val     = short_opt;
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2856475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            if (option_seen.find(short_opt) == option_seen.end())
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
2876475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                option_seen[short_opt] = i;
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
2896475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            else if (short_opt)
290ec9c2d2785c9c035e36c504618488a8764ecfddbGreg Clayton            {
2916475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                m_getopt_table[i].val = 0;
2926475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                std::map<int, uint32_t>::const_iterator pos = option_seen.find(short_opt);
2936475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                StreamString strm;
2942eafcaafe722598d937cc64fd5ae4a3bb49e8dcfDaniel Malea                if (isprint8(short_opt))
2956475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    Host::SystemLog (Host::eSystemLogError, "option[%u] --%s has a short option -%c that conflicts with option[%u] --%s, short option won't be used for --%s\n",
2966475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                i,
2976475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                opt_defs[i].long_option,
2986475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                short_opt,
2996475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                pos->second,
3006475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                m_getopt_table[pos->second].name,
3016475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                opt_defs[i].long_option);
3026475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                else
3036475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    Host::SystemLog (Host::eSystemLogError, "option[%u] --%s has a short option 0x%x that conflicts with option[%u] --%s, short option won't be used for --%s\n",
3046475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                i,
3056475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                opt_defs[i].long_option,
3066475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                short_opt,
3076475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                pos->second,
3086475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                m_getopt_table[pos->second].name,
3096475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                opt_defs[i].long_option);
310ec9c2d2785c9c035e36c504618488a8764ecfddbGreg Clayton            }
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3133f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton        //getopt_long_only requires a NULL final entry in the table:
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3156475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        m_getopt_table[i].name    = NULL;
3166475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        m_getopt_table[i].has_arg = 0;
3176475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        m_getopt_table[i].flag    = NULL;
3186475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        m_getopt_table[i].val     = 0;
31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32153d68e749f0715691a95f23e9490d97e484b15daGreg Clayton    if (m_getopt_table.empty())
32253d68e749f0715691a95f23e9490d97e484b15daGreg Clayton        return NULL;
32353d68e749f0715691a95f23e9490d97e484b15daGreg Clayton
32453d68e749f0715691a95f23e9490d97e484b15daGreg Clayton    return &m_getopt_table.front();
32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This function takes INDENT, which tells how many spaces to output at the front of each line; SPACES, which is
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// a string containing 80 spaces; and TEXT, which is the text that is to be output.   It outputs the text, on
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// multiple lines if necessary, to RESULT, with INDENT spaces at the front of each line.  It breaks lines on spaces,
33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// tabs or newlines, shortening the line if necessary to not break in the middle of a word.  It assumes that each
33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::OutputFormattedUsageText
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Stream &strm,
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *text,
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t output_max_columns
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int len = strlen (text);
34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Will it all fit on one line?
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ((len + strm.GetIndentLevel()) < output_max_columns)
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Output it as a single line.
35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        strm.Indent (text);
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        strm.EOL();
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // We need to break it up into multiple lines.
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int text_width = output_max_columns - strm.GetIndentLevel() - 1;
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int start = 0;
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int end = start;
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int final_end = strlen (text);
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int sub_len;
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (end < final_end)
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Don't start the 'text' on a space, since we're already outputting the indentation.
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            while ((start < final_end) && (text[start] == ' '))
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                start++;
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            end = start + text_width;
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (end > final_end)
37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                end = final_end;
37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // If we're not at the end of the text, make sure we break the line on white space.
37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                while (end > start
37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                       && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    end--;
37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            sub_len = end - start;
38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (start != 0)
38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                strm.EOL();
38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            strm.Indent();
38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            assert (start < final_end);
38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            assert (start + sub_len <= final_end);
38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            strm.Write(text + start, sub_len);
38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            start = end + 1;
38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        strm.EOL();
39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
393d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Claytonbool
394d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg ClaytonOptions::SupportsLongOption (const char *long_option)
395d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton{
396d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton    if (long_option && long_option[0])
397d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton    {
398d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton        const OptionDefinition *opt_defs = GetDefinitions ();
399d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton        if (opt_defs)
400d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton        {
401b51693999473f5dc7cb9681bbbc4a65028eea35bGreg Clayton            const char *long_option_name = long_option;
402d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton            if (long_option[0] == '-' && long_option[1] == '-')
403d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                long_option_name += 2;
404d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton
405d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton            for (uint32_t i = 0; opt_defs[i].long_option; ++i)
406d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton            {
407d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                if (strcmp(opt_defs[i].long_option, long_option_name) == 0)
408d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                    return true;
409d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton            }
410d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton        }
411d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton    }
412d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton    return false;
413d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton}
414d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton
4156475c42148a8ea1ca86e5db465db7eca742d897dGreg Claytonenum OptionDisplayType
4166475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton{
4176475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    eDisplayBestOption,
4186475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    eDisplayShortOption,
4196475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    eDisplayLongOption
4206475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton};
4216475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
4226475c42148a8ea1ca86e5db465db7eca742d897dGreg Claytonstatic bool
4236475c42148a8ea1ca86e5db465db7eca742d897dGreg ClaytonPrintOption (const OptionDefinition &opt_def,
4246475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton             OptionDisplayType display_type,
4256475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton             const char *header,
4266475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton             const char *footer,
4276475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton             bool show_optional,
4286475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton             Stream &strm)
4296475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton{
4302eafcaafe722598d937cc64fd5ae4a3bb49e8dcfDaniel Malea    const bool has_short_option = isprint8(opt_def.short_option) != 0;
4316475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
4326475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    if (display_type == eDisplayShortOption && !has_short_option)
4336475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        return false;
4346475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
4356475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    if (header && header[0])
4366475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        strm.PutCString(header);
4376475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
4386475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    if (show_optional && !opt_def.required)
4396475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    strm.PutChar('[');
4406475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    const bool show_short_option = has_short_option && display_type != eDisplayLongOption;
4416475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    if (show_short_option)
4426475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        strm.Printf ("-%c", opt_def.short_option);
4436475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    else
4446475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        strm.Printf ("--%s", opt_def.long_option);
4456475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    switch (opt_def.option_has_arg)
4466475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    {
4476475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        case no_argument:
4486475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            break;
4496475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        case required_argument:
4506475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            strm.Printf (" <%s>", CommandObject::GetArgumentName (opt_def.argument_type));
4516475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            break;
4526475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
4536475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        case optional_argument:
4546475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            strm.Printf ("%s[<%s>]",
4556475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                         show_short_option ? "" : "=",
4566475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                         CommandObject::GetArgumentName (opt_def.argument_type));
4576475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            break;
4586475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    }
4596475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    if (show_optional && !opt_def.required)
4606475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        strm.PutChar(']');
4616475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    if (footer && footer[0])
4626475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        strm.PutCString(footer);
4636475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    return true;
4646475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton}
4656475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::GenerateOptionUsage
46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
46924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Stream &strm,
470238c0a1e7b733cee539258faa656159c63f9e893Greg Clayton    CommandObject *cmd
471238c0a1e7b733cee539258faa656159c63f9e893Greg Clayton)
47224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
473f15996eea072cdaa8a092f22d3a1212b3d95f0ecGreg Clayton    const uint32_t screen_width = m_interpreter.GetDebugger().GetTerminalWidth();
4746e4c5ce0f697eb9899a54854a2a9004e961b0de2Caroline Tice
475d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton    const OptionDefinition *opt_defs = GetDefinitions();
47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t save_indent_level = strm.GetIndentLevel();
47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *name;
47824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
479fb355113cef81a6fa56b468bec7798a24d027b6dCaroline Tice    StreamString arguments_str;
480fb355113cef81a6fa56b468bec7798a24d027b6dCaroline Tice
48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (cmd)
482fb355113cef81a6fa56b468bec7798a24d027b6dCaroline Tice    {
483238c0a1e7b733cee539258faa656159c63f9e893Greg Clayton        name = cmd->GetCommandName();
484fb355113cef81a6fa56b468bec7798a24d027b6dCaroline Tice        cmd->GetFormattedCommandArguments (arguments_str);
485fb355113cef81a6fa56b468bec7798a24d027b6dCaroline Tice    }
48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
487238c0a1e7b733cee539258faa656159c63f9e893Greg Clayton        name = "";
48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    strm.PutCString ("\nCommand Options Usage:\n");
49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    strm.IndentMore(2);
49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //                                                   <cmd> [options-for-level-1]
49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //                                                   etc.
49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t num_options = NumCommandOptions();
49834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    if (num_options == 0)
49934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        return;
50034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
5017e20fea4aff79b345ab504f88844796ccd2901cbAndy Gibbs    uint32_t num_option_sets = GetRequiredOptions().size();
50234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t i;
50434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
50534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set)
50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
50734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        uint32_t opt_set_mask;
50834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
50934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        opt_set_mask = 1 << opt_set;
51034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        if (opt_set > 0)
51134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            strm.Printf ("\n");
51234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        strm.Indent (name);
513e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice
5146183fccd61b67e814d9e7e85b25516a28edfe864Johnny Chen        // Different option sets may require different args.
5156183fccd61b67e814d9e7e85b25516a28edfe864Johnny Chen        StreamString args_str;
5166f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham        if (cmd)
5176f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham            cmd->GetFormattedCommandArguments(args_str, opt_set_mask);
5186183fccd61b67e814d9e7e85b25516a28edfe864Johnny Chen
519fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        // First go through and print all options that take no arguments as
520fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        // a single string. If a command has "-a" "-b" and "-c", this will show
521fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        // up as [-abc]
522fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton
5236475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        std::set<int> options;
5246475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        std::set<int>::const_iterator options_pos, options_end;
525d387b462eecb908af265ecc7006781b4532073adGreg Clayton        for (i = 0; i < num_options; ++i)
526fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        {
5272eafcaafe722598d937cc64fd5ae4a3bb49e8dcfDaniel Malea            if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
528fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            {
529fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                // Add current option to the end of out_stream.
530fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton
531d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                if (opt_defs[i].required == true &&
532d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                    opt_defs[i].option_has_arg == no_argument)
533fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                {
534d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                    options.insert (opt_defs[i].short_option);
535fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                }
536fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            }
537fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        }
538fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton
539fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        if (options.empty() == false)
540fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        {
541fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            // We have some required options with no arguments
542fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            strm.PutCString(" -");
543fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            for (i=0; i<2; ++i)
544fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                for (options_pos = options.begin(), options_end = options.end();
545fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                     options_pos != options_end;
546fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                     ++options_pos)
547fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                {
5486475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    if (i==0 && ::islower (*options_pos))
549fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                        continue;
5506475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    if (i==1 && ::isupper (*options_pos))
551fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                        continue;
5526475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    strm << (char)*options_pos;
553fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                }
554fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        }
555fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton
556fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        for (i = 0, options.clear(); i < num_options; ++i)
557fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        {
5582eafcaafe722598d937cc64fd5ae4a3bb49e8dcfDaniel Malea            if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
559fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            {
560fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                // Add current option to the end of out_stream.
561fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton
562d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                if (opt_defs[i].required == false &&
563d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                    opt_defs[i].option_has_arg == no_argument)
564fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                {
565d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton                    options.insert (opt_defs[i].short_option);
566fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                }
567fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            }
568fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        }
569fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton
570fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        if (options.empty() == false)
571fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        {
572fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            // We have some required options with no arguments
573fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            strm.PutCString(" [-");
574fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            for (i=0; i<2; ++i)
575fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                for (options_pos = options.begin(), options_end = options.end();
576fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                     options_pos != options_end;
577fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                     ++options_pos)
578fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                {
5796475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    if (i==0 && ::islower (*options_pos))
580fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                        continue;
5816475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    if (i==1 && ::isupper (*options_pos))
582fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                        continue;
5836475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    strm << (char)*options_pos;
584fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton                }
585fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton            strm.PutChar(']');
586fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton        }
587fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton
588e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice        // First go through and print the required options (list them up front).
58934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
59034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        for (i = 0; i < num_options; ++i)
59124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
5922eafcaafe722598d937cc64fd5ae4a3bb49e8dcfDaniel Malea            if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
59324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
5946475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                if (opt_defs[i].required && opt_defs[i].option_has_arg != no_argument)
5956475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    PrintOption (opt_defs[i], eDisplayBestOption, " ", NULL, true, strm);
596e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice            }
597e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice        }
598e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice
599e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice        // Now go through again, and this time only print the optional options.
600e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice
601e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice        for (i = 0; i < num_options; ++i)
602e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice        {
603d8a218d998d0dd805a8e4ec7bbaa9aeb229590ccGreg Clayton            if (opt_defs[i].usage_mask & opt_set_mask)
604e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice            {
605e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice                // Add current option to the end of out_stream.
606e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice
6076475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                if (!opt_defs[i].required && opt_defs[i].option_has_arg != no_argument)
6086475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    PrintOption (opt_defs[i], eDisplayBestOption, " ", NULL, true, strm);
60924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
61024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
6119798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan
6126183fccd61b67e814d9e7e85b25516a28edfe864Johnny Chen        if (args_str.GetSize() > 0)
6139798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan        {
6149798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan            if (cmd->WantsRawCommandString())
6159798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan                strm.Printf(" --");
6169798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan
6176183fccd61b67e814d9e7e85b25516a28edfe864Johnny Chen            strm.Printf (" %s", args_str.GetData());
6189798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan        }
61924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
6209798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan
6216f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham    if (cmd &&
6226f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham        cmd->WantsRawCommandString() &&
6239798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan        arguments_str.GetSize() > 0)
6249798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan    {
6259798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan        strm.PutChar('\n');
6269798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan        strm.Indent(name);
6279798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan        strm.Printf(" %s", arguments_str.GetData());
6289798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan    }
6299798d7b0999b189d9ba64c4f1c9c635bdfda9a7bSean Callanan
63024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    strm.Printf ("\n\n");
63124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
63224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Now print out all the detailed information about the various options:  long form, short form and help text:
633fe424a92fc6fd92f810d243912461fe028a2b63cGreg Clayton    //   --long_name <argument>  ( -short <argument> )
63424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //   help text
63524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
63624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // This variable is used to keep track of which options' info we've printed out, because some options can be in
63724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // more than one usage level, but we only want to print the long form of its information once.
63824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6396475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    std::multimap<int, uint32_t> options_seen;
64024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    strm.IndentMore (5);
64124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
642e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice    // Put the unique command options in a vector & sort it, so we can output them alphabetically (by short_option)
643e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice    // when writing out detailed help for each option.
644e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice
64524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i = 0; i < num_options; ++i)
6466475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        options_seen.insert(std::make_pair(opt_defs[i].short_option, i));
647e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice
648e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice    // Go through the unique'd and alphabetically sorted vector of options, find the table entry for each option
649e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice    // and write out the detailed help information for that option.
650e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice
6516475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    bool first_option_printed = false;;
6526475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
6536475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    for (auto pos : options_seen)
654e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice    {
6556475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        i = pos.second;
6566475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        //Print out the help information for this option.
6576475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
6586475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        // Put a newline separation between arguments
6596475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        if (first_option_printed)
6606475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            strm.EOL();
6616475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        else
6626475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            first_option_printed = true;
6636475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
6646475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        CommandArgumentType arg_type = opt_defs[i].argument_type;
6656475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
6666475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        StreamString arg_name_str;
6676475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type));
6686475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
6696475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        strm.Indent ();
6702eafcaafe722598d937cc64fd5ae4a3bb49e8dcfDaniel Malea        if (opt_defs[i].short_option && isprint8(opt_defs[i].short_option))
671e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice        {
6726475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            PrintOption (opt_defs[i], eDisplayShortOption, NULL, NULL, false, strm);
6736475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            PrintOption (opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
6746475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        }
6756475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        else
6766475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        {
6776475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            // Short option is not printable, just print long option
6786475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            PrintOption (opt_defs[i], eDisplayLongOption, NULL, NULL, false, strm);
6796475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        }
6806475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        strm.EOL();
6816475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
6826475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        strm.IndentMore (5);
6836475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton
6846475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        if (opt_defs[i].usage_text)
6856475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            OutputFormattedUsageText (strm,
6866475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                      opt_defs[i].usage_text,
6876475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                                      screen_width);
6886475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        if (opt_defs[i].enum_values != NULL)
6896475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        {
6906475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            strm.Indent ();
6916475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            strm.Printf("Values: ");
6926475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            for (int k = 0; opt_defs[i].enum_values[k].string_value != NULL; k++)
693e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice            {
6946475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                if (k == 0)
6956475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
696e5f18b09a1f4097bf1578edc878bb8605a6f9de3Caroline Tice                else
6976475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                    strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
69824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
6996475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            strm.EOL();
70024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
7016475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        strm.IndentLess (5);
70224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
70324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
70424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Restore the indent level
70524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    strm.SetIndentLevel (save_indent_level);
70624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
70724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
70824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This function is called when we have been given a potentially incomplete set of
70924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// options, such as when an alias has been defined (more options might be added at
71024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// at the time the alias is invoked).  We need to verify that the options in the set
71124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// m_seen_options are all part of a set that may be used together, but m_seen_options
71224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// may be missing some of the "required" options.
71324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
71424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
71524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::VerifyPartialOptions (CommandReturnObject &result)
71624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
71724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool options_are_valid = false;
71824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7198b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham    int num_levels = GetRequiredOptions().size();
72024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (num_levels)
72124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner      {
72224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for (int i = 0; i < num_levels && !options_are_valid; ++i)
72324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner          {
72424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // In this case we are treating all options as optional rather than required.
72524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Therefore a set of options is correct if m_seen_options is a subset of the
72624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // union of m_required_options and m_optional_options.
72724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            OptionSet union_set;
7288b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham            OptionsSetUnion (GetRequiredOptions()[i], GetOptionalOptions()[i], union_set);
72924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (IsASubset (m_seen_options, union_set))
73024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                options_are_valid = true;
73124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner          }
73224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner      }
73324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
73424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return options_are_valid;
73524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
73624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
73724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
73824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::HandleOptionCompletion
73924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
74024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Args &input,
74124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    OptionElementVector &opt_element_vector,
74224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int cursor_index,
74324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int char_pos,
74424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int match_start_point,
74524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int max_return_elements,
746802f8b0e11525a61f6becfd3562222b2cfaea965Jim Ingham    bool &word_complete,
74724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lldb_private::StringList &matches
74824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
74924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
750802f8b0e11525a61f6becfd3562222b2cfaea965Jim Ingham    word_complete = true;
751802f8b0e11525a61f6becfd3562222b2cfaea965Jim Ingham
75224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // For now we just scan the completions to see if the cursor position is in
75324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // an option or its argument.  Otherwise we'll call HandleArgumentCompletion.
75424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // In the future we can use completion to validate options as well if we want.
75524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
75624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const OptionDefinition *opt_defs = GetDefinitions();
75724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
75824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    std::string cur_opt_std_str (input.GetArgumentAtIndex(cursor_index));
75924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    cur_opt_std_str.erase(char_pos);
76024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *cur_opt_str = cur_opt_std_str.c_str();
76124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7623e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs    for (size_t i = 0; i < opt_element_vector.size(); i++)
76324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
76424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int opt_pos = opt_element_vector[i].opt_pos;
76524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int opt_arg_pos = opt_element_vector[i].opt_arg_pos;
76624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int opt_defs_index = opt_element_vector[i].opt_defs_index;
76724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (opt_pos == cursor_index)
76824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
76924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // We're completing the option itself.
7708b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham
7718b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham            if (opt_defs_index == OptionArgElement::eBareDash)
7728b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham            {
7738b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                // We're completing a bare dash.  That means all options are open.
7748b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                // FIXME: We should scan the other options provided and only complete options
7758b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                // within the option group they belong to.
7768b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                char opt_str[3] = {'-', 'a', '\0'};
7778b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham
778bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                for (int j = 0 ; opt_defs[j].short_option != 0 ; j++)
7798b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                {
780bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                    opt_str[1] = opt_defs[j].short_option;
7818b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                    matches.AppendString (opt_str);
7828b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                }
7838b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                return true;
7848b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham            }
7858b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham            else if (opt_defs_index == OptionArgElement::eBareDoubleDash)
7868b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham            {
7878b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                std::string full_name ("--");
788bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                for (int j = 0 ; opt_defs[j].short_option != 0 ; j++)
7898b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                {
7908b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                    full_name.erase(full_name.begin() + 2, full_name.end());
791bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                    full_name.append (opt_defs[j].long_option);
7928b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                    matches.AppendString (full_name.c_str());
7938b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                }
7948b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham                return true;
7958b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham            }
7968b9af1caac91c9e66440370a79705a3370e0a360Jim Ingham            else if (opt_defs_index != OptionArgElement::eUnrecognizedArg)
79724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
7983f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton                // We recognized it, if it an incomplete long option, complete it anyway (getopt_long_only is
79924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // happy with shortest unique string, but it's still a nice thing to do.)  Otherwise return
80024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // The string so the upper level code will know this is a full match and add the " ".
80124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (cur_opt_str && strlen (cur_opt_str) > 2
80224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    && cur_opt_str[0] == '-' && cur_opt_str[1] == '-'
80324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    && strcmp (opt_defs[opt_defs_index].long_option, cur_opt_str) != 0)
80424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
80524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        std::string full_name ("--");
80624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        full_name.append (opt_defs[opt_defs_index].long_option);
80724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        matches.AppendString(full_name.c_str());
80824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        return true;
80924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
81024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                else
81124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
81224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    matches.AppendString(input.GetArgumentAtIndex(cursor_index));
81324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return true;
81424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
81524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
81624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
81724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
81824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // FIXME - not handling wrong options yet:
81924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // Check to see if they are writing a long option & complete it.
82024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // I think we will only get in here if the long option table has two elements
8213f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton                // that are not unique up to this point.  getopt_long_only does shortest unique match
82224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // for long options already.
82324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
82424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (cur_opt_str && strlen (cur_opt_str) > 2
82524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    && cur_opt_str[0] == '-' && cur_opt_str[1] == '-')
82624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
827bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                    for (int j = 0 ; opt_defs[j].short_option != 0 ; j++)
82824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
829bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                        if (strstr(opt_defs[j].long_option, cur_opt_str + 2) == opt_defs[j].long_option)
83024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
83124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            std::string full_name ("--");
832bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                            full_name.append (opt_defs[j].long_option);
83324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            // The options definitions table has duplicates because of the
83424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            // way the grouping information is stored, so only add once.
83524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            bool duplicate = false;
8363e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs                            for (size_t k = 0; k < matches.GetSize(); k++)
83724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
838bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                                if (matches.GetStringAtIndex(k) == full_name)
83924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                {
84024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    duplicate = true;
84124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    break;
84224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                }
84324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
84424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            if (!duplicate)
84524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                matches.AppendString(full_name.c_str());
84624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
84724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
84824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
84924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return true;
85024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
85124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
85224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
85324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
85424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else if (opt_arg_pos == cursor_index)
85524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
85624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Okay the cursor is on the completion of an argument.
85724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // See if it has a completion, otherwise return no matches.
85824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
85924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (opt_defs_index != -1)
86024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
861f15996eea072cdaa8a092f22d3a1212b3d95f0ecGreg Clayton                HandleOptionArgumentCompletion (input,
86263094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                cursor_index,
86363094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                strlen (input.GetArgumentAtIndex(cursor_index)),
86463094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                opt_element_vector,
86563094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                i,
86663094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                match_start_point,
86763094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                max_return_elements,
868802f8b0e11525a61f6becfd3562222b2cfaea965Jim Ingham                                                word_complete,
86963094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                matches);
87024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return true;
87124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
87224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
87324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
87424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // No completion callback means no completions...
87524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return true;
87624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
87724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
87824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
87924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
88024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
88124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Not the last element, keep going.
88224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            continue;
88324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
88424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
88524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
88624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
88724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
88824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
88924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerOptions::HandleOptionArgumentCompletion
89024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
89124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Args &input,
89224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int cursor_index,
89324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int char_pos,
89424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    OptionElementVector &opt_element_vector,
89524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int opt_element_index,
89624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int match_start_point,
89724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int max_return_elements,
898802f8b0e11525a61f6becfd3562222b2cfaea965Jim Ingham    bool &word_complete,
89924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lldb_private::StringList &matches
90024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
90124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
90224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const OptionDefinition *opt_defs = GetDefinitions();
903102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton    std::unique_ptr<SearchFilter> filter_ap;
90424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
90524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
90624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
90724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
90824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // See if this is an enumeration type option, and if so complete it here:
90924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
91024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values;
91124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (enum_values != NULL)
91224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
91324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        bool return_value = false;
91424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        std::string match_string(input.GetArgumentAtIndex (opt_arg_pos), input.GetArgumentAtIndex (opt_arg_pos) + char_pos);
91524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for (int i = 0; enum_values[i].string_value != NULL; i++)
91624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
91724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (strstr(enum_values[i].string_value, match_string.c_str()) == enum_values[i].string_value)
91824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
91924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                matches.AppendString (enum_values[i].string_value);
92024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return_value = true;
92124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
92224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
92324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return return_value;
92424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
92524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
92624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // If this is a source file or symbol type completion, and  there is a
92724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // -shlib option somewhere in the supplied arguments, then make a search filter
92824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // for that shared library.
92924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // FIXME: Do we want to also have an "OptionType" so we don't have to match string names?
93024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9315e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    uint32_t completion_mask = opt_defs[opt_defs_index].completion_type;
9325e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton
9335e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    if (completion_mask == 0)
9345e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    {
9355e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        lldb::CommandArgumentType option_arg_type = opt_defs[opt_defs_index].argument_type;
9365e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        if (option_arg_type != eArgTypeNone)
9375e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        {
9385e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton            CommandObject::ArgumentTableEntry *arg_entry = CommandObject::FindArgumentDataByType (opt_defs[opt_defs_index].argument_type);
9395e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton            if (arg_entry)
9405e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton                completion_mask = arg_entry->completion_type;
9415e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        }
9425e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    }
9435e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton
94424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (completion_mask & CommandCompletions::eSourceFileCompletion
94524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        || completion_mask & CommandCompletions::eSymbolCompletion)
94624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
9473e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs        for (size_t i = 0; i < opt_element_vector.size(); i++)
94824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
94924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            int cur_defs_index = opt_element_vector[i].opt_defs_index;
95024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            int cur_arg_pos    = opt_element_vector[i].opt_arg_pos;
95124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            const char *cur_opt_name = opt_defs[cur_defs_index].long_option;
95224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
95324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // If this is the "shlib" option and there was an argument provided,
95424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // restrict it to that shared library.
95524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (strcmp(cur_opt_name, "shlib") == 0 && cur_arg_pos != -1)
95624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
95724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                const char *module_name = input.GetArgumentAtIndex(cur_arg_pos);
95824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (module_name)
95924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
960537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton                    FileSpec module_spec(module_name, false);
961f15996eea072cdaa8a092f22d3a1212b3d95f0ecGreg Clayton                    lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
96224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    // Search filters require a target...
963987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton                    if (target_sp)
96424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        filter_ap.reset (new SearchFilterByModule (target_sp, module_spec));
96524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
96624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                break;
96724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
96824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
96924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
97024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
971f15996eea072cdaa8a092f22d3a1212b3d95f0ecGreg Clayton    return CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
97263094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                completion_mask,
97363094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                input.GetArgumentAtIndex (opt_arg_pos),
97463094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                match_start_point,
97563094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                max_return_elements,
97663094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                filter_ap.get(),
977802f8b0e11525a61f6becfd3562222b2cfaea965Jim Ingham                                                                word_complete,
97863094e0bb161580564954dee512955c1c79d3476Greg Clayton                                                                matches);
97963094e0bb161580564954dee512955c1c79d3476Greg Clayton
98024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
981143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton
982143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton
983143fcc3a15425659b381502ed4e1e50a3e726f36Greg Claytonvoid
98457b3c6b12812b0a7a79f896855c787bd4d893ecbGreg ClaytonOptionGroupOptions::Append (OptionGroup* group)
98557b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton{
98657b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton    const OptionDefinition* group_option_defs = group->GetDefinitions ();
98757b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton    const uint32_t group_option_count = group->GetNumDefinitions();
98857b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton    for (uint32_t i=0; i<group_option_count; ++i)
98957b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton    {
99057b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton        m_option_infos.push_back (OptionInfo (group, i));
99157b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton        m_option_defs.push_back (group_option_defs[i]);
99257b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton    }
99357b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton}
99457b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Clayton
99557b3c6b12812b0a7a79f896855c787bd4d893ecbGreg Claytonvoid
9965e342f50b42b265d8568e1c926328858e74b2c0aGreg ClaytonOptionGroupOptions::Append (OptionGroup* group,
9975e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton                            uint32_t src_mask,
9985e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton                            uint32_t dst_mask)
999143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton{
1000143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    const OptionDefinition* group_option_defs = group->GetDefinitions ();
1001143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    const uint32_t group_option_count = group->GetNumDefinitions();
1002143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    for (uint32_t i=0; i<group_option_count; ++i)
1003143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    {
10045e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        if (group_option_defs[i].usage_mask & src_mask)
10055e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        {
10065e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton            m_option_infos.push_back (OptionInfo (group, i));
10075e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton            m_option_defs.push_back (group_option_defs[i]);
10085e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton            m_option_defs.back().usage_mask = dst_mask;
10095e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        }
1010143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    }
1011143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton}
1012143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton
1013143fcc3a15425659b381502ed4e1e50a3e726f36Greg Claytonvoid
1014143fcc3a15425659b381502ed4e1e50a3e726f36Greg ClaytonOptionGroupOptions::Finalize ()
1015143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton{
1016143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    m_did_finalize = true;
1017143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    OptionDefinition empty_option_def = { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL };
1018143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    m_option_defs.push_back (empty_option_def);
1019143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton}
1020143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton
1021143fcc3a15425659b381502ed4e1e50a3e726f36Greg ClaytonError
1022143fcc3a15425659b381502ed4e1e50a3e726f36Greg ClaytonOptionGroupOptions::SetOptionValue (uint32_t option_idx,
1023143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton                                    const char *option_value)
1024143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton{
1025143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    // After calling OptionGroupOptions::Append(...), you must finalize the groups
1026143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    // by calling OptionGroupOptions::Finlize()
1027143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    assert (m_did_finalize);
10285e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    assert (m_option_infos.size() + 1 == m_option_defs.size());
10295e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    Error error;
10305e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    if (option_idx < m_option_infos.size())
1031143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    {
10325e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        error = m_option_infos[option_idx].option_group->SetOptionValue (m_interpreter,
10335e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton                                                                         m_option_infos[option_idx].option_index,
10345e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton                                                                         option_value);
10355e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton
10365e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    }
10375e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    else
10385e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    {
10395e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        error.SetErrorString ("invalid option index"); // Shouldn't happen...
1040143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    }
1041143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    return error;
1042143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton}
1043143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton
1044143fcc3a15425659b381502ed4e1e50a3e726f36Greg Claytonvoid
1045143fcc3a15425659b381502ed4e1e50a3e726f36Greg ClaytonOptionGroupOptions::OptionParsingStarting ()
1046143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton{
10475e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    std::set<OptionGroup*> group_set;
10485e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    OptionInfos::iterator pos, end = m_option_infos.end();
10495e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    for (pos = m_option_infos.begin(); pos != end; ++pos)
10505e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    {
10515e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        OptionGroup* group = pos->option_group;
10525e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        if (group_set.find(group) == group_set.end())
10535e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        {
10545e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton            group->OptionParsingStarting (m_interpreter);
10555e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton            group_set.insert(group);
10565e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        }
10575e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    }
1058143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton}
1059143fcc3a15425659b381502ed4e1e50a3e726f36Greg ClaytonError
1060143fcc3a15425659b381502ed4e1e50a3e726f36Greg ClaytonOptionGroupOptions::OptionParsingFinished ()
1061143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton{
10625e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    std::set<OptionGroup*> group_set;
1063143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    Error error;
10645e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    OptionInfos::iterator pos, end = m_option_infos.end();
10655e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    for (pos = m_option_infos.begin(); pos != end; ++pos)
1066143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    {
10675e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        OptionGroup* group = pos->option_group;
10685e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        if (group_set.find(group) == group_set.end())
10695e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        {
10705e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton            error = group->OptionParsingFinished (m_interpreter);
10715e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton            group_set.insert(group);
10725e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton            if (error.Fail())
10735e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton                return error;
10745e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton        }
1075143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    }
1076143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton    return error;
1077143fcc3a15425659b381502ed4e1e50a3e726f36Greg Clayton}
1078