1 //===-- CommandObjectType.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 "CommandObjectType.h" 11 12 // C Includes 13 // C++ Includes 14 15 #include "lldb/Core/ConstString.h" 16 #include "lldb/Core/Debugger.h" 17 #include "lldb/Core/FormatManager.h" 18 #include "lldb/Core/RegularExpression.h" 19 #include "lldb/Core/State.h" 20 #include "lldb/Interpreter/CommandInterpreter.h" 21 #include "lldb/Interpreter/CommandObject.h" 22 #include "lldb/Interpreter/CommandReturnObject.h" 23 #include "lldb/Interpreter/Options.h" 24 25 using namespace lldb; 26 using namespace lldb_private; 27 28 //------------------------------------------------------------------------- 29 // CommandObjectTypeFormatAdd 30 //------------------------------------------------------------------------- 31 32 class CommandObjectTypeFormatAdd : public CommandObject 33 { 34 35 private: 36 37 class CommandOptions : public Options 38 { 39 public: 40 41 CommandOptions (CommandInterpreter &interpreter) : 42 Options (interpreter) 43 { 44 } 45 46 virtual 47 ~CommandOptions (){} 48 49 virtual Error 50 SetOptionValue (uint32_t option_idx, const char *option_arg) 51 { 52 Error error; 53 char short_option = (char) m_getopt_table[option_idx].val; 54 bool success; 55 56 switch (short_option) 57 { 58 case 'C': 59 m_cascade = Args::StringToBoolean(option_arg, true, &success); 60 if (!success) 61 error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg); 62 break; 63 case 'f': 64 error = Args::StringToFormat(option_arg, m_format, NULL); 65 break; 66 case 'p': 67 m_skip_pointers = true; 68 break; 69 case 'r': 70 m_skip_references = true; 71 break; 72 default: 73 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); 74 break; 75 } 76 77 return error; 78 } 79 80 void 81 OptionParsingStarting () 82 { 83 m_cascade = true; 84 m_format = eFormatInvalid; 85 m_skip_pointers = false; 86 m_skip_references = false; 87 } 88 89 const OptionDefinition* 90 GetDefinitions () 91 { 92 return g_option_table; 93 } 94 95 // Options table: Required for subclasses of Options. 96 97 static OptionDefinition g_option_table[]; 98 99 // Instance variables to hold the values for command options. 100 101 bool m_cascade; 102 lldb::Format m_format; 103 bool m_skip_references; 104 bool m_skip_pointers; 105 }; 106 107 CommandOptions m_options; 108 109 virtual Options * 110 GetOptions () 111 { 112 return &m_options; 113 } 114 115 public: 116 CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) : 117 CommandObject (interpreter, 118 "type format add", 119 "Add a new formatting style for a type.", 120 NULL), m_options (interpreter) 121 { 122 CommandArgumentEntry type_arg; 123 CommandArgumentData type_style_arg; 124 125 type_style_arg.arg_type = eArgTypeName; 126 type_style_arg.arg_repetition = eArgRepeatPlus; 127 128 type_arg.push_back (type_style_arg); 129 130 m_arguments.push_back (type_arg); 131 132 SetHelpLong( 133 "Some examples of using this command.\n" 134 "We use as reference the following snippet of code:\n" 135 "\n" 136 "typedef int Aint;\n" 137 "typedef float Afloat;\n" 138 "typedef Aint Bint;\n" 139 "typedef Afloat Bfloat;\n" 140 "\n" 141 "Aint ix = 5;\n" 142 "Bint iy = 5;\n" 143 "\n" 144 "Afloat fx = 3.14;\n" 145 "BFloat fy = 3.14;\n" 146 "\n" 147 "Typing:\n" 148 "type format add -f hex AInt\n" 149 "frame variable iy\n" 150 "will produce an hex display of iy, because no formatter is available for Bint and the one for Aint is used instead\n" 151 "To prevent this type\n" 152 "type format add -f hex -C no AInt\n" 153 "\n" 154 "A similar reasoning applies to\n" 155 "type format add -f hex -C no float -p\n" 156 "which now prints all floats and float&s as hexadecimal, but does not format float*s\n" 157 "and does not change the default display for Afloat and Bfloat objects.\n" 158 ); 159 } 160 161 ~CommandObjectTypeFormatAdd () 162 { 163 } 164 165 bool 166 Execute (Args& command, CommandReturnObject &result) 167 { 168 const size_t argc = command.GetArgumentCount(); 169 170 if (argc < 1) 171 { 172 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 173 result.SetStatus(eReturnStatusFailed); 174 return false; 175 } 176 177 if(m_options.m_format == eFormatInvalid) 178 { 179 result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str()); 180 result.SetStatus(eReturnStatusFailed); 181 return false; 182 } 183 184 ValueFormatSP entry; 185 186 entry.reset(new ValueFormat(m_options.m_format, 187 m_options.m_cascade, 188 m_options.m_skip_pointers, 189 m_options.m_skip_references)); 190 191 // now I have a valid format, let's add it to every type 192 193 for(int i = 0; i < argc; i++) { 194 const char* typeA = command.GetArgumentAtIndex(i); 195 ConstString typeCS(typeA); 196 if (typeCS) 197 Debugger::ValueFormats::Add(typeCS, entry); 198 else 199 { 200 result.AppendError("empty typenames not allowed"); 201 result.SetStatus(eReturnStatusFailed); 202 return false; 203 } 204 } 205 206 result.SetStatus(eReturnStatusSuccessFinishNoResult); 207 return result.Succeeded(); 208 } 209 }; 210 211 OptionDefinition 212 CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] = 213 { 214 { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."}, 215 { LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, eArgTypeFormat, "The format to use to display this type."}, 216 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for pointers-to-type objects."}, 217 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for references-to-type objects."}, 218 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 219 }; 220 221 222 //------------------------------------------------------------------------- 223 // CommandObjectTypeFormatDelete 224 //------------------------------------------------------------------------- 225 226 class CommandObjectTypeFormatDelete : public CommandObject 227 { 228 public: 229 CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) : 230 CommandObject (interpreter, 231 "type format delete", 232 "Delete an existing formatting style for a type.", 233 NULL) 234 { 235 CommandArgumentEntry type_arg; 236 CommandArgumentData type_style_arg; 237 238 type_style_arg.arg_type = eArgTypeName; 239 type_style_arg.arg_repetition = eArgRepeatPlain; 240 241 type_arg.push_back (type_style_arg); 242 243 m_arguments.push_back (type_arg); 244 245 } 246 247 ~CommandObjectTypeFormatDelete () 248 { 249 } 250 251 bool 252 Execute (Args& command, CommandReturnObject &result) 253 { 254 const size_t argc = command.GetArgumentCount(); 255 256 if (argc != 1) 257 { 258 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 259 result.SetStatus(eReturnStatusFailed); 260 return false; 261 } 262 263 const char* typeA = command.GetArgumentAtIndex(0); 264 ConstString typeCS(typeA); 265 266 if(!typeCS) 267 { 268 result.AppendError("empty typenames not allowed"); 269 result.SetStatus(eReturnStatusFailed); 270 return false; 271 } 272 273 274 if (Debugger::ValueFormats::Delete(typeCS)) 275 { 276 result.SetStatus(eReturnStatusSuccessFinishNoResult); 277 return result.Succeeded(); 278 } 279 else 280 { 281 result.AppendErrorWithFormat ("no custom format for %s.\n", typeA); 282 result.SetStatus(eReturnStatusFailed); 283 return false; 284 } 285 286 } 287 288 }; 289 290 //------------------------------------------------------------------------- 291 // CommandObjectTypeFormatClear 292 //------------------------------------------------------------------------- 293 294 class CommandObjectTypeFormatClear : public CommandObject 295 { 296 public: 297 CommandObjectTypeFormatClear (CommandInterpreter &interpreter) : 298 CommandObject (interpreter, 299 "type format clear", 300 "Delete all existing format styles.", 301 NULL) 302 { 303 } 304 305 ~CommandObjectTypeFormatClear () 306 { 307 } 308 309 bool 310 Execute (Args& command, CommandReturnObject &result) 311 { 312 Debugger::ValueFormats::Clear(); 313 result.SetStatus(eReturnStatusSuccessFinishResult); 314 return result.Succeeded(); 315 } 316 317 }; 318 319 //------------------------------------------------------------------------- 320 // CommandObjectTypeFormatList 321 //------------------------------------------------------------------------- 322 323 bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, const char* type, const ValueFormat::SharedPointer& entry); 324 325 class CommandObjectTypeFormatList; 326 327 struct CommandObjectTypeFormatList_LoopCallbackParam { 328 CommandObjectTypeFormatList* self; 329 CommandReturnObject* result; 330 RegularExpression* regex; 331 CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R, 332 RegularExpression* X = NULL) : self(S), result(R), regex(X) {} 333 }; 334 335 class CommandObjectTypeFormatList : public CommandObject 336 { 337 public: 338 CommandObjectTypeFormatList (CommandInterpreter &interpreter) : 339 CommandObject (interpreter, 340 "type format list", 341 "Show a list of current formatting styles.", 342 NULL) 343 { 344 CommandArgumentEntry type_arg; 345 CommandArgumentData type_style_arg; 346 347 type_style_arg.arg_type = eArgTypeName; 348 type_style_arg.arg_repetition = eArgRepeatOptional; 349 350 type_arg.push_back (type_style_arg); 351 352 m_arguments.push_back (type_arg); 353 } 354 355 ~CommandObjectTypeFormatList () 356 { 357 } 358 359 bool 360 Execute (Args& command, CommandReturnObject &result) 361 { 362 const size_t argc = command.GetArgumentCount(); 363 364 CommandObjectTypeFormatList_LoopCallbackParam *param; 365 366 if (argc == 1) { 367 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 368 regex->Compile(command.GetArgumentAtIndex(0)); 369 param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex); 370 } 371 else 372 param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result); 373 Debugger::ValueFormats::LoopThrough(CommandObjectTypeFormatList_LoopCallback, param); 374 delete param; 375 result.SetStatus(eReturnStatusSuccessFinishResult); 376 return result.Succeeded(); 377 } 378 379 private: 380 381 bool 382 LoopCallback (const char* type, 383 const ValueFormat::SharedPointer& entry, 384 RegularExpression* regex, 385 CommandReturnObject *result) 386 { 387 if (regex == NULL || regex->Execute(type)) 388 { 389 result->GetOutputStream().Printf ("%s: %s%s%s%s\n", type, 390 FormatManager::GetFormatAsCString (entry->m_format), 391 entry->m_cascades ? "" : " (not cascading)", 392 entry->m_skip_pointers ? " (skip pointers)" : "", 393 entry->m_skip_references ? " (skip references)" : ""); 394 } 395 return true; 396 } 397 398 friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, const char* type, const ValueFormat::SharedPointer& entry); 399 400 }; 401 402 bool 403 CommandObjectTypeFormatList_LoopCallback ( 404 void* pt2self, 405 const char* type, 406 const ValueFormat::SharedPointer& entry) 407 { 408 CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self; 409 return param->self->LoopCallback(type, entry, param->regex, param->result); 410 } 411 412 413 414 415 //------------------------------------------------------------------------- 416 // CommandObjectTypeSummaryAdd 417 //------------------------------------------------------------------------- 418 419 class CommandObjectTypeSummaryAdd : public CommandObject 420 { 421 422 private: 423 424 class CommandOptions : public Options 425 { 426 public: 427 428 CommandOptions (CommandInterpreter &interpreter) : 429 Options (interpreter) 430 { 431 } 432 433 virtual 434 ~CommandOptions (){} 435 436 virtual Error 437 SetOptionValue (uint32_t option_idx, const char *option_arg) 438 { 439 Error error; 440 char short_option = (char) m_getopt_table[option_idx].val; 441 bool success; 442 443 switch (short_option) 444 { 445 case 'C': 446 m_cascade = Args::StringToBoolean(option_arg, true, &success); 447 if (!success) 448 error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg); 449 break; 450 case 'e': 451 m_no_children = false; 452 break; 453 case 'v': 454 m_no_value = true; 455 break; 456 case 'c': 457 m_one_liner = true; 458 break; 459 case 'f': 460 m_format_string = std::string(option_arg); 461 break; 462 case 'p': 463 m_skip_pointers = true; 464 break; 465 case 'r': 466 m_skip_references = true; 467 break; 468 case 'x': 469 m_regex = true; 470 break; 471 case 'n': 472 m_name = new ConstString(option_arg); 473 break; 474 default: 475 error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); 476 break; 477 } 478 479 return error; 480 } 481 482 void 483 OptionParsingStarting () 484 { 485 m_cascade = true; 486 m_no_children = true; 487 m_no_value = false; 488 m_one_liner = false; 489 m_skip_references = false; 490 m_skip_pointers = false; 491 m_regex = false; 492 m_name = NULL; 493 } 494 495 const OptionDefinition* 496 GetDefinitions () 497 { 498 return g_option_table; 499 } 500 501 // Options table: Required for subclasses of Options. 502 503 static OptionDefinition g_option_table[]; 504 505 // Instance variables to hold the values for command options. 506 507 bool m_cascade; 508 bool m_no_children; 509 bool m_no_value; 510 bool m_one_liner; 511 bool m_skip_references; 512 bool m_skip_pointers; 513 bool m_regex; 514 std::string m_format_string; 515 ConstString* m_name; 516 }; 517 518 CommandOptions m_options; 519 520 virtual Options * 521 GetOptions () 522 { 523 return &m_options; 524 } 525 526 public: 527 CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) : 528 CommandObject (interpreter, 529 "type summary add", 530 "Add a new summary style for a type.", 531 NULL), m_options (interpreter) 532 { 533 CommandArgumentEntry type_arg; 534 CommandArgumentData type_style_arg; 535 536 type_style_arg.arg_type = eArgTypeName; 537 type_style_arg.arg_repetition = eArgRepeatPlus; 538 539 type_arg.push_back (type_style_arg); 540 541 m_arguments.push_back (type_arg); 542 543 SetHelpLong( 544 "Some examples of using this command.\n" 545 "We use as reference the following snippet of code:\n" 546 "struct JustADemo\n" 547 "{\n" 548 "int* ptr;\n" 549 "float value;\n" 550 "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n" 551 "};\n" 552 "JustADemo object(42,3.14);\n" 553 "struct AnotherDemo : public JustADemo\n" 554 "{\n" 555 "uint8_t byte;\n" 556 "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n" 557 "};\n" 558 "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n" 559 "\n" 560 "type summary add -f \"the answer is ${*var.ptr}\" JustADemo\n" 561 "when typing frame variable object you will get \"the answer is 42\"\n" 562 "type summary add -f \"the answer is ${*var.ptr}, and the question is ${var.value}\" JustADemo\n" 563 "when typing frame variable object you will get \"the answer is 42 and the question is 3.14\"\n" 564 "\n" 565 "Alternatively, you could also say\n" 566 "type summary add -f \"${var%V} -> ${*var}\" \"int *\"\n" 567 "and replace the above summary string with\n" 568 "type summary add -f \"the answer is ${var.ptr}, and the question is ${var.value}\" JustADemo\n" 569 "to obtain a similar result\n" 570 "\n" 571 "To add a summary valid for both JustADemo and AnotherDemo you can use the scoping operator, as in:\n" 572 "type summary add -f \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes\n" 573 "\n" 574 "This will be used for both variables of type JustADemo and AnotherDemo. To prevent this, change the -C to read -C no\n" 575 "If you do not want pointers to be shown using that summary, you can use the -p option, as in:\n" 576 "type summary add -f \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes -p\n" 577 "A similar option -r exists for references.\n" 578 "\n" 579 "If you simply want a one-line summary of the content of your variable, without typing an explicit string to that effect\n" 580 "you can use the -c option, without giving any summary string:\n" 581 "type summary add -c JustADemo\n" 582 "frame variable object\n" 583 "the output being similar to (ptr=0xsomeaddress, value=3.14)\n" 584 "\n" 585 "If you want to display some summary text, but also expand the structure of your object, you can add the -e option, as in:\n" 586 "type summary add -e -f \"*ptr = ${*var.ptr}\" JustADemo\n" 587 "Here the value of the int* is displayed, followed by the standard LLDB sequence of children objects, one per line.\n" 588 "to get an output like:\n" 589 "\n" 590 "*ptr = 42 {\n" 591 " ptr = 0xsomeaddress\n" 592 " value = 3.14\n" 593 "}\n" 594 "\n" 595 "A command you may definitely want to try if you're doing C++ debugging is:\n" 596 "type summary add -f \"${var._M_dataplus._M_p}\" std::string\n" 597 ); 598 } 599 600 ~CommandObjectTypeSummaryAdd () 601 { 602 } 603 604 bool 605 Execute (Args& command, CommandReturnObject &result) 606 { 607 const size_t argc = command.GetArgumentCount(); 608 609 if (argc < 1 && !m_options.m_name) 610 { 611 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 612 result.SetStatus(eReturnStatusFailed); 613 return false; 614 } 615 616 if(!m_options.m_one_liner && m_options.m_format_string.empty()) 617 { 618 result.AppendError("empty summary strings not allowed"); 619 result.SetStatus(eReturnStatusFailed); 620 return false; 621 } 622 623 const char* format_cstr = (m_options.m_one_liner ? "" : m_options.m_format_string.c_str()); 624 625 Error error; 626 627 SummaryFormat::SharedPointer entry(new SummaryFormat(format_cstr,m_options.m_cascade, 628 m_options.m_no_children,m_options.m_no_value, 629 m_options.m_one_liner, 630 m_options.m_skip_pointers, 631 m_options.m_skip_references)); 632 633 if (error.Fail()) 634 { 635 result.AppendError(error.AsCString()); 636 result.SetStatus(eReturnStatusFailed); 637 return false; 638 } 639 640 // now I have a valid format, let's add it to every type 641 642 for(int i = 0; i < argc; i++) { 643 const char* typeA = command.GetArgumentAtIndex(i); 644 if (!typeA || typeA[0] == '\0') 645 { 646 result.AppendError("empty typenames not allowed"); 647 result.SetStatus(eReturnStatusFailed); 648 return false; 649 } 650 ConstString typeCS(typeA); 651 if (!m_options.m_regex) 652 { 653 Debugger::SummaryFormats::Add(typeCS, entry); 654 } 655 else 656 { 657 RegularExpressionSP typeRX(new RegularExpression()); 658 if(!typeRX->Compile(typeA)) 659 { 660 result.AppendError("regex format error (maybe this is not really a regex?)"); 661 result.SetStatus(eReturnStatusFailed); 662 return false; 663 } 664 Debugger::RegexSummaryFormats::Delete(typeCS); 665 Debugger::RegexSummaryFormats::Add(typeRX, entry); 666 } 667 } 668 669 if (m_options.m_name) 670 { 671 if( (bool)(*(m_options.m_name)) ) 672 { 673 Debugger::NamedSummaryFormats::Add(*(m_options.m_name), entry); 674 } 675 else 676 { 677 result.AppendError("added to types, but not given a name"); 678 result.SetStatus(eReturnStatusFailed); 679 return false; 680 } 681 } 682 683 result.SetStatus(eReturnStatusSuccessFinishNoResult); 684 return result.Succeeded(); 685 } 686 687 }; 688 689 OptionDefinition 690 CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] = 691 { 692 { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."}, 693 { LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeBoolean, "Don't show the value, just show the summary, for this type."}, 694 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for pointers-to-type objects."}, 695 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for references-to-type objects."}, 696 { LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeBoolean, "Type names are actually regular expressions."}, 697 { LLDB_OPT_SET_1 , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeBoolean, "If true, inline all child values into summary string."}, 698 { LLDB_OPT_SET_2 , true, "format-string", 'f', required_argument, NULL, 0, eArgTypeSummaryString, "Format string used to display text and object contents."}, 699 { LLDB_OPT_SET_2, false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean, "Expand aggregate data types to show children on separate lines."}, 700 { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeName, "A name for this summary string."}, 701 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 702 }; 703 704 705 //------------------------------------------------------------------------- 706 // CommandObjectTypeSummaryDelete 707 //------------------------------------------------------------------------- 708 709 class CommandObjectTypeSummaryDelete : public CommandObject 710 { 711 public: 712 CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) : 713 CommandObject (interpreter, 714 "type summary delete", 715 "Delete an existing summary style for a type.", 716 NULL) 717 { 718 CommandArgumentEntry type_arg; 719 CommandArgumentData type_style_arg; 720 721 type_style_arg.arg_type = eArgTypeName; 722 type_style_arg.arg_repetition = eArgRepeatPlain; 723 724 type_arg.push_back (type_style_arg); 725 726 m_arguments.push_back (type_arg); 727 728 } 729 730 ~CommandObjectTypeSummaryDelete () 731 { 732 } 733 734 bool 735 Execute (Args& command, CommandReturnObject &result) 736 { 737 const size_t argc = command.GetArgumentCount(); 738 739 if (argc != 1) 740 { 741 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 742 result.SetStatus(eReturnStatusFailed); 743 return false; 744 } 745 746 const char* typeA = command.GetArgumentAtIndex(0); 747 ConstString typeCS(typeA); 748 749 if(!typeCS) 750 { 751 result.AppendError("empty typenames not allowed"); 752 result.SetStatus(eReturnStatusFailed); 753 return false; 754 } 755 756 bool delete_summary = Debugger::SummaryFormats::Delete(typeCS); 757 bool delete_regex = Debugger::RegexSummaryFormats::Delete(typeCS); 758 bool delete_named = Debugger::NamedSummaryFormats::Delete(typeCS); 759 760 if (delete_summary || delete_regex || delete_named) 761 { 762 result.SetStatus(eReturnStatusSuccessFinishNoResult); 763 return result.Succeeded(); 764 } 765 else 766 { 767 result.AppendErrorWithFormat ("no custom summary for %s.\n", typeA); 768 result.SetStatus(eReturnStatusFailed); 769 return false; 770 } 771 772 } 773 774 }; 775 776 //------------------------------------------------------------------------- 777 // CommandObjectTypeSummaryClear 778 //------------------------------------------------------------------------- 779 780 class CommandObjectTypeSummaryClear : public CommandObject 781 { 782 public: 783 CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) : 784 CommandObject (interpreter, 785 "type summary clear", 786 "Delete all existing summary styles.", 787 NULL) 788 { 789 } 790 791 ~CommandObjectTypeSummaryClear () 792 { 793 } 794 795 bool 796 Execute (Args& command, CommandReturnObject &result) 797 { 798 Debugger::SummaryFormats::Clear(); 799 Debugger::RegexSummaryFormats::Clear(); 800 Debugger::NamedSummaryFormats::Clear(); 801 result.SetStatus(eReturnStatusSuccessFinishResult); 802 return result.Succeeded(); 803 } 804 805 }; 806 807 //------------------------------------------------------------------------- 808 // CommandObjectTypeSummaryList 809 //------------------------------------------------------------------------- 810 811 bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry); 812 bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SummaryFormat::SharedPointer& entry); 813 814 class CommandObjectTypeSummaryList; 815 816 struct CommandObjectTypeSummaryList_LoopCallbackParam { 817 CommandObjectTypeSummaryList* self; 818 CommandReturnObject* result; 819 RegularExpression* regex; 820 CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R, 821 RegularExpression* X = NULL) : self(S), result(R), regex(X) {} 822 }; 823 824 struct CommandObjectTypeRXSummaryList_LoopCallbackParam { 825 CommandObjectTypeSummaryList* self; 826 CommandReturnObject* result; 827 RegularExpression* regex; 828 CommandObjectTypeRXSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R, 829 RegularExpression* X = NULL) : self(S), result(R), regex(X) {} 830 }; 831 832 class CommandObjectTypeSummaryList : public CommandObject 833 { 834 public: 835 CommandObjectTypeSummaryList (CommandInterpreter &interpreter) : 836 CommandObject (interpreter, 837 "type summary list", 838 "Show a list of current summary styles.", 839 NULL) 840 { 841 CommandArgumentEntry type_arg; 842 CommandArgumentData type_style_arg; 843 844 type_style_arg.arg_type = eArgTypeName; 845 type_style_arg.arg_repetition = eArgRepeatOptional; 846 847 type_arg.push_back (type_style_arg); 848 849 m_arguments.push_back (type_arg); 850 } 851 852 ~CommandObjectTypeSummaryList () 853 { 854 } 855 856 bool 857 Execute (Args& command, CommandReturnObject &result) 858 { 859 const size_t argc = command.GetArgumentCount(); 860 861 CommandObjectTypeSummaryList_LoopCallbackParam *param; 862 CommandObjectTypeRXSummaryList_LoopCallbackParam *rxparam; 863 864 if (argc == 1) { 865 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 866 regex->Compile(command.GetArgumentAtIndex(0)); 867 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex); 868 } 869 else 870 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result); 871 Debugger::SummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param); 872 delete param; 873 874 if(Debugger::RegexSummaryFormats::GetCount() > 0) 875 { 876 result.GetOutputStream().Printf("Regex-based summaries (slower):\n"); 877 if (argc == 1) { 878 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 879 regex->Compile(command.GetArgumentAtIndex(0)); 880 rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result,regex); 881 } 882 else 883 rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result); 884 Debugger::RegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam); 885 delete rxparam; 886 } 887 888 if(Debugger::NamedSummaryFormats::GetCount() > 0) 889 { 890 result.GetOutputStream().Printf("Named summaries:\n"); 891 if (argc == 1) { 892 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 893 regex->Compile(command.GetArgumentAtIndex(0)); 894 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex); 895 } 896 else 897 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result); 898 Debugger::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param); 899 delete param; 900 } 901 902 result.SetStatus(eReturnStatusSuccessFinishResult); 903 return result.Succeeded(); 904 } 905 906 private: 907 908 bool 909 LoopCallback (const char* type, 910 const SummaryFormat::SharedPointer& entry, 911 RegularExpression* regex, 912 CommandReturnObject *result) 913 { 914 if (regex == NULL || regex->Execute(type)) 915 { 916 result->GetOutputStream().Printf ("%s: `%s`%s%s%s%s%s%s\n", type, 917 entry->m_format.c_str(), 918 entry->m_cascades ? "" : " (not cascading)", 919 entry->m_dont_show_children ? "" : " (show children)", 920 entry->m_dont_show_value ? " (hide value)" : "", 921 entry->m_show_members_oneliner ? " (one-line printout)" : "", 922 entry->m_skip_pointers ? " (skip pointers)" : "", 923 entry->m_skip_references ? " (skip references)" : ""); 924 } 925 return true; 926 } 927 928 friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry); 929 friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SummaryFormat::SharedPointer& entry); 930 931 }; 932 933 bool 934 CommandObjectTypeSummaryList_LoopCallback ( 935 void* pt2self, 936 const char* type, 937 const SummaryFormat::SharedPointer& entry) 938 { 939 CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self; 940 return param->self->LoopCallback(type, entry, param->regex, param->result); 941 } 942 943 bool 944 CommandObjectTypeRXSummaryList_LoopCallback ( 945 void* pt2self, 946 lldb::RegularExpressionSP regex, 947 const SummaryFormat::SharedPointer& entry) 948 { 949 CommandObjectTypeRXSummaryList_LoopCallbackParam* param = (CommandObjectTypeRXSummaryList_LoopCallbackParam*)pt2self; 950 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 951 } 952 953 954 955 956 class CommandObjectTypeFormat : public CommandObjectMultiword 957 { 958 public: 959 CommandObjectTypeFormat (CommandInterpreter &interpreter) : 960 CommandObjectMultiword (interpreter, 961 "type format", 962 "A set of commands for editing variable value display options", 963 "type format [<sub-command-options>] ") 964 { 965 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter))); 966 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter))); 967 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter))); 968 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFormatList (interpreter))); 969 } 970 971 972 ~CommandObjectTypeFormat () 973 { 974 } 975 }; 976 977 class CommandObjectTypeSummary : public CommandObjectMultiword 978 { 979 public: 980 CommandObjectTypeSummary (CommandInterpreter &interpreter) : 981 CommandObjectMultiword (interpreter, 982 "type summary", 983 "A set of commands for editing variable summary display options", 984 "type summary [<sub-command-options>] ") 985 { 986 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter))); 987 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter))); 988 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter))); 989 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter))); 990 } 991 992 993 ~CommandObjectTypeSummary () 994 { 995 } 996 }; 997 998 //------------------------------------------------------------------------- 999 // CommandObjectType 1000 //------------------------------------------------------------------------- 1001 1002 CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) : 1003 CommandObjectMultiword (interpreter, 1004 "type", 1005 "A set of commands for operating on the type system", 1006 "type [<sub-command-options>]") 1007 { 1008 LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter))); 1009 LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter))); 1010 } 1011 1012 1013 CommandObjectType::~CommandObjectType () 1014 { 1015 } 1016 1017 1018