void PosBuffer::filter_pydb(string& answer) { if (already_read != PosComplete && !answer.contains('\n')) { // Position info is incomplete answer_buffer = answer; answer = ""; already_read = PosPart; return; } // `Breakpoint N, FUNCTION (ARGS...) at file:line_no' // rxstopped_func defined for GDB...if it changes, change here int fn_index = index(answer, rxstopped_func, "Breakpoint"); if (fn_index >= 0) { fetch_function(answer, fn_index, func_buffer); } else { // `#FRAME FUNCTION(args) at file:line_no' // Likewise rxframe_func defined for GDB int frame_index = index(answer, rxframe_addr, "#"); if (frame_index == 0 || frame_index > 0 && answer[frame_index - 1] == '\n') { fetch_function(answer, frame_index, func_buffer); } } int lineinfo = answer.index("Lineinfo"); // Lineinfo <function> at file:lineno if (lineinfo == 0 || (lineinfo > 0 && answer[lineinfo - 1] == '\n')) { answer = answer.after('<'); func_buffer = answer.before('>'); } string result = answer.after(" at "); result = result.before('\n'); if (result.contains(':')) { pos_buffer = result; already_read = PosComplete; } // Don't need the answer anymore when line matches 'Lineinfo' if (lineinfo >= 0) { answer = ""; } }
void PosBuffer::filter_gdb(string& answer) { // Try to find out current PC even for non-existent source if (check_pc && pc_buffer.empty()) { // `$pc = ADDRESS' #if RUNTIME_REGEX static regex rxpc("\\$pc *= *" RXADDRESS); #endif int pc_index = index(answer, rxpc, "$pc "); if (pc_index >= 0) { int addr_index = answer.index('='); fetch_address(answer, addr_index, pc_buffer); // Strip this line from ANSWER int end_line = answer.index('\n', pc_index); int start_line = pc_index; while (start_line > 0 && answer[start_line - 1] != '\n') start_line--; if (end_line < 0) answer.from(start_line) = ""; else answer.at(start_line, end_line - start_line + 1) = ""; } } if (check_pc && pc_buffer.empty() || check_func && func_buffer.empty()) { // `Breakpoint N, ADDRESS in FUNCTION (ARGS...)' #if RUNTIME_REGEX static regex rxstopped_addr("Breakpoint *[1-9][0-9]*, *" RXADDRESS); #endif int pc_index = index(answer, rxstopped_addr, "Breakpoint"); if (pc_index >= 0) { annotate("stopped"); pc_index = answer.index(','); fetch_address(answer, pc_index, pc_buffer); fetch_in_function(answer, pc_index, func_buffer); } } if (check_pc && pc_buffer.empty() || check_func && func_buffer.empty()) { // `#FRAME ADDRESS in FUNCTION (ARGS...)' #if RUNTIME_REGEX static regex rxframe_addr("#[0-9][0-9]* *" RXADDRESS); #endif int pc_index = index(answer, rxframe_addr, "#"); if (pc_index == 0 || pc_index > 0 && answer[pc_index - 1] == '\n') { pc_index = answer.index(' '); fetch_address(answer, pc_index, pc_buffer); fetch_in_function(answer, pc_index, func_buffer); } } if (check_pc && pc_buffer.empty() || check_func && func_buffer.empty()) { // `No line number available for // address ADDRESS <FUNCTION>' #if RUNTIME_REGEX static regex rxaddr("address *" RXADDRESS); #endif int pc_index = index(answer, rxaddr, "address "); if (pc_index >= 0) { pc_index = answer.index(' '); fetch_address(answer, pc_index, pc_buffer); if (func_buffer.empty()) { string line = answer.from(pc_index); line = line.after('<'); line = line.before('>'); if (!line.empty()) func_buffer = line; } } } if (check_pc && pc_buffer.empty() && !answer.empty()) { // `ADDRESS in FUNCTION' #if RUNTIME_REGEX static regex rxaddress_in(RXADDRESS " in "); #endif int pc_index = -1; if (is_address_start(answer[0]) && answer.contains(rxaddress_in, 0)) { pc_index = 0; } else { #if RUNTIME_REGEX static regex rxnladdress_in("\n" RXADDRESS " in "); #endif pc_index = index(answer, rxnladdress_in, "\n"); } if (pc_index >= 0) { fetch_address(answer, pc_index, pc_buffer); fetch_in_function(answer, pc_index, func_buffer); } } // Try to find out current function name, even for // non-existing addresses if (check_func && func_buffer.empty()) { // `Breakpoint N, FUNCTION (ARGS...)' // This regex used for PYDB as well. #if RUNTIME_REGEX static regex rxstopped_func("Breakpoint *[1-9][0-9]*, *"); #endif int bp_index = index(answer, rxstopped_func, "Breakpoint"); if (bp_index >= 0) fetch_function(answer, bp_index, func_buffer); } if (check_func && func_buffer.empty()) { // `#FRAME FUNCTION' #if RUNTIME_REGEX static regex rxframe_func("#[0-9][0-9]* *[a-zA-Z_].*[(]"); #endif int frame_index = index(answer, rxframe_addr, "#"); if (frame_index == 0 || frame_index > 0 && answer[frame_index - 1] == '\n') { fetch_function(answer, frame_index, func_buffer); } } if (check_func && func_buffer.empty()) { // FUNCTION (ARGS...) at FILE:POS int at_index = answer.index(" at "); if (at_index > 0) { int nl_index = answer.index('\n', at_index - answer.length() - 1) + 1; fetch_function(answer, nl_index, func_buffer); // Try to construct position from `at FILE:POS' (vxworks) string file = answer.after(" at "); file = file.before('\n'); if (file.contains(rxaddress, 0)) { // This is `at ADDRESS' (GDB output) } else if (file.contains(":") && !file.contains(": ")) { pos_buffer = file; already_read = PosComplete; return; } } } // Look for regular source info // (GDB's annotations are prefixed with "^Z^Z") int index1 = answer.index ("\032\032"); if (index1 < 0) { int index_p = answer.index ("\032"); if (index_p >= 0 && index_p == int(answer.length()) - 1) { // Possible begin of position info at end of ANSWER answer_buffer = "\032"; answer = answer.before (index_p); already_read = PosPart; return; } // Handle erroneous `info line' output like // `Line number 10 is out of range for "t1.f".' // At least get the file name. #if RUNTIME_REGEX static regex rxout_of_range( "Line number [0-9]+ is out of range for "); #endif index_p = index(answer, rxout_of_range, "Line number"); if (index_p >= 0) { string file = answer.after('\"', index_p); file = file.before('\"'); pos_buffer = file + ":1"; already_read = PosComplete; return; } // Try to construct position from `Line xxxx of "filename"' (vxworks) // which is the output of an 'info line' command string line = answer.after("Line "); string file = answer.after('\"'); if (!line.empty() && !file.empty()) { line = line.before(" of"); file = file.before('\"') + ":" + line; if (!line.empty() && !file.empty()) { pos_buffer = file; already_read = PosComplete; return; } } // Try FUNCTION (ARGS...) at FILE:POS // here to properly handle up/down commands int at_index = answer.index(" at "); int br_index = answer.index("Break"); if ( (at_index > 0) && (br_index < 0) ) { int nl_index = answer.index('\n', at_index - answer.length() - 1) + 1; fetch_function(answer, nl_index, func_buffer); // Try to construct position from `at FILE:POS' (vxworks) string file = answer.after(" at "); file = file.before('\n'); if (!file.empty()) { pos_buffer = file; already_read = PosComplete; return; } } // Nothing found return; } // ANSWER contains position info int index2 = answer.index ("\n", index1); if (index2 == -1) { // Position info is incomplete answer_buffer = answer.from (index1); answer = answer.before (index1); already_read = PosPart; return; } assert (index1 < index2); // Position info is complete pos_buffer = answer.at(index1 + 2, index2 - (index1 + 2)); if (pos_buffer.contains("source ", 0)) { // This happens with GDB in annotation level 2 pos_buffer = pos_buffer.after("source "); } int last_colon = pos_buffer.index(':', -1); pc_buffer = pos_buffer.after(last_colon); if (!pc_buffer.contains(rxaddress_start, 0)) pc_buffer = "0x" + pc_buffer; pc_buffer = pc_buffer.through(rxaddress); answer.at(index1, index2 - index1 + 1) = ""; if (!pos_buffer.empty()) already_read = PosComplete; }
// Same, but requires " in " before function inline void fetch_in_function(const string& answer, int index, string& buffer) { fetch_function(answer, index, buffer, true); }