📄 xgdb.c
字号:
#ifndef lintstatic char rcsid[] = "$Header: xgdb.c,v 1.2 93/02/24 14:52:46 van Exp $";#endif lint/* * Interface from GDB to X windows. Copyright (C) 1987 Free Software * Foundation, Inc. * * GDB is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY. No author or distributor accepts responsibility to anyone for * the consequences of using it or for whether it serves any particular * purpose or works at all, unless he says so in writing. Refer to the GDB * General Public License for full details. * * Everyone is granted permission to copy, modify and redistribute GDB, but only * under the conditions described in the GDB General Public License. A copy * of this license is supposed to have been given to you along with GDB so * you can know your rights and responsibilities. It should be in a file * named COPYING. Among other things, the copyright notice and this notice * must be preserved on all copies. * * In other words, go ahead and share GDB, but don't try to stop anyone else * from sharing it farther. Help stamp out software hoarding! *//* * Original version was contributed by Derek Beatty, 30 June 87. * This version is essentially a re-write of the original by Van * Jacobson (van@ee.lbl.gov), Nov, 90. *//* Include/define this before gcc-include/stddef.h */#include <sys/types.h>#ifndef _SIZE_T#define _SIZE_T#define _PTRDIFF_T#define _WCHAR_T#endif#include "defs.h"#include "symtab.h"#include "frame.h"#include "inferior.h"#include <stdio.h>#include <X11/Xatom.h>#include <X11/IntrinsicP.h>#include <X11/StringDefs.h>#include <X11/Xaw/Text.h>#include <X11/Xaw/AsciiSink.h>#include <X11/Xaw/AsciiText.h>#include <X11/Xaw/Box.h>#include <X11/Xaw/Command.h>#include <X11/Xaw/Label.h>#include <X11/Xaw/Paned.h>#include <ctype.h>#include <sys/file.h>#include <sys/errno.h>extern int errno;extern char *index();extern char *getenv();extern void printf();extern void fprintf();extern void bcopy();extern void fflush();extern int select();extern int get_filename_and_charpos();extern int source_line_charpos();extern int source_charpos_line();extern void execute_command();extern void error_no_arg();extern void add_com();/* The X display where the window appears. */static char *displayname;static Display *display;static XtAppContext app_context;/* Windows manipulated by this package. */static Widget main_widget;static Widget containing_widget;static Widget source_name_widget;static Widget source_text_widget;static Widget button_box_widget;/* Source text display. */static struct frame_info *last_fi;static CORE_ADDR last_pc;static struct symtab *last_cur_symtab;static int last_cur_line;static int source_window_line;static char *source_window_file;static struct symtab *source_window_symtab;static char version_label[64];extern char *version;/* Forward declarations */static Widget create_text_widget();static intsafe_strcmp(a, b) register char *a, *b;{ register int i; if (a == b) return (0); if (!a && b) return (1); if (a && !b) return (-1); return (strcmp(a, b));}/* Display an appropriate piece of source code in the source window. */voidxgdb_display_source(){ char *filename = NULL; struct symtab_and_line get_selected_frame_sal(); struct symtab_and_line sal; struct frame_info *fi; /* Do nothing if called before we are initialized */ if (!containing_widget) return; /* * Figure out what to display (the appropriate hooks to tell * us don't exist so we guess): If there's a current frame * and it or its pc changed from the last time we were here, * display appropriate source line. Otherwise if the current * source symtab or line is different, display that line. * Otherwise nothing changed so leave the display alone. */ fi = get_frame_info(selected_frame); if (fi && (fi != last_fi || fi->pc != last_pc)) { last_fi = fi; last_pc = fi->pc; sal = find_pc_line(fi->pc, fi->next_frame); if (sal.symtab == NULL) { /* XXX */ sal.symtab = current_source_symtab; sal.line = current_source_line; } current_source_symtab = sal.symtab; current_source_line = sal.line; } else if (current_source_symtab != last_cur_symtab || current_source_line != last_cur_line) { sal.symtab = last_cur_symtab = current_source_symtab; sal.line = last_cur_line = current_source_line; } else return; /* * Do a path search and get the exact filename of this source file. * Also scan it and find its source lines if not already done. */ if (sal.symtab && filename == NULL) { if (get_filename_and_charpos(sal.symtab, &filename)) /* line numbers may have changed - force highlight */ source_window_line = -1; } /* * If the source window is wrong, destroy it and make a new one. */ if (safe_strcmp(filename, source_window_file)) { Arg args[1]; Widget src = XawTextGetSource(source_text_widget); if (filename) { XtSetArg(args[0], XtNstring, filename); XtSetValues(src, args, XtNumber(args)); args[0].name = XtNlabel; XtSetValues(source_name_widget, args, XtNumber(args)); } else { XtSetArg(args[0], XtNstring, "/dev/null"); XtSetValues(src, args, XtNumber(args)); XtSetArg(args[0], XtNlabel, "???"); XtSetValues(source_name_widget, args, XtNumber(args)); } source_window_file = filename; source_window_line = sal.line + 1; /* force highlight */ } if (sal.symtab && source_window_line != sal.line) { /* * Update display and cursor positions as necessary. * Cursor should be placed on line sal.line. */ XawTextPosition l, r; source_window_symtab = sal.symtab; source_window_line = sal.line; l = source_line_charpos(source_window_symtab, sal.line); r = source_line_charpos(source_window_symtab, sal.line + 1); if (r < l) r = l + 1; XawTextSetSelection(source_text_widget, l, r); XawTextScrollToLine(source_text_widget, l, 10, 3); XawTextSetInsertionPoint(source_text_widget, l); }}/* * Handlers for buttons. */static intcurrent_lineno(){ XawTextPosition start, finish; XawTextGetSelectionPos(source_text_widget, &start, &finish); if (start >= finish) start = XawTextGetInsertionPoint(source_text_widget); return (source_charpos_line(source_window_symtab, start));}static char *append_selection(cp) char *cp;{ int len; XawTextPosition l, r; XawTextGetSelectionPos(source_text_widget, &l, &r); if ((len = r - l) > 0) { Widget src = XawTextGetSource(source_text_widget); while (len > 0) { XawTextBlock tb; XawTextSourceRead(src, l, &tb, len); bcopy(tb.ptr, cp, tb.length); cp += tb.length; len -= tb.length; } if (cp[-1] == 0) --cp; } return (cp);}static char *append_selection_word(cp) register char *cp;{ register int len; XawTextPosition l, r; XawTextBlock tb; register char c; register Widget src = XawTextGetSource(source_text_widget); XawTextGetSelectionPos(source_text_widget, &l, &r); if ((len = r - l) <= 0) { l = XawTextGetInsertionPoint(source_text_widget); len = 128; /* XXX */ /* might have clicked in middle of word -- back up to start */ for ( ; l > 0; --l) { XawTextSourceRead(src, l - 1, &tb, 1); c = tb.ptr[0]; if (! isalnum(c) && c != '_' && c != '$') break; } } while (len > 0) { char *sp; int i; XawTextSourceRead(src, l, &tb, len); for (sp = tb.ptr, i = tb.length; --i >= 0; ) { c = *sp++; if (!isalnum(c) && c != '_' && c != '$') return (cp); *cp++ = c; } len -= tb.length; } return (cp);}static char *append_selection_expr(cp) char *cp;{ int len; XawTextPosition l, r; Widget src = XawTextGetSource(source_text_widget); XawTextBlock tb; char *sp; char c; XawTextGetSelectionPos(source_text_widget, &l, &r); if (r > l) return (append_selection(cp)); l = XawTextGetInsertionPoint(source_text_widget); /* might have clicked in middle of word -- back up to start */ for ( ; l > 0; --l) { XawTextSourceRead(src, l - 1, &tb, 1); c = tb.ptr[0]; if (! isalnum(c) && c != '_' && c != '$') break; } len = 128; /* XXX */ while (len > 0) { int i; char pstack[64]; int pcnt = 0; XawTextSourceRead(src, l, &tb, len); for (sp = tb.ptr, i = tb.length; --i >= 0; ) { switch (c = *sp++) { case '\n': case ';': return (cp); case '=': if (cp[-1] != '=') return (cp - 1); if (len == 128) return (cp); break; case ',': if (pcnt <= 0) return (cp); break; case '(': pstack[pcnt] = ')'; if (++pcnt >= sizeof(pstack)) return (cp); break; case '[': pstack[pcnt] = ']'; if (++pcnt >= sizeof(pstack)) return (cp); break; case ')': case ']': if (--pcnt < 0 || pstack[pcnt] != c) return (cp); break; } *cp++ = c; } len -= tb.length; } return (cp);}static int input_avail; /* XXX kluge: do_command sets this when command * data from button is avaialble to force top level * to break out of its loop. *//* * Handle a button by running the command COMMAND. */static voiddo_command(w, command, call_data) Widget w; register char *command; caddr_t call_data;{ char cmd_line[256]; char buf[256]; register char *out = cmd_line; char *cp; register char c; bpstat bpstat; int brkno; extern char *finish_command_input(); while (c = *command++) { if (c == '%') { switch (*command++) { case 's': /* current selection */ out = append_selection(out); break; case 'S': /* 1st selected "word" at curor */ out = append_selection_word(out); break; case 'e': /* echo cmd before executing */ break; case 'E': /* 1st selected expression at curor */ out = append_selection_expr(out); break; case 'l': /* current line number */ (void) sprintf(buf, "%d", current_lineno()); for (cp = buf; c = *cp++; *out++ = c) ; break; case 'L': /* line we're stopped at */ (void) sprintf(buf, "%d", source_window_line);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -