// Find path of source file SOURCE string dbx_path(const string& source) { string path; if (gdb->has_setenv_command() && gdb->has_edit_command()) { // The DBX `file' command issues only the base name of the // current file. The `edit' command, however, invokes an // editor with the entire path. So, we misuse the `edit' // command such that it reports the entire path. gdb_question("setenv EDITOR \"echo\""); path = gdb_question("edit " + source); gdb_question(string("setenv EDITOR ") + quote(getenv("EDITOR") ? getenv("EDITOR") : "vi")); } else if (gdb->type() == DBX) { // We have DBX, but no `setenv' and no `edit' command. Check // whether the `file' command with no arguments provides the // full path, as in AIX DBX 3.1. This shouldn't affect other // DBX variants as `file' will simply return the same thing // already contained in source. gdb_question("file " + source); path = gdb_question("file"); } strip_leading_space(path); if (!path.contains('/', 0) || path.contains(' ')) path = source; // Sanity check strip_trailing_space(path); return path; }
// Remove and return display name from DISPLAY string read_disp_name (string& display, GDBAgent *gdb) { strip_leading_space(display); string name = display.before (" = "); display = get_disp_value_str(display, gdb); return name; }
// Return next display from DISPLAYS ("" if none); remove it from // DISPLAYS string read_next_display (string& displays, GDBAgent *gdb) { string next_display; strip_leading_space(displays); // string old_displays = displays; // std::clog << "read_next_display(" << quote(old_displays) << ")...\n"; if (is_disabling(displays, gdb)) { // After a `disabling' message, `display' output finishes next_display = displays; displays = ""; } else { for (;;) { next_display += read_token(displays); if (displays.empty()) break; // All done if (next_display.contains(":()", -1)) { // AIX DBX gives weird `members' like // "pcg = OM_PCGDownCasters:()\n(_root = 0x2004c248 ..." // Be sure to continue such displays. continue; } if (next_is_nl(displays)) break; // At end of display } } displays = displays.after('\n'); strip_leading_space(displays); // std::clog << "read_next_display(" << quote(old_displays) << ") = " // << quote(next_display) << "\n"; return next_display; }
bool add_running_arguments(string& cmd, Widget origin) { if (cmd == "run") cmd = gdb->rerun_command(); if (gdb->type() != JDB) return true; // Ok, perform the command if (!is_run_cmd(cmd)) return true; // Ok, perform the command strip_leading_space(cmd); string args = cmd.after(rxwhite); ProgramInfo info; if (args.empty() && gdb->has_debug_command()) { // JDB 1.1 requires at least a class name after the `run' command. cmd += " " + info.file; } if (info.running && !gdb->has_debug_command()) { // JDB 1.2 cannot rerun a program after it has been started. // Offer to restart JDB instead. static Widget restart_jdb = 0; static string saved_run_command; if (restart_jdb == 0) { restart_jdb = verify(XmCreateQuestionDialog(find_shell(origin), XMST("confirm_restart_gdb_dialog"), ArgList(0), 0)); Delay::register_shell(restart_jdb); XtAddCallback(restart_jdb, XmNhelpCallback, ImmediateHelpCB, XtPointer(0)); XtAddCallback(restart_jdb, XmNokCallback, RestartAndRunCB, (XtPointer)&saved_run_command); } saved_run_command = cmd; XtManageChild(restart_jdb); return false; // Don't perform the command yet } return true; }
// Store first function name in ANSWER after INDEX in BUFFER static void fetch_function(const string& answer, int index, string& buffer, bool in_required = false) { if (!buffer.empty()) return; // Already have a function string line = answer.from(index); line = line.before('\n'); if (in_required) line = line.after(" in "); // The function name is the word before the opening parenthesis line = line.before('('); strip_trailing_space(line); int ws_index = line.index(' ', -1) + 1; line = line.from(ws_index); strip_leading_space(line); if (!line.empty() && line.contains(rxidentifier, 0)) buffer = line; }
// True if more sequence members are coming bool DispValue::sequence_pending(const string& value, const DispValue *parent) { if (parent != 0) { switch (parent->type()) { case Sequence: case List: case Struct: case Reference: case Array: // In a composite, we always read everything up to the // final delimiter. return false; case Simple: case Pointer: case Text: case UnknownType: break; } } string v = value; strip_leading_space(v); if (!v.empty() && parent == 0) return true; // Still more to read if (!is_delimited(value)) return true; // Not at delimiter - more stuff follows // Sequence is done return false; }
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; }
// True if CMD quits GDB bool is_quit_cmd (const string& cmd) { string c = cmd; strip_leading_space(c); return c.contains('q', 0); // `quit', `q', or whatever }
string dbx_lookup(const string& func_name, bool silent) { // Protect against `1' or `' being looked up as function names if (!func_name.contains(rxidentifier, 0)) return ""; // Bad function name if (pos_cache.has(func_name)) { string pos = pos_cache[func_name]; if (silent || !pos.empty()) return pos; } string reply; switch (gdb->type()) { case DBG: case DBX: case GDB: case JDB: case PYDB: reply = gdb_question("list " + func_name, 0, true); break; case XDB: reply = gdb_question("v " + func_name, 0, true); break; case PERL: reply = gdb_question("l " + func_name, 0, true); break; case BASH: reply = gdb_question("l " + func_name, 0, true); break; case MAKE: reply = gdb_question("target " + func_name, 0, true); break; } if (reply == NO_GDB_ANSWER) { // post_gdb_busy(); return ""; } string file = ""; int line = 0; switch (gdb->type()) { case GDB: case PYDB: // XXX { file = reply.from('\"'); file = file.before('\"'); const string line_s = reply.after("Line "); line = atoi(line_s.chars()); break; } case DBX: line = line_of_listing(reply, silent); if (line > 0) { file = gdb_question("file"); strip_trailing_space(file); } break; case BASH: case DBG: case JDB: case MAKE: case PERL: line = line_of_listing(reply, silent); file = source_view->line_of_cursor(); file = file.before(':'); break; case XDB: { #if RUNTIME_REGEX static regex rxcolons("[^:]*:[^:]*: *[0-9][0-9]*.*"); #endif if (reply.matches(rxcolons)) { file = reply.before(':'); reply = reply.after(':'); // Skip file reply = reply.after(':'); // Skip function strip_leading_space(reply); const string line_s = reply.before(':'); line = atoi(line_s.chars()); } else { // post_gdb_message(reply); return ""; } break; } } string pos = ""; if (line > 0) pos = file + ":" + itostring(line); pos_cache[func_name] = pos; return pos; }
// If LINE is an argument-setting command, add it to the list of arguments void add_to_arguments(const string& line) { if (is_set_args_cmd(line)) { string args = line.after("args"); args = args.after(rxwhite); add_argument(args, run_arguments, last_run_argument, run_arguments_updated); } else if (gdb->type() == PERL && line.contains("@ARGV = ", 0)) { // @ARGV = ('arg1', 'arg2', ) string args = line.after("('"); args.gsub("', '", " "); args = args.before("', )"); add_argument(args, run_arguments, last_run_argument, run_arguments_updated); } else if (is_run_cmd(line)) { string args; if (gdb->type() == JDB) { // `run CLASS ARGS...' args = line.after(rxwhite); args = args.after(rxwhite); } else if (gdb->type() == PERL && line.contains("exec ", 0)) { // `exec "perl -d PROGRAM ARGS..."' args = line.after("exec "); strip_leading_space(args); if (args.contains('\"', 0) || args.contains('\'', 0)) args = unquote(args); args = args.after("-d "); strip_leading_space(args); args = args.after(rxwhite); } else { // `run ARGS...' args = line.after(rxwhite); } add_argument(args, run_arguments, last_run_argument, run_arguments_updated); } else if (is_make_cmd(line)) { string args = line.after("make"); args = args.after(rxwhite); add_argument(args, make_arguments, last_make_argument, make_arguments_updated); } else if (gdb->type() == PERL && line.contains("system 'make", 0)) { string args = line.after("make"); args = args.after(rxwhite); args = args.before("'"); add_argument(args, make_arguments, last_make_argument, make_arguments_updated); } else if (is_cd_cmd(line)) { string dir = line.after("cd"); dir = dir.after(rxwhite); dir = source_view->full_path(dir); if (dir.contains('/', 0)) add_argument(dir, cd_arguments, last_cd_argument, cd_arguments_updated); } else if (gdb->type() == PERL && line.contains("chdir '", 0)) { string dir = line.after("'"); dir = dir.before("'"); add_argument(dir, cd_arguments, last_cd_argument, cd_arguments_updated); } else if (gdb->type() == PERL && is_file_cmd(line, gdb)) { string args = line.after(" -d "); args = args.after(rxwhite); // Skip file name args = args.before('\"'); add_argument(args, run_arguments, last_run_argument, run_arguments_updated); } }
void PosBuffer::filter_dbx(string& answer) { string file; // File name found string line; // Line number found // When reaching a breakpoint, DBX issues the breakpoint // number before the status line. Check for this and // initialize defaults from breakpoint position. strip_leading_space(answer); if (answer.contains('(', 0) || answer.contains('[', 0)) { // Get breakpoint position string ans = answer; int num = read_positive_nr(ans); string pos = source_view->bp_pos(num); if (!pos.empty()) { file = pos.before(':'); line = pos.after(':'); } } // DEC DBX way issue warnings like // `warning: "./cxxtest.C":157 has no code associated with it' // right within the position info. int start_of_warning = answer.index("\nwarning"); if (start_of_warning >= 0) { int open_bracket = answer.index('['); int close_bracket = answer.index(']'); if (open_bracket >= 0 && open_bracket < start_of_warning && close_bracket >= 0 && close_bracket > start_of_warning) { // Remove warning int end_of_warning = answer.index('\n', start_of_warning + 1); while (end_of_warning < int(answer.length()) && answer[end_of_warning] == '\n') end_of_warning++; while (start_of_warning > 0 && answer[start_of_warning - 1] == '\n') start_of_warning--; int warning_length = end_of_warning - start_of_warning; answer.at(start_of_warning, warning_length) = ""; } } #if RUNTIME_REGEX static regex rxdbxfunc2( ".*line *[1-9][0-9]* *in *(file *)?\"[^\"]*\"\n.*"); #endif if (already_read != PosComplete && answer.matches(rxdbxfunc2)) { // AIX DBX issues `up', `down' and `func' output // in the format `FUNCTION(ARGS), line LINE in "FILE"'. // SUN DBX uses `line LINE in file "FILE"' instead. // We check for the `line LINE' part. line = answer.after(" line "); line = line.through(rxint); file = answer.after('\"'); file = file.before('\"'); if (!line.empty()) { already_read = PosComplete; // answer = answer.after("\n"); } } #if RUNTIME_REGEX static regex rxdbxpos("[[][^]]*:[1-9][0-9]*[^]]*[]].*"); #endif int dbxpos_index = -1; if (already_read != PosComplete && (dbxpos_index = index(answer, rxdbxpos, "[")) >= 0) { // DEC DBX issues breakpoint lines in the format // "[new_tree:113 ,0x400858] \ttree->right = NULL;" line = answer.from(dbxpos_index); if (line.contains("[#", 0)) { // This is a Ladebug breakpoint, no position info. } else { // Note that the function name may contain "::" sequences. while (line.contains("::")) line = line.after("::"); line = line.after(":"); line = line.through(rxint); if (!line.empty()) { if (answer.index('\n', dbxpos_index) >= 0) { already_read = PosComplete; // Strip position info and line strip_leading_space(answer); if (answer.contains('[', 0)) answer = answer.after("\n"); } else { // Wait for `\n' such that we can delete the line answer_buffer = answer; answer = ""; already_read = PosPart; return; } } } } if (already_read != PosComplete && (answer.contains("stopped in ") || answer.contains("stopped at "))) { int stopped_index = answer.index("stopped"); assert(stopped_index >= 0); // Stop reached // AIX DBX issues lines like // `[4] stopped in unnamed block $b382 at line 4259 in file // "/msdev/sms/ms7/riosqa/src/tffi/fi2tofu.c" ($t1)' int in_file_index = answer.index("in file ", stopped_index); int bracket_index = answer.index("[", stopped_index); if (in_file_index >= 0) { // File name given file = answer.from(in_file_index); file = file.after("in file "); if (file.contains('\n')) file = file.before('\n'); if (file.contains('"', 0)) { file = file.after('"'); file = file.before('"'); } } else if (bracket_index >= 0) { // DEC DBX and SGI DBX output format: // `[3] Process 1852 (cxxtest) // stopped at [::main:266 ,0x1000a028]' line = answer.after(bracket_index); func_buffer = line; while (line.contains("::")) line = line.after("::"); line = line.from(":"); func_buffer = func_buffer.before(line); line = line.after(":"); line = line.through(rxint); // answer = answer.after("\n"); } else { // Function name given string func = answer.after(stopped_index); func = func.after("stopped"); if (func.contains(" at ")) func = func.before(" at "); func_buffer = func; } if (!func_buffer.empty()) { // With DEC's `ladebug', the function name is fully qualified, // as in `stopped at [void tree_test(void):277 0x120003f44]' // We use only the base name (`tree_test' in this case). // (We could avoid this if `ladebug' offered a way to look // up fully qualified names. Does it? - AZ) if (func_buffer.contains('(')) func_buffer = func_buffer.before('('); while (func_buffer.contains(' ')) func_buffer = func_buffer.after(' '); } if (line.empty()) { line = answer.after("at line ", stopped_index); line = line.through(rxint); if ((!file.empty() || !func_buffer.empty()) && !answer.contains("at line ")) line = "0"; } if (!line.empty()) already_read = PosComplete; } #if RUNTIME_REGEX static regex rxdbxfunc("[a-zA-Z_][^[]*: *[1-9][0-9]* *.*"); #endif if (already_read != PosComplete && answer.matches(rxdbxfunc)) { // DEC DBX issues `up', `down' and `func' output // in the format `FUNCTION: LINE TEXT' // Note that the function name may contain "::" sequences. line = answer; while (line.contains("::")) line = line.after("::"); line = line.after(":"); strip_leading_space(line); if (line.contains(rxint, 0)) { line = line.through(rxint); if (!line.empty()) { if (answer.contains('\n')) { // Got it! already_read = PosComplete; answer = answer.after("\n"); } else { // Wait for `\n' such that we can delete the line answer_buffer = answer; answer = ""; already_read = PosPart; return; } } } } if (already_read != PosComplete && answer.contains("Current function is ")) { // Up/Down command entered string nr = answer.after("\n"); if (!nr.empty()) { line = itostring(atoi(nr.chars())); already_read = PosComplete; // Show current function only answer = answer.from("Current function is "); answer = answer.through("\n"); func_buffer = answer.after("function is "); func_buffer = func_buffer.before("\n"); } else { answer_buffer = answer; answer = ""; already_read = PosPart; return; } } if (already_read != PosComplete && (!answer.contains('\n') || (answer.contains('[') && !answer.contains(']')))) { // Position info is incomplete answer_buffer = answer; answer = ""; already_read = PosPart; return; } if (already_read == PosComplete && !line.empty()) { if (!file.empty()) pos_buffer = file + ":" + line; else pos_buffer = line; } if (already_read == PosComplete && pos_buffer.empty()) already_read = Null; }
void PosBuffer::filter_dbg(string& answer) { int idx1, idx2; if (already_read != PosComplete && !answer.contains('\n')) { // Position info is incomplete answer_buffer = answer; answer = ""; already_read = PosPart; return; } idx1 = 0; while (idx1 < (int)answer.length()) { idx2 = answer.index('\n', idx1); if (idx2 < 0) idx2 = answer.length(); string line = answer.at(idx1, idx2 - idx1); if (line.contains('\n')) line = line.before('\n'); strip_trailing_space(line); // DBG uses a format like `test.php:4 <main>\n echo $a."hello world."' #if RUNTIME_REGEX static regex rxdbgpos("[^ \t]*:[ \t]*[1-9][0-9]*[ \t]*<.*>"); static regex rxdbgframepos("#[0-9]*[ \t]*<.*>[ \t]*at[ \t]*[^ \t]*:[ \t]*[1-9][0-9]*"); #endif if (line.matches(rxdbgpos)) { string file = line.before(':'); line = line.after(':'); string line_no = line; strip_leading_space(line_no); line_no = line_no.before(' '); line = line.after('<'); func_buffer = line.before('>'); strip_leading_space(func_buffer); pos_buffer = file + ":" + line_no; // Delete this line from output answer.at(idx1, idx2 - idx1 + 1) = ""; already_read = PosComplete; break; } else if (line.matches(rxdbgframepos)) { string addr = line.before(">"); func_buffer = addr.after('<'); strip_leading_space(func_buffer); string file = line.after(">"); file = file.after("at"); strip_leading_space(file); string line_no = file.after(':'); strip_leading_space(line_no); file = file.before(':'); pos_buffer = file + ":" + line_no; // Delete this line from output answer.at(idx1, idx2 - idx1 + 1) = ""; already_read = PosComplete; break; } idx1 = idx2+1; } }
void PosBuffer::filter_xdb(string& answer) { if (already_read != PosComplete && !answer.contains('\n')) { // Position info is incomplete answer_buffer = answer; answer = ""; already_read = PosPart; return; } // INDEX points at the start of a line int index = 0; while (index >= 0 && !answer.empty()) { string line = answer.from(index); if (line.contains('\n')) line = line.before('\n'); strip_trailing_space(line); // XDB uses a format like `ctest.c: main: 4: int a = 33;' #if RUNTIME_REGEX static regex rxxdbpos("[^ \t]*:.*: [1-9][0-9]*[: ].*"); #endif if (line.matches(rxxdbpos)) { string file = line.before(':'); line = line.after(':'); // The function name may contain "::" string func = line; while (line.contains("::")) line = line.after("::"); line = line.from(':'); func = func.before(line); line = line.after(':'); string line_no = line.before(':'); strip_leading_space(func); strip_leading_space(line_no); line_no = line_no.through(rxint); pos_buffer = file + ":" + line_no; func_buffer = func; already_read = PosComplete; // Delete this line from output int next_index = answer.index('\n', index); if (next_index < 0) next_index = answer.length(); else next_index++; answer.at(index, next_index - index) = ""; break; } else { // Look at next line index = answer.index('\n', index); if (index >= 0) index++; } } // Check for trailing `:' in last line index = answer.index('\n', -1) + 1; if (already_read != PosComplete && answer.index(':', index) >= 0) { answer_buffer = answer.from(index); answer.from(index) = ""; already_read = PosPart; return; } }
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'); } }
// 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(); }
int cddb_handle_data (const char *data, char **artist, char **dtitle, char *titles[], int *totaltracks, char **year, char **dgenre) { char *row, *mark; const char *tmp = data; int i, j, counter = 0, track, previoustrack = 100, ttcounter = 0; char *tempstr; if (strncmp (data, "# xmcd", 6) != 0) return -1; (*dtitle) = NULL; while (*tmp != 0) { /* check against end of string */ /* get the row */ i = strcspn (tmp, "\r\n"); while (tmp[i] == '\r' || tmp[i] == '\n') i++; row = (char *) malloc (i + 1); strncpy (row, tmp, i); row[i] = 0; tmp += i; /* eval the row */ if (strncmp (row, "DYEAR", 5) == 0) { /* CD Year */ tempstr = malloc (MAX_YEAR_LENGTH); strcpy (tempstr, row); tempstr = strchr (row, '='); tempstr++; j = strlen (tempstr); (*year) = (char *) malloc (j + 1); strncpy ((*year), tempstr, (j + 1)); remove_non_unix_chars (*year); } else if (strncmp (row, "DGENRE", 6) == 0) { /* Disc Genre */ tempstr = malloc (MAX_GENRE_LENGTH); strcpy (tempstr, row); tempstr = strchr (row, '='); tempstr++; j = strlen (tempstr); (*dgenre) = (char *) malloc (j + 1); strncpy ((*dgenre), tempstr, (j + 1)); remove_non_unix_chars (*dgenre); } else if (strncmp (row, "TTITLE", 6) == 0) { /* Track Title */ /* get the track number before going on */ /* skip the TTITLE */ mark = row + 6; counter = 0; /* convert ascii -> int */ while (*mark != '=') { counter *= 10; counter += *mark - 0x30; mark++; } mark++; /* and skip the '=' */ track = counter; if (previoustrack != track) ttcounter++; /* create the filename. Append previous title if necessary */ tempstr = malloc (MAX_TITLE_LENGTH); if (previoustrack == track) strcpy (tempstr, titles[track]); else strcpy (tempstr, ""); /* put in the track name */ titles[track] = strcat (tempstr, mark); strip_trailing_space (&titles[track]); strip_leading_space (&titles[track]); previoustrack = track; remove_non_unix_chars (titles[track]); #ifdef DEBUG printf ("Track %d: %s\n", track, titles[track]); #endif } else if ((strncmp (row, "DTITLE", 6) == 0) && (*dtitle == NULL)) { /* CD Title */ i = strcspn (row, "="); i++; /* skip to the data */ mark = row + i; // tm: hack around bogus CDDB entries if (strstr (mark, " / ")) { j = strstr (mark, " / ") - mark + 1; (*artist) = (char *) malloc (j + 1); strncpy ((*artist), mark, j); (*artist)[j] = 0; (*dtitle) = (char *) malloc (strlen (mark) - j); mark = mark + j + 1; strcpy ((*dtitle), mark); } else { #ifdef DEBUG printf ("malformed DTITLE, copying full DTITLE into both artist and dtitle\n"); #endif j = strlen (mark); (*artist) = (char *) malloc (j + 1); strncpy ((*artist), mark, j); (*artist)[j] = 0; (*dtitle) = (char *) malloc (j + 1); strncpy ((*dtitle), mark, j); (*dtitle)[j] = 0; } strip_trailing_space (artist); strip_leading_space (artist); strip_trailing_space (dtitle); strip_leading_space (dtitle); remove_non_unix_chars (*artist); remove_non_unix_chars (*dtitle); convert_slashes (*artist, '_'); // dc: _ Artist, - others convert_slashes (*dtitle, '-'); #ifdef CONVERT_SPACES_IN_ID3_DATA if (((int) config_read (CONF_CDDB_CONVSPC)) == TRUE) { convert_spaces (*artist, '_'); convert_spaces (*dtitle, '_'); } #endif #ifdef DEBUG printf ("Artist: %s\n", (*artist)); printf ("Dtitle: %s\n", (*dtitle)); #endif } /* ignore any other results */ free (row); } *totaltracks = ttcounter; return 0; }