diff options
Diffstat (limited to 'lldb/source/Core')
-rw-r--r-- | lldb/source/Core/Args.cpp | 1103 | ||||
-rw-r--r-- | lldb/source/Core/ConnectionFileDescriptor.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Core/Options.cpp | 734 | ||||
-rw-r--r-- | lldb/source/Core/Scalar.cpp | 2 |
4 files changed, 2 insertions, 1839 deletions
diff --git a/lldb/source/Core/Args.cpp b/lldb/source/Core/Args.cpp deleted file mode 100644 index 5ff57afc990..00000000000 --- a/lldb/source/Core/Args.cpp +++ /dev/null @@ -1,1103 +0,0 @@ -//===-- Args.cpp ------------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <getopt.h> -#include <cstdlib> -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Args.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/Options.h" -#include "lldb/Interpreter/CommandReturnObject.h" - -using namespace lldb; -using namespace lldb_private; - -static const char *k_space_characters = "\t\n\v\f\r "; -static const char *k_space_characters_with_slash = "\t\n\v\f\r \\"; - - -//---------------------------------------------------------------------- -// Args constructor -//---------------------------------------------------------------------- -Args::Args (const char *command) : - m_args(), - m_argv() -{ - SetCommandString (command); -} - - -Args::Args (const char *command, size_t len) : - m_args(), - m_argv() -{ - SetCommandString (command, len); -} - - - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -Args::~Args () -{ -} - -void -Args::Dump (Stream *s) -{ -// int argc = GetArgumentCount(); -// -// arg_sstr_collection::const_iterator pos, begin = m_args.begin(), end = m_args.end(); -// for (pos = m_args.begin(); pos != end; ++pos) -// { -// s->Indent(); -// s->Printf("args[%zu]=%s\n", std::distance(begin, pos), pos->c_str()); -// } -// s->EOL(); - const int argc = m_argv.size(); - for (int i=0; i<argc; ++i) - { - s->Indent(); - const char *arg_cstr = m_argv[i]; - if (arg_cstr) - s->Printf("argv[%i]=\"%s\"\n", i, arg_cstr); - else - s->Printf("argv[%i]=NULL\n", i); - } - s->EOL(); -} - -bool -Args::GetCommandString (std::string &command) -{ - command.clear(); - int argc = GetArgumentCount(); - for (int i=0; i<argc; ++i) - { - if (i > 0) - command += ' '; - command += m_argv[i]; - } - return argc > 0; -} - -void -Args::SetCommandString (const char *command, size_t len) -{ - // Use std::string to make sure we get a NULL terminated string we can use - // as "command" could point to a string within a large string.... - std::string null_terminated_command(command, len); - SetCommandString(null_terminated_command.c_str()); -} - -void -Args::SetCommandString (const char *command) -{ - m_args.clear(); - m_argv.clear(); - if (command && command[0]) - { - const char *arg_start; - const char *next_arg_start; - for (arg_start = command, next_arg_start = NULL; - arg_start && arg_start[0]; - arg_start = next_arg_start, next_arg_start = NULL) - { - // Skip any leading space characters - arg_start = ::strspn (arg_start, k_space_characters) + arg_start; - - // If there were only space characters to the end of the line, then - // we're done. - if (*arg_start == '\0') - break; - - std::string arg; - const char *arg_end = NULL; - - switch (*arg_start) - { - case '\'': - case '"': - case '`': - { - // Look for either a quote character, or the backslash - // character - const char quote_char = *arg_start; - char find_chars[3] = { quote_char, '\\' , '\0'}; - bool is_backtick = (quote_char == '`'); - if (quote_char == '"' || quote_char == '`') - m_args_quote_char.push_back(quote_char); - else - m_args_quote_char.push_back('\0'); - - while (*arg_start != '\0') - { - arg_end = ::strcspn (arg_start + 1, find_chars) + arg_start + 1; - - if (*arg_end == '\0') - { - arg.append (arg_start); - break; - } - - // Watch out for quote characters prefixed with '\' - if (*arg_end == '\\') - { - if (arg_end[1] == quote_char) - { - // The character following the '\' is our quote - // character so strip the backslash character - arg.append (arg_start, arg_end); - } - else - { - // The character following the '\' is NOT our - // quote character, so include the backslash - // and continue - arg.append (arg_start, arg_end + 1); - } - arg_start = arg_end + 1; - continue; - } - else - { - arg.append (arg_start, arg_end + 1); - next_arg_start = arg_end + 1; - break; - } - } - - // Skip single and double quotes, but leave backtick quotes - if (!is_backtick) - { - char first_c = arg[0]; - arg.erase(0,1); - // Only erase the last character if it is the same as the first. - // Otherwise, we're parsing an incomplete command line, and we - // would be stripping off the last character of that string. - if (arg[arg.size() - 1] == first_c) - arg.erase(arg.size() - 1, 1); - } - } - break; - default: - { - m_args_quote_char.push_back('\0'); - // Look for the next non-escaped space character - while (*arg_start != '\0') - { - arg_end = ::strcspn (arg_start, k_space_characters_with_slash) + arg_start; - - if (arg_end == NULL) - { - arg.append(arg_start); - break; - } - - if (*arg_end == '\\') - { - // Append up to the '\' char - arg.append (arg_start, arg_end); - - if (arg_end[1] == '\0') - break; - - // Append the character following the '\' if it isn't - // the end of the string - arg.append (1, arg_end[1]); - arg_start = arg_end + 2; - continue; - } - else - { - arg.append (arg_start, arg_end); - next_arg_start = arg_end; - break; - } - } - } - break; - } - - m_args.push_back(arg); - } - } - UpdateArgvFromArgs(); -} - -void -Args::UpdateArgsAfterOptionParsing() -{ - // Now m_argv might be out of date with m_args, so we need to fix that - arg_cstr_collection::const_iterator argv_pos, argv_end = m_argv.end(); - arg_sstr_collection::iterator args_pos; - arg_quote_char_collection::iterator quotes_pos; - - for (argv_pos = m_argv.begin(), args_pos = m_args.begin(), quotes_pos = m_args_quote_char.begin(); - argv_pos != argv_end && args_pos != m_args.end(); - ++argv_pos) - { - const char *argv_cstr = *argv_pos; - if (argv_cstr == NULL) - break; - - while (args_pos != m_args.end()) - { - const char *args_cstr = args_pos->c_str(); - if (args_cstr == argv_cstr) - { - // We found the argument that matches the C string in the - // vector, so we can now look for the next one - ++args_pos; - ++quotes_pos; - break; - } - else - { - quotes_pos = m_args_quote_char.erase (quotes_pos); - args_pos = m_args.erase (args_pos); - } - } - } - - if (args_pos != m_args.end()) - m_args.erase (args_pos, m_args.end()); - - if (quotes_pos != m_args_quote_char.end()) - m_args_quote_char.erase (quotes_pos, m_args_quote_char.end()); -} - -void -Args::UpdateArgvFromArgs() -{ - m_argv.clear(); - arg_sstr_collection::const_iterator pos, end = m_args.end(); - for (pos = m_args.begin(); pos != end; ++pos) - m_argv.push_back(pos->c_str()); - m_argv.push_back(NULL); -} - -size_t -Args::GetArgumentCount() const -{ - if (m_argv.empty()) - return 0; - return m_argv.size() - 1; -} - -const char * -Args::GetArgumentAtIndex (size_t idx) const -{ - if (idx < m_argv.size()) - return m_argv[idx]; - return NULL; -} - -char -Args::GetArgumentQuoteCharAtIndex (size_t idx) const -{ - if (idx < m_args_quote_char.size()) - return m_args_quote_char[idx]; - return '\0'; -} - -char ** -Args::GetArgumentVector() -{ - if (!m_argv.empty()) - return (char **)&m_argv[0]; - return NULL; -} - -const char ** -Args::GetConstArgumentVector() const -{ - if (!m_argv.empty()) - return (const char **)&m_argv[0]; - return NULL; -} - -void -Args::Shift () -{ - // Don't pop the last NULL terminator from the argv array - if (m_argv.size() > 1) - { - m_argv.erase(m_argv.begin()); - m_args.pop_front(); - m_args_quote_char.erase(m_args_quote_char.begin()); - } -} - -const char * -Args::Unshift (const char *arg_cstr, char quote_char) -{ - m_args.push_front(arg_cstr); - m_argv.insert(m_argv.begin(), m_args.front().c_str()); - m_args_quote_char.insert(m_args_quote_char.begin(), quote_char); - return GetArgumentAtIndex (0); -} - -void -Args::AppendArguments (const Args &rhs) -{ - const size_t rhs_argc = rhs.GetArgumentCount(); - for (size_t i=0; i<rhs_argc; ++i) - AppendArgument(rhs.GetArgumentAtIndex(i)); -} - -const char * -Args::AppendArgument (const char *arg_cstr, char quote_char) -{ - return InsertArgumentAtIndex (GetArgumentCount(), arg_cstr, quote_char); -} - -const char * -Args::InsertArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char) -{ - // Since we are using a std::list to hold onto the copied C string and - // we don't have direct access to the elements, we have to iterate to - // find the value. - arg_sstr_collection::iterator pos, end = m_args.end(); - size_t i = idx; - for (pos = m_args.begin(); i > 0 && pos != end; ++pos) - --i; - - pos = m_args.insert(pos, arg_cstr); - - - m_args_quote_char.insert(m_args_quote_char.begin() + idx, quote_char); - - UpdateArgvFromArgs(); - return GetArgumentAtIndex(idx); -} - -const char * -Args::ReplaceArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char) -{ - // Since we are using a std::list to hold onto the copied C string and - // we don't have direct access to the elements, we have to iterate to - // find the value. - arg_sstr_collection::iterator pos, end = m_args.end(); - size_t i = idx; - for (pos = m_args.begin(); i > 0 && pos != end; ++pos) - --i; - - if (pos != end) - { - pos->assign(arg_cstr); - assert(idx < m_argv.size() - 1); - m_argv[idx] = pos->c_str(); - m_args_quote_char[idx] = quote_char; - return GetArgumentAtIndex(idx); - } - return NULL; -} - -void -Args::DeleteArgumentAtIndex (size_t idx) -{ - // Since we are using a std::list to hold onto the copied C string and - // we don't have direct access to the elements, we have to iterate to - // find the value. - arg_sstr_collection::iterator pos, end = m_args.end(); - size_t i = idx; - for (pos = m_args.begin(); i > 0 && pos != end; ++pos) - --i; - - if (pos != end) - { - m_args.erase (pos); - assert(idx < m_argv.size() - 1); - m_argv.erase(m_argv.begin() + idx); - m_args_quote_char.erase(m_args_quote_char.begin() + idx); - } -} - -void -Args::SetArguments (int argc, const char **argv) -{ - // m_argv will be rebuilt in UpdateArgvFromArgs() below, so there is - // no need to clear it here. - m_args.clear(); - m_args_quote_char.clear(); - - // Make a copy of the arguments in our internal buffer - size_t i; - // First copy each string - for (i=0; i<argc; ++i) - { - m_args.push_back (argv[i]); - if ((argv[i][0] == '"') || (argv[i][0] == '`')) - m_args_quote_char.push_back (argv[i][0]); - else - m_args_quote_char.push_back ('\0'); - } - - UpdateArgvFromArgs(); -} - - -Error -Args::ParseOptions (Options &options) -{ - StreamString sstr; - int i; - Error error; - struct option *long_options = options.GetLongOptions(); - if (long_options == NULL) - { - error.SetErrorStringWithFormat("Invalid long options.\n"); - return error; - } - - for (i=0; long_options[i].name != NULL; ++i) - { - if (long_options[i].flag == NULL) - { - sstr << (char)long_options[i].val; - switch (long_options[i].has_arg) - { - default: - case no_argument: break; - case required_argument: sstr << ':'; break; - case optional_argument: sstr << "::"; break; - } - } - } -#ifdef __GLIBC__ - optind = 0; -#else - optreset = 1; - optind = 1; -#endif - int val; - while (1) - { - int long_options_index = -1; - val = ::getopt_long(GetArgumentCount(), GetArgumentVector(), sstr.GetData(), long_options, - &long_options_index); - if (val == -1) - break; - - // Did we get an error? - if (val == '?') - { - error.SetErrorStringWithFormat("Unknown or ambiguous option.\n"); - break; - } - // The option auto-set itself - if (val == 0) - continue; - - ((Options *) &options)->OptionSeen (val); - - // Lookup the long option index - if (long_options_index == -1) - { - for (int i=0; - long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val; - ++i) - { - if (long_options[i].val == val) - { - long_options_index = i; - break; - } - } - } - // Call the callback with the option - if (long_options_index >= 0) - { - error = options.SetOptionValue(long_options_index, - long_options[long_options_index].has_arg == no_argument ? NULL : optarg); - } - else - { - error.SetErrorStringWithFormat("Invalid option with value '%i'.\n", val); - } - if (error.Fail()) - break; - } - - // Update our ARGV now that get options has consumed all the options - m_argv.erase(m_argv.begin(), m_argv.begin() + optind); - UpdateArgsAfterOptionParsing (); - return error; -} - -void -Args::Clear () -{ - m_args.clear (); - m_argv.clear (); - m_args_quote_char.clear(); -} - -int32_t -Args::StringToSInt32 (const char *s, int32_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = NULL; - int32_t uval = ::strtol (s, &end, base); - if (*end == '\0') - { - if (success_ptr) *success_ptr = true; - return uval; // All characters were used, return the result - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - -uint32_t -Args::StringToUInt32 (const char *s, uint32_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = NULL; - uint32_t uval = ::strtoul (s, &end, base); - if (*end == '\0') - { - if (success_ptr) *success_ptr = true; - return uval; // All characters were used, return the result - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - - -int64_t -Args::StringToSInt64 (const char *s, int64_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = NULL; - int64_t uval = ::strtoll (s, &end, base); - if (*end == '\0') - { - if (success_ptr) *success_ptr = true; - return uval; // All characters were used, return the result - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - -uint64_t -Args::StringToUInt64 (const char *s, uint64_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = NULL; - uint64_t uval = ::strtoull (s, &end, base); - if (*end == '\0') - { - if (success_ptr) *success_ptr = true; - return uval; // All characters were used, return the result - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - -lldb::addr_t -Args::StringToAddress (const char *s, lldb::addr_t fail_value, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = NULL; - lldb::addr_t addr = ::strtoull (s, &end, 0); - if (*end == '\0') - { - if (success_ptr) *success_ptr = true; - return addr; // All characters were used, return the result - } - // Try base 16 with no prefix... - addr = ::strtoull (s, &end, 16); - if (*end == '\0') - { - if (success_ptr) *success_ptr = true; - return addr; // All characters were used, return the result - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - -bool -Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr) -{ - if (s && s[0]) - { - if (::strcasecmp (s, "false") == 0 || - ::strcasecmp (s, "off") == 0 || - ::strcasecmp (s, "no") == 0 || - ::strcmp (s, "0") == 0) - { - if (success_ptr) - *success_ptr = true; - return false; - } - else - if (::strcasecmp (s, "true") == 0 || - ::strcasecmp (s, "on") == 0 || - ::strcasecmp (s, "yes") == 0 || - ::strcmp (s, "1") == 0) - { - if (success_ptr) *success_ptr = true; - return true; - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - -int32_t -Args::StringToOptionEnum (const char *s, lldb::OptionEnumValueElement *enum_values, int32_t fail_value, bool *success_ptr) -{ - if (enum_values && s && s[0]) - { - for (int i = 0; enum_values[i].string_value != NULL ; i++) - { - if (strstr(enum_values[i].string_value, s) == enum_values[i].string_value) - { - if (success_ptr) *success_ptr = true; - return enum_values[i].value; - } - } - } - if (success_ptr) *success_ptr = false; - - return fail_value; -} - -ScriptLanguage -Args::StringToScriptLanguage (const char *s, ScriptLanguage fail_value, bool *success_ptr) -{ - if (s && s[0]) - { - if ((::strcasecmp (s, "python") == 0) || - (::strcasecmp (s, "default") == 0 && eScriptLanguagePython == eScriptLanguageDefault)) - { - if (success_ptr) *success_ptr = true; - return eScriptLanguagePython; - } - if (::strcasecmp (s, "none")) - { - if (success_ptr) *success_ptr = true; - return eScriptLanguageNone; - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - -Error -Args::StringToFormat -( - const char *s, - lldb::Format &format -) -{ - format = eFormatInvalid; - Error error; - - if (s && s[0]) - { - switch (s[0]) - { - case 'y': format = eFormatBytes; break; - case 'Y': format = eFormatBytesWithASCII; break; - case 'b': format = eFormatBinary; break; - case 'B': format = eFormatBoolean; break; - case 'c': format = eFormatChar; break; - case 'C': format = eFormatCharPrintable; break; - case 'o': format = eFormatOctal; break; - case 'i': - case 'd': format = eFormatDecimal; break; - case 'u': format = eFormatUnsigned; break; - case 'x': format = eFormatHex; break; - case 'f': - case 'e': - case 'g': format = eFormatFloat; break; - case 'p': format = eFormatPointer; break; - case 's': format = eFormatCString; break; - default: - error.SetErrorStringWithFormat("Invalid format character '%c'. Valid values are:\n" - " b - binary\n" - " B - boolean\n" - " c - char\n" - " C - printable char\n" - " d - signed decimal\n" - " e - float\n" - " f - float\n" - " g - float\n" - " i - signed decimal\n" - " o - octal\n" - " s - c-string\n" - " u - unsigned decimal\n" - " x - hex\n" - " y - bytes\n" - " Y - bytes with ASCII\n", s[0]); - break; - } - - if (error.Fail()) - return error; - } - else - { - error.SetErrorStringWithFormat("%s option string.\n", s ? "empty" : "invalid"); - } - return error; -} - -void -Args::LongestCommonPrefix (std::string &common_prefix) -{ - arg_sstr_collection::iterator pos, end = m_args.end(); - pos = m_args.begin(); - if (pos == end) - common_prefix.clear(); - else - common_prefix = (*pos); - - for (++pos; pos != end; ++pos) - { - int new_size = (*pos).size(); - - // First trim common_prefix if it is longer than the current element: - if (common_prefix.size() > new_size) - common_prefix.erase (new_size); - - // Then trim it at the first disparity: - - for (int i = 0; i < common_prefix.size(); i++) - { - if ((*pos)[i] != common_prefix[i]) - { - common_prefix.erase(i); - break; - } - } - - // If we've emptied the common prefix, we're done. - if (common_prefix.empty()) - break; - } -} - -void -Args::ParseAliasOptions -( - Options &options, - CommandReturnObject &result, - OptionArgVector *option_arg_vector -) -{ - StreamString sstr; - int i; - struct option *long_options = options.GetLongOptions(); - - if (long_options == NULL) - { - result.AppendError ("invalid long options"); - result.SetStatus (eReturnStatusFailed); - return; - } - - for (i = 0; long_options[i].name != NULL; ++i) - { - if (long_options[i].flag == NULL) - { - sstr << (char) long_options[i].val; - switch (long_options[i].has_arg) - { - default: - case no_argument: - break; - case required_argument: - sstr << ":"; - break; - case optional_argument: - sstr << "::"; - break; - } - } - } - -#ifdef __GLIBC__ - optind = 0; -#else - optreset = 1; - optind = 1; -#endif - int val; - while (1) - { - int long_options_index = -1; - val = ::getopt_long (GetArgumentCount(), GetArgumentVector(), sstr.GetData(), long_options, - &long_options_index); - - if (val == -1) - break; - - if (val == '?') - { - result.AppendError ("unknown or ambiguous option"); - result.SetStatus (eReturnStatusFailed); - break; - } - - if (val == 0) - continue; - - ((Options *) &options)->OptionSeen (val); - - // Look up the long option index - if (long_options_index == -1) - { - for (int j = 0; - long_options[j].name || long_options[j].has_arg || long_options[j].flag || long_options[j].val; - ++j) - { - if (long_options[j].val == val) - { - long_options_index = j; - break; - } - } - } - - // See if the option takes an argument, and see if one was supplied. - if (long_options_index >= 0) - { - StreamString option_str; - option_str.Printf ("-%c", (char) val); - - switch (long_options[long_options_index].has_arg) - { - case no_argument: - option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), "<no-argument>")); - break; - case required_argument: - if (optarg != NULL) - { - option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), - std::string (optarg))); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendErrorWithFormat ("Option '%s' is missing argument specifier.\n", - option_str.GetData()); - result.SetStatus (eReturnStatusFailed); - } - break; - case optional_argument: - if (optarg != NULL) - { - option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), - std::string (optarg))); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - option_arg_vector->push_back (OptionArgPair (std::string (option_str.GetData()), - "<no-argument>")); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - break; - default: - result.AppendErrorWithFormat - ("error with options table; invalid value in has_arg field for option '%c'.\n", - (char) val); - result.SetStatus (eReturnStatusFailed); - break; - } - } - else - { - result.AppendErrorWithFormat ("Invalid option with value '%c'.\n", (char) val); - result.SetStatus (eReturnStatusFailed); - } - if (!result.Succeeded()) - break; - } -} - -void -Args::ParseArgsForCompletion -( - Options &options, - OptionElementVector &option_element_vector -) -{ - StreamString sstr; - int i; - struct option *long_options = options.GetLongOptions(); - option_element_vector.clear(); - - if (long_options == NULL) - { - return; - } - - // Leading : tells getopt to return a : for a missing option argument AND - // to suppress error messages. - - sstr << ":"; - for (i = 0; long_options[i].name != NULL; ++i) - { - if (long_options[i].flag == NULL) - { - sstr << (char) long_options[i].val; - switch (long_options[i].has_arg) - { - default: - case no_argument: - break; - case required_argument: - sstr << ":"; - break; - case optional_argument: - sstr << "::"; - break; - } - } - } - -#ifdef __GLIBC__ - optind = 0; -#else - optreset = 1; - optind = 1; -#endif - opterr = 0; - - int val; - const OptionDefinition *opt_defs = options.GetDefinitions(); - - // Fooey... getopt_long permutes the GetArgumentVector for no apparent reason. - // So we have to build another Arg and pass that to getopt_long so it doesn't - // screw up the one we have. - - std::vector<const char *> dummy_vec(GetArgumentVector(), GetArgumentVector() + GetArgumentCount() + 1); - - while (1) - { - bool missing_argument = false; - int parse_start = optind; - int long_options_index = -1; - val = ::getopt_long (dummy_vec.size() - 1,(char *const *) dummy_vec.data(), sstr.GetData(), long_options, - &long_options_index); - - if (val == -1) - break; - - else if (val == '?') - { - option_element_vector.push_back (OptionArgElement (-1, parse_start, -1)); - continue; - } - else if (val == 0) - { - continue; - } - else if (val == ':') - { - // This is a missing argument. - val = optopt; - missing_argument = true; - } - - ((Options *) &options)->OptionSeen (val); - - // Look up the long option index - if (long_options_index == -1) - { - for (int j = 0; - long_options[j].name || long_options[j].has_arg || long_options[j].flag || long_options[j].val; - ++j) - { - if (long_options[j].val == val) - { - long_options_index = j; - break; - } - } - } - - // See if the option takes an argument, and see if one was supplied. - if (long_options_index >= 0) - { - int opt_defs_index = -1; - for (int i = 0; ; i++) - { - if (opt_defs[i].short_option == 0) - break; - else if (opt_defs[i].short_option == val) - { - opt_defs_index = i; - break; - } - } - - switch (long_options[long_options_index].has_arg) - { - case no_argument: - option_element_vector.push_back (OptionArgElement (opt_defs_index, parse_start, 0)); - break; - case required_argument: - if (optarg != NULL) - { - int arg_index; - if (missing_argument) - arg_index = -1; - else - arg_index = parse_start + 1; - - option_element_vector.push_back (OptionArgElement (opt_defs_index, parse_start, arg_index)); - } - else - { - option_element_vector.push_back (OptionArgElement (opt_defs_index, parse_start, -1)); - } - break; - case optional_argument: - if (optarg != NULL) - { - option_element_vector.push_back (OptionArgElement (opt_defs_index, parse_start, 0)); - } - else - { - option_element_vector.push_back (OptionArgElement (opt_defs_index, parse_start, parse_start + 1)); - } - break; - default: - // The options table is messed up. Here we'll just continue - option_element_vector.push_back (OptionArgElement (-1, parse_start, -1)); - break; - } - } - else - { - option_element_vector.push_back (OptionArgElement (-1, parse_start, -1)); - } - } -} diff --git a/lldb/source/Core/ConnectionFileDescriptor.cpp b/lldb/source/Core/ConnectionFileDescriptor.cpp index a8097e85f14..60d78f618fc 100644 --- a/lldb/source/Core/ConnectionFileDescriptor.cpp +++ b/lldb/source/Core/ConnectionFileDescriptor.cpp @@ -25,7 +25,7 @@ // Other libraries and framework includes // Project includes #include "lldb/lldb-private-log.h" -#include "lldb/Core/Args.h" +#include "lldb/Interpreter/Args.h" #include "lldb/Core/Communication.h" #include "lldb/Core/Log.h" #include "lldb/Core/RegularExpression.h" diff --git a/lldb/source/Core/Options.cpp b/lldb/source/Core/Options.cpp deleted file mode 100644 index f43dc7c823e..00000000000 --- a/lldb/source/Core/Options.cpp +++ /dev/null @@ -1,734 +0,0 @@ -//===-- Options.cpp ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Core/Options.h" - -// C Includes -// C++ Includes -#include <bitset> - -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObject.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/CommandCompletions.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Target/Target.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------- -// Options -//------------------------------------------------------------------------- -Options::Options () : - m_getopt_table () -{ - BuildValidOptionSets(); -} - -Options::~Options () -{ -} - - -void -Options::ResetOptionValues () -{ - m_seen_options.clear(); -} - -void -Options::OptionSeen (int option_idx) -{ - m_seen_options.insert ((char) option_idx); -} - -// Returns true is set_a is a subset of set_b; Otherwise returns false. - -bool -Options::IsASubset (const OptionSet& set_a, const OptionSet& set_b) -{ - bool is_a_subset = true; - OptionSet::const_iterator pos_a; - OptionSet::const_iterator pos_b; - - // set_a is a subset of set_b if every member of set_a is also a member of set_b - - for (pos_a = set_a.begin(); pos_a != set_a.end() && is_a_subset; ++pos_a) - { - pos_b = set_b.find(*pos_a); - if (pos_b == set_b.end()) - is_a_subset = false; - } - - return is_a_subset; -} - -// Returns the set difference set_a - set_b, i.e. { x | ElementOf (x, set_a) && !ElementOf (x, set_b) } - -size_t -Options::OptionsSetDiff (const OptionSet& set_a, const OptionSet& set_b, OptionSet& diffs) -{ - size_t num_diffs = 0; - OptionSet::const_iterator pos_a; - OptionSet::const_iterator pos_b; - - for (pos_a = set_a.begin(); pos_a != set_a.end(); ++pos_a) - { - pos_b = set_b.find(*pos_a); - if (pos_b == set_b.end()) - { - ++num_diffs; - diffs.insert(*pos_a); - } - } - - return num_diffs; -} - -// Returns the union of set_a and set_b. Does not put duplicate members into the union. - -void -Options::OptionsSetUnion (const OptionSet &set_a, const OptionSet &set_b, OptionSet &union_set) -{ - OptionSet::const_iterator pos; - OptionSet::iterator pos_union; - - // Put all the elements of set_a into the union. - - for (pos = set_a.begin(); pos != set_a.end(); ++pos) - union_set.insert(*pos); - - // Put all the elements of set_b that are not already there into the union. - for (pos = set_b.begin(); pos != set_b.end(); ++pos) - { - pos_union = union_set.find(*pos); - if (pos_union == union_set.end()) - union_set.insert(*pos); - } -} - -bool -Options::VerifyOptions (CommandReturnObject &result) -{ - bool options_are_valid = false; - - int num_levels = m_required_options.size(); - if (num_levels) - { - for (int i = 0; i < num_levels && !options_are_valid; ++i) - { - // This is the correct set of options if: 1). m_seen_options contains all of m_required_options[i] - // (i.e. all the required options at this level are a subset of m_seen_options); AND - // 2). { m_seen_options - m_required_options[i] is a subset of m_options_options[i] (i.e. all the rest of - // m_seen_options are in the set of optional options at this level. - - // Check to see if all of m_required_options[i] are a subset of m_seen_options - if (IsASubset (m_required_options[i], m_seen_options)) - { - // Construct the set difference: remaining_options = {m_seen_options} - {m_required_options[i]} - OptionSet remaining_options; - OptionsSetDiff (m_seen_options, m_required_options[i], remaining_options); - // Check to see if remaining_options is a subset of m_optional_options[i] - if (IsASubset (remaining_options, m_optional_options[i])) - options_are_valid = true; - } - } - } - else - { - options_are_valid = true; - } - - if (options_are_valid) - { - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendError ("invalid combination of options for the given command"); - result.SetStatus (eReturnStatusFailed); - } - - return options_are_valid; -} - -// This is called in the Options constructor, though we could call it lazily if that ends up being -// a performance problem. - -void -Options::BuildValidOptionSets () -{ - // Check to see if we already did this. - if (m_required_options.size() != 0) - return; - - // Check to see if there are any options. - int num_options = NumCommandOptions (); - if (num_options == 0) - return; - - const lldb::OptionDefinition *full_options_table = GetDefinitions(); - m_required_options.resize(1); - m_optional_options.resize(1); - - // First count the number of option sets we've got. Ignore LLDB_ALL_OPTION_SETS... - - uint32_t num_option_sets = 0; - - for (int i = 0; i < num_options; i++) - { - uint32_t this_usage_mask = full_options_table[i].usage_mask; - if (this_usage_mask == LLDB_OPT_SET_ALL) - { - if (num_option_sets == 0) - num_option_sets = 1; - } - else - { - for (int j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++) - { - if (this_usage_mask & 1 << j) - { - if (num_option_sets <= j) - num_option_sets = j + 1; - } - } - } - } - - if (num_option_sets > 0) - { - m_required_options.resize(num_option_sets); - m_optional_options.resize(num_option_sets); - - for (int i = 0; i < num_options; ++i) - { - for (int j = 0; j < num_option_sets; j++) - { - if (full_options_table[i].usage_mask & 1 << j) - { - if (full_options_table[i].required) - m_required_options[j].insert(full_options_table[i].short_option); - else - m_optional_options[j].insert(full_options_table[i].short_option); - } - } - } - } -} - -uint32_t -Options::NumCommandOptions () -{ - const lldb::OptionDefinition *full_options_table = GetDefinitions (); - if (full_options_table == NULL) - return 0; - - int i = 0; - - if (full_options_table != NULL) - { - while (full_options_table[i].long_option != NULL) - ++i; - } - - return i; -} - -struct option * -Options::GetLongOptions () -{ - // Check to see if this has already been done. - if (m_getopt_table.empty()) - { - // Check to see if there are any options. - const uint32_t num_options = NumCommandOptions(); - if (num_options == 0) - return NULL; - - uint32_t i; - uint32_t j; - const lldb::OptionDefinition *full_options_table = GetDefinitions(); - - std::bitset<256> option_seen; - - m_getopt_table.resize(num_options + 1); - for (i = 0, j = 0; i < num_options; ++i) - { - char short_opt = full_options_table[i].short_option; - - if (option_seen.test(short_opt) == false) - { - m_getopt_table[j].name = full_options_table[i].long_option; - m_getopt_table[j].has_arg = full_options_table[i].option_has_arg; - m_getopt_table[j].flag = NULL; - m_getopt_table[j].val = full_options_table[i].short_option; - option_seen.set(short_opt); - ++j; - } - } - - //getopt_long requires a NULL final entry in the table: - - m_getopt_table[j].name = NULL; - m_getopt_table[j].has_arg = 0; - m_getopt_table[j].flag = NULL; - m_getopt_table[j].val = 0; - } - - return m_getopt_table.data(); -} - - -// This function takes INDENT, which tells how many spaces to output at the front of each line; SPACES, which is -// a string containing 80 spaces; and TEXT, which is the text that is to be output. It outputs the text, on -// multiple lines if necessary, to RESULT, with INDENT spaces at the front of each line. It breaks lines on spaces, -// tabs or newlines, shortening the line if necessary to not break in the middle of a word. It assumes that each -// output line should contain a maximum of OUTPUT_MAX_COLUMNS characters. - - -void -Options::OutputFormattedUsageText -( - Stream &strm, - const char *text, - uint32_t output_max_columns -) -{ - int len = strlen (text); - - // Will it all fit on one line? - - if ((len + strm.GetIndentLevel()) < output_max_columns) - { - // Output it as a single line. - strm.Indent (text); - strm.EOL(); - } - else - { - // We need to break it up into multiple lines. - - int text_width = output_max_columns - strm.GetIndentLevel() - 1; - int start = 0; - int end = start; - int final_end = strlen (text); - int sub_len; - - while (end < final_end) - { - // Don't start the 'text' on a space, since we're already outputting the indentation. - while ((start < final_end) && (text[start] == ' ')) - start++; - - end = start + text_width; - if (end > final_end) - end = final_end; - else - { - // If we're not at the end of the text, make sure we break the line on white space. - while (end > start - && text[end] != ' ' && text[end] != '\t' && text[end] != '\n') - end--; - } - - sub_len = end - start; - if (start != 0) - strm.EOL(); - strm.Indent(); - assert (start < final_end); - assert (start + sub_len <= final_end); - strm.Write(text + start, sub_len); - start = end + 1; - } - strm.EOL(); - } -} - -void -Options::GenerateOptionUsage -( - Stream &strm, - CommandObject *cmd, - const char *program_name) -{ - uint32_t screen_width = 80; - const lldb::OptionDefinition *full_options_table = GetDefinitions(); - const uint32_t save_indent_level = strm.GetIndentLevel(); - const char *name; - - if (cmd) - name = cmd->GetCommandName(); - else - name = program_name; - - strm.PutCString ("\nCommand Options Usage:\n"); - - strm.IndentMore(2); - - // First, show each usage level set of options, e.g. <cmd> [options-for-level-0] - // <cmd> [options-for-level-1] - // etc. - - const uint32_t num_options = NumCommandOptions(); - if (num_options == 0) - return; - - BuildValidOptionSets (); - int num_option_sets = m_required_options.size(); - - uint32_t i; - - for (uint32_t opt_set = 0; opt_set < num_option_sets; ++opt_set) - { - uint32_t opt_set_mask; - - opt_set_mask = 1 << opt_set; - if (opt_set > 0) - strm.Printf ("\n"); - strm.Indent (name); - - for (i = 0; i < num_options; ++i) - { - if (full_options_table[i].usage_mask & opt_set_mask) - { - // Add current option to the end of out_stream. - - if (full_options_table[i].required) - { - if (full_options_table[i].option_has_arg == required_argument) - { - strm.Printf (" -%c %s", - full_options_table[i].short_option, - full_options_table[i].argument_name); - } - else if (full_options_table[i].option_has_arg == optional_argument) - { - strm.Printf (" -%c [%s]", - full_options_table[i].short_option, - full_options_table[i].argument_name); - } - else - strm.Printf (" -%c", full_options_table[i].short_option); - } - else - { - if (full_options_table[i].option_has_arg == required_argument) - strm.Printf (" [-%c %s]", full_options_table[i].short_option, - full_options_table[i].argument_name); - else if (full_options_table[i].option_has_arg == optional_argument) - strm.Printf (" [-%c [%s]]", full_options_table[i].short_option, - full_options_table[i].argument_name); - else - strm.Printf (" [-%c]", full_options_table[i].short_option); - } - } - } - } - strm.Printf ("\n\n"); - - // Now print out all the detailed information about the various options: long form, short form and help text: - // -- long_name <argument> - // - short <argument> - // help text - - // This variable is used to keep track of which options' info we've printed out, because some options can be in - // more than one usage level, but we only want to print the long form of its information once. - - OptionSet options_seen; - OptionSet::iterator pos; - strm.IndentMore (5); - - int first_option_printed = 1; - for (i = 0; i < num_options; ++i) - { - // Only print out this option if we haven't already seen it. - pos = options_seen.find (full_options_table[i].short_option); - if (pos == options_seen.end()) - { - // Put a newline separation between arguments - if (first_option_printed) - first_option_printed = 0; - else - strm.EOL(); - - options_seen.insert (full_options_table[i].short_option); - strm.Indent (); - strm.Printf ("-%c ", full_options_table[i].short_option); - if (full_options_table[i].argument_name != NULL) - strm.PutCString(full_options_table[i].argument_name); - strm.EOL(); - strm.Indent (); - strm.Printf ("--%s ", full_options_table[i].long_option); - if (full_options_table[i].argument_name != NULL) - strm.PutCString(full_options_table[i].argument_name); - strm.EOL(); - - strm.IndentMore (5); - - if (full_options_table[i].usage_text) - OutputFormattedUsageText (strm, - full_options_table[i].usage_text, - screen_width); - if (full_options_table[i].enum_values != NULL) - { - strm.Indent (); - strm.Printf("Values: "); - for (int j = 0; full_options_table[i].enum_values[j].string_value != NULL; j++) - { - if (j == 0) - strm.Printf("%s", full_options_table[i].enum_values[j].string_value); - else - strm.Printf(" | %s", full_options_table[i].enum_values[j].string_value); - } - strm.EOL(); - } - strm.IndentLess (5); - } - } - - // Restore the indent level - strm.SetIndentLevel (save_indent_level); -} - -// This function is called when we have been given a potentially incomplete set of -// options, such as when an alias has been defined (more options might be added at -// at the time the alias is invoked). We need to verify that the options in the set -// m_seen_options are all part of a set that may be used together, but m_seen_options -// may be missing some of the "required" options. - -bool -Options::VerifyPartialOptions (CommandReturnObject &result) -{ - bool options_are_valid = false; - - int num_levels = m_required_options.size(); - if (num_levels) - { - for (int i = 0; i < num_levels && !options_are_valid; ++i) - { - // In this case we are treating all options as optional rather than required. - // Therefore a set of options is correct if m_seen_options is a subset of the - // union of m_required_options and m_optional_options. - OptionSet union_set; - OptionsSetUnion (m_required_options[i], m_optional_options[i], union_set); - if (IsASubset (m_seen_options, union_set)) - options_are_valid = true; - } - } - - return options_are_valid; -} - -bool -Options::HandleOptionCompletion -( - Args &input, - OptionElementVector &opt_element_vector, - int cursor_index, - int char_pos, - int match_start_point, - int max_return_elements, - lldb_private::CommandInterpreter *interpreter, - lldb_private::StringList &matches -) -{ - // For now we just scan the completions to see if the cursor position is in - // an option or its argument. Otherwise we'll call HandleArgumentCompletion. - // In the future we can use completion to validate options as well if we want. - - const OptionDefinition *opt_defs = GetDefinitions(); - - std::string cur_opt_std_str (input.GetArgumentAtIndex(cursor_index)); - cur_opt_std_str.erase(char_pos); - const char *cur_opt_str = cur_opt_std_str.c_str(); - - for (int i = 0; i < opt_element_vector.size(); i++) - { - int opt_pos = opt_element_vector[i].opt_pos; - int opt_arg_pos = opt_element_vector[i].opt_arg_pos; - int opt_defs_index = opt_element_vector[i].opt_defs_index; - if (opt_pos == cursor_index) - { - // We're completing the option itself. - if (opt_defs_index != -1) - { - // We recognized it, if it an incomplete long option, complete it anyway (getopt_long is - // happy with shortest unique string, but it's still a nice thing to do.) Otherwise return - // The string so the upper level code will know this is a full match and add the " ". - if (cur_opt_str && strlen (cur_opt_str) > 2 - && cur_opt_str[0] == '-' && cur_opt_str[1] == '-' - && strcmp (opt_defs[opt_defs_index].long_option, cur_opt_str) != 0) - { - std::string full_name ("--"); - full_name.append (opt_defs[opt_defs_index].long_option); - matches.AppendString(full_name.c_str()); - return true; - } - else - { - matches.AppendString(input.GetArgumentAtIndex(cursor_index)); - return true; - } - } - else - { - // FIXME - not handling wrong options yet: - // Check to see if they are writing a long option & complete it. - // I think we will only get in here if the long option table has two elements - // that are not unique up to this point. getopt_long does shortest unique match - // for long options already. - - if (cur_opt_str && strlen (cur_opt_str) > 2 - && cur_opt_str[0] == '-' && cur_opt_str[1] == '-') - { - for (int i = 0 ; opt_defs[i].short_option != 0 ; i++) - { - if (strstr(opt_defs[i].long_option, cur_opt_str + 2) == opt_defs[i].long_option) - { - std::string full_name ("--"); - full_name.append (opt_defs[i].long_option); - // The options definitions table has duplicates because of the - // way the grouping information is stored, so only add once. - bool duplicate = false; - for (int j = 0; j < matches.GetSize(); j++) - { - if (matches.GetStringAtIndex(j) == full_name) - { - duplicate = true; - break; - } - } - if (!duplicate) - matches.AppendString(full_name.c_str()); - } - } - } - return true; - } - - - } - else if (opt_arg_pos == cursor_index) - { - // Okay the cursor is on the completion of an argument. - // See if it has a completion, otherwise return no matches. - - if (opt_defs_index != -1) - { - HandleOptionArgumentCompletion (input, - cursor_index, - strlen (input.GetArgumentAtIndex(cursor_index)), - opt_element_vector, - i, - match_start_point, - max_return_elements, - interpreter, - matches); - return true; - } - else - { - // No completion callback means no completions... - return true; - } - - } - else - { - // Not the last element, keep going. - continue; - } - } - return false; -} - -bool -Options::HandleOptionArgumentCompletion -( - Args &input, - int cursor_index, - int char_pos, - OptionElementVector &opt_element_vector, - int opt_element_index, - int match_start_point, - int max_return_elements, - lldb_private::CommandInterpreter *interpreter, - lldb_private::StringList &matches -) -{ - const OptionDefinition *opt_defs = GetDefinitions(); - std::auto_ptr<SearchFilter> filter_ap; - - int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; - int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; - - // See if this is an enumeration type option, and if so complete it here: - - OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values; - if (enum_values != NULL) - { - bool return_value = false; - std::string match_string(input.GetArgumentAtIndex (opt_arg_pos), input.GetArgumentAtIndex (opt_arg_pos) + char_pos); - for (int i = 0; enum_values[i].string_value != NULL; i++) - { - if (strstr(enum_values[i].string_value, match_string.c_str()) == enum_values[i].string_value) - { - matches.AppendString (enum_values[i].string_value); - return_value = true; - } - } - return return_value; - } - - // If this is a source file or symbol type completion, and there is a - // -shlib option somewhere in the supplied arguments, then make a search filter - // for that shared library. - // FIXME: Do we want to also have an "OptionType" so we don't have to match string names? - - uint32_t completion_mask = opt_defs[opt_defs_index].completionType; - if (completion_mask & CommandCompletions::eSourceFileCompletion - || completion_mask & CommandCompletions::eSymbolCompletion) - { - for (int i = 0; i < opt_element_vector.size(); i++) - { - int cur_defs_index = opt_element_vector[i].opt_defs_index; - int cur_arg_pos = opt_element_vector[i].opt_arg_pos; - const char *cur_opt_name = opt_defs[cur_defs_index].long_option; - - // If this is the "shlib" option and there was an argument provided, - // restrict it to that shared library. - if (strcmp(cur_opt_name, "shlib") == 0 && cur_arg_pos != -1) - { - const char *module_name = input.GetArgumentAtIndex(cur_arg_pos); - if (module_name) - { - FileSpec module_spec(module_name); - lldb::TargetSP target_sp = interpreter->Context()->GetTarget()->GetSP(); - // Search filters require a target... - if (target_sp != NULL) - filter_ap.reset (new SearchFilterByModule (target_sp, module_spec)); - } - break; - } - } - } - - return CommandCompletions::InvokeCommonCompletionCallbacks (completion_mask, - input.GetArgumentAtIndex (opt_arg_pos), - match_start_point, - max_return_elements, - interpreter, - filter_ap.get(), - matches); - -} diff --git a/lldb/source/Core/Scalar.cpp b/lldb/source/Core/Scalar.cpp index 56590b8d69e..57b70282a17 100644 --- a/lldb/source/Core/Scalar.cpp +++ b/lldb/source/Core/Scalar.cpp @@ -11,7 +11,7 @@ #include <math.h> -#include "lldb/Core/Args.h" +#include "lldb/Interpreter/Args.h" #include "lldb/Core/Error.h" #include "lldb/Core/Stream.h" #include "lldb/Core/DataExtractor.h" |