📄 datadpy.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 * *****************************************************************************//* dataDpy.c: * * Provide graphical display of C pointers and structures. * * BuildLinePos(): Construct an array indexing the character position of * each line. * PositionToLine(): Return the character position of a given line. * SelectPointer(): Action proc for double click on a pointer value, * CreateDataPopup(): Create a popup to display the object pointed to by a * pointer. * UpdateDataPopup(): Update an unused popupshell to display data. * AppendList(): Append a popup to the list. * DeleteList(): Delete a popup from the list. * pop_down(): pop down the popup and free storage. * DestroyDataPopup():event handler for destroying a popup, call DeleteList() * and pop_down() (CRL mod 25) * MovePopup(): Position the popup. * print_handler(): Action handler for displaying pointers and structures. *//* * 01FEB94: bugs fixed (klamer) * xxgdb does not allow the graphically displaying of members of parents * from a class. * xxgdb does not allow the graphically displaying of data through a * reference. */#include <string.h>#include "global.h"#include "regex.h"#include "datadpy.h"#define MAXLEVELS 20 /* max level of indentation */#ifdef GDB#define INDENT 2 /* # of spaces for each indentation */#else#define INDENT 8 /* # of spaces for each indentation */#endif /* GDB */#define EMPTY 0#define UNUSED 1#define USED 2#define LEFT_MARGIN 10#define SCROLLBAR_WIDTH 15static DataDpyRec **dataDpyTable;static int dataDpyTableSize = 0;static DataDpyRec *Parent = NULL;static DataDpyList *TopParentList = NULL;static int font_height, font_width;#ifdef OBSOLETEstatic void DestroyDataPopup();#else/* CRL mod 25 4/12/91 GWC - changed label widget to command widget in popups */static void DestroyDataCallback();#endif/* * Build an array which gives the starting text position of each line. * Very similar to the routine in source.c. */static void BuildLinePos(dataDpy)DataDpyRec *dataDpy;{ char *p; int line, nlines; int max=0; nlines = MAX(1, dataDpy->buflen/CHARS_PER_LINE); dataDpy->linepos = (XawTextPosition *) XtMalloc ((nlines+2) * sizeof(XawTextPosition)); p = dataDpy->buf; line = 0; dataDpy->linepos[line++] = 0; dataDpy->linepos[line++] = 0; while (*p) { if (*p++ == '\n') { if (line == nlines) { /* buffer full, need more memory */ dataDpy->linepos = (XawTextPosition *)XtRealloc( (void*)dataDpy->linepos, (nlines + ADD_LINES) * sizeof(XawTextPosition)); nlines += ADD_LINES; } dataDpy->linepos[line] = p - dataDpy->buf; AssignMax(max, dataDpy->linepos[line] - dataDpy->linepos[line-1]); line++; } } dataDpy->numlines = line - 2; dataDpy->maxLineLength = max; /* shrink to min size */ dataDpy->linepos = (XawTextPosition *) XtRealloc ((void*)dataDpy->linepos, line * sizeof(XawTextPosition));}/* * Return the line number for the specified text position. */static int PositionToLine(dataDpy, pos)DataDpyRec *dataDpy;XawTextPosition pos;{ int line; if (dataDpy && pos >= 0) { for (line = 1; pos >= dataDpy->linepos[line]; line++); return (line-1); } else return (0);}/* ARGSUSED *//* * Called by double click of pointer button. * If the selected text is a valid pointer, this routine parses the data * output to obtain the full qualified name of the pointer, and asks * dbx to print the value of the object the pointer is pointing to. */static void SelectPointer(w, event, params, num_params) Widget w; XEvent *event; String *params; Cardinal *num_params;{#ifndef GDB struct re_registers regs; char *field[MAXLEVELS]; int line, n, r, level, newlevel; char name[LINESIZ];#endif XawTextPosition left, right; char *selection, *p; DataDpyRec *dataDpy; int fromLine; int i, nbytes; char command[LINESIZ]; /* Find out which data display output does the selection belong to */ dataDpy = NULL; for (i=0; dataDpyTable[i]; i++) if ((Widget) w == (Widget) dataDpyTable[i]->dataDpyWindow) { dataDpy = dataDpyTable[i]; Parent = dataDpy; break; } if (!dataDpy) return; /* Get the selection and check if it's a pointer value, 0x???? */ selection = XFetchBytes(display, &nbytes); if (re_match(dataPattern[D_POINTER].buf, selection, strlen(selection), 0, 0) < 0) { Parent = NULL; return; } /* Parse the output to get the fully qualified name of the pointer */ XawTextGetSelectionPos(w, &left, &right); fromLine = PositionToLine(dataDpy, left); p = dataDpy->buf + dataDpy->linepos[fromLine];#ifdef GDB /* (PW) we now use a new parser which should work better, in particular for arrays */ { char *parse_gdb_print(); char *newcommand; newcommand = parse_gdb_print(command, dataDpy->buf, dataDpy->buf + left ); if (*newcommand) { if (strchr(selection, '@')) { char *p = strchr(newcommand, '*'); if (p != 0) *p = ' '; } PopupMode = True; query_gdb(newcommand, PARSE_ON | ECHO_OFF | FILTER_OFF); } }#else /* not GDB */ if (re_match(dataPattern[D_FIELD].buf, p, strlen(p), 0, ®s) >= 0) { r = dataPattern[D_FIELD].reg_token[TK_POINTER]; if (strncmp(selection, p+regs.start[r], regs.end[r]-regs.start[r])) return; r = dataPattern[D_FIELD].reg_token[TK_INDENT]; level = regs.end[r]/INDENT; field[level+1] = NULL; r = dataPattern[D_FIELD].reg_token[TK_FIELD]; n = regs.end[r] - regs.start[r]; field[level] = (char *) XtMalloc ((n+1) * sizeof(char)); strncpy(field[level], p+regs.start[r], n); field[level][n] = '\0'; for (line = fromLine-1; line > 0; line--) { p = dataDpy->buf + dataDpy->linepos[line]; if (re_match(dataPattern[D_STRUCT].buf, p, strlen(p), 0, ®s)>=0){ r = dataPattern[D_STRUCT].reg_token[TK_INDENT]; newlevel = regs.end[r]/INDENT; if (newlevel == level-1) { level--; r = dataPattern[D_STRUCT].reg_token[TK_FIELD]; n = regs.end[r] - regs.start[r]; field[level] = (char *) XtMalloc ((n+1) * sizeof(char)); strncpy(field[level], p+regs.start[r], n); field[level][n] = '\0'; } } } if (*field[0] == '*' && field[1]) sprintf(name, "(%s)", field[0]+1); else strcpy(name, field[0]); for (i=1; field[i]; i++) { strcat(name, "."); strcat(name, field[i]); } sprintf(command, "print *(%s)\n", name); PopupMode = True;#ifdef GDB query_gdb(command, PARSE_ON | ECHO_OFF | FILTER_OFF);#else query_dbx(command);#endif /* GDB */ }#endif /* GDB */} /* * Create a data display with a label. * The popupshell has a form widget which consists of a label and a text * widget. */static void CreateDataPopup(dataDpy, label)DataDpyRec *dataDpy;char *label;{ Arg args[MAXARGS]; Cardinal n; Dimension dataDpyHeight, dataDpyWidth; XFontStruct *text_font; static XtActionsRec datadpy_actions[] = { {"SelectPointer", (XtActionProc) SelectPointer}, {NULL, NULL} }; static String translations = "#override \n\ <Btn1Down>: SelectStart() SelectWord() SelectPointer() \n\ <Btn1Up>: SelectEnd() \n\ "; n = 0; dataDpy->popupshell = XtCreatePopupShell("Data Popup", transientShellWidgetClass, toplevel, args, n); n = 0; XtSetArg(args[n], XtNdefaultDistance, 0); n++; dataDpy->popup = XtCreateManagedWidget("popup", formWidgetClass, dataDpy->popupshell, args, n); /* Create the label */ n = 0; XtSetArg(args[n], XtNtop, (XtArgVal) XawChainTop); n++; XtSetArg(args[n], XtNbottom, (XtArgVal) XawChainTop); n++; XtSetArg(args[n], XtNright, (XtArgVal) XawChainRight); n++; XtSetArg(args[n], XtNleft, (XtArgVal) XawChainLeft); n++; XtSetArg(args[n], XtNlabel, (XtArgVal) label); n++; XtSetArg(args[n], XtNresize, (XtArgVal) False); n++; XtSetArg(args[n], XtNjustify, (XtArgVal) XtJustifyCenter); n++;#ifdef OBSOLETE dataDpy->label = XtCreateManagedWidget("label", labelWidgetClass, dataDpy->popup, args, n);/* GWC says it is better to use ButtonReleaseMask instead of ButtonPressMask.*/ XtAddEventHandler(dataDpy->label, (EventMask) ButtonPressMask, False, DestroyDataPopup, dataDpy);#else/* CRL mod 25 4/12/91 GWC - changed label widget to command widget inpopups */ dataDpy->label = XtCreateManagedWidget("command", commandWidgetClass, dataDpy->popup, args, n); XtAddCallback(dataDpy->label, XtNcallback, DestroyDataCallback, dataDpy);#endif /* Create the text window */ n = 0; XtSetArg(args[n], XtNfromVert, (XtArgVal) dataDpy->label); n++; XtSetArg(args[n], XtNtop, (XtArgVal) XawChainTop); n++; XtSetArg(args[n], XtNbottom, (XtArgVal) XawChainBottom); n++; XtSetArg(args[n], XtNright, (XtArgVal) XawChainRight); n++; XtSetArg(args[n], XtNleft, (XtArgVal) XawChainLeft); n++; XtSetArg(args[n], XtNleftMargin, (XtArgVal) LEFT_MARGIN); n++; XtSetArg(args[n], XtNuseStringInPlace, (XtArgVal) True); n++; XtSetArg(args[n], XtNstring, (XtArgVal) dataDpy->buf); n++; XtSetArg(args[n], XtNlength, (XtArgVal) dataDpy->buflen); n++; XtSetArg(args[n], XtNeditType, (XtArgVal) XawtextRead); n++; XtSetArg(args[n], XtNscrollHorizontal, XawtextScrollWhenNeeded); n++; XtSetArg(args[n], XtNscrollVertical, XawtextScrollWhenNeeded); n++; XtSetArg(args[n], XtNtranslations, XtParseTranslationTable(translations)); n++; dataDpy->dataDpyWindow = XtCreateManagedWidget("dataDpyWindow", asciiTextWidgetClass, dataDpy->popup, args, n); XtAppAddActions(app_context, datadpy_actions, XtNumber(datadpy_actions)); /* Get the text font */ n = 0; XtSetArg(args[n], XtNfont, &text_font); n++; XtGetValues(dataDpy->dataDpyWindow, args, n); /* Estimate the size of the text widget, dataDpyWindow, with the number of lines and the maximum length of a line. Assume fixed font width. */ font_height = text_font->ascent + text_font->descent; font_width = text_font->max_bounds.width; dataDpyHeight = dataDpy->numlines * font_height + 5; dataDpyWidth = dataDpy->maxLineLength * font_width + LEFT_MARGIN; if (dataDpyHeight > app_resources.dataDpyMaxHeight) dataDpyWidth += SCROLLBAR_WIDTH; #if 1 /*(PW)17DEC90 : bug ! */#define SCROLLBAR_HEIGHT 15 if (dataDpyWidth > app_resources.dataDpyMaxWidth) dataDpyHeight += SCROLLBAR_HEIGHT;#endif AssignMin(dataDpyHeight, app_resources.dataDpyMaxHeight); AssignMin(dataDpyWidth, app_resources.dataDpyMaxWidth); n = 0; XtSetArg(args[n], XtNheight, (XtArgVal) dataDpyHeight); n++; XtSetArg(args[n], XtNwidth, (XtArgVal) dataDpyWidth); n++; XtSetValues(dataDpy->dataDpyWindow, args, n); n = 0; XtSetArg(args[n], XtNwidth, (XtArgVal) dataDpyWidth); n++; XtSetValues(dataDpy->label, args, n);}/* * Instead of creating a new popupshell, this routine uses an already * existing popupshell for data display. * It changes the label, calculates the size of the popupshell, * and sets the source of the text window to that of the new data. */static void UpdateDataPopup(dataDpy, label)DataDpyRec *dataDpy;char *label;{ Arg args[MAXARGS]; Cardinal n; Dimension popupHeight, popupWidth, dataDpyHeight, dataDpyWidth, labelHeight, labelBorderWidth, dataDpyBorderWidth; /* Update the label */ n = 0; XtSetArg(args[n], XtNlabel, (XtArgVal) label); n++; XtSetValues(dataDpy->label, args, n); /* Calculate the size of popupshell */ dataDpyHeight = dataDpy->numlines * font_height + 5; dataDpyWidth = dataDpy->maxLineLength * font_width + 2*10; #if 1 /*(PW)18DEC90 : bug ! */ if (dataDpyHeight > app_resources.dataDpyMaxHeight) dataDpyWidth += SCROLLBAR_WIDTH; if (dataDpyWidth > app_resources.dataDpyMaxWidth) dataDpyHeight += SCROLLBAR_HEIGHT;#endif AssignMin(dataDpyHeight, app_resources.dataDpyMaxHeight); AssignMin(dataDpyWidth, app_resources.dataDpyMaxWidth); n = 0; XtSetArg(args[n], XtNheight, (XtArgVal) &labelHeight); n++; XtSetArg(args[n], XtNborderWidth, (XtArgVal) &labelBorderWidth); n++; XtGetValues(dataDpy->label, args, n); n = 0; XtSetArg(args[n], XtNborderWidth, (XtArgVal) &dataDpyBorderWidth); n++; XtGetValues(dataDpy->dataDpyWindow, args, n); popupHeight = dataDpyHeight + labelHeight + 2*labelBorderWidth + 2*dataDpyBorderWidth; popupWidth = dataDpyWidth; n = 0; XtSetArg(args[n], XtNheight, (XtArgVal) popupHeight); n++; XtSetArg(args[n], XtNwidth, (XtArgVal) popupWidth); n++; XtSetValues(dataDpy->popupshell, args, n); /* Set the text source */ n = 0; XtSetArg(args[n], XtNstring, (XtArgVal) dataDpy->buf); n++; XtSetArg(args[n], XtNlength, (XtArgVal) dataDpy->buflen); n++; XawTextSetSource(dataDpy->dataDpyWindow, XtCreateWidget("textsrc", asciiSrcObjectClass, dataDpy->dataDpyWindow, args, n), 0);}/* * Append dataDpy to a DataDpyList pointed to by head. */static void AppendList(head, dataDpy)DataDpyList **head;DataDpyRec *dataDpy;{ DataDpyList *p, *q, *r; p = (DataDpyList *) XtNew (DataDpyList); p->dataDpy = dataDpy; p->next = NULL; q = *head; if (!q) *head = p; else { while ((r = q->next)) q = r; q->next = p; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -