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