1 /*****************************************************************************
2  *
3  *  xdbx - X Window System interface to the dbx debugger
4  *
5  *  Copyright 1989 The University of Texas at Austin
6  *  Copyright 1990 Microelectronics and Computer Technology Corporation
7  *
8  *  Permission to use, copy, modify, and distribute this software and its
9  *  documentation for any purpose and without fee is hereby granted,
10  *  provided that the above copyright notice appear in all copies and that
11  *  both that copyright notice and this permission notice appear in
12  *  supporting documentation, and that the name of The University of Texas
13  *  and Microelectronics and Computer Technology Corporation (MCC) not be
14  *  used in advertising or publicity pertaining to distribution of
15  *  the software without specific, written prior permission.  The
16  *  University of Texas and MCC makes no representations about the
17  *  suitability of this software for any purpose.  It is provided "as is"
18  *  without express or implied warranty.
19  *
20  *  THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO
21  *  THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
22  *  FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR
23  *  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
24  *  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
25  *  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
26  *  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27  *
28  *  Author:  	Po Cheung
29  *  Created:   	March 10, 1989
30  *
31  *****************************************************************************
32  *
33  *  xxgdb - X Window System interface to the gdb debugger
34  *
35  * 	Copyright 1990,1993 Thomson Consumer Electronics, Inc.
36  *
37  *  Permission to use, copy, modify, and distribute this software and its
38  *  documentation for any purpose and without fee is hereby granted,
39  *  provided that the above copyright notice appear in all copies and that
40  *  both that copyright notice and this permission notice appear in
41  *  supporting documentation, and that the name of Thomson Consumer
42  *  Electronics (TCE) not be used in advertising or publicity pertaining
43  *  to distribution of the software without specific, written prior
44  *  permission.  TCE makes no representations about the suitability of
45  *  this software for any purpose.  It is provided "as is" without express
46  *  or implied warranty.
47  *
48  *  TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
49  *  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
50  *  SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
51  *  OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
52  *  WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
53  *  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
54  *  SOFTWARE.
55  *
56  *  Adaptation to GDB:  Pierre Willard
57  *  XXGDB Created:   	December, 1990
58  *
59  *****************************************************************************/
60 
61 /*  xdbx.c
62  *
63  *    Contain main program and initialization, command line options handling,
64  *    and resource database management.
65  *
66  *    Syntax():		Print an error message if xdbx is invoked with an
67  *			incorrect number of arguments.
68  *    main_init():	Initialization routine.
69  *    dbxoptions():	Construct command line arguments for dbx.
70  *    main():		Main program.
71  */
72 
73 #ifdef GDB
74 #define XGDBVERSION	"1.12"
75 #endif
76 
77 #   include <stdio.h>
78 #   include <stdlib.h>
79 #   include <sys/param.h>
80 
81 #include "global.h"
82 #include "bitmaps.h"
83 #include "patchlevel.h"
84 
85 #define VERSION	"2.1"
86 #define Offset(field) (XtOffset(XdbxResources *, field))
87 
88 char *progname;
89 
90 char            cwd[MAXPATHLEN];        /* The current working directory */
91 XtAppContext  	app_context; 		/* application context */
92 Widget  	toplevel; 		/* top level widget */
93 Display		*display;		/* connection to X server */
94 Cursor		watch;			/* XC_watch cursor */
95 XdbxResources 	app_resources;		/* application resources of xdbx */
96 char 		xdbxinit[LINESIZ];	/* initialization file name */
97 Boolean		Tstartup = False;	/* if True, remove xdbxinit */
98 Boolean		debug = False;		/* debug mode for xdbx */
99 
100 
101 #ifdef GDB
102 char gdbinit[LINESIZ];	/* initialization file name (.gdbinit) */
103 #endif /* GDB */
104 
105 
106 static XtResource resources[] = {
107     {"bell", "Bell", XtRBoolean, sizeof(Boolean),
108 	Offset(bell), XtRImmediate, (caddr_t)False},
109     {"displayWindow", "DisplayWindow", XtRBoolean, sizeof(Boolean),
110 	Offset(displayWindow), XtRImmediate, (caddr_t)False},
111     {"prompt", "Prompt", XtRString, sizeof(char *),
112 	Offset(prompt), XtRImmediate, (caddr_t)NULL},
113 
114 /* CRL mod 4 3/15/91 GWC - added two new application resources */
115     {"db_name", "Prompt", XtRString, sizeof(char *),
116 	Offset(db_name), XtRImmediate, (caddr_t)NULL},
117     {"db_prompt", "Prompt", XtRString, sizeof(char *),
118 	Offset(db_prompt), XtRImmediate, (caddr_t)NULL},
119 
120     {"nx", "nx", XtRBoolean, sizeof(Boolean),
121 	Offset(nx), XtRImmediate, (caddr_t)False},
122 
123     {"delimiters", "Delimiters", XtRString, sizeof(char *),
124 	Offset(delimiters), XtRImmediate, (caddr_t)NULL},
125     {"stop_color", "StopColor", XtRPixel, sizeof(Pixel),
126 	Offset(stop_color), XtRString, "Red"},
127     {"arrow_color", "ArrowColor", XtRPixel, sizeof(Pixel),
128 	Offset(arrow_color), XtRString, "Blue"},
129     {"updown_color", "UpdownColor", XtRPixel, sizeof(Pixel),
130 	Offset(updown_color), XtRString, "Blue"},
131     {"bomb_color", "bombColor", XtRPixel, sizeof(Pixel),
132 	Offset(bomb_color), XtRString, "Red"},
133     {"dataDpyMaxHeight", "DataDpyMaxHeight", XtRDimension, sizeof(Dimension),
134 	Offset(dataDpyMaxHeight), XtRString, "300"},
135     {"dataDpyMaxWidth", "DataDpyMaxWidth", XtRDimension, sizeof(Dimension),
136 	Offset(dataDpyMaxWidth), XtRString, "600"},
137     {"tabstop", "TabStop", XtRInt, sizeof(int),
138 	Offset(tabstop), XtRString, "8"},
139     {"bigicon", "Xdbxoptions", XtRBoolean, sizeof(Boolean),
140 	Offset(bigicon), XtRImmediate, (caddr_t)False},
141     {"debug", "Xdbxoptions", XtRBoolean, sizeof(Boolean),
142 	Offset(debug), XtRImmediate, (caddr_t)False},
143     {"dbxopt_r", "Dbxoptions", XtRBoolean, sizeof(Boolean),
144 	Offset(dbxopt_r), XtRImmediate, (caddr_t)False},
145     {"dbxopt_i", "Dbxoptions", XtRBoolean, sizeof(Boolean),
146 	Offset(dbxopt_i), XtRImmediate, (caddr_t)False},
147     {"includeDir", "Dbxoptions", XtRString, sizeof(char *),
148 	Offset(includeDir), XtRImmediate, (caddr_t)NULL},
149     {"dbxopt_k", "Dbxoptions", XtRBoolean, sizeof(Boolean),
150 	Offset(dbxopt_k), XtRImmediate, (caddr_t)False},
151     {"cfile", "Dbxoptions", XtRString, sizeof(char *),
152 	Offset(cfile), XtRImmediate, (caddr_t)NULL},
153     {"dbxopt_kbd", "Dbxoptions", XtRBoolean, sizeof(Boolean),
154 	Offset(dbxopt_kbd), XtRImmediate, (caddr_t)False},
155     {"fcount", "Dbxoptions", XtRString, sizeof(char *),
156 	Offset(fcount), XtRImmediate, (caddr_t)NULL},
157     {"bindings", "Xdbxoptions", XtRString, sizeof(char *),
158 	Offset(bindings), XtRImmediate, (caddr_t)NULL},
159 #ifdef GDB
160     {"gdbinit", "Dbxoptions", XtRString, sizeof(char *),
161 	Offset(gdbinit), XtRImmediate, (caddr_t)NULL},
162 #endif /* GDB */
163     {"startup", "Dbxoptions", XtRString, sizeof(char *),
164 	Offset(startup), XtRImmediate, (caddr_t)NULL},
165     {"tstartup", "Dbxoptions", XtRString, sizeof(char *),
166 	Offset(tstartup), XtRImmediate, (caddr_t)NULL},
167 };
168 
169 
170 String fallback_resources[] = {
171     "*allowShellResize:                 True",
172     "*borderWidth:			1",
173     "*font:                             fixed",
174     "*vpane.width:                      550",
175     "*fileWindow*font:     		variable",
176     "*fileLabel.width:     		500",
177     "*lineLabel.width:     		50",
178 #ifdef NEW_INTERFACE
179     "*sourceShell.geometry:             550x260+0+380",
180     "*sourceForm.top:                   ChainTop",
181     "*sourceForm.bottom:                ChainBottom",
182     "*sourceForm.left:                  ChainLeft",
183     "*sourceForm.right:                 ChainRight",
184     "*sourceForm.fromVert:              fileWindow",
185     "*sourceWindow.width:               558",
186     "*sourceWindow.height:              220",
187 #else
188     "*sourceForm.preferredPaneSize:     320",
189 #endif
190     "*sourceWindow.leftMargin:          35",
191     "*sourceWindow.scrollHorizontal:	whenNeeded",
192     "*sourceWindow.translations:	#override \\n\
193         <Btn1Down>:             SelectStart() SelectWord() \\n\
194         Shift<Btn1Up>:          Update() SelectEnd() PrintSelection() \\n\
195         <Btn1Up>:               Update() SelectEnd() \\n",
196     "*messageWindow*font:  		variable",
197     "*messageWindow.min:  		30",
198     "*messageWindow.max:  		30",
199     "*dialogWindow.preferredPaneSize:	240",
200     "*dialogWindow.resizeToPreferred:	True",
201     "*dialogWindow.translations:	#override \\n\
202         <Btn1Down>:     SelectStart() SelectWord() \\n\
203         Shift<Btn1Up>:  SelectEnd() PrintSelection() \\n\
204         <Btn1Up>:       SelectEnd() \\n",
205 #ifdef NEW_INTERFACE
206     "*commandShell.geometry:            190x370+590+0",
207 #else
208     "*commandWindow.preferredPaneSize:  146",
209     "*commandWindow.skipAdjust:		True",
210 #endif
211     "*commandWindow.hSpace:		6",
212     "*commandWindow.vSpace:		6",
213     "*Command.height:                   20",
214     "*Command.width:                    80",
215     "*List.columnSpacing:               10",
216 #ifdef NEW_INTERFACE
217     "*displayShell.geometry:            +590+450",
218     "*displayWindow.top:                ChainTop",
219     "*displayWindow.bottom:             ChainBottom",
220     "*displayWindow.left:               ChainLeft",
221     "*displayWindow.right:              ChainRight",
222     "*displayWindow.width:              300",
223     "*displayWindow.height:             100",
224 #else
225     "*displayWindow.preferredPaneSize:  50",
226     "*displayWindow.skipAdjust:         True",
227 #endif
228     "*displayWindow.scrollVertical:	whenNeeded",
229     "*displayWindow.scrollHorizontal:	whenNeeded",
230     "*displayWindow.translations:	#override \\n\
231         <Btn1Down>:             SelectStart() SelectWord() \\n\
232         Shift<Btn1Up>:          SelectEnd() PrintSelection() \\n\
233         <Btn1Up>:               SelectEnd() \\n",
234     "*popup*showGrip:  			False",
235     "*bindings:                         emacs",
236     NULL,
237 };
238 
239 static XrmOptionDescRec options[] = {
240     {"-bigicon","bigicon",	XrmoptionNoArg, "True"},
241     {"-debug",	"debug",	XrmoptionNoArg, "True"},
242 
243 /* CRL mod 4 4/1/91 GWC - command line options for db_name and db_prompt */
244     {"-db_name","db_name",      XrmoptionSepArg, NULL},
245     {"-db_prompt","db_prompt",  XrmoptionSepArg, NULL},
246 
247 #ifdef GDB
248     {"-bindings",	"bindings",       XrmoptionSepArg, "emacs"},
249     {"-d",	"includeDir",	XrmoptionSepArg, NULL},
250     {"-nx",	"nx",			XrmoptionNoArg, "True"},
251     {"-i",	"gdbinit",	XrmoptionSepArg, NULL},	/* (PW)28DEC93 : add .gdbinit overwrite */
252 #else
253     {"-r",	"dbxopt_r",	XrmoptionNoArg, "True"},
254     {"-i",	"dbxopt_i",	XrmoptionNoArg, "True"},
255     {"-I",	"includeDir",	XrmoptionSepArg, NULL},
256     {"-k",	"dbxopt_k",	XrmoptionNoArg, "True"},
257 #ifdef BSD   /* Berkeley dbx */
258     {"-c",	"cfile",	XrmoptionSepArg, NULL},
259 #else	     /* Sun dbx */
260     {"-kbd",	"dbxopt_kbd",	XrmoptionNoArg, "True"},
261     {"-f",	"fcount",	XrmoptionSepArg, NULL},
262     {"-s",	"startup",	XrmoptionSepArg, NULL},
263     {"-sr",	"tstartup",	XrmoptionSepArg, NULL},
264 #endif
265 #ifdef MIPS  /* Mips dbx */
266     {"-pixie",  "pixie",	XrmoptionNoArg, "True"},
267 #endif
268 #endif	/* not GDB */
269 };
270 
271 XtActionsRec xdbx_actions[] = {
272     {"SelectStart",	(XtActionProc) SelectStart},
273     {"SelectEnd",	(XtActionProc) SelectEnd},
274     {"SelectWord",	(XtActionProc) SelectWord},
275     {"PrintSelection",	(XtActionProc) PrintSelection},
276     {"Update",		(XtActionProc) Update},
277     {"DeleteWord",	(XtActionProc) DeleteWord},
278     {"DeleteLine",	(XtActionProc) DeleteLine},
279     {NULL, NULL}
280 };
281 
Syntax(call)282 static void Syntax(call)
283 char *call;
284 {
285     fprintf(stderr,
286 #ifdef GDB
287 	    "Usage: %s [-toolkitoptions] [-gdboptions] [objfile [corefile]]\n",
288 #else
289 	    "Usage: %s [-toolkitoptions] [-dbxoptions] [objfile [corefile]]\n",
290 #endif	/* not GDB */
291 	    call);
292     exit(1);
293 }
294 
295 /*  Set window manager hints to indicate display accepts input.
296  *  Initialize routines in source.c, signs.c and parser.c.
297  *  Disable window resize of fileWindow.
298  *  Get the name of the dbx command initialization file.
299  */
main_init()300 static void main_init()
301 {
302     XWMHints	wmhints;
303     char	title[100];
304 
305     display = XtDisplay(toplevel);
306     watch = XCreateFontCursor(display, XC_watch);
307 
308 #ifdef GDB
309     sprintf(title, "xxgdb %s", XGDBVERSION);
310     XStoreName(display, XtWindow(toplevel), title);
311     XSetIconName(display, XtWindow(toplevel), "xxgdb");
312 #else
313     sprintf(title, "xdbx %s (patch level %d)", VERSION, PATCHLEVEL);
314     XStoreName(display, XtWindow(toplevel), title);
315     XSetIconName(display, XtWindow(toplevel), "xdbx");
316 #endif	/* not GDB */
317     wmhints.input = True;
318     if (app_resources.bigicon)
319 	wmhints.icon_pixmap = XCreateBitmapFromData(display, XtWindow(toplevel),
320 	    xdbx64_bits, xdbx64_width, xdbx64_height);
321     else
322 	wmhints.icon_pixmap = XCreateBitmapFromData(display, XtWindow(toplevel),
323 	    xdbx48_bits, xdbx48_width, xdbx48_height);
324     wmhints.flags = IconPixmapHint | InputHint;
325     XSetWMHints(display, XtWindow(toplevel), &wmhints);
326 
327     if (!app_resources.delimiters ||
328 	strcmp(app_resources.delimiters, "") == 0)
329 	app_resources.delimiters = XtNewString(DELIMITERS);
330     if (app_resources.prompt && strcmp(app_resources.prompt, "") != 0)
331 	xdbxprompt = app_resources.prompt;
332     else
333 	xdbxprompt = XtNewString(XDBXPROMPT);
334     debug = app_resources.debug;
335     DisableWindowResize(fileWindow);
336 
337 #ifdef GDB
338 	/* (PW)28DEC93: we can override the default .gdbinit file */
339 	if (app_resources.gdbinit)
340 		strcpy(gdbinit, app_resources.gdbinit);
341 	else
342 		strcpy (gdbinit, ".gdbinit");
343 
344 	if (debug)
345 		fprintf(stderr,"Startup file would be \"%s\"\n", gdbinit);
346 
347 	if (app_resources.nx)
348 		strcpy(xdbxinit, "");
349 	else
350 		{
351 	    strcpy(xdbxinit, gdbinit);
352 	    if (access(xdbxinit, R_OK) == -1)
353 	    	{
354 	    	sprintf(xdbxinit, "%s/%s", (char *) getenv("HOME"), gdbinit);
355     		if (access(xdbxinit, R_OK) == -1)
356 	    		strcpy(xdbxinit, "");
357 	    	}
358     	}
359 #else
360     strcpy(xdbxinit, ".dbxinit");
361     if (access(xdbxinit, R_OK) == -1) {
362     	sprintf(xdbxinit, "%s/%s", (char *) getenv("HOME"), ".dbxinit");
363     	if (access(xdbxinit, R_OK) == -1)
364 	    	strcpy(xdbxinit, "");
365     }
366 #endif	/* not GDB */
367     source_init();
368     signs_init();
369     parser_init();
370 }
371 
372 
373 /*  Reconstruct command line arguments for calling dbx.
374  *  Return the argument list for dbx and new value of argc.
375  */
dbxoptions(argc,argv,app_resources)376 static char **dbxoptions(argc, argv, app_resources)
377     int  *argc;
378     char **argv;
379     XdbxResources *app_resources;
380 {
381     char **dbxargv;
382 #ifndef GDB
383     char *temp = (char *)XtNewString("xdbx.XXXXXX");
384 #endif
385     int  i=0;
386 
387     dbxargv = (char **) XtMalloc (MAXARGS * sizeof(char *));
388     for (i=0; i < *argc; i++)
389 	dbxargv[i] = argv[i];
390 
391 #ifdef GDB
392 	dbxargv[i++] = "-fullname";	/* see gdb_regex.h */
393 #endif	/* GDB */
394 
395     if (app_resources->dbxopt_r)
396 	dbxargv[i++] = "-r";
397     if (app_resources->dbxopt_i)
398 	dbxargv[i++] = "-i";
399     if (app_resources->includeDir) {
400 #ifdef GDB
401 	dbxargv[i++] = "-d";
402 #else
403 	dbxargv[i++] = "-I";
404 #endif	/* not GDB */
405 	dbxargv[i++] = app_resources->includeDir;
406     }
407     if (app_resources->dbxopt_k)
408 	dbxargv[i++] = "-k";
409     if (app_resources->cfile) {
410 	dbxargv[i++] = "-c";
411 	dbxargv[i++] = app_resources->cfile;
412     }
413     if (app_resources->dbxopt_kbd)
414 	dbxargv[i++] = "-kbd";
415     if (app_resources->fcount) {
416 	dbxargv[i++] = "-f";
417 	dbxargv[i++] = app_resources->fcount;
418     }
419     /*  If .dbxinit exists in the local or home directory, include the option
420      *  -c (Berkeley dbx) or -s (Sun dbx) and a dummy filename as the option
421      *	argument.  This will prevent dbx from reading the user's command
422      *	initialization file.  Xdbx will read each line and pass it to dbx
423      *  instead.
424      */
425 
426 #ifdef GDB
427      /* for GDB, always use option -nx */
428 	dbxargv[i++] = "-nx";
429 #else
430     if (strcmp(xdbxinit, "")) {		/* .dbxinit or ~/.dbxinit exists */
431 #ifdef BSD
432 	dbxargv[i++] = "-c";
433 #else
434 	dbxargv[i++] = "-s";
435 #endif
436 	dbxargv[i++] = (char *) mktemp(temp);
437     }
438 #endif	/* not GDB */
439     if (app_resources->startup) {	/* overwrites dbxinit */
440 	Tstartup = False;
441 	strcpy(xdbxinit, app_resources->startup);
442     }
443     if (app_resources->tstartup) {	/* overwrites dbxinit */
444 	Tstartup = True;
445 	strcpy(xdbxinit, app_resources->tstartup);
446     }
447 #ifndef GDB
448 #ifdef MIPS
449     if (app_resources->pixie) {		/* pixie output */
450 	dbxargv[i++] = "-pixie";
451     }
452 #endif
453 #endif	/* not GDB */
454     dbxargv[i] = NULL;
455     *argc = i;
456     return dbxargv;
457 }
458 
main(argc,argv)459 void main(argc, argv)
460 int argc;
461 char **argv;
462 {
463     char 	**dbxargv;
464 
465     progname = argv[0];			/* (MJH) */
466 
467 #ifndef GDB /* (PW)12MAR93 : for gdb, use pwd command of gdb */
468 #ifdef SYSV
469     getcwd((char *)cwd, MAXPATHLEN);
470 #endif
471 #endif /* not GDB */
472 
473     trap_signals();
474 
475     toplevel = XtAppInitialize(&app_context, "XDbx", options, XtNumber(options),
476 			       &argc, argv, fallback_resources, NULL, 0);
477     if (argc > 3) Syntax(argv[0]);
478 
479     XtGetApplicationResources(toplevel, &app_resources, resources,
480                               XtNumber(resources), NULL, 0);
481     XtAppAddActions(app_context, xdbx_actions, XtNumber(xdbx_actions));
482     CreateSubWindows(toplevel);
483     XtRealizeWidget(toplevel);
484 
485     main_init();
486 
487 #ifdef GDB
488     AppendDialogText("XXGDB comes with ABSOLUTELY NO WARRANTY.\n");
489 #endif
490 
491     dbxargv = dbxoptions(&argc, argv, &app_resources);
492     calldbx(argc, dbxargv);
493 
494 #ifdef NEW_INTERFACE
495     State_Transient(sourceToggle, sourceShell, NULL);
496     State_Transient(commandToggle, commandShell, NULL);
497 #ifdef GDB
498     State_Transient(displayToggle, displayShell, NULL);
499 #endif
500     XtRealizeWidget(toplevel); /* just to bring the window ahead */
501 #endif /* NEW_INTERFACE */
502 
503     XtAppMainLoop(app_context);
504 }
505