pierre@tce.COM (Pierre Willard) (03/07/91)
Submitted-by: pierre@tce.COM (Pierre Willard) Posting-number: Volume 11, Issue 51 Archive-name: xxgdb/part04 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 6 (of 8)." # Contents: gdb_regex.h source.c # Wrapped by gilbert@phi on Tue Jan 15 13:12:49 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'gdb_regex.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gdb_regex.h'\" else echo shar: Extracting \"'gdb_regex.h'\" \(16887 characters\) sed "s/^X//" >'gdb_regex.h' <<'END_OF_FILE' X/***************************************************************************** X * X * xdbx - X Window System interface to the dbx debugger X * X * Copyright 1989 The University of Texas at Austin X * Copyright 1990 Microelectronics and Computer Technology Corporation X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of The University of Texas X * and Microelectronics and Computer Technology Corporation (MCC) not be X * used in advertising or publicity pertaining to distribution of X * the software without specific, written prior permission. The X * University of Texas and MCC makes no representations about the X * suitability of this software for any purpose. It is provided "as is" X * without express or implied warranty. X * X * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO X * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR X * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X * X * Author: Po Cheung X * Created: March 10, 1989 X * X ***************************************************************************** X * X * xxgdb - X Window System interface to the gdb debugger X * X * Copyright 1990 Thomson Consumer Electronics, Inc. X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of Thomson Consumer X * Electronics (TCE) not be used in advertising or publicity pertaining X * to distribution of the software without specific, written prior X * permission. TCE makes no representations about the suitability of X * this software for any purpose. It is provided "as is" without express X * or implied warranty. X * X * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT X * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES X * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS X * SOFTWARE. X * X * Adaptation to GDB: Pierre Willard X * XXGDB Created: December, 1990 X * X *****************************************************************************/ X X/* X * gdb_regex.h: X * X * Regular expression pattern matching for GNU gdb. X * X * The reg_token array indicates the register no. for each token type. X * reg_token[0] : message X * reg_token[1] : stop number X * reg_token[2] : function name X * reg_token[3] : line number X * reg_token[4] : file name X * reg_token[5] : display command output X */ X X#define TK_MESG 0 X#define TK_STOP 1 X#define TK_FUNC 2 X#define TK_LINE 3 X#define TK_FILE 4 X#define TK_DISP 5 X X#define O_EXEC_MESS_AFTER 0 X#define O_EXEC_MESS_BEFORE 1 X#define O_EXEC 2 X#define O_DONE 3 X#define O_BREAK 4 /* Instead of O_STOPAT & O_STOPIN */ X#define O_INFO_DIR 5 /* NEW for GDB */ X#define O_FRAME_CURR 6 /* O_FRAME_CURR = O_UPDOWN */ X#define O_UPDOWN 6 X#define O_BELL 7 X#define O_SEARCH 8 X#define O_INFO_LINE 9 /* Instead of O_FILE */ X#define O_PRINT 10 X#define O_DEBUG 11 X#define O_DIRECTORY 12 X#define O_LIST 13 /* for dbx, O_LIST = O_SEARCH */ X#define O_DISPLAY 14 X#define O_DISPLAY_INFO 15 X#define O_PWD 16 X#define O_CD 16 /* O_PWD = O_CD */ X#define O_RECEIVED_SIGNAL 17 /* test program received signal */ X#define O_EXEC_DISPLAY 18 /* special for filter_display_info */ X#define O_READING_SYMBOLS 19 /* special for filter_reading_symbols */ X X X#define C_ANY -1 X#define C_EXEC 0 X#define C_BREAK 1 /* Instead of C_STOPAT & C_STOPIN */ X#define C_INFO_DIR 2 /* NEW for GDB */ X#define C_FRAME_CURR 3 X#define C_UPDOWN 4 X#define C_DELETE 5 X#define C_FINISH 6 /* Instead of C_FUNC */ X#define C_INFO_LINE 7 /* Instead of C_FILE */ X#define C_SYMBOL_FILE 8 X#define C_CD 9 X#define C_DIRECTORY 10 /* Instead of C_USE */ X#define C_PWD 11 X#define C_LIST 12 X#define C_SEARCH 13 X#define C_DISPLAY_INFO 14 /* must be BEFORE C_DISPLAY ! */ X#define C_DISPLAY 15 X#define C_UNDISPLAY 16 X#define C_PRINT 17 X#define C_INFO_BREAK 18 X#define C_SOURCE 19 X#define C_EXEC_FILE 20 X X/*--------------------------------------------------------------------------+ X| | X| DBX | X| | X| Reading symbolic information... | X| Read 46 symbols | X| (dbx) | X| (dbx) | X| stopped in main at line 5 in file "pw.c" | X| 5 for (i=0; i<100; i++) | X| (dbx) use | X| /usr1/gnu_sun4/xdbx/ | X| (dbx) file | X| pw.c | X| (dbx) file | X| No current source file | X| | X+--------------------------------------------------------------------------*/ X/*--------------------------------------------------------------------------+ X| | X| GDB | X| | X| Reading symbol data from /usr1/gnu_sun4/xdbx/pw...done. | X| Type "help" for a list of commands. | X| (gdb) | X| (gdb) | X| Bpt 1, main () (pw.c line 5) | X| 5 for (i=0; i<100; i++) | X| (gdb) info directories | X| Source directories searched: /usr1/gnu_sun4/xdbx:/usr1/toto | X| (gdb) info line | X| Line 10 of "pw.c" starts at pc 0x22dc and ends at 0x22e4. | X| (gdb) info line | X| No source file specified. | X| | X+--------------------------------------------------------------------------*/ X/*--------------------------------------------------------------------------+ X| | X| GDB -fullname | X| | X| | X| We use option -fullname (see dbxoptions() in xdbx.c). | X| | X| GDB prints (see source.c of gdb): | X| | X| "\032\032%s:%d:%d:%s:0x%x\n", s->fullname, | X| line, s->line_charpos[line - 1], | X| mid_statement ? "middle" : "beg", | X| get_frame_pc (get_current_frame())); | X| | X| (gdb) break main | X| Reading in symbols for pw.c...done. | X| Breakpoint 1 at 0x229c: file pw.c, line 5. | X| (gdb) run | X| Starting program: /usr1/gnu_sun4/xdbx/pw | X| | X| Bpt 1, main () (pw.c line 5) | X| /usr1/gnu_sun4/xdbx/pw.c:5:17:beg:0x229c | X| (gdb) step | X| /usr1/gnu_sun4/xdbx/pw.c:6:40:beg:0x22b0 | X| (gdb) | X| | X| (gdb) info directories | X| Source directories searched: /usr1/gnu_sun4/xdbx | X| (gdb) info line | X| Line 10 of "pw.c" starts at pc 0x22dc and ends at 0x22e4. | X| (gdb) info line | X| No source file specified. | X| (gdb) info line | X| Line number 34 is out of range for "bug1.c". | X| | X| (gdb) display i | X| 3: i = 0 | X| (gdb) display | X| 4: i + 1 = 1 | X| 3: i = 0 | X| (gdb) undisplay 2 | X| (gdb) display | X| (gdb) | X| | X| (gdb) up | X| #2 0x2314 in main () (pw.c line 35) | X| /usr1/gnu_sun4/xdbx/pw.c:35:158:beg:0x2360 | X| (gdb) up | X| Initial frame selected; you cannot go up. | X| (gdb) | X| | X| (gdb) down | X| #0 glop (number=1) (pw2.c line 5) | X| /usr1/gnu_sun4/xdbx/pw2.c:5:33:beg:0x2360 | X| (gdb) down | X| Bottom (i.e., innermost) frame selected; you cannot go down. | X| (gdb) | X| | X| (gdb) pwd | X| Working directory /usr1/gnu_sun4/xdbx. | X| (gdb) cd .. | X| Working directory /usr1/gnu_sun4. | X| (gdb) cd xdbx | X| Working directory /usr1/gnu_sun4/xdbx. | X| (gdb) cd toto | X| toto: No such file or directory. | X| (gdb) | X| | X| Program exited with code 01. | X| (gdb) | X| | X+--------------------------------------------------------------------------*/ X/* X X . --> any character but '\n' X * --> any character 0 to n times X + --> any character 1 to n times X ? --> any character 0 or 1 time X ^ --> begin of line or NOT following character X $ --> end of line or '$' X \\w --> character '0..9a..zA...Z' X \\W --> character NOT '0..9a..zA...Z' X \\< --> word begin (word is composed of 0..9a..zA...Z) X \\> --> word end (word is composed of 0..9a..zA...Z) X \\b --> word bound X \\B --> not word bound X \\| --> means OR X \\` --> begin buffer X \\\' --> end buffer X X X>> WARNING : be carefull with \\| (OR) : the re_match() function X>> will NOT correctly update the string for a pattern which is X>> optional ! X>> --> The number SHOULD NOT point to a patterm which is optional ! X X*/ X X /* (PW)5DEC90: I have a problem if we say \\(Bpt.*\n\\)? in exec pattern. X That is why I have two cases : with or without Bpt... X Note that 'exec without Message' includes 'exec with Message'. X We display 'Bpt...' in the message window. */ X X /* (PW)14JAN91 (v1.01) : use X \\(\\([0-9]+:.*\n\\(\\( .*\n\\)*}\n\\)?\\)*\\) X instead of X \\(\\([0-9]+:.*\n\\)*\\) X for display pattern. X */ X X Xstatic PatternRec output_pattern[] = { X /* exec with Message after */ X {"\\(.*\n\\)*\032\032\\([^ ]+\\):\\([0-9]+\\):\\([0-9]+\\):\\([^ ]+\\):0x.+\n\\([ ]*[^0-9].*\n\\)\\(\\([0-9]+:.*\n\\(\\( .*\n\\)*}\n\\)?\\)*\\)", X NULL, X {6, -1, -1, 3, 2, 7} X }, X /* exec with Message before */ X {"\\(.*\n\\)*\\([ ]*[^ ].*\n\\)\032\032\\([^ ]+\\):\\([0-9]+\\):\\([0-9]+\\):\\([^ ]+\\):0x.+\n\\(\\([0-9]+:.*\n\\(\\( .*\n\\)*}\n\\)?\\)*\\)", X NULL, X {2, -1, -1, 4, 3, 7} X }, X /* exec without Message */ X {"\\(.*\n\\)*\032\032\\(\\([^ ]+\\):\\([0-9]+\\):\\([0-9]+\\):\\([^ ]+\\):0x.+\n\\)\\(\\([0-9]+:.*\n\\(\\( .*\n\\)*}\n\\)?\\)*\\)", X NULL, X {2, -1, -1, 4, 3, 7} X }, X /* done */ X {"\\(.*\n\\)*\n\\(Program terminated with signal \\|Program exited with code 0\\|Program exited normally\\).*\n\\(.*\n\\)*", X NULL, X {-1, -1, -1, -1, -1, -1} X }, X /* break */ X {"\\(.*\n\\)*Breakpoint \\([0-9]+\\) at [^ ]+: file \\([^ ]+\\), line \\([0-9]+\\).\n", X NULL, X {-1, 2, -1, 4, 3, -1} X }, X /* info directories */ X {"Source directories searched:[ ]*\\([^ ]+\\)[ ]*\n", X NULL, X { -1, -1, -1, -1, 1, -1} X }, X /* up, down */ X {"\\(.*\n\\)*\\(#[0-9]+[ ]+\\(0x[^ ]+[ ]+in[ ]+\\)?\\([^ ]+\\).*\n\\)\\(Source file is more recent than executable.\n\\)?\032\032\\([^ ]+\\):\\([0-9]+\\):\\([0-9]+\\):\\([^ ]+\\):0x.+\n", X NULL, X {2, -1, 4, 7, 6, -1} X }, X /* bell */ X {"\\(Undefined command: .*\n\\|Already at the \\(top\\|bottom\\) call level\n\\|\ XNo active stack frames\n\\|no program to run\n\\|no process to run\n\\|\ Xprogram is not active\n\\|can't continue execution\n\\|\ X.*\ncan't write to process.*\n\\|\ X\\(Top\\|End\\)-of-file; did not find search string:.*\n\\)", X NULL, X {-1, -1, -1, -1, -1} X }, X /* search */ X {"\\([0-9]+\\).*\n", X NULL, X {-1, -1, -1, 1, -1, -1} X }, X /* info line */ X {"\\(Line \\(number \\)?[0-9]+ \\(of\\|is out of range for\\) \"\\([^ ]+\\)\".*\\)\n", X NULL, X {-1, -1, -1, -1, 4, -1} X }, X /* print */ X {"\\(warning: .*\n\\)?\\(\\(.*\\) = .*\n\\(.*\n\\)*\\)", X NULL, X { 3, -1, -1, -1, -1, 2} X }, X /* start gdb (debug) */ X {"\\(.*\n\\)*Type \"help\" for a list of commands.\n", X NULL, X { -1, -1, -1, -1, -1, -1} X }, X /* directory */ X {"\\([^ ]+ is already in the source path.[ ]*\n\\)*Source directories searched:[ ]*\\([^ ]+\\)[ ]*\n", X NULL, X { -1, -1, -1, -1, 1, -1} X }, X /* list */ X {"\\(.*\n\\)*\\(\\([0-9]+\\).*\n\\)", X NULL, X { -1, -1, -1, 3, -1, -1} X }, X /* display */ X {"\\([0-9]+:.*\n\\)", X NULL, X { -1, -1, -1, -1, -1, 1} X }, X /* info display */ X {"\\(\\([0-9]+:.*\n\\(\\( .*\n\\)*}\n\\)?\\)*\\)", X NULL, X { -1, -1, -1, -1, -1, 1} X }, X /* pwd or cd */ X {"Working directory[ ]+\\([^ ]+\\).[ ]*\n\\([ ]*(canonically[ ]+\\([^ ]+\\)).\n\\)?", X NULL, X { 1, -1, -1, -1, -1, 3} X }, X /* program received signal */ X {"\\(.*\n\\)*\n\\(Program received signal \\([-]?[0-9]+\\), [^ ]+.*\n\\)\\(.*\n\\)*", X NULL, X { 2, 3, -1, -1, -1, -1} X }, X /* special for test in filter_display_info() */ X {"\\([^0-9].*\n\\)*\\([0-9]+:.*\n\\)\\(.*\n\\)*", X NULL, X { -1, -1, -1, -1, -1, 2} X }, X /* special for test in filter_reading_symbols() */ X {"\\(.*\n\\)*\\(Reading in symbols for .*done.\n\\)\\(.*\n\\)*", X NULL, X { 2, -1, -1, -1, -1, -1} X }, X NULL X}; X X/* X X To simplify the patterns, I used for example : X X "fr[ame]*" instead of "frame\\|fram\\|fra||fr". X X This will cause 'frmeame' to be accepted. But this is X no problem because 'Undefined command' output is parsed X before parsing the command line (see parse() in parser.c). X*/ X Xstatic PatternRec command_pattern[] = { X /* run -r - cont - c - next - n - step - s - nexti - ni - stepi - si - return X jump - until - u */ X {"[ ]*\\(run\\|r\\|cont\\|c\\|next\\|n\\|step\\|s\\|nexti\\|stepi\\|ni\\|si\\|ret[urn]*\\|j[ump]*\\|unt[il]*\\|u\\)\\( .*\\)?\n", X NULL, {-1, -1, -1, -1, -1, -1}}, X /* break - tbreak */ X {"[ ]*\\(t\\)?\\(b\\|br\\|bre\\|brea\\|break\\)\\( .*\\)?\n", X NULL, {-1, -1, -1, -1, -1, -1}}, X {"[ ]*info[ ]+directories[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* 'frame' is special case of 'frame n' since it does not change the X current frame. Else 'frame n' is like up or down. */ X {"[ ]*fr[ame]*[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X {"[ ]*\\(up\\|down\\|dow\\|do\\|fr[ame]*\\)\\( .*\\)?\n", X NULL, {-1, -1, -1, -1, -1, -1}}, X X /* delete - d - clear - enable - disable - dis - disa */ X /* gdb commands 'delete display' 'enable display' and 'delete environment' X are also found here. This is superfluous, but no problem */ X X {"[ ]*\\(del[ete]*\\|d\\|cl[ear]*\\|en[able]*\\|disab[le]*\\|dis\\|disa\\)\\( .*\\)?\n", X NULL, {-1, -1, -1, -1, -1, -1}}, X X {"[ ]*fi[nish]*[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X {"[ ]*info[ ]+line[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* symbol-file */ X {"[ ]*sy.*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X {"[ ]*cd[ ]*[^ ]+[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* directory */ X {"[ ]*dir.*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X {"[ ]*pwd[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X /* list */ X {"[ ]*l.*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* forward-search or reverse-search or search */ X X {"[ ]*\\(fo[rward-search]*\\|rev[erse-search]*\\|sea[rch]*\\)[ ]*", X NULL, {-1, -1, -1, -1, -1, -1}}, X X /* 'display' is a special case of 'display exp' since it does not X add any expression to be displayed */ X {"[ ]*disp[lay]*[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X {"[ ]*disp[lay]\\(/[^ ]+\\)?*[ ]*[^ ]+[ ]*.*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* undisplay */ X {"[ ]*und.*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* Note that Token.mesg (if any) is updated with print command (see 1) */ X X {"[ ]*print[ ]*\\([^ ]?\\([ ]+[^ ]+\\)*\\)[ ]*\n", NULL, { 1, -1, -1, -1, -1, -1}}, X {"[ ]*info[ ]+break[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* source (note that Token.TK_FILE is updated here) */ X {"[ ]*so[urce]*[ ]*\\(.*\\)\n", NULL, {-1, -1, -1, -1, 1, -1}}, X X /* exec-file (just used internally) */ X {"[ ]*exec-file .*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X NULL X}; END_OF_FILE if test 16887 -ne `wc -c <'gdb_regex.h'`; then echo shar: \"'gdb_regex.h'\" unpacked with wrong size! fi # end of 'gdb_regex.h' fi if test -f 'source.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'source.c'\" else echo shar: Extracting \"'source.c'\" \(21173 characters\) sed "s/^X//" >'source.c' <<'END_OF_FILE' X/***************************************************************************** X * X * xdbx - X Window System interface to the dbx debugger X * X * Copyright 1989 The University of Texas at Austin X * Copyright 1990 Microelectronics and Computer Technology Corporation X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of The University of Texas X * and Microelectronics and Computer Technology Corporation (MCC) not be X * used in advertising or publicity pertaining to distribution of X * the software without specific, written prior permission. The X * University of Texas and MCC makes no representations about the X * suitability of this software for any purpose. It is provided "as is" X * without express or implied warranty. X * X * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO X * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR X * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X * X * Author: Po Cheung X * Created: March 10, 1989 X * X ***************************************************************************** X * X * xxgdb - X Window System interface to the gdb debugger X * X * Copyright 1990 Thomson Consumer Electronics, Inc. X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of Thomson Consumer X * Electronics (TCE) not be used in advertising or publicity pertaining X * to distribution of the software without specific, written prior X * permission. TCE makes no representations about the suitability of X * this software for any purpose. It is provided "as is" without express X * or implied warranty. X * X * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT X * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES X * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS X * SOFTWARE. X * X * Adaptation to GDB: Pierre Willard X * XXGDB Created: December, 1990 X * X *****************************************************************************/ X X/* source.c X * X * Create the source window and handle display of file. X * X * source_init(): Initialization routine. X * Update(): Action proc to update source window on scrollbar action. X * NotifyResize(): Action proc to update source window on resize. X * CreateSourceWindow(): Create the source window. X * BuildLinePos(): Build an array of starting text position of each line. X * LookUpFileTable():Check out source file info from a file table. X * SaveDisplayedFileInfo(): records displayed file info into file table. X * DisplayFile(): Display a file on the source window X * LoadFile(): Search for a file and open it for display. X */ X X#include <X11/Xos.h> X#include <sys/stat.h> X#include <pwd.h> X#include "global.h" X X#define MAXDIRS 256 /* max number of dirs in dirList */ X Xchar CurrentFile[MAXNAME]; /* current contents of file variable */ XWidget sourceForm, /* parent of sourceWindow */ X sourceWindow; /* text window for source file */ XFileRec *displayedFile; /* pointer to table entry of currently X displayed file */ X Xstatic FileRec **fileTable; /* table of file records */ Xstatic int fileTableSize; /* size of file table */ Xstatic char *dirList[MAXDIRS]; /* list of dirs for searching files */ X Xvoid source_init() X{ X dirList[0] = NULL; X} X X/* X * Update topline, bottomline, arrow sign, updown sign, stop signs, and X * line label. X */ X/* ARGSUSED */ Xvoid Update(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition pos; X int topline; X FileRec *file; X X if (displayedFile) { X file = displayedFile; X pos = XawTextTopPosition(sourceWindow); X file->topPosition = pos; X topline = TextPositionToLine(pos); X /* Update the symbols only if the text scrolls */ X if (file->topline != topline) { X file->topline = topline; X file->bottomline = MIN (file->topline + file->lines - 1, X file->lastline); X XawTextSetInsertionPoint(sourceWindow, file->linepos[file->topline]); X UpdateLineLabel(file->topline); X UpdateStops(file); X UpdateArrow(file); X UpdateUpdown(file); X UpdateBomb(file); X } X else {/* Update caret position only */ X pos = XawTextGetInsertionPoint(sourceWindow); X UpdateLineLabel(TextPositionToLine(pos)); X } X } X} X X/* X * Update bottomline, arrow sign, updown sign and stop signs on resize. X * Invoked by ConfigureNotify event. X */ X/* ARGSUSED */ Xstatic void NotifyResize(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition pos; X TextWidget ctx = (TextWidget) sourceWindow; X FileRec *file; X X if (file = displayedFile) { X file->lines = ctx->text.lt.lines; X pos = XawTextTopPosition(sourceWindow); X file->topline = TextPositionToLine(pos); X file->bottomline = MIN (file->topline + file->lines - 1, X file->lastline); X UpdateStops(file); X UpdateArrow(file); X UpdateUpdown(file); X UpdateBomb(file); X } X} X X/* Update the position of the caret */ X/* ARGSUSED */ X#ifdef notdef Xvoid UpdateLine(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition pos; X int line; X X pos = XawTextGetInsertionPoint(w); X line = TextPositionToLine(pos); X UpdateLineLabel(line); X} X#endif X X/* My select-start routine that cancels the effect of automatic scrolling X * near the bottom of an Athena text widget window. X */ X/* ARGSUSED */ Xvoid SelectStart(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition topPosition; X X /* remember the top display position before automatic scrolling */ X /* displayedFile->topPosition = XawTextTopPosition(w); */ X topPosition = XawTextTopPosition(w); X X XtCallActionProc(w, "select-start", event, params, num_params); X X /* reset to remembered position if top position changed */ X /* if (XawTextTopPosition(w) != displayedFile->topPosition) X TextSetTopPosition(w, displayedFile->topPosition); */ X if (XawTextTopPosition(w) != topPosition) X TextSetTopPosition(w, topPosition); X} X X/* My select-end routine to store the text selection into both the PRIMARY X * selection and cut buffer 0. X */ X/* ARGSUSED */ Xvoid SelectEnd(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition begin, end, start; X Widget textsrc; X XawTextBlock buffer; X char s[10000]; X int nchars; X X XawTextGetSelectionPos(w, &begin, &end); X XawTextSetSelection(w, begin, end); X if (begin == end) return; X textsrc = XawTextGetSource(w); X strcpy(s, ""); X for (start=begin, nchars=end-begin; nchars > 0; X start=begin+buffer.length, nchars-=buffer.length) { X XawTextSourceRead(textsrc, start, &buffer, nchars); X strncat(s, buffer.ptr, buffer.length); X } X XStoreBytes(display, s, strlen(s)); X} X X/* This is my own select word routine to replace the standard action X * procedure provided by the Text widget. X * It selects a word delimited by DELIMITERS, not whitespace. X */ X/* ARGSUSED */ Xvoid SelectWord(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition pos, left, right, start; X XawTextBlock buffer; X Widget textsrc; X char s[LINESIZ]; X char *p, *ls, *rs; X int nchars; X X pos = XawTextGetInsertionPoint(w); X textsrc = XawTextGetSource(w); X X XawTextSourceRead(textsrc, pos, &buffer, 1); X if (buffer.length == 0 || (buffer.length == 1 && X strchr(app_resources.delimiters, (int)*(buffer.ptr)) != NULL)) { X XStoreBytes(display, NULL, 0); X return; X } X X left = XawTextSourceScan(textsrc, pos+1, XawstWhiteSpace, XawsdLeft, 1, X FALSE); X right = XawTextSourceScan(textsrc, left, XawstWhiteSpace, XawsdRight, 1, X FALSE); X X strcpy(s, ""); X for (start=left, nchars=right-left; nchars > 0; X start=left+buffer.length, nchars-=buffer.length) { X XawTextSourceRead(textsrc, start, &buffer, nchars); X strncat(s, buffer.ptr, buffer.length); X } X X if (!strcmp(s, "")) return; X p = s+pos-left; X ls = (char *) strtok(s, app_resources.delimiters); X rs = (char *) strtok(NULL, app_resources.delimiters); X if (!ls) return; X while (rs<=p && rs!=NULL) { X ls = rs; X rs = (char *) strtok(NULL, app_resources.delimiters); X } X left = left + ls - s; X right = left + strlen(ls) - 1; X X XawTextUnsetSelection(w); X XStoreBytes(display, ls, strlen(ls)); X XawTextSetSelection(w, left, right+1); X} X X/* Print the value of the expression in cut buffer 0. */ X/* ARGSUSED */ Xvoid PrintSelection(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X char command[LINESIZ]; X char *string; X int nbytes; X X string = XFetchBytes(display, &nbytes); X if (nbytes == 0) { X UpdateMessageWindow(PRINT_HELP, NULL); X bell(0); X return; X } X sprintf(command, "print %s\n", string); X send_command(command); X AppendDialogText(command); X} X X/* X * On top of a form widget, we have a text widget with scrollbar, label X * widgets for the stop sign, arrow sign, and updown signs. X */ Xvoid CreateSourceWindow(parent) XWidget parent; X{ X TextWidget ctx; X Arg args[MAXARGS]; X Cardinal n; X X static XtActionsRec sbar_actions[] = { X {"NotifyResize", NotifyResize}, X {"Update", Update}, X {NULL, NULL} X }; X X static String sbarTranslations = "\ X <Configure>: NotifyResize() \n\ X <Btn2Down>: StartScroll(Continuous) MoveThumb() NotifyThumb() \ X Update() \n\ X <Btn2Motion>: MoveThumb() NotifyThumb() Update() \n\ X <BtnUp>: NotifyScroll(Proportional) EndScroll() Update() \n\ X "; X X n = 0; X XtSetArg(args[n], XtNdefaultDistance, 0); n++; X sourceForm = XtCreateManagedWidget("sourceForm", formWidgetClass, X parent, args, n); X X n = 0; X XtSetArg(args[n], XtNborderWidth, 0); n++; X XtSetArg(args[n], XtNtype, (XtArgVal)XawAsciiFile); n++; X XtSetArg(args[n], XtNstring, (XtArgVal)"/dev/null"); n++; X XtSetArg(args[n], XtNscrollVertical, (XtArgVal) XawtextScrollAlways);n++; X sourceWindow = XtCreateManagedWidget("sourceWindow", asciiTextWidgetClass, X sourceForm, args, n); X X ctx = (TextWidget) sourceWindow; X if (ctx->text.vbar) X XtOverrideTranslations(ctx->text.vbar, X XtParseTranslationTable(sbarTranslations)); X XtAppAddActions(app_context, sbar_actions, XtNumber(sbar_actions)); X} X X X/* X * Build the array which gives the starting text position of each line. X * > Estimate the number of lines in the file and allocate memory buffer. X * > Starting position of line #1 is 0, and is stored in linepos[1]. X * > Search for '\n' till end of buffer. X */ Xstatic void BuildLinePos(file) XFileRec *file; X{ X char *p; X int line, nlines; X X nlines = MAX(1, file->filesize/CHARS_PER_LINE); X file->linepos = (XawTextPosition *) X XtMalloc ((nlines+2) * sizeof(XawTextPosition)); X p = file->buf; X line = 0; X file->linepos[line++] = 0; X file->linepos[line++] = 0; X while (*p) { X if (*p++ == '\n') { X if (line == nlines) { /* buffer full, need more memory */ X file->linepos = (XawTextPosition *) XtRealloc (file->linepos, X (nlines + ADD_LINES) * sizeof(XawTextPosition)); X nlines += ADD_LINES; X } X file->linepos[line++] = p - file->buf; X } X } X file->lastline = line - 2; X file->linepos = (XawTextPosition *) XtRealloc /* shrink to min size */ X (file->linepos, line * sizeof(XawTextPosition)); X} X X X/* X * Look up the file table for an entry with "filename" X * If not found, create an entry and initialize proper fields, X * else, return pointer to entry found. X */ Xstatic LookUpFileTable(pathname, filename, file) Xchar *pathname, *filename; XFileRec **file; X{ X struct stat fileinfo; X int fd; X int i, j, n; X X for (i=0; fileTable && fileTable[i] && i<fileTableSize; i++) { X if (strcmp(fileTable[i]->pathname, pathname) == NULL) { /* file found */ X if (stat(pathname, &fileinfo) == -1) { X UpdateMessageWindow("Error: cannot stat file %s", pathname); X *file = fileTable[i]; X return 0; X } X if (fileinfo.st_mtime > fileTable[i]->mtime) { /* file modified */ X XtFree((char *)fileTable[i]->buf); X XtFree((char *)fileTable[i]->linepos); X XtFree((char *)fileTable[i]); X displayedFile = NULL; X break; X } X else if (displayedFile && /* same as displayed file */ X strcmp(pathname, displayedFile->pathname) == 0) { X *file = NULL; X return 0; X } X else { X *file = fileTable[i]; X return 0; X } X } X } X X /* Record file into file table */ X X if (i == fileTableSize) { /* file table full, enlarge it */ X fileTableSize += ADD_SIZE; X fileTable = (FileRec **) X XtRealloc (fileTable, fileTableSize * sizeof(FileRec *)); X for (j=i; j<fileTableSize; j++) X fileTable[j] = NULL; X } X if ((fd = open(pathname, O_RDONLY)) == -1) { X UpdateMessageWindow("Error: cannot open file %s", pathname); X return -1; X } X if (fstat(fd, &fileinfo) == -1) { X UpdateMessageWindow("Error: cannot fstat file %s", pathname); X close(fd); X return -1; X } X fileTable[i] = (FileRec *) XtMalloc (sizeof(FileRec)); X fileTable[i]->filesize = fileinfo.st_size + 1; X fileTable[i]->mtime = fileinfo.st_mtime; X fileTable[i]->buf = XtMalloc((int)fileTable[i]->filesize); X if ((n = read(fd, fileTable[i]->buf, (int) fileTable[i]->filesize)) == -1) { X UpdateMessageWindow("Error: cannot read file %s", pathname); X XtFree(fileTable[i]->buf); X XtFree(fileTable[i]); X fileTable[i] = NULL; X close(fd); X return -1; X } X fileTable[i]->buf[n] = '\0'; X fileTable[i]->pathname = XtNewString(pathname); X fileTable[i]->filename = XtNewString(filename); X fileTable[i]->currentline = 1; X fileTable[i]->topline = 1; X fileTable[i]->bottomline = 0; X fileTable[i]->topPosition = 0; X BuildLinePos(fileTable[i]); X close(fd); X *file = fileTable[i]; X return 0; X} X X/* X * Remember file position and current line before closing. X */ Xstatic void SaveDisplayedFileInfo() X{ X XawTextPosition pos; X X if (displayedFile) { X displayedFile->topPosition = XawTextTopPosition(sourceWindow); X pos = XawTextGetInsertionPoint(sourceWindow); X displayedFile->currentline = TextPositionToLine(pos); X } X} X X X/* DisplayFile() displays the file onto the source window. It X * uses topPosition to remember where it was last opened. But it X * must recalculate bottomline because the window size might be X * different. X */ Xstatic void DisplayFile(file) XFileRec *file; X{ X Arg args[MAXARGS]; X Cardinal n; X TextWidget ctx = (TextWidget) sourceWindow; X X n = 0; X XtSetArg(args[n], XtNdisplayPosition, (XtArgVal)file->topPosition); n++; X XtSetArg(args[n], XtNstring, (XtArgVal) file->pathname); n++; X XtSetArg(args[n], XtNeditType, (XtArgVal) XawtextRead); n++; X XtSetValues(sourceWindow, args, n); X file->lines = ctx->text.lt.lines; X file->bottomline = MIN (file->topline + file->lines - 1, file->lastline); X} X X X/* Given a filename starting with a tilde (`~'), it expands ~[user] to X * the home directory of that user, or to the login home directory if user X * is not specified. X */ Xstatic char *expand(filename) Xchar *filename; X{ X struct passwd *pwd; X char *string, *name, newfile[MAXNAME]; X X string = XtNewString(filename+1); X if (*string == '\0' || *string == '/') X name = (char *) getlogin(); X else X name = (char *) strtok(string, "/"); X if (name == NULL) X return filename; X pwd = (struct passwd *) getpwnam(name); X if (pwd && pwd->pw_dir) { X sprintf(newfile, "%s%s", pwd->pw_dir, filename+strlen(name)+1); X return XtNewString(newfile); X } X else X return filename; X} X X X/* Create a list of directories for searching source files. X * It reads the list of directories specified by the user, adding X * the current directory into the list if it is not already there. X * X * With fix from Dave Gagne (daveg@fs1.ee.ubc.ca) 7/30/90 X */ Xvoid MakeDirList(output) Xchar *output; X{ X char *s, list[BUFSIZ], command[LINESIZ]; X int i, use_cwd; X X for (i=0; dirList[i]; i++) /* remove old list */ X XtFree(dirList[i]); X i = 0; X use_cwd = TRUE; X if (output) { /* create list */ X#ifdef GDB /* GDB uses ':' as separator character */ X s = (char *) strtok(output, ": \n"); X#else X s = (char *) strtok(output, " \n"); X#endif /* GDB */ X while (s) { X dirList[i] = XtNewString(s); X X if (dirList[i][0] == '~') /* expand '~' */ X dirList[i] = expand(dirList[i]); X if (LASTCH(dirList[i]) == '/') /* remove last '/' */ X LASTCH(dirList[i]) = '\0'; X if (strcmp(dirList[i], ".") == NULL) /* watch for "." */ X use_cwd = FALSE; X X ++i; X s = (char *) strtok(NULL, " \n"); X } X dirList[i] = NULL; X } X X if (use_cwd) { /* include current dir */ X dirList[i++] = XtNewString("."); X dirList[i] = NULL; X } X strcpy(list, ""); /* tell dbx our new list */ X for (i=0; dirList[i]; i++) { X strcat(list, dirList[i]); X strcat(list, " "); X } X#ifdef GDB X sprintf(command, "directory %s\n", list); X#else X sprintf(command, "use %s\n", list); X#endif /* GDB */ X Parse = False; X query_dbx(command); X} X X X/* Returns the full pathname of a given file. X * It searches for the file from a list of directories. X */ Xchar *GetPathname(filename) Xchar *filename; X{ X char pathname[LINESIZ]; X int i; X X if (filename == NULL || strcmp(filename, "") == NULL) X return NULL; X for (i=0; dirList[i]; i++) { X if (*filename == '/' && access(filename, R_OK) == -1) { X /* this handles the exceptional case of sun4 dbx output */ X strcpy(filename, &filename[1]); X } X if (*filename == '/' || *filename == '~') X strcpy(pathname, filename); X else if (strcmp(dirList[i], ".") == NULL) X sprintf(pathname, "%s/%s", cwd, filename); X else if (*dirList[i] == '/' || *dirList[i] == '~') X sprintf(pathname, "%s/%s", dirList[i], filename); X else X sprintf(pathname, "%s/%s/%s", cwd, dirList[i], filename); X if (access(pathname, R_OK) == 0) X return XtNewString(pathname); X } X UpdateMessageWindow("File not found: %s", filename); X return NULL; X} X X/* X * Given a file name, LoadFile attempts to open it and displays it onto X * the source window: X * 1. get the full pathname of the file X * 2. LookUpFileTable() returns a pointer to the file's entry if it's X * already in the table; else, creates an entry and return a pointer. X * 3. save the current displayedFile info X * 4. display the file X * 5. update the file label and the various signs on the source window. X * LoadFile returns 0 upon successful completion, -1 otherwise. X */ Xint LoadFile(filename) Xchar *filename; X{ X FileRec *file; X char *pathname; X X pathname = GetPathname(filename); X if (pathname == NULL) { X return -1; X } X if (LookUpFileTable(pathname, filename, &file) != -1) { X if (file) { /* load new file */ X SaveDisplayedFileInfo(); X DisplayFile(file); X UpdateFileLabel(pathname); X XawTextUnsetSelection(sourceWindow); X XawTextSetInsertionPoint(sourceWindow, file->linepos[file->currentline]); X UpdateLineLabel(file->currentline); X UpdateStops(file); X UpdateArrow(file); X UpdateUpdown(file); X UpdateBomb(file); X displayedFile = file; X } X return 0; X } X else { /* LookUpFileTable() fails */ X return -1; X } X} X Xint LoadCurrentFile() X{ X#ifdef GDB X query_dbx("info line\n"); X#else X query_dbx("file\n"); X#endif /* GDB */ X return LoadFile(CurrentFile); X} END_OF_FILE if test 21173 -ne `wc -c <'source.c'`; then echo shar: \"'source.c'\" unpacked with wrong size! fi # end of 'source.c' fi echo shar: End of archive 6 \(of 8\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 8 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 8 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Dan Heller ------------------------------------------------ O'Reilly && Associates Z-Code Software Senior Writer President argv@ora.com argv@zipcode.com
pierre@tce.COM (Pierre Willard) (03/27/91)
Submitted-by: pierre@tce.COM (Pierre Willard) Posting-number: Volume 11, Issue 51 Archive-name: xxgdb/part04 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 6 (of 8)." # Contents: gdb_regex.h source.c # Wrapped by gilbert@phi on Tue Jan 15 13:12:49 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'gdb_regex.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gdb_regex.h'\" else echo shar: Extracting \"'gdb_regex.h'\" \(16887 characters\) sed "s/^X//" >'gdb_regex.h' <<'END_OF_FILE' X/***************************************************************************** X * X * xdbx - X Window System interface to the dbx debugger X * X * Copyright 1989 The University of Texas at Austin X * Copyright 1990 Microelectronics and Computer Technology Corporation X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of The University of Texas X * and Microelectronics and Computer Technology Corporation (MCC) not be X * used in advertising or publicity pertaining to distribution of X * the software without specific, written prior permission. The X * University of Texas and MCC makes no representations about the X * suitability of this software for any purpose. It is provided "as is" X * without express or implied warranty. X * X * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO X * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR X * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X * X * Author: Po Cheung X * Created: March 10, 1989 X * X ***************************************************************************** X * X * xxgdb - X Window System interface to the gdb debugger X * X * Copyright 1990 Thomson Consumer Electronics, Inc. X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of Thomson Consumer X * Electronics (TCE) not be used in advertising or publicity pertaining X * to distribution of the software without specific, written prior X * permission. TCE makes no representations about the suitability of X * this software for any purpose. It is provided "as is" without express X * or implied warranty. X * X * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT X * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES X * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS X * SOFTWARE. X * X * Adaptation to GDB: Pierre Willard X * XXGDB Created: December, 1990 X * X *****************************************************************************/ X X/* X * gdb_regex.h: X * X * Regular expression pattern matching for GNU gdb. X * X * The reg_token array indicates the register no. for each token type. X * reg_token[0] : message X * reg_token[1] : stop number X * reg_token[2] : function name X * reg_token[3] : line number X * reg_token[4] : file name X * reg_token[5] : display command output X */ X X#define TK_MESG 0 X#define TK_STOP 1 X#define TK_FUNC 2 X#define TK_LINE 3 X#define TK_FILE 4 X#define TK_DISP 5 X X#define O_EXEC_MESS_AFTER 0 X#define O_EXEC_MESS_BEFORE 1 X#define O_EXEC 2 X#define O_DONE 3 X#define O_BREAK 4 /* Instead of O_STOPAT & O_STOPIN */ X#define O_INFO_DIR 5 /* NEW for GDB */ X#define O_FRAME_CURR 6 /* O_FRAME_CURR = O_UPDOWN */ X#define O_UPDOWN 6 X#define O_BELL 7 X#define O_SEARCH 8 X#define O_INFO_LINE 9 /* Instead of O_FILE */ X#define O_PRINT 10 X#define O_DEBUG 11 X#define O_DIRECTORY 12 X#define O_LIST 13 /* for dbx, O_LIST = O_SEARCH */ X#define O_DISPLAY 14 X#define O_DISPLAY_INFO 15 X#define O_PWD 16 X#define O_CD 16 /* O_PWD = O_CD */ X#define O_RECEIVED_SIGNAL 17 /* test program received signal */ X#define O_EXEC_DISPLAY 18 /* special for filter_display_info */ X#define O_READING_SYMBOLS 19 /* special for filter_reading_symbols */ X X X#define C_ANY -1 X#define C_EXEC 0 X#define C_BREAK 1 /* Instead of C_STOPAT & C_STOPIN */ X#define C_INFO_DIR 2 /* NEW for GDB */ X#define C_FRAME_CURR 3 X#define C_UPDOWN 4 X#define C_DELETE 5 X#define C_FINISH 6 /* Instead of C_FUNC */ X#define C_INFO_LINE 7 /* Instead of C_FILE */ X#define C_SYMBOL_FILE 8 X#define C_CD 9 X#define C_DIRECTORY 10 /* Instead of C_USE */ X#define C_PWD 11 X#define C_LIST 12 X#define C_SEARCH 13 X#define C_DISPLAY_INFO 14 /* must be BEFORE C_DISPLAY ! */ X#define C_DISPLAY 15 X#define C_UNDISPLAY 16 X#define C_PRINT 17 X#define C_INFO_BREAK 18 X#define C_SOURCE 19 X#define C_EXEC_FILE 20 X X/*--------------------------------------------------------------------------+ X| | X| DBX | X| | X| Reading symbolic information... | X| Read 46 symbols | X| (dbx) | X| (dbx) | X| stopped in main at line 5 in file "pw.c" | X| 5 for (i=0; i<100; i++) | X| (dbx) use | X| /usr1/gnu_sun4/xdbx/ | X| (dbx) file | X| pw.c | X| (dbx) file | X| No current source file | X| | X+--------------------------------------------------------------------------*/ X/*--------------------------------------------------------------------------+ X| | X| GDB | X| | X| Reading symbol data from /usr1/gnu_sun4/xdbx/pw...done. | X| Type "help" for a list of commands. | X| (gdb) | X| (gdb) | X| Bpt 1, main () (pw.c line 5) | X| 5 for (i=0; i<100; i++) | X| (gdb) info directories | X| Source directories searched: /usr1/gnu_sun4/xdbx:/usr1/toto | X| (gdb) info line | X| Line 10 of "pw.c" starts at pc 0x22dc and ends at 0x22e4. | X| (gdb) info line | X| No source file specified. | X| | X+--------------------------------------------------------------------------*/ X/*--------------------------------------------------------------------------+ X| | X| GDB -fullname | X| | X| | X| We use option -fullname (see dbxoptions() in xdbx.c). | X| | X| GDB prints (see source.c of gdb): | X| | X| "\032\032%s:%d:%d:%s:0x%x\n", s->fullname, | X| line, s->line_charpos[line - 1], | X| mid_statement ? "middle" : "beg", | X| get_frame_pc (get_current_frame())); | X| | X| (gdb) break main | X| Reading in symbols for pw.c...done. | X| Breakpoint 1 at 0x229c: file pw.c, line 5. | X| (gdb) run | X| Starting program: /usr1/gnu_sun4/xdbx/pw | X| | X| Bpt 1, main () (pw.c line 5) | X| /usr1/gnu_sun4/xdbx/pw.c:5:17:beg:0x229c | X| (gdb) step | X| /usr1/gnu_sun4/xdbx/pw.c:6:40:beg:0x22b0 | X| (gdb) | X| | X| (gdb) info directories | X| Source directories searched: /usr1/gnu_sun4/xdbx | X| (gdb) info line | X| Line 10 of "pw.c" starts at pc 0x22dc and ends at 0x22e4. | X| (gdb) info line | X| No source file specified. | X| (gdb) info line | X| Line number 34 is out of range for "bug1.c". | X| | X| (gdb) display i | X| 3: i = 0 | X| (gdb) display | X| 4: i + 1 = 1 | X| 3: i = 0 | X| (gdb) undisplay 2 | X| (gdb) display | X| (gdb) | X| | X| (gdb) up | X| #2 0x2314 in main () (pw.c line 35) | X| /usr1/gnu_sun4/xdbx/pw.c:35:158:beg:0x2360 | X| (gdb) up | X| Initial frame selected; you cannot go up. | X| (gdb) | X| | X| (gdb) down | X| #0 glop (number=1) (pw2.c line 5) | X| /usr1/gnu_sun4/xdbx/pw2.c:5:33:beg:0x2360 | X| (gdb) down | X| Bottom (i.e., innermost) frame selected; you cannot go down. | X| (gdb) | X| | X| (gdb) pwd | X| Working directory /usr1/gnu_sun4/xdbx. | X| (gdb) cd .. | X| Working directory /usr1/gnu_sun4. | X| (gdb) cd xdbx | X| Working directory /usr1/gnu_sun4/xdbx. | X| (gdb) cd toto | X| toto: No such file or directory. | X| (gdb) | X| | X| Program exited with code 01. | X| (gdb) | X| | X+--------------------------------------------------------------------------*/ X/* X X . --> any character but '\n' X * --> any character 0 to n times X + --> any character 1 to n times X ? --> any character 0 or 1 time X ^ --> begin of line or NOT following character X $ --> end of line or '$' X \\w --> character '0..9a..zA...Z' X \\W --> character NOT '0..9a..zA...Z' X \\< --> word begin (word is composed of 0..9a..zA...Z) X \\> --> word end (word is composed of 0..9a..zA...Z) X \\b --> word bound X \\B --> not word bound X \\| --> means OR X \\` --> begin buffer X \\\' --> end buffer X X X>> WARNING : be carefull with \\| (OR) : the re_match() function X>> will NOT correctly update the string for a pattern which is X>> optional ! X>> --> The number SHOULD NOT point to a patterm which is optional ! X X*/ X X /* (PW)5DEC90: I have a problem if we say \\(Bpt.*\n\\)? in exec pattern. X That is why I have two cases : with or without Bpt... X Note that 'exec without Message' includes 'exec with Message'. X We display 'Bpt...' in the message window. */ X X /* (PW)14JAN91 (v1.01) : use X \\(\\([0-9]+:.*\n\\(\\( .*\n\\)*}\n\\)?\\)*\\) X instead of X \\(\\([0-9]+:.*\n\\)*\\) X for display pattern. X */ X X Xstatic PatternRec output_pattern[] = { X /* exec with Message after */ X {"\\(.*\n\\)*\032\032\\([^ ]+\\):\\([0-9]+\\):\\([0-9]+\\):\\([^ ]+\\):0x.+\n\\([ ]*[^0-9].*\n\\)\\(\\([0-9]+:.*\n\\(\\( .*\n\\)*}\n\\)?\\)*\\)", X NULL, X {6, -1, -1, 3, 2, 7} X }, X /* exec with Message before */ X {"\\(.*\n\\)*\\([ ]*[^ ].*\n\\)\032\032\\([^ ]+\\):\\([0-9]+\\):\\([0-9]+\\):\\([^ ]+\\):0x.+\n\\(\\([0-9]+:.*\n\\(\\( .*\n\\)*}\n\\)?\\)*\\)", X NULL, X {2, -1, -1, 4, 3, 7} X }, X /* exec without Message */ X {"\\(.*\n\\)*\032\032\\(\\([^ ]+\\):\\([0-9]+\\):\\([0-9]+\\):\\([^ ]+\\):0x.+\n\\)\\(\\([0-9]+:.*\n\\(\\( .*\n\\)*}\n\\)?\\)*\\)", X NULL, X {2, -1, -1, 4, 3, 7} X }, X /* done */ X {"\\(.*\n\\)*\n\\(Program terminated with signal \\|Program exited with code 0\\|Program exited normally\\).*\n\\(.*\n\\)*", X NULL, X {-1, -1, -1, -1, -1, -1} X }, X /* break */ X {"\\(.*\n\\)*Breakpoint \\([0-9]+\\) at [^ ]+: file \\([^ ]+\\), line \\([0-9]+\\).\n", X NULL, X {-1, 2, -1, 4, 3, -1} X }, X /* info directories */ X {"Source directories searched:[ ]*\\([^ ]+\\)[ ]*\n", X NULL, X { -1, -1, -1, -1, 1, -1} X }, X /* up, down */ X {"\\(.*\n\\)*\\(#[0-9]+[ ]+\\(0x[^ ]+[ ]+in[ ]+\\)?\\([^ ]+\\).*\n\\)\\(Source file is more recent than executable.\n\\)?\032\032\\([^ ]+\\):\\([0-9]+\\):\\([0-9]+\\):\\([^ ]+\\):0x.+\n", X NULL, X {2, -1, 4, 7, 6, -1} X }, X /* bell */ X {"\\(Undefined command: .*\n\\|Already at the \\(top\\|bottom\\) call level\n\\|\ XNo active stack frames\n\\|no program to run\n\\|no process to run\n\\|\ Xprogram is not active\n\\|can't continue execution\n\\|\ X.*\ncan't write to process.*\n\\|\ X\\(Top\\|End\\)-of-file; did not find search string:.*\n\\)", X NULL, X {-1, -1, -1, -1, -1} X }, X /* search */ X {"\\([0-9]+\\).*\n", X NULL, X {-1, -1, -1, 1, -1, -1} X }, X /* info line */ X {"\\(Line \\(number \\)?[0-9]+ \\(of\\|is out of range for\\) \"\\([^ ]+\\)\".*\\)\n", X NULL, X {-1, -1, -1, -1, 4, -1} X }, X /* print */ X {"\\(warning: .*\n\\)?\\(\\(.*\\) = .*\n\\(.*\n\\)*\\)", X NULL, X { 3, -1, -1, -1, -1, 2} X }, X /* start gdb (debug) */ X {"\\(.*\n\\)*Type \"help\" for a list of commands.\n", X NULL, X { -1, -1, -1, -1, -1, -1} X }, X /* directory */ X {"\\([^ ]+ is already in the source path.[ ]*\n\\)*Source directories searched:[ ]*\\([^ ]+\\)[ ]*\n", X NULL, X { -1, -1, -1, -1, 1, -1} X }, X /* list */ X {"\\(.*\n\\)*\\(\\([0-9]+\\).*\n\\)", X NULL, X { -1, -1, -1, 3, -1, -1} X }, X /* display */ X {"\\([0-9]+:.*\n\\)", X NULL, X { -1, -1, -1, -1, -1, 1} X }, X /* info display */ X {"\\(\\([0-9]+:.*\n\\(\\( .*\n\\)*}\n\\)?\\)*\\)", X NULL, X { -1, -1, -1, -1, -1, 1} X }, X /* pwd or cd */ X {"Working directory[ ]+\\([^ ]+\\).[ ]*\n\\([ ]*(canonically[ ]+\\([^ ]+\\)).\n\\)?", X NULL, X { 1, -1, -1, -1, -1, 3} X }, X /* program received signal */ X {"\\(.*\n\\)*\n\\(Program received signal \\([-]?[0-9]+\\), [^ ]+.*\n\\)\\(.*\n\\)*", X NULL, X { 2, 3, -1, -1, -1, -1} X }, X /* special for test in filter_display_info() */ X {"\\([^0-9].*\n\\)*\\([0-9]+:.*\n\\)\\(.*\n\\)*", X NULL, X { -1, -1, -1, -1, -1, 2} X }, X /* special for test in filter_reading_symbols() */ X {"\\(.*\n\\)*\\(Reading in symbols for .*done.\n\\)\\(.*\n\\)*", X NULL, X { 2, -1, -1, -1, -1, -1} X }, X NULL X}; X X/* X X To simplify the patterns, I used for example : X X "fr[ame]*" instead of "frame\\|fram\\|fra||fr". X X This will cause 'frmeame' to be accepted. But this is X no problem because 'Undefined command' output is parsed X before parsing the command line (see parse() in parser.c). X*/ X Xstatic PatternRec command_pattern[] = { X /* run -r - cont - c - next - n - step - s - nexti - ni - stepi - si - return X jump - until - u */ X {"[ ]*\\(run\\|r\\|cont\\|c\\|next\\|n\\|step\\|s\\|nexti\\|stepi\\|ni\\|si\\|ret[urn]*\\|j[ump]*\\|unt[il]*\\|u\\)\\( .*\\)?\n", X NULL, {-1, -1, -1, -1, -1, -1}}, X /* break - tbreak */ X {"[ ]*\\(t\\)?\\(b\\|br\\|bre\\|brea\\|break\\)\\( .*\\)?\n", X NULL, {-1, -1, -1, -1, -1, -1}}, X {"[ ]*info[ ]+directories[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* 'frame' is special case of 'frame n' since it does not change the X current frame. Else 'frame n' is like up or down. */ X {"[ ]*fr[ame]*[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X {"[ ]*\\(up\\|down\\|dow\\|do\\|fr[ame]*\\)\\( .*\\)?\n", X NULL, {-1, -1, -1, -1, -1, -1}}, X X /* delete - d - clear - enable - disable - dis - disa */ X /* gdb commands 'delete display' 'enable display' and 'delete environment' X are also found here. This is superfluous, but no problem */ X X {"[ ]*\\(del[ete]*\\|d\\|cl[ear]*\\|en[able]*\\|disab[le]*\\|dis\\|disa\\)\\( .*\\)?\n", X NULL, {-1, -1, -1, -1, -1, -1}}, X X {"[ ]*fi[nish]*[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X {"[ ]*info[ ]+line[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* symbol-file */ X {"[ ]*sy.*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X {"[ ]*cd[ ]*[^ ]+[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* directory */ X {"[ ]*dir.*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X {"[ ]*pwd[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X /* list */ X {"[ ]*l.*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* forward-search or reverse-search or search */ X X {"[ ]*\\(fo[rward-search]*\\|rev[erse-search]*\\|sea[rch]*\\)[ ]*", X NULL, {-1, -1, -1, -1, -1, -1}}, X X /* 'display' is a special case of 'display exp' since it does not X add any expression to be displayed */ X {"[ ]*disp[lay]*[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X {"[ ]*disp[lay]\\(/[^ ]+\\)?*[ ]*[^ ]+[ ]*.*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* undisplay */ X {"[ ]*und.*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* Note that Token.mesg (if any) is updated with print command (see 1) */ X X {"[ ]*print[ ]*\\([^ ]?\\([ ]+[^ ]+\\)*\\)[ ]*\n", NULL, { 1, -1, -1, -1, -1, -1}}, X {"[ ]*info[ ]+break[ ]*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X X /* source (note that Token.TK_FILE is updated here) */ X {"[ ]*so[urce]*[ ]*\\(.*\\)\n", NULL, {-1, -1, -1, -1, 1, -1}}, X X /* exec-file (just used internally) */ X {"[ ]*exec-file .*\n", NULL, {-1, -1, -1, -1, -1, -1}}, X NULL X}; END_OF_FILE if test 16887 -ne `wc -c <'gdb_regex.h'`; then echo shar: \"'gdb_regex.h'\" unpacked with wrong size! fi # end of 'gdb_regex.h' fi if test -f 'source.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'source.c'\" else echo shar: Extracting \"'source.c'\" \(21173 characters\) sed "s/^X//" >'source.c' <<'END_OF_FILE' X/***************************************************************************** X * X * xdbx - X Window System interface to the dbx debugger X * X * Copyright 1989 The University of Texas at Austin X * Copyright 1990 Microelectronics and Computer Technology Corporation X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of The University of Texas X * and Microelectronics and Computer Technology Corporation (MCC) not be X * used in advertising or publicity pertaining to distribution of X * the software without specific, written prior permission. The X * University of Texas and MCC makes no representations about the X * suitability of this software for any purpose. It is provided "as is" X * without express or implied warranty. X * X * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO X * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR X * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X * X * Author: Po Cheung X * Created: March 10, 1989 X * X ***************************************************************************** X * X * xxgdb - X Window System interface to the gdb debugger X * X * Copyright 1990 Thomson Consumer Electronics, Inc. X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of Thomson Consumer X * Electronics (TCE) not be used in advertising or publicity pertaining X * to distribution of the software without specific, written prior X * permission. TCE makes no representations about the suitability of X * this software for any purpose. It is provided "as is" without express X * or implied warranty. X * X * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT X * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES X * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS X * SOFTWARE. X * X * Adaptation to GDB: Pierre Willard X * XXGDB Created: December, 1990 X * X *****************************************************************************/ X X/* source.c X * X * Create the source window and handle display of file. X * X * source_init(): Initialization routine. X * Update(): Action proc to update source window on scrollbar action. X * NotifyResize(): Action proc to update source window on resize. X * CreateSourceWindow(): Create the source window. X * BuildLinePos(): Build an array of starting text position of each line. X * LookUpFileTable():Check out source file info from a file table. X * SaveDisplayedFileInfo(): records displayed file info into file table. X * DisplayFile(): Display a file on the source window X * LoadFile(): Search for a file and open it for display. X */ X X#include <X11/Xos.h> X#include <sys/stat.h> X#include <pwd.h> X#include "global.h" X X#define MAXDIRS 256 /* max number of dirs in dirList */ X Xchar CurrentFile[MAXNAME]; /* current contents of file variable */ XWidget sourceForm, /* parent of sourceWindow */ X sourceWindow; /* text window for source file */ XFileRec *displayedFile; /* pointer to table entry of currently X displayed file */ X Xstatic FileRec **fileTable; /* table of file records */ Xstatic int fileTableSize; /* size of file table */ Xstatic char *dirList[MAXDIRS]; /* list of dirs for searching files */ X Xvoid source_init() X{ X dirList[0] = NULL; X} X X/* X * Update topline, bottomline, arrow sign, updown sign, stop signs, and X * line label. X */ X/* ARGSUSED */ Xvoid Update(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition pos; X int topline; X FileRec *file; X X if (displayedFile) { X file = displayedFile; X pos = XawTextTopPosition(sourceWindow); X file->topPosition = pos; X topline = TextPositionToLine(pos); X /* Update the symbols only if the text scrolls */ X if (file->topline != topline) { X file->topline = topline; X file->bottomline = MIN (file->topline + file->lines - 1, X file->lastline); X XawTextSetInsertionPoint(sourceWindow, file->linepos[file->topline]); X UpdateLineLabel(file->topline); X UpdateStops(file); X UpdateArrow(file); X UpdateUpdown(file); X UpdateBomb(file); X } X else {/* Update caret position only */ X pos = XawTextGetInsertionPoint(sourceWindow); X UpdateLineLabel(TextPositionToLine(pos)); X } X } X} X X/* X * Update bottomline, arrow sign, updown sign and stop signs on resize. X * Invoked by ConfigureNotify event. X */ X/* ARGSUSED */ Xstatic void NotifyResize(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition pos; X TextWidget ctx = (TextWidget) sourceWindow; X FileRec *file; X X if (file = displayedFile) { X file->lines = ctx->text.lt.lines; X pos = XawTextTopPosition(sourceWindow); X file->topline = TextPositionToLine(pos); X file->bottomline = MIN (file->topline + file->lines - 1, X file->lastline); X UpdateStops(file); X UpdateArrow(file); X UpdateUpdown(file); X UpdateBomb(file); X } X} X X/* Update the position of the caret */ X/* ARGSUSED */ X#ifdef notdef Xvoid UpdateLine(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition pos; X int line; X X pos = XawTextGetInsertionPoint(w); X line = TextPositionToLine(pos); X UpdateLineLabel(line); X} X#endif X X/* My select-start routine that cancels the effect of automatic scrolling X * near the bottom of an Athena text widget window. X */ X/* ARGSUSED */ Xvoid SelectStart(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition topPosition; X X /* remember the top display position before automatic scrolling */ X /* displayedFile->topPosition = XawTextTopPosition(w); */ X topPosition = XawTextTopPosition(w); X X XtCallActionProc(w, "select-start", event, params, num_params); X X /* reset to remembered position if top position changed */ X /* if (XawTextTopPosition(w) != displayedFile->topPosition) X TextSetTopPosition(w, displayedFile->topPosition); */ X if (XawTextTopPosition(w) != topPosition) X TextSetTopPosition(w, topPosition); X} X X/* My select-end routine to store the text selection into both the PRIMARY X * selection and cut buffer 0. X */ X/* ARGSUSED */ Xvoid SelectEnd(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition begin, end, start; X Widget textsrc; X XawTextBlock buffer; X char s[10000]; X int nchars; X X XawTextGetSelectionPos(w, &begin, &end); X XawTextSetSelection(w, begin, end); X if (begin == end) return; X textsrc = XawTextGetSource(w); X strcpy(s, ""); X for (start=begin, nchars=end-begin; nchars > 0; X start=begin+buffer.length, nchars-=buffer.length) { X XawTextSourceRead(textsrc, start, &buffer, nchars); X strncat(s, buffer.ptr, buffer.length); X } X XStoreBytes(display, s, strlen(s)); X} X X/* This is my own select word routine to replace the standard action X * procedure provided by the Text widget. X * It selects a word delimited by DELIMITERS, not whitespace. X */ X/* ARGSUSED */ Xvoid SelectWord(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X XawTextPosition pos, left, right, start; X XawTextBlock buffer; X Widget textsrc; X char s[LINESIZ]; X char *p, *ls, *rs; X int nchars; X X pos = XawTextGetInsertionPoint(w); X textsrc = XawTextGetSource(w); X X XawTextSourceRead(textsrc, pos, &buffer, 1); X if (buffer.length == 0 || (buffer.length == 1 && X strchr(app_resources.delimiters, (int)*(buffer.ptr)) != NULL)) { X XStoreBytes(display, NULL, 0); X return; X } X X left = XawTextSourceScan(textsrc, pos+1, XawstWhiteSpace, XawsdLeft, 1, X FALSE); X right = XawTextSourceScan(textsrc, left, XawstWhiteSpace, XawsdRight, 1, X FALSE); X X strcpy(s, ""); X for (start=left, nchars=right-left; nchars > 0; X start=left+buffer.length, nchars-=buffer.length) { X XawTextSourceRead(textsrc, start, &buffer, nchars); X strncat(s, buffer.ptr, buffer.length); X } X X if (!strcmp(s, "")) return; X p = s+pos-left; X ls = (char *) strtok(s, app_resources.delimiters); X rs = (char *) strtok(NULL, app_resources.delimiters); X if (!ls) return; X while (rs<=p && rs!=NULL) { X ls = rs; X rs = (char *) strtok(NULL, app_resources.delimiters); X } X left = left + ls - s; X right = left + strlen(ls) - 1; X X XawTextUnsetSelection(w); X XStoreBytes(display, ls, strlen(ls)); X XawTextSetSelection(w, left, right+1); X} X X/* Print the value of the expression in cut buffer 0. */ X/* ARGSUSED */ Xvoid PrintSelection(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X char command[LINESIZ]; X char *string; X int nbytes; X X string = XFetchBytes(display, &nbytes); X if (nbytes == 0) { X UpdateMessageWindow(PRINT_HELP, NULL); X bell(0); X return; X } X sprintf(command, "print %s\n", string); X send_command(command); X AppendDialogText(command); X} X X/* X * On top of a form widget, we have a text widget with scrollbar, label X * widgets for the stop sign, arrow sign, and updown signs. X */ Xvoid CreateSourceWindow(parent) XWidget parent; X{ X TextWidget ctx; X Arg args[MAXARGS]; X Cardinal n; X X static XtActionsRec sbar_actions[] = { X {"NotifyResize", NotifyResize}, X {"Update", Update}, X {NULL, NULL} X }; X X static String sbarTranslations = "\ X <Configure>: NotifyResize() \n\ X <Btn2Down>: StartScroll(Continuous) MoveThumb() NotifyThumb() \ X Update() \n\ X <Btn2Motion>: MoveThumb() NotifyThumb() Update() \n\ X <BtnUp>: NotifyScroll(Proportional) EndScroll() Update() \n\ X "; X X n = 0; X XtSetArg(args[n], XtNdefaultDistance, 0); n++; X sourceForm = XtCreateManagedWidget("sourceForm", formWidgetClass, X parent, args, n); X X n = 0; X XtSetArg(args[n], XtNborderWidth, 0); n++; X XtSetArg(args[n], XtNtype, (XtArgVal)XawAsciiFile); n++; X XtSetArg(args[n], XtNstring, (XtArgVal)"/dev/null"); n++; X XtSetArg(args[n], XtNscrollVertical, (XtArgVal) XawtextScrollAlways);n++; X sourceWindow = XtCreateManagedWidget("sourceWindow", asciiTextWidgetClass, X sourceForm, args, n); X X ctx = (TextWidget) sourceWindow; X if (ctx->text.vbar) X XtOverrideTranslations(ctx->text.vbar, X XtParseTranslationTable(sbarTranslations)); X XtAppAddActions(app_context, sbar_actions, XtNumber(sbar_actions)); X} X X X/* X * Build the array which gives the starting text position of each line. X * > Estimate the number of lines in the file and allocate memory buffer. X * > Starting position of line #1 is 0, and is stored in linepos[1]. X * > Search for '\n' till end of buffer. X */ Xstatic void BuildLinePos(file) XFileRec *file; X{ X char *p; X int line, nlines; X X nlines = MAX(1, file->filesize/CHARS_PER_LINE); X file->linepos = (XawTextPosition *) X XtMalloc ((nlines+2) * sizeof(XawTextPosition)); X p = file->buf; X line = 0; X file->linepos[line++] = 0; X file->linepos[line++] = 0; X while (*p) { X if (*p++ == '\n') { X if (line == nlines) { /* buffer full, need more memory */ X file->linepos = (XawTextPosition *) XtRealloc (file->linepos, X (nlines + ADD_LINES) * sizeof(XawTextPosition)); X nlines += ADD_LINES; X } X file->linepos[line++] = p - file->buf; X } X } X file->lastline = line - 2; X file->linepos = (XawTextPosition *) XtRealloc /* shrink to min size */ X (file->linepos, line * sizeof(XawTextPosition)); X} X X X/* X * Look up the file table for an entry with "filename" X * If not found, create an entry and initialize proper fields, X * else, return pointer to entry found. X */ Xstatic LookUpFileTable(pathname, filename, file) Xchar *pathname, *filename; XFileRec **file; X{ X struct stat fileinfo; X int fd; X int i, j, n; X X for (i=0; fileTable && fileTable[i] && i<fileTableSize; i++) { X if (strcmp(fileTable[i]->pathname, pathname) == NULL) { /* file found */ X if (stat(pathname, &fileinfo) == -1) { X UpdateMessageWindow("Error: cannot stat file %s", pathname); X *file = fileTable[i]; X return 0; X } X if (fileinfo.st_mtime > fileTable[i]->mtime) { /* file modified */ X XtFree((char *)fileTable[i]->buf); X XtFree((char *)fileTable[i]->linepos); X XtFree((char *)fileTable[i]); X displayedFile = NULL; X break; X } X else if (displayedFile && /* same as displayed file */ X strcmp(pathname, displayedFile->pathname) == 0) { X *file = NULL; X return 0; X } X else { X *file = fileTable[i]; X return 0; X } X } X } X X /* Record file into file table */ X X if (i == fileTableSize) { /* file table full, enlarge it */ X fileTableSize += ADD_SIZE; X fileTable = (FileRec **) X XtRealloc (fileTable, fileTableSize * sizeof(FileRec *)); X for (j=i; j<fileTableSize; j++) X fileTable[j] = NULL; X } X if ((fd = open(pathname, O_RDONLY)) == -1) { X UpdateMessageWindow("Error: cannot open file %s", pathname); X return -1; X } X if (fstat(fd, &fileinfo) == -1) { X UpdateMessageWindow("Error: cannot fstat file %s", pathname); X close(fd); X return -1; X } X fileTable[i] = (FileRec *) XtMalloc (sizeof(FileRec)); X fileTable[i]->filesize = fileinfo.st_size + 1; X fileTable[i]->mtime = fileinfo.st_mtime; X fileTable[i]->buf = XtMalloc((int)fileTable[i]->filesize); X if ((n = read(fd, fileTable[i]->buf, (int) fileTable[i]->filesize)) == -1) { X UpdateMessageWindow("Error: cannot read file %s", pathname); X XtFree(fileTable[i]->buf); X XtFree(fileTable[i]); X fileTable[i] = NULL; X close(fd); X return -1; X } X fileTable[i]->buf[n] = '\0'; X fileTable[i]->pathname = XtNewString(pathname); X fileTable[i]->filename = XtNewString(filename); X fileTable[i]->currentline = 1; X fileTable[i]->topline = 1; X fileTable[i]->bottomline = 0; X fileTable[i]->topPosition = 0; X BuildLinePos(fileTable[i]); X close(fd); X *file = fileTable[i]; X return 0; X} X X/* X * Remember file position and current line before closing. X */ Xstatic void SaveDisplayedFileInfo() X{ X XawTextPosition pos; X X if (displayedFile) { X displayedFile->topPosition = XawTextTopPosition(sourceWindow); X pos = XawTextGetInsertionPoint(sourceWindow); X displayedFile->currentline = TextPositionToLine(pos); X } X} X X X/* DisplayFile() displays the file onto the source window. It X * uses topPosition to remember where it was last opened. But it X * must recalculate bottomline because the window size might be X * different. X */ Xstatic void DisplayFile(file) XFileRec *file; X{ X Arg args[MAXARGS]; X Cardinal n; X TextWidget ctx = (TextWidget) sourceWindow; X X n = 0; X XtSetArg(args[n], XtNdisplayPosition, (XtArgVal)file->topPosition); n++; X XtSetArg(args[n], XtNstring, (XtArgVal) file->pathname); n++; X XtSetArg(args[n], XtNeditType, (XtArgVal) XawtextRead); n++; X XtSetValues(sourceWindow, args, n); X file->lines = ctx->text.lt.lines; X file->bottomline = MIN (file->topline + file->lines - 1, file->lastline); X} X X X/* Given a filename starting with a tilde (`~'), it expands ~[user] to X * the home directory of that user, or to the login home directory if user X * is not specified. X */ Xstatic char *expand(filename) Xchar *filename; X{ X struct passwd *pwd; X char *string, *name, newfile[MAXNAME]; X X string = XtNewString(filename+1); X if (*string == '\0' || *string == '/') X name = (char *) getlogin(); X else X name = (char *) strtok(string, "/"); X if (name == NULL) X return filename; X pwd = (struct passwd *) getpwnam(name); X if (pwd && pwd->pw_dir) { X sprintf(newfile, "%s%s", pwd->pw_dir, filename+strlen(name)+1); X return XtNewString(newfile); X } X else X return filename; X} X X X/* Create a list of directories for searching source files. X * It reads the list of directories specified by the user, adding X * the current directory into the list if it is not already there. X * X * With fix from Dave Gagne (daveg@fs1.ee.ubc.ca) 7/30/90 X */ Xvoid MakeDirList(output) Xchar *output; X{ X char *s, list[BUFSIZ], command[LINESIZ]; X int i, use_cwd; X X for (i=0; dirList[i]; i++) /* remove old list */ X XtFree(dirList[i]); X i = 0; X use_cwd = TRUE; X if (output) { /* create list */ X#ifdef GDB /* GDB uses ':' as separator character */ X s = (char *) strtok(output, ": \n"); X#else X s = (char *) strtok(output, " \n"); X#endif /* GDB */ X while (s) { X dirList[i] = XtNewString(s); X X if (dirList[i][0] == '~') /* expand '~' */ X dirList[i] = expand(dirList[i]); X if (LASTCH(dirList[i]) == '/') /* remove last '/' */ X LASTCH(dirList[i]) = '\0'; X if (strcmp(dirList[i], ".") == NULL) /* watch for "." */ X use_cwd = FALSE; X X ++i; X s = (char *) strtok(NULL, " \n"); X } X dirList[i] = NULL; X } X X if (use_cwd) { /* include current dir */ X dirList[i++] = XtNewString("."); X dirList[i] = NULL; X } X strcpy(list, ""); /* tell dbx our new list */ X for (i=0; dirList[i]; i++) { X strcat(list, dirList[i]); X strcat(list, " "); X } X#ifdef GDB X sprintf(command, "directory %s\n", list); X#else X sprintf(command, "use %s\n", list); X#endif /* GDB */ X Parse = False; X query_dbx(command); X} X X X/* Returns the full pathname of a given file. X * It searches for the file from a list of directories. X */ Xchar *GetPathname(filename) Xchar *filename; X{ X char pathname[LINESIZ]; X int i; X X if (filename == NULL || strcmp(filename, "") == NULL) X return NULL; X for (i=0; dirList[i]; i++) { X if (*filename == '/' && access(filename, R_OK) == -1) { X /* this handles the exceptional case of sun4 dbx output */ X strcpy(filename, &filename[1]); X } X if (*filename == '/' || *filename == '~') X strcpy(pathname, filename); X else if (strcmp(dirList[i], ".") == NULL) X sprintf(pathname, "%s/%s", cwd, filename); X else if (*dirList[i] == '/' || *dirList[i] == '~') X sprintf(pathname, "%s/%s", dirList[i], filename); X else X sprintf(pathname, "%s/%s/%s", cwd, dirList[i], filename); X if (access(pathname, R_OK) == 0) X return XtNewString(pathname); X } X UpdateMessageWindow("File not found: %s", filename); X return NULL; X} X X/* X * Given a file name, LoadFile attempts to open it and displays it onto X * the source window: X * 1. get the full pathname of the file X * 2. LookUpFileTable() returns a pointer to the file's entry if it's X * already in the table; else, creates an entry and return a pointer. X * 3. save the current displayedFile info X * 4. display the file X * 5. update the file label and the various signs on the source window. X * LoadFile returns 0 upon successful completion, -1 otherwise. X */ Xint LoadFile(filename) Xchar *filename; X{ X FileRec *file; X char *pathname; X X pathname = GetPathname(filename); X if (pathname == NULL) { X return -1; X } X if (LookUpFileTable(pathname, filename, &file) != -1) { X if (file) { /* load new file */ X SaveDisplayedFileInfo(); X DisplayFile(file); X UpdateFileLabel(pathname); X XawTextUnsetSelection(sourceWindow); X XawTextSetInsertionPoint(sourceWindow, file->linepos[file->currentline]); X UpdateLineLabel(file->currentline); X UpdateStops(file); X UpdateArrow(file); X UpdateUpdown(file); X UpdateBomb(file); X displayedFile = file; X } X return 0; X } X else { /* LookUpFileTable() fails */ X return -1; X } X} X Xint LoadCurrentFile() X{ X#ifdef GDB X query_dbx("info line\n"); X#else X query_dbx("file\n"); X#endif /* GDB */ X return LoadFile(CurrentFile); X} END_OF_FILE if test 21173 -ne `wc -c <'source.c'`; then echo shar: \"'source.c'\" unpacked with wrong size! fi # end of 'source.c' fi echo shar: End of archive 6 \(of 8\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 8 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 8 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Dan Heller ------------------------------------------------ O'Reilly && Associates Z-Code Software Senior Writer President argv@ora.com argv@zipcode.com ------------------------------------------------ General Email: argv@sun.com Comp-sources-x stuff: comp-sources.x@uunet.uu.net