void BreakPoint::process_jdb(string& info_output) { int colon = info_output.index(':'); if (colon >= 0) { string class_name = info_output.before(colon); int line_no = get_positive_nr(info_output.after(colon)); if (line_no >= 0 && !class_name.empty()) { // Strip JDB 1.2 info like `breakpoint', etc. strip_space(class_name); int last_space = class_name.index(" ", -1); if (last_space > 0) class_name = class_name.after(last_space); myfile_name = class_name; myline_nr = line_no; // Kill this line int beginning_of_line = colon; while (beginning_of_line >= 0 && info_output[beginning_of_line] != '\n') beginning_of_line--; beginning_of_line++; int next_nl = info_output.index('\n', colon); if (next_nl >= 0) info_output = info_output.before(beginning_of_line) + info_output.from(next_nl); else info_output = info_output.before(beginning_of_line); } } }
// Set history size void process_history_size(string answer) { answer = answer.from(rxint); int ret = get_positive_nr(answer); if (ret >= 0) gdb_history_size = ret; }
// Create new breakpoint from INFO_OUTPUT BreakPoint::BreakPoint(string& info_output, const string& arg, int number, string& file) : mynumber(number), mytype(BREAKPOINT), mydispo(BPKEEP), myenabled(true), myfile_name(file), myline_nr(0), myaddress(""), myfunc(""), myexpr(""), myinfos(""), myignore_count(0), mycondition(""), mycommands(0), myarg(arg), mywatch_mode(WATCH_CHANGE), myenabled_changed(true), myfile_changed(true), myposition_changed(true), myaddress_changed(true), myselected(false), mysource_glyph(0), mycode_glyph(0) { if (gdb->has_numbered_breakpoints()) { // Read leading breakpoint number strip_leading_space(info_output); string number_str = read_nr_str (info_output); int number = get_positive_nr (number_str); if (number < 0) return; mynumber = number; } if (gdb->type() != PERL) strip_leading_space(info_output); switch(gdb->type()) { case GDB: case MAKE: case BASH: process_gdb(info_output); break; case DBX: process_dbx(info_output); break; case XDB: process_xdb(info_output); break; case JDB: process_jdb(info_output); break; case PYDB: process_pydb(info_output); break; case PERL: process_perl(info_output); break; case DBG: process_dbg(info_output); break; } // If we found a file name, propagate it to next breakpoint file = file_name(); }
void BreakPoint::process_xdb(string& info_output) { // Strip leading `:'. // Bob Wiegand <*****@*****.**> if (info_output.contains(':', 0)) info_output = info_output.after(0); strip_leading_space(info_output); // Skip `count: N' if (info_output.contains("count:", 0)) { info_output = info_output.after("count:"); strip_leading_space(info_output); string count = info_output.before(rxblanks_or_tabs); info_output = info_output.after(rxblanks_or_tabs); myignore_count = atoi(count.chars()); } // Check for `Active' or `Suspended' and strip them // Bob Wiegand <*****@*****.**> if (info_output.contains("Active", 0)) { info_output = info_output.after("Active"); myenabled = true; } else if (info_output.contains("Suspended", 0)) { info_output = info_output.after("Suspended"); myenabled = false; } // Get function name and position info_output = info_output.after(rxblanks_or_tabs); myfunc = info_output.before(": "); const string pos = dbx_lookup(myfunc); if (!pos.empty()) { myfile_name = pos.before(":"); } info_output = info_output.after(": "); myline_nr = get_positive_nr(info_output); info_output = info_output.after('\n'); // Examine commands for condition string commands = info_output; strip_leading_space(commands); if (commands.contains('{', 0)) { // A condition has the form `{if COND {} {Q; c}}'. if (commands.contains("{if ", 0)) { string cond = commands.after("{if "); cond = cond.before('{'); strip_space(cond); mycondition = cond; } // Skip this line, too info_output = info_output.after('\n'); } }
void BreakPoint::process_dbx(string& info_output) { if (info_output.contains("PC==", 0) || info_output.contains("stop ", 0) || info_output.contains("stopped ", 0)) { // Breakpoint info_output = info_output.after(rxblanks_or_tabs); strip_leading_space (info_output); if (info_output.contains ("at ", 0)) { info_output = info_output.after(rxblanks_or_tabs); string file_name; if (info_output.contains('"', 0)) { // `stop at "FILE":LINE' file_name = unquote(info_output.before(":")); info_output = info_output.after (":"); } else if (info_output.contains('[', 0)) { // `stop at [file:line ...]' file_name = info_output.before(":"); file_name = file_name.after('['); info_output = info_output.after (":"); } else { // `stop at LINE' file_name = ""; } int new_line_nr = 0; if (!info_output.empty() && isdigit(info_output[0])) new_line_nr = get_positive_nr(info_output); if (!file_name.empty()) myfile_name = file_name; if (new_line_nr != 0) myline_nr = new_line_nr; // DBX issues either locations or functions myfunc = ""; } else if (info_output.contains ("in ", 0)) { string line = info_output.after("in "); if (line.contains('\n')) line = line.before('\n'); if (line.contains("\":")) { // Ladebug output: // `PC==x in TYPE FUNC(ARGS...) "FILE":LINE { COMMANDS } myfile_name = line.after("\""); myfile_name = myfile_name.before("\""); myline_nr = get_positive_nr(line.after("\":")); myfunc = line.before("\""); strip_space(myfunc); // Be sure to remove TYPE while (myfunc.contains(" ")) myfunc = myfunc.after(" "); } else { // DBX output: // `stop in FUNC' myfunc = line.before(rxblanks_or_tabs); strip_space(myfunc); myfile_name = ""; myline_nr = 0; // Attempt to get exact position of FUNC const string pos = dbx_lookup(myfunc); if (!pos.empty()) { const string file_name = pos.before(":"); const string line_s = pos.after(":"); int new_line_nr = get_positive_nr(line_s); myfile_name = file_name; if (new_line_nr != 0) myline_nr = new_line_nr; } } } else { // `stop VAR' mytype = WATCHPOINT; mywatch_mode = WATCH_CHANGE; string expr = info_output; if (expr.contains('\n')) expr = expr.before('\n'); if (expr.contains(rxblanks_or_tabs)) expr = expr.before(rxblanks_or_tabs); myexpr = expr; } // Sun DBX 3.0 issues extra characters like // (2) stop in main -count 0/10 // [3] stop in main -disable string options; if (info_output.contains('\n')) options = info_output.before('\n'); else options = info_output; bool new_enabled = !options.contains(" -disable"); myenabled = new_enabled; myinfos = ""; if (options.contains(" -count ")) { string count = options.after(" -count "); strip_leading_space(count); if (count.contains(' ')) count = count.before(' '); myinfos = "count " + count; if (count.contains('/')) count = count.after('/'); myignore_count = atoi(count.chars()); } if (options.contains(" if ") || options.contains(" -if ")) { string cond = options.after("if "); if (!myinfos.empty()) myinfos += '\n'; myinfos += "stop only if " + cond; mycondition = cond; } } info_output = info_output.after('\n'); }
void BreakPoint::process_gdb(string& info_output) { // Read type (`breakpoint' or `watchpoint') // The type may be prefixed by `hw ' or other details. const string word1 = info_output.before('\n'); const string word2 = word1.after(rxblanks_or_tabs); if (word1.contains("watchpoint", 0) || word2.contains("watchpoint", 0)) { mytype = WATCHPOINT; // Fetch breakpoint mode detail (`acc' or `read') if (word1.contains("acc ", 0)) mywatch_mode = WATCH_ACCESS; else if (word1.contains("read ", 0)) mywatch_mode = WATCH_READ; else mywatch_mode = WATCH_CHANGE; } else if (word1.contains("breakpoint", 0) || word2.contains("breakpoint", 0)) { mytype = BREAKPOINT; } info_output = info_output.after("point"); info_output = info_output.after(rxblanks_or_tabs); // Read disposition (`dis', `del', or `keep') if (info_output.contains("dis", 0)) { mydispo = BPDIS; } else if (info_output.contains("del", 0)) { mydispo = BPDEL; } else if (info_output.contains("keep", 0)) { mydispo = BPKEEP; } info_output = info_output.after(rxblanks_or_tabs); // Read enabled flag (`y' or `n') if (info_output.contains('y', 0)) { myenabled = true; } else if (info_output.contains('n', 0)) { myenabled = false; } info_output = info_output.after(rxblanks_or_tabs); string new_info = ""; if (mytype == BREAKPOINT) { if (MAKE != gdb->type() && BASH != gdb->type()) { // Read address myaddress = info_output.through(rxalphanum); info_output = info_output.after(myaddress); strip_leading_space(info_output); } if (BASH != gdb->type()) { if (info_output.contains("in ", 0)) { // Function name string func = info_output.after("in "); if (func.contains('\n')) func = func.before('\n'); if (func.contains(" at ")) func = func.before(" at "); strip_space(func); myfunc = func; } } // Location string remainder = info_output.through('\n'); info_output = info_output.after('\n'); // GDB 5.0 may issue an (indented) file name in the following line if (!remainder.contains(rxname_colon_int_nl)) { remainder += info_output.through('\n'); if (remainder.contains(rxname_colon_int_nl)) info_output = info_output.after('\n'); } remainder = remainder.from(rxname_colon_int_nl); myfile_name = remainder.before(":"); remainder = remainder.after(":"); if (!remainder.empty() && isdigit(remainder[0])) myline_nr = get_positive_nr(remainder); } else if (mytype == WATCHPOINT) { // Read watched expression myexpr = info_output.before('\n'); info_output = info_output.after('\n'); } int ignore_count = 0; string cond = ""; StringArray commands; if (!info_output.empty() && !isdigit(info_output[0])) { // Extra info follows int next_nl = index(info_output, rxnl_int, "\n"); if (next_nl == -1) { new_info += info_output; info_output = ""; } else { new_info += info_output.through(next_nl); info_output = info_output.after(next_nl); } int n = new_info.freq('\n'); string *lines = new string[n + 1]; split(new_info, lines, n + 1, '\n'); string newer_info = ""; for (int i = 0; i < n; i++) { bool save_info = true; string line = lines[i]; bool starts_with_space = (!line.empty() && isspace(line[0])); strip_leading_space(line); if (line.contains("ignore next ", 0)) { // Fetch ignore count string count = line.after("ignore next "); count = count.before(" hits"); ignore_count = atoi(count.chars()); } else if (line.contains("stop only if ", 0)) { // Fetch condition cond = line.after("stop only if "); } else if (line.contains("stop ", 0)) { // Any info (no GDB command starts with `stop') } else if (line.contains("breakpoint ", 0)) { // Any info (no GDB command starts with `breakpoint') } else if (starts_with_space) { // A command (GDB indents all commands) commands += line; save_info = false; } else { // Some other info } if (save_info) newer_info += line + '\n'; } new_info = newer_info; delete[] lines; } myinfos = new_info; myignore_count = ignore_count; mycondition = cond; mycommands = commands; }
// Answer GDB question static void select_from_gdb(const string& question, string& reply) { int count = question.freq('\n') + 1; string *choices = new string[count]; bool *selected = new bool[count]; split(question, choices, count, '\n'); // Highlight choice #1 by default for (int i = 0; i < count; i++) { if (!has_nr(choices[i])) { // Choice has no number (prompt) - remove it for (int j = i; j < count - 1; j++) choices[j] = choices[j + 1]; count--; i--; } else { selected[i] = (get_positive_nr(choices[i]) == 1); } } if (count < 2) { // Nothing to choose from if (count == 1) { // Take the first choice. reply = itostring(atoi(choices[0].chars())) + "\n"; } delete[] choices; delete[] selected; return; } // Popup selection dialog static string selection_reply; if (gdb_selection_dialog == 0) { Arg args[10]; Cardinal arg = 0; XtSetArg(args[arg], XmNautoUnmanage, False); arg++; gdb_selection_dialog = verify(XmCreateSelectionDialog(find_shell(gdb_w), XMST("gdb_selection_dialog"), args, arg)); Delay::register_shell(gdb_selection_dialog); XtUnmanageChild(XmSelectionBoxGetChild(gdb_selection_dialog, XmDIALOG_TEXT)); XtUnmanageChild(XmSelectionBoxGetChild(gdb_selection_dialog, XmDIALOG_SELECTION_LABEL)); XtUnmanageChild(XmSelectionBoxGetChild(gdb_selection_dialog, XmDIALOG_APPLY_BUTTON)); gdb_selection_list_w = XmSelectionBoxGetChild(gdb_selection_dialog, XmDIALOG_LIST); XtVaSetValues(gdb_selection_list_w, XmNselectionPolicy, XmSINGLE_SELECT, XtPointer(0)); XtAddCallback(gdb_selection_dialog, XmNokCallback, SelectCB, &selection_reply); XtAddCallback(gdb_selection_dialog, XmNcancelCallback, CancelCB, &selection_reply); XtAddCallback(gdb_selection_dialog, XmNhelpCallback, ImmediateHelpCB, 0); } setLabelList(gdb_selection_list_w, choices, selected, count, false, false); delete[] choices; delete[] selected; manage_and_raise(gdb_selection_dialog); selection_reply = ""; while (selection_reply.empty() && gdb->running() && !gdb->isReadyWithPrompt()) XtAppProcessEvent(XtWidgetToApplicationContext(gdb_w), XtIMAll); // Found a reply - return reply = selection_reply; }