📄 gdb_parser.c
字号:
int gdb_define_command(command,fp)char *command;FILE *fp;{char s[LINESIZ];int error_cmd;int end_found; if ((command && (match(command_pattern, command, C_DEFINE) != -1)) || (command && (match(command_pattern, command, C_DOCUMENT) != -1))) { AppendDialogText(command); /* because silly gdb 4.0 displays nothing with def/doc command when confirm is on (possibly a gdb bug) , I just reset confirm to on just for this command !. */ if (new_gdb4()) query_gdb("set confirm on\n", PARSE_OFF | ECHO_OFF | FILTER_OFF); write_dbx (command); /* gdb could ask : "Redefine command \"%s\"? " "Really redefine built-in command \"%s\"? " gdb could display "Type commands for definition of \"%s\".\n" "End with a line saying just \"end\" or "Type documentation for \"%s\".\n" "End with a line saying just \"end\".\n" or "Command \"%s\" is built-in."*/ error_cmd = FALSE; /* read message from gdb */ while (1) if (fgets(s, LINESIZ, dbxfp)) { if (debug) fprintf(stderr, "=>%s", s); if (strstr(s," is built-in.")) /* error for document of built-in command */ { AppendDialogText(s); error_cmd = TRUE; bell(0); break; } if (strstr(s,"Redefine command ") || strstr(s,"Really redefine built-in command ")) write_dbx ("y\n"); /* answer to question if any */ else { if (strcmp(s,"End with a line saying just \"end\".\n") == 0) break; } } /* write command definition */ end_found = FALSE; while (fgets (s, LINESIZ, fp)) { if (!error_cmd) { AppendDialogText(s); write_dbx (s); } if (match(command_pattern, s, C_END) != -1) { end_found = TRUE; break; } } if ((!error_cmd) && (!end_found)) { AppendDialogText("Error : missing \"end\" in file.\n"); bell(0); write_dbx ("end\n"); } command_sent++; /* flag gdb is busy (because of read_gdb) */ insert_command("end\n"); /* insert 'end' at head of queue */ read_until_prompt (PARSE_OFF | ECHO_ON | FILTER_OFF); /* return when prompt */ if (new_gdb4()) /* reset confirm to off */ query_gdb("set confirm off\n", PARSE_OFF | ECHO_OFF | FILTER_OFF); return TRUE; } return FALSE;}#ifndef NO_MY_FGETS/* * cope with non-blocking I/O correctly * ie: exit if child closes pty, but return if would block. * * This function seems to fail on some systems (??) * */static char *#ifdef __STDC__my_fgets(char *buf, int size, FILE *f)#elsemy_fgets(buf, size, f)char *buf;int size;FILE *f;#endif{ char *orig_buf = buf; while(size > 1) { int cc; cc = read(fileno(f), buf, 1); if(cc == -1) { if(errno == EAGAIN || errno == EWOULDBLOCK) { break; } perror("read from gdb"); exit(1); /*NOTREACHED*/ } if(cc == 0) {#ifdef READ_ZERO_NOT_EOF /* for RS6000 */ break;#else (void) fprintf(stderr, "EOF from gdb\n"); exit(1);#endif /*NOTREACHED*/ } buf++; size--; if(*(buf-1) == '\n') break; } *buf = '\0'; if (buf == orig_buf) { return NULL; } else { return(orig_buf); }}#endif /* NO_MY_FGETS *//*--------------------------------------------------------------------------+| || Read gdb output until fgets returns no string. || || The ouptut is process according to flags. || || In case the gdb prompt is found, the command on top of the || command queue (ie, the one which is assumed to correspond || to this output) is remove from the queue, and 'command_sent' || is decremented to say that gdb is no longer busy. || |+--------------------------------------------------------------------------*/static int parse_flags = PARSE_ON | ECHO_ON | FILTER_ON; /* last flags used in read_gdb */void read_gdb (flags)int flags;{ static char *output = NULL; /* buffer for gdb output */ static char *next_string = NULL; static char *command; char *string = NULL; char *prompt_pointer; char s[LINESIZ]; int before_prompt; Boolean more; Boolean local_prompt; parse_flags = flags; /* just remember flags for read_dbx() */ more = True; Prompt = False; local_prompt = False; while (more) { /* keep reading until no more or until prompt arrives */#ifdef NO_MY_FGETS while ((more = (fgets(s, LINESIZ, dbxfp) != NULL)))#else while ((more = (my_fgets(s, LINESIZ, dbxfp) != NULL)))#endif { if (debug) fprintf(stderr, "=>%s", s); /* new gdb might add '>' characters in front of input for define commands, we have to test for them here ! */ /* receive prompt? */#if 1 /* (PW)16NOV94 : new gdb might add '>' characters in front of input when defining commands, we have to test for them here ! so use strstr() to catch all prompts... */ if ((prompt_pointer = strstr(s, dbxprompt)) != NULL)#else if (strncmp(s, dbxprompt, strlen(dbxprompt)) == 0)#endif { Prompt = True; local_prompt = True; before_prompt = prompt_pointer - s; /* more stuff behind prompt? */ if (s[before_prompt+ strlen(dbxprompt)]) { /* remember it */ next_string = XtNewString(s+before_prompt+strlen(dbxprompt)); } /* destroy contents */ strcpy(s, ""); if (debug) fprintf(stderr, " Prompt detected\n"); } string = concat(string, s); strcpy(s, ""); if (local_prompt) { /* do not read next line if prompt is found */ break; } } output = concat(output, string); command = get_command(); /* read queue's top command */ if (flags & FILTER_ON) { filter (string, output, command); } if ((flags & ECHO_ON) && local_prompt) { AppendDialogText(xdbxprompt); } if (string) { XtFree(string); string = NULL; } if (next_string) { string = concat(string, next_string); XtFree(next_string); next_string = NULL; } if ((flags & PARSE_ON) && local_prompt) { parse (output, command, flags); } /* note : it is important to decrement 'command_sent' AFTER parse() is executed, so that no other commands will mix-up the commands sent by the function handlers executed by parse(). */ if (local_prompt) { delete_command(); /* remove top command from queue */ if (command && command_sent) command_sent--; XtFree(output); output = NULL; local_prompt = False; } }}/*--------------------------------------------------------------------------+| * || * This is a callback procedure invoked everytime when input is pending || * on the file descriptor to dbx. || * o reads all the data available on the file descriptor line by line || * into local variable 'string' and global variable 'output'. || * 'output' records the entire dbx output whereas 'string' records || * only the data read in this invocation of read_dbx(). || * o in Echo mode, the contents in 'string' is edited by filter() || * before it gets displayed on the dialog window. || * o once the dbx prompt is read, calls parse() to analyse the dbx output || * and take appropriate action. || * |+--------------------------------------------------------------------------*/static volatile int in_read_dbx;/* ARGSUSED */void read_dbx(master, source, id)XtPointer master;int *source;XtInputId *id;{ if (in_read_dbx++) /* already running */ return; do { read_gdb (parse_flags); /* do not write any more command, if prompt was not seen yet */ if (Prompt) { write_dbx_available (); } } while (--in_read_dbx);}/*--------------------------------------------------------------------------+| || Read gdb output until prompt. || The ouptut is process according to flags. || |+--------------------------------------------------------------------------*/void read_until_prompt (flags)int flags;{ Prompt = False; while (!Prompt) read_gdb (flags);}/*--------------------------------------------------------------------------+| || * Sends a command to gdb and read the corresponding output, directly || * invoking the Xt input procedure, read_gdb(). || * || * Same as query_dbx() in dbx.c except that echo, filter and parse. || * are passed in argument flags: || * PARSE_ON | PARSE_OFF | ECHO_ON | ECHO_OFF | FILTER_ON | FILTER_OFF || * |+--------------------------------------------------------------------------*/void query_gdb(command, flags)char *command;int flags;{ command_sent++; /* flag gdb is busy */ write_dbx(command); /* send command to gdb */ insert_command(command); /* insert at head of queue */ read_until_prompt (flags); /* return when prompt */ /* test if we are at the top command, and if some commands are waiting */ write_dbx_available (); /* send next waiting command */}/*--------------------------------------------------------------------------+| || Function to send the first command of the command queue to gdb only in || case gdb is waiting for a command. || || WARNING : we must test for 'source' command. || || The commands in the command queue are from the keyboard and from || the buttons. || |+--------------------------------------------------------------------------*/void write_dbx_available(){char *command; if ((command = get_command ())) { if (command_sent++ == 0) { /* here, the source command is already displayed, say echo command = FALSE */ if (gdb_source_command (command, FALSE)) { delete_command(); /* remove source command from top of queue */ command_sent--; /* tell gdb to send its prompt */ query_gdb(" \n", PARSE_OFF | ECHO_ON | FILTER_OFF); return; } if (xxgdb_command (command, FALSE)) { delete_command(); /* remove xxgdb command from top of queue */ command_sent--; /* tell gdb to send its prompt */ query_gdb(" \n", PARSE_OFF | ECHO_ON | FILTER_OFF); return; } parse_flags = PARSE_ON | ECHO_ON | FILTER_ON; /* for read_gdb */ write_dbx (command); Prompt = False; return; /* return with command_sent incremented */ } else { if (command_sent) /* should never be zero ! (just to be safe) */ command_sent--; /* command is not sent, restore previous value */ return; } }}/*--------------------------------------------------------------------------+| || Function to filter xxgdb only commands || || input : command (from .gdbinit or source command or keyboard), || echo is TRUE if source command must be echoed. || || output : TRUE if source command was recognized || || In case source command is recognized, it is executed here. || |+--------------------------------------------------------------------------*/int xxgdb_command (command, echo)char *command;int echo;{#ifdef CREATE_IO_WINDOW if (command && (!strcmp(command,"iowin\n"))) /* test for 'iowin' command */ { if (echo) AppendDialogText(command); if (!iowinpid) { char ttycommand[50]; create_io_window (); sprintf (ttycommand, "tty %s\n", iowintty); query_gdb (ttycommand, PARSE_OFF | ECHO_OFF | FILTER_OFF); } return TRUE; }#endif /* CREATE_IO_WINDOW */ return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -