📄 gdb_parser.c
字号:
/***************************************************************************** * * xdbx - X Window System interface to the dbx debugger * * Copyright 1989 The University of Texas at Austin * Copyright 1990 Microelectronics and Computer Technology Corporation * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of The University of Texas * and Microelectronics and Computer Technology Corporation (MCC) not be * used in advertising or publicity pertaining to distribution of * the software without specific, written prior permission. The * University of Texas and MCC makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Po Cheung * Created: March 10, 1989 * ***************************************************************************** * * xxgdb - X Window System interface to the gdb debugger * * Copyright 1990,1993 Thomson Consumer Electronics, Inc. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Thomson Consumer * Electronics (TCE) not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. TCE makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * * Adaptation to GDB: Pierre Willard * XXGDB Created: December, 1990 * *****************************************************************************//* gdb_parser.c: * * WARNING : gdb_parser.c is included by parser.c for GDB. * * Parse output messages from dbx using regular expression pattern matching, * and take appropriate action. * * parse(): Parse the dbx output and invoke the appropriate action * handler. * filter(): Modify the dbx output before it gets displayed on the * dialog window. * gdb_source_command(): Test for source command. *//* * iand 94/02/10 cope better with non-blocking I/O. Exit when pty is closed rather * than spinning in a loop. * */#include <string.h>#include <stdio.h>#include <errno.h>extern Boolean Prompt; /* True when gdb prompt arrives *//*--------------------------------------------------------------------------+| || Function to output a message and ring bell when a answer || from gdb has not been recognized (possibly because of bug || in xxgdb which does not anticipate this particular answer). || || ECHO_ON means that all the output from gdb was displayed || on the dialog window (so no need to display any error message). || In particular we can arrive here because the user typed a || wrong command. || || ECHO_OFF means that the gdb command was issued internally by || xxgdb, and that the user has no knowledge of it. || || ECHO_ON and FILTER_ON means that only part of the || gdb answer to the command is displayed in the dialog window. || What is displayed or not is chosen by the filter() function. || In fact, filter() in this case will display gdb error messages || from the command sent internally by xxgdb. || || This function will only display error messages when echo and || filter are off. This is more for xxgdb debug than for the user. || |+--------------------------------------------------------------------------*/ void unknown_output (outputstr, command, flags)char *outputstr;char *command;int flags;{ if (command) { if (debug) fprintf(stderr, "\noutput from \"%s\" is not recognized\n", command); /* if the command was completely silent, we output this error message */ if ((flags & (ECHO_ON | FILTER_ON)) == 0) { AppendDialogText("xxgdb error: output from \""); AppendDialogText(command); AppendDialogText("\" command is not recognized.\n"); } } if (outputstr) if ((flags & (ECHO_ON | FILTER_ON)) == 0) AppendDialogText(outputstr); bell(0); /* ring the bell in ALL cases */}/*--------------------------------------------------------------------------+| || Function to remove all 'Reading in symbols' message || from a string. || || This function is used in parser() before matching the output || because this message can happen any time. || |+--------------------------------------------------------------------------*/void filter_reading_symbols(output)char *output;{struct re_registers regs;int r;char *p1;char *p2; /* test for reading symbols message */ while (re_match(output_pattern[O_READING_SYMBOLS].buf,output,strlen(output),0,®s) > 0) { /* we found a "Reading in symbols for ...done." pattern */ r = output_pattern[O_READING_SYMBOLS].reg_token[TK_MESG]; p1= output+regs.start[r]; p2 = output+regs.end[r]; /* remove "Reading in symbols for ...done." */ while((*(p1++) = *(p2++))); }}/*--------------------------------------------------------------------------+| || * This routine first parses the command string. || * If the command is one of run, cont, next, step, stop at, stop in, || * where, up, or down, it parses the dbx output to decide what action || * to take and dispatch it to one of the handlers. || * For other commands, the appropriate handler is called. || * || * !!! This routine has to be re-entrant. || * |+--------------------------------------------------------------------------*/void parse(output, command, flags)char *output;char *command;int flags;{ int command_type; char *output_string; if (debug) { char *temp; if(!command)temp="";else temp=command; fprintf(stderr, "parse(output = %s, command = %s, flags = %d)\n", output, temp, flags); } /* Make a local copy of `output' and use that instead */ output_string = XtNewString(output); if (output) strcpy(output, ""); /* test for GDB start-up */ if (!command) {/* (PW)28AUG91 : do no test for O_DEBUG pattern because of gdb 4.0who most of the times displays nothing before the promt.if (match(output_pattern, output_string, O_DEBUG) != -1)*/ { query_gdb_directories(); /* will tell if running gdb 4.0 */ debug_handler(); /* some init to gdb, and try to display main() */ /* test if a core file was used in input arguments, an display bomb if necessary. */ if (match(output_pattern, output_string, O_CORE_FILE) != -1) core_file_handler(); } debug_init(); /* read .gdbinit file (if any) */ XtFree(output_string); return; } /* if not GDB start-up */ if (match(output_pattern, output_string, O_BELL) != -1) { /* test if this is 'show undefined'. If yes then we are not executing the new gdb (4.0). (see show_is_undefined in gdb_handler.c) */ if (match(output_pattern, output_string, O_UNDEF_SHOW) != -1) show_is_undefined(); else unknown_output (output_string,command, flags); XtFree(output_string); return; } command_type = match(command_pattern, command, C_ANY); /* remove all "Reading in symbols for pw.c...done." */ filter_reading_symbols(output_string); switch (command_type) { case C_EXEC: case C_FINISH: { char * message; int signal = 0; if (debug) { fprintf(stderr, "C_EXEC or C_FINISH\n"); } message = 0; if (match(output_pattern, output_string, O_RECEIVED_SIGNAL) != -1) { message = XtNewString(Token.mesg); signal = Token.stop; /* signal number received */ } /* warning : the order of the matching tests is important */ if ((match(output_pattern, output_string, O_EXEC_MESS_AFTER) != -1) || (match(output_pattern, output_string, O_EXEC_MESS_BEFORE) != -1) || (match(output_pattern, output_string, O_EXEC_GDB) != -1)) { exec_handler(message,signal); } else { if (match(output_pattern, output_string, O_DONE) != -1) done_handler(message,signal); else unknown_output(output_string, command, flags); } if (message) { bell(0); XtFree(message); } } break; case C_UPDOWN: if (debug) { fprintf(stderr, "C_UPDOWN\n"); } if (match(output_pattern, output_string, O_UPDOWN) != -1) updown_handler(); else if (match(output_pattern, output_string, O_UPDOWN_NOSOURCE) != -1) /* here Token.msg and Token.func are updated. Do nothing with them. We are in a function with no source information. */ bell(0); else unknown_output (output_string, command, flags); break; case C_SEARCH: if (debug) { fprintf(stderr, "C_SEARCH\n"); } if (match(output_pattern, output_string, O_SEARCH) != -1) search_handler(); else unknown_output(output_string, command, flags); break; case C_DELETE: if (debug) { fprintf(stderr, "C_DELETE\n"); } delete_handler(); break; case C_LIST: if (debug) { fprintf(stderr, "C_LIST\n"); } if (match(output_pattern, output_string, O_LIST) != -1) list_handler(); else unknown_output(output_string, command, flags); break; case C_BREAK: if (debug) { fprintf(stderr, "C_BREAK\n"); } if (match(output_pattern, output_string, O_BREAK) != -1) break_handler(); else unknown_output(output_string, command, flags); break; case C_INFO_DIR: if (debug) { fprintf(stderr, "C_INFO_DIR\n"); } if (match(output_pattern, output_string, O_INFO_DIR) != -1) info_dir_handler(); else unknown_output(output_string, command, flags); break; case C_DIRECTORY: if (debug) { fprintf(stderr, "C_DIRECTORY\n"); } directory_handler(); break; case C_INFO_LINE: if (debug) { fprintf(stderr, "C_INFO_LINE\n"); } if (match(output_pattern, output_string, O_INFO_LINE) != -1) info_line_handler(); /* command was 'info line' */ else unknown_output(output_string, command, flags); break; case C_INFO_BREAK: if (debug) { fprintf(stderr, "C_INFO_BREAK\n"); } info_break_handler(output_string); break; case C_DISPLAY: /* means "display foo\n" command */ if (debug) { fprintf(stderr, "C_DISPLAY\n"); } { if ((strcmp(output_string, "") == 0) || (match(output_pattern, output_string, O_DISPLAY) != -1)) display_handler(); else unknown_output(output_string, command, flags); } break; case C_UNDISPLAY: if (debug) { fprintf(stderr, "C_UNDISPLAY\n"); } if (strcmp(output_string, "") == 0) display_handler(); else unknown_output(output_string, command, flags); break; case C_DISPLAY_INFO: /* means "display\n" command */ if (debug) { fprintf(stderr, "C_DISPLAY_INFO\n"); } { if ((strcmp(output_string, "") == 0) || (match(output_pattern, output_string, O_DISPLAY_INFO) != -1)) display_info_handler(); else unknown_output(output_string, command, flags); } break; case C_CD: if (debug) { fprintf(stderr, "C_CD\n"); } if (new_gdb4()) /* this fixes where cd and pwd dont work right for 4.x (cd doesn't do anything but beep, pwd doesn't work when cwd is not cannonical) */ query_gdb ("pwd\n", PARSE_ON); else if (match(output_pattern, output_string, O_CD) != -1) cd_handler(Token.mesg); else unknown_output(output_string, command, flags); break; case C_PWD: if (debug) { fprintf(stderr, "C_PWD\n"); } if (match(output_pattern, output_string, O_PWD) != -1) pwd_handler(Token.display? Token.display : Token.mesg); else unknown_output(output_string, command, flags); break; case C_FRAME_CURR: if (debug) { fprintf(stderr, "C_FRAME_CURR\n"); } if (match(output_pattern, output_string, O_FRAME_CURR) != -1) frame_curr_handler(); else unknown_output(output_string, command, flags); break; case C_PRINT: if (debug) { fprintf(stderr, "C_PRINT\n"); } { /* for GDB, the label of the popup display is the expression string which is printed instead of $n */ char * prtname; prtname = 0; if ((Token.mesg) && (PopupMode)) prtname = XtNewString(Token.mesg); if (match(output_pattern, output_string, O_PRINT) != -1) { if (prtname) { XtFree(Token.mesg); Token.mesg = prtname; prtname = 0; /* not to XtFree twice this string */ } print_handler(output_string); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -