Mon Nov 9 18:22:55 1998 Dave Brolley <brolley@cygnus.com>
[deliverable/binutils-gdb.git] / gdb / gdbtk.c
CommitLineData
ca4e7e14 1/* Startup code for gdbtk.
a5f4fbff 2 Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
4604b34c
SG
3
4 Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support.
754e5da2
SG
5
6This file is part of GDB.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
6c9638b4 20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
754e5da2
SG
21
22#include "defs.h"
23#include "symtab.h"
24#include "inferior.h"
25#include "command.h"
26#include "bfd.h"
27#include "symfile.h"
28#include "objfiles.h"
29#include "target.h"
018d76dd
KS
30#include "gdbcore.h"
31#include "tracepoint.h"
929db6e5 32#include "demangle.h"
018d76dd
KS
33
34#ifdef _WIN32
35#include <winuser.h>
36#endif
37
e6e9507d
EZ
38#include <sys/stat.h>
39
754e5da2
SG
40#include <tcl.h>
41#include <tk.h>
2476848a
MH
42#include <itcl.h>
43#include <tix.h>
dd3dd918 44#include "guitcl.h"
ca4e7e14 45#include "gdbtk.h"
2476848a
MH
46
47#ifdef IDE
018d76dd 48/* start-sanitize-ide */
2476848a
MH
49#include "event.h"
50#include "idetcl.h"
018d76dd
KS
51#include "ilutk.h"
52/* end-sanitize-ide */
2476848a
MH
53#endif
54
73d3dbd4 55#ifdef ANSI_PROTOTYPES
85c613aa
C
56#include <stdarg.h>
57#else
cd2df226 58#include <varargs.h>
85c613aa 59#endif
cd2df226
SG
60#include <signal.h>
61#include <fcntl.h>
8532893d 62#include <unistd.h>
86db943c
SG
63#include <setjmp.h>
64#include "top.h"
736a82e7 65#include <sys/ioctl.h>
2b576293 66#include "gdb_string.h"
09722039 67#include "dis-asm.h"
6131622e
SG
68#include <stdio.h>
69#include "gdbcmd.h"
736a82e7 70
929db6e5 71#include "annotate.h"
018d76dd 72#include <sys/time.h>
018d76dd 73
ca4e7e14
JI
74/* For Cygwin32, we use a timer to periodically check for Windows
75 messages. FIXME: It would be better to not poll, but to instead
76 rewrite the target_wait routines to serve as input sources.
77 Unfortunately, that will be a lot of work. */
78static sigset_t nullsigmask;
79static struct sigaction act1, act2;
80static struct itimerval it_on, it_off;
8b3f9ed6 81
94a6f14f
MH
82extern int Tktable_Init PARAMS ((Tcl_Interp *interp));
83
2476848a 84static void gdbtk_init PARAMS ((char *));
ca4e7e14 85void gdbtk_interactive PARAMS ((void));
b607efe7
FF
86static void cleanup_init PARAMS ((int));
87static void tk_command PARAMS ((char *, int));
ca4e7e14 88
6f5af15b 89void gdbtk_add_hooks PARAMS ((void));
ca4e7e14
JI
90int gdbtk_test PARAMS ((char *));
91
92/*
93 * gdbtk_fputs is defined in the gdbtk_hooks.c, but we need it here
94 * because we delay adding this hook till all the setup is done. That
95 * way errors will go to stdout.
96 */
97
98extern void gdbtk_fputs PARAMS ((const char *, FILE *));
b607efe7 99
754e5da2 100/* Handle for TCL interpreter */
7f6cb62e 101Tcl_Interp *gdbtk_interp = NULL;
754e5da2 102
0776b0b0 103static int gdbtk_timer_going = 0;
0776b0b0 104
4ff5d55a
MH
105/* linked variable used to tell tcl what the current thread is */
106int gdb_context = 0;
107
ca4e7e14
JI
108/* This variable is true when the inferior is running. See note in
109 * gdbtk.h for details.
110 */
ca4e7e14 111int running_now;
fda6fadc
SS
112
113/* This variable determines where memory used for disassembly is read from.
ca4e7e14
JI
114 * See note in gdbtk.h for details.
115 */
ca4e7e14 116int disassemble_from_exec = -1;
09722039 117
7f6cb62e
KS
118/* This variable holds the name of a Tcl file which should be sourced by the
119 interpreter when it goes idle at startup. Used with the testsuite. */
ca4e7e14
JI
120static char *gdbtk_source_filename = NULL;
121\f
9b119644
ILT
122#ifndef _WIN32
123
124/* Supply malloc calls for tcl/tk. We do not want to do this on
125 Windows, because Tcl_Alloc is probably in a DLL which will not call
126 the mmalloc routines. */
8c19daa1
SG
127
128char *
a5a6e3bd 129Tcl_Alloc (size)
8c19daa1
SG
130 unsigned int size;
131{
132 return xmalloc (size);
133}
134
135char *
136Tcl_Realloc (ptr, size)
137 char *ptr;
138 unsigned int size;
139{
140 return xrealloc (ptr, size);
141}
142
143void
144Tcl_Free(ptr)
145 char *ptr;
146{
147 free (ptr);
148}
149
018d76dd 150#endif /* ! _WIN32 */
9b119644 151
018d76dd
KS
152#ifdef _WIN32
153
154/* On Windows, if we hold a file open, other programs can't write to
ca4e7e14
JI
155 * it. In particular, we don't want to hold the executable open,
156 * because it will mean that people have to get out of the debugging
157 * session in order to remake their program. So we close it, although
158 * this will cost us if and when we need to reopen it.
159 */
018d76dd 160
ca4e7e14 161void
018d76dd
KS
162close_bfds ()
163{
164 struct objfile *o;
165
166 ALL_OBJFILES (o)
167 {
168 if (o->obfd != NULL)
169 bfd_cache_close (o->obfd);
170 }
171
172 if (exec_bfd != NULL)
173 bfd_cache_close (exec_bfd);
174}
175
176#endif /* _WIN32 */
177
754e5da2 178\f
ca4e7e14
JI
179/* TclDebug (const char *fmt, ...) works just like printf() but
180 * sends the output to the GDB TK debug window.
181 * Not for normal use; just a convenient tool for debugging
182 */
41756e56 183
ca4e7e14 184void
41756e56 185#ifdef ANSI_PROTOTYPES
ca4e7e14 186TclDebug (const char *fmt, ...)
41756e56 187#else
ca4e7e14 188TclDebug (va_alist)
41756e56
FF
189 va_dcl
190#endif
191{
192 va_list args;
ca4e7e14 193 char buf[512], *v[2], *merge;
41756e56
FF
194
195#ifdef ANSI_PROTOTYPES
ca4e7e14 196 va_start (args, fmt);
41756e56 197#else
ca4e7e14 198 char *fmt;
41756e56 199 va_start (args);
ca4e7e14 200 fmt = va_arg (args, char *);
41756e56
FF
201#endif
202
ca4e7e14
JI
203 v[0] = "debug";
204 v[1] = buf;
41756e56 205
ca4e7e14
JI
206 vsprintf (buf, fmt, args);
207 va_end (args);
018d76dd 208
ca4e7e14
JI
209 merge = Tcl_Merge (2, v);
210 Tcl_Eval (gdbtk_interp, merge);
211 Tcl_Free (merge);
41756e56
FF
212}
213
ca4e7e14
JI
214\f
215/*
216 * The rest of this file contains the start-up, and event handling code for gdbtk.
217 */
218
219/*
220 * This cleanup function is added to the cleanup list that surrounds the Tk
221 * main in gdbtk_init. It deletes the Tcl interpreter.
222 */
223
41756e56 224static void
ca4e7e14
JI
225cleanup_init (ignored)
226 int ignored;
41756e56 227{
ca4e7e14
JI
228 if (gdbtk_interp != NULL)
229 Tcl_DeleteInterp (gdbtk_interp);
230 gdbtk_interp = NULL;
41756e56
FF
231}
232
ca4e7e14
JI
233/* Come here during long calculations to check for GUI events. Usually invoked
234 via the QUIT macro. */
235
236void
237gdbtk_interactive ()
929db6e5 238{
ca4e7e14 239 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
929db6e5
EZ
240}
241
ca4e7e14
JI
242
243void
244gdbtk_start_timer ()
6131622e 245{
ca4e7e14
JI
246 static int first = 1;
247 /*TclDebug ("Starting timer....");*/
248 if (first)
249 {
250 /* first time called, set up all the structs */
251 first = 0;
252 sigemptyset (&nullsigmask);
85c613aa 253
ca4e7e14
JI
254 act1.sa_handler = x_event;
255 act1.sa_mask = nullsigmask;
256 act1.sa_flags = 0;
6131622e 257
ca4e7e14
JI
258 act2.sa_handler = SIG_IGN;
259 act2.sa_mask = nullsigmask;
260 act2.sa_flags = 0;
6131622e 261
ca4e7e14
JI
262 it_on.it_interval.tv_sec = 0;
263 it_on.it_interval.tv_usec = 250000; /* .25 sec */
264 it_on.it_value.tv_sec = 0;
265 it_on.it_value.tv_usec = 250000;
6131622e 266
ca4e7e14
JI
267 it_off.it_interval.tv_sec = 0;
268 it_off.it_interval.tv_usec = 0;
269 it_off.it_value.tv_sec = 0;
270 it_off.it_value.tv_usec = 0;
271 }
272
273 if (!gdbtk_timer_going)
274 {
275 sigaction (SIGALRM, &act1, NULL);
276 setitimer (ITIMER_REAL, &it_on, NULL);
277 gdbtk_timer_going = 1;
278 }
6131622e
SG
279}
280
ca4e7e14
JI
281void
282gdbtk_stop_timer ()
8a19b35a 283{
ca4e7e14 284 if (gdbtk_timer_going)
8a19b35a 285 {
ca4e7e14
JI
286 gdbtk_timer_going = 0;
287 /*TclDebug ("Stopping timer.");*/
288 setitimer (ITIMER_REAL, &it_off, NULL);
289 sigaction (SIGALRM, &act2, NULL);
8a19b35a 290 }
8a19b35a
MH
291}
292
ca4e7e14 293/* gdbtk_init installs this function as a final cleanup. */
6131622e 294
ca4e7e14
JI
295static void
296gdbtk_cleanup (dummy)
297 PTR dummy;
298{
4d14b252 299 Tcl_Eval (gdbtk_interp, "gdbtk_cleanup");
ca4e7e14 300#ifdef IDE
1dd251f9
DM
301 {
302 struct ide_event_handle *h = (struct ide_event_handle *) dummy;
303 ide_interface_deregister_all (h);
304 }
ca4e7e14
JI
305#endif
306 Tcl_Finalize ();
6131622e
SG
307}
308
ca4e7e14
JI
309/* Initialize gdbtk. This involves creating a Tcl interpreter,
310 * defining all the Tcl commands that the GUI will use, pointing
311 * all the gdb "hooks" to the correct functions,
312 * and setting the Tcl auto loading environment so that we can find all
313 * the Tcl based library files.
314 */
315
754e5da2 316static void
ca4e7e14
JI
317gdbtk_init ( argv0 )
318 char *argv0;
754e5da2 319{
ca4e7e14
JI
320 struct cleanup *old_chain;
321 char *lib, *gdbtk_lib, *gdbtk_lib_tmp, *gdbtk_file;
6f5af15b 322 int found_main;
ca4e7e14 323 Tcl_Obj *auto_path_elem, *auto_path_name;
6f5af15b 324
ca4e7e14
JI
325#ifdef IDE
326 /* start-sanitize-ide */
327 struct ide_event_handle *h;
328 const char *errmsg;
329 char *libexecdir;
330 /* end-sanitize-ide */
331#endif
332
333 /* If there is no DISPLAY environment variable, Tk_Init below will fail,
334 causing gdb to abort. If instead we simply return here, gdb will
335 gracefully degrade to using the command line interface. */
754e5da2 336
ca4e7e14
JI
337#ifndef WINNT
338 if (getenv ("DISPLAY") == NULL)
754e5da2 339 return;
ca4e7e14 340#endif
754e5da2 341
ad3b8c4a 342 old_chain = make_cleanup ((make_cleanup_func) cleanup_init, 0);
929db6e5 343
ca4e7e14
JI
344 /* First init tcl and tk. */
345 Tcl_FindExecutable (argv0);
346 gdbtk_interp = Tcl_CreateInterp ();
754e5da2 347
ca4e7e14
JI
348#ifdef TCL_MEM_DEBUG
349 Tcl_InitMemory (gdbtk_interp);
350#endif
754e5da2 351
ca4e7e14
JI
352 if (!gdbtk_interp)
353 error ("Tcl_CreateInterp failed");
754e5da2 354
ca4e7e14
JI
355 if (Tcl_Init(gdbtk_interp) != TCL_OK)
356 error ("Tcl_Init failed: %s", gdbtk_interp->result);
754e5da2 357
ca4e7e14
JI
358#ifndef IDE
359 /* For the IDE we register the cleanup later, after we've
360 initialized events. */
361 make_final_cleanup (gdbtk_cleanup, NULL);
746d1df4
SG
362#endif
363
ca4e7e14
JI
364 /* Initialize the Paths variable. */
365 if (ide_initialize_paths (gdbtk_interp, "gdbtcl") != TCL_OK)
366 error ("ide_initialize_paths failed: %s", gdbtk_interp->result);
746d1df4 367
ca4e7e14
JI
368#ifdef IDE
369 /* start-sanitize-ide */
370 /* Find the directory where we expect to find idemanager. We ignore
371 errors since it doesn't really matter if this fails. */
372 libexecdir = Tcl_GetVar2 (gdbtk_interp, "Paths", "libexecdir", TCL_GLOBAL_ONLY);
746d1df4 373
ca4e7e14 374 IluTk_Init ();
929db6e5 375
ca4e7e14
JI
376 h = ide_event_init_from_environment (&errmsg, libexecdir);
377 make_final_cleanup (gdbtk_cleanup, h);
378 if (h == NULL)
746d1df4 379 {
ca4e7e14
JI
380 Tcl_AppendResult (gdbtk_interp, "can't initialize event system: ", errmsg,
381 (char *) NULL);
382 fprintf(stderr, "WARNING: ide_event_init_client failed: %s\n", gdbtk_interp->result);
746d1df4 383
ca4e7e14 384 Tcl_SetVar (gdbtk_interp, "IDE_ENABLED", "0", 0);
746d1df4 385 }
ca4e7e14 386 else
3d9f68c0 387 {
ca4e7e14
JI
388 if (ide_create_tclevent_command (gdbtk_interp, h) != TCL_OK)
389 error ("ide_create_tclevent_command failed: %s", gdbtk_interp->result);
0422b59e 390
ca4e7e14
JI
391 if (ide_create_edit_command (gdbtk_interp, h) != TCL_OK)
392 error ("ide_create_edit_command failed: %s", gdbtk_interp->result);
393
394 if (ide_create_property_command (gdbtk_interp, h) != TCL_OK)
395 error ("ide_create_property_command failed: %s", gdbtk_interp->result);
018d76dd 396
ca4e7e14
JI
397 if (ide_create_build_command (gdbtk_interp, h) != TCL_OK)
398 error ("ide_create_build_command failed: %s", gdbtk_interp->result);
754e5da2 399
ca4e7e14
JI
400 if (ide_create_window_register_command (gdbtk_interp, h, "gdb-restore")
401 != TCL_OK)
402 error ("ide_create_window_register_command failed: %s",
403 gdbtk_interp->result);
fda6fadc 404
ca4e7e14
JI
405 if (ide_create_window_command (gdbtk_interp, h) != TCL_OK)
406 error ("ide_create_window_command failed: %s", gdbtk_interp->result);
0b7148e4 407
ca4e7e14
JI
408 if (ide_create_exit_command (gdbtk_interp, h) != TCL_OK)
409 error ("ide_create_exit_command failed: %s", gdbtk_interp->result);
018d76dd 410
ca4e7e14
JI
411 if (ide_create_help_command (gdbtk_interp) != TCL_OK)
412 error ("ide_create_help_command failed: %s", gdbtk_interp->result);
018d76dd 413
ca4e7e14
JI
414 /*
415 if (ide_initialize (gdbtk_interp, "gdb") != TCL_OK)
416 error ("ide_initialize failed: %s", gdbtk_interp->result);
417 */
479f0f18 418
ca4e7e14 419 Tcl_SetVar (gdbtk_interp, "IDE_ENABLED", "1", 0);
7234efcb 420 }
ca4e7e14
JI
421 /* end-sanitize-ide */
422#else
423 Tcl_SetVar (gdbtk_interp, "IDE_ENABLED", "0", 0);
424#endif /* IDE */
0776b0b0 425
ca4e7e14
JI
426 /* We don't want to open the X connection until we've done all the
427 IDE initialization. Otherwise, goofy looking unfinished windows
428 pop up when ILU drops into the TCL event loop. */
86db943c 429
ca4e7e14
JI
430 if (Tk_Init(gdbtk_interp) != TCL_OK)
431 error ("Tk_Init failed: %s", gdbtk_interp->result);
86db943c 432
ca4e7e14
JI
433 if (Itcl_Init(gdbtk_interp) == TCL_ERROR)
434 error ("Itcl_Init failed: %s", gdbtk_interp->result);
435 Tcl_StaticPackage(gdbtk_interp, "Tktable", Tktable_Init,
436 (Tcl_PackageInitProc *) NULL);
09722039 437
ca4e7e14
JI
438 if (Tix_Init(gdbtk_interp) != TCL_OK)
439 error ("Tix_Init failed: %s", gdbtk_interp->result);
440 Tcl_StaticPackage(gdbtk_interp, "Tktable", Tktable_Init,
441 (Tcl_PackageInitProc *) NULL);
86db943c 442
ca4e7e14
JI
443 if (Tktable_Init(gdbtk_interp) != TCL_OK)
444 error ("Tktable_Init failed: %s", gdbtk_interp->result);
929db6e5 445
ca4e7e14
JI
446 Tcl_StaticPackage(gdbtk_interp, "Tktable", Tktable_Init,
447 (Tcl_PackageInitProc *) NULL);
448 /*
449 * These are the commands to do some Windows Specific stuff...
450 */
018d76dd 451
ca4e7e14
JI
452#ifdef __CYGWIN32__
453 if (ide_create_messagebox_command (gdbtk_interp) != TCL_OK)
454 error ("messagebox command initialization failed");
455 /* On Windows, create a sizebox widget command */
456 if (ide_create_sizebox_command (gdbtk_interp) != TCL_OK)
457 error ("sizebox creation failed");
458 if (ide_create_winprint_command (gdbtk_interp) != TCL_OK)
459 error ("windows print code initialization failed");
018d76dd 460 /* start-sanitize-ide */
ca4e7e14
JI
461 /* An interface to ShellExecute. */
462 if (ide_create_shell_execute_command (gdbtk_interp) != TCL_OK)
463 error ("shell execute command initialization failed");
018d76dd 464 /* end-sanitize-ide */
ca4e7e14
JI
465 if (ide_create_win_grab_command (gdbtk_interp) != TCL_OK)
466 error ("grab support command initialization failed");
467 /* Path conversion functions. */
468 if (ide_create_cygwin_path_command (gdbtk_interp) != TCL_OK)
469 error ("cygwin path command initialization failed");
470#endif
018d76dd 471
ca4e7e14
JI
472 /*
473 * This adds all the Gdbtk commands.
474 */
475
476 if (Gdbtk_Init(gdbtk_interp) != TCL_OK)
018d76dd 477 {
ca4e7e14 478 error("Gdbtk_Init failed: %s", gdbtk_interp->result);
018d76dd 479 }
4f17e6eb 480
ca4e7e14
JI
481 Tcl_StaticPackage(gdbtk_interp, "Gdbtk", Gdbtk_Init, NULL);
482
483 /* This adds all the hooks that call up from the bowels of gdb
484 * back into Tcl-land...
485 */
e0f7db02 486
ca4e7e14
JI
487 gdbtk_add_hooks();
488
489 /* Add a back door to Tk from the gdb console... */
e0f7db02 490
ca4e7e14
JI
491 add_com ("tk", class_obscure, tk_command,
492 "Send a command directly into tk.");
e0f7db02 493
ca4e7e14
JI
494 Tcl_LinkVar (gdbtk_interp, "disassemble-from-exec", (char *) &disassemble_from_exec,
495 TCL_LINK_INT);
e0f7db02 496
ca4e7e14 497 /* find the gdb tcl library and source main.tcl */
929db6e5 498
ca4e7e14
JI
499 gdbtk_lib = getenv ("GDBTK_LIBRARY");
500 if (!gdbtk_lib)
6f5af15b
MH
501 {
502 if (access ("gdbtcl/main.tcl", R_OK) == 0)
503 gdbtk_lib = "gdbtcl";
504 else
505 gdbtk_lib = GDBTK_LIBRARY;
506 }
507
ca4e7e14 508 gdbtk_lib_tmp = xstrdup (gdbtk_lib);
929db6e5 509
ca4e7e14
JI
510 found_main = 0;
511 /* see if GDBTK_LIBRARY is a path list */
512 lib = strtok (gdbtk_lib_tmp, GDBTK_PATH_SEP);
929db6e5 513
ca4e7e14 514 auto_path_name = Tcl_NewStringObj ("auto_path", -1);
929db6e5 515
ca4e7e14 516 do
929db6e5 517 {
ca4e7e14
JI
518 auto_path_elem = Tcl_NewStringObj (lib, -1);
519 if (Tcl_ObjSetVar2 (gdbtk_interp, auto_path_name, NULL, auto_path_elem,
520 TCL_GLOBAL_ONLY | TCL_APPEND_VALUE | TCL_LIST_ELEMENT ) == NULL)
929db6e5 521 {
ca4e7e14
JI
522 fputs_unfiltered (Tcl_GetVar (gdbtk_interp, "errorInfo", 0), gdb_stderr);
523 error ("");
929db6e5 524 }
ca4e7e14 525 if (!found_main)
929db6e5 526 {
ca4e7e14
JI
527 gdbtk_file = concat (lib, "/main.tcl", (char *) NULL);
528 if (access (gdbtk_file, R_OK) == 0)
929db6e5 529 {
ca4e7e14
JI
530 found_main++;
531 Tcl_SetVar (gdbtk_interp, "GDBTK_LIBRARY", lib, 0);
929db6e5
EZ
532 }
533 }
ca4e7e14
JI
534 }
535 while ((lib = strtok (NULL, ":")) != NULL);
929db6e5 536
ca4e7e14
JI
537 free (gdbtk_lib_tmp);
538 Tcl_DecrRefCount(auto_path_name);
e0f7db02 539
ca4e7e14 540 if (!found_main)
e6e9507d 541 {
ca4e7e14 542 /* Try finding it with the auto path. */
929db6e5 543
ca4e7e14
JI
544 static const char script[] ="\
545proc gdbtk_find_main {} {\n\
546 global auto_path GDBTK_LIBRARY\n\
547 foreach dir $auto_path {\n\
548 set f [file join $dir main.tcl]\n\
549 if {[file exists $f]} then {\n\
550 set GDBTK_LIBRARY $dir\n\
551 return $f\n\
552 }\n\
553 }\n\
554 return ""\n\
555}\n\
556gdbtk_find_main";
929db6e5 557
ca4e7e14
JI
558 if (Tcl_GlobalEval (gdbtk_interp, (char *) script) != TCL_OK)
559 {
560 fputs_unfiltered (Tcl_GetVar (gdbtk_interp, "errorInfo", 0), gdb_stderr);
561 error ("");
562 }
929db6e5 563
ca4e7e14 564 if (gdbtk_interp->result[0] != '\0')
929db6e5 565 {
ca4e7e14
JI
566 gdbtk_file = xstrdup (gdbtk_interp->result);
567 found_main++;
929db6e5
EZ
568 }
569 }
11f91b2b 570
ca4e7e14 571 if (!found_main)
929db6e5 572 {
ca4e7e14
JI
573 fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
574 if (getenv("GDBTK_LIBRARY"))
929db6e5 575 {
ca4e7e14
JI
576 fprintf_unfiltered (stderr, "Unable to find main.tcl in %s\n",getenv("GDBTK_LIBRARY"));
577 fprintf_unfiltered (stderr,
578 "Please set GDBTK_LIBRARY to a path that includes the GDB tcl files.\n");
929db6e5
EZ
579 }
580 else
581 {
ca4e7e14
JI
582 fprintf_unfiltered (stderr, "Unable to find main.tcl in %s\n", GDBTK_LIBRARY);
583 fprintf_unfiltered (stderr, "You might want to set GDBTK_LIBRARY\n");
929db6e5 584 }
ca4e7e14 585 error("");
929db6e5 586 }
11f91b2b 587
ca4e7e14
JI
588/* Defer setup of fputs_unfiltered_hook to near the end so that error messages
589 prior to this point go to stdout/stderr. */
929db6e5 590
ca4e7e14 591 fputs_unfiltered_hook = gdbtk_fputs;
929db6e5 592
ca4e7e14
JI
593/* start-sanitize-tclpro */
594#ifdef TCLPRO_DEBUGGER
595 {
596 Tcl_DString source_cmd;
929db6e5 597
ca4e7e14
JI
598 Tcl_DStringInit (&source_cmd);
599 Tcl_DStringAppend (&source_cmd,
600 "if {[info exists env(DEBUG_STUB)]} {source $env(DEBUG_STUB); " -1);
601 Tcl_DStringAppend (&source_cmd, "debugger_init; debugger_eval {source {", -1);
602 Tcl_DStringAppend (&source_cmd, gdbtk_file, -1);
603 Tcl_DStringAppend (&source_cmd, "}}} else {source {", -1);
604 Tcl_DStringAppend (&source_cmd, gdbtk_file, -1);
605 Tcl_DStringAppend (&source_cmd, "}}", -1);
606 if (Tcl_GlobalEval (gdbtk_interp, Tcl_DStringValue (&source_cmd)) != TCL_OK)
607#else
608/* end-sanitize-tclpro */
609 if (Tcl_EvalFile (gdbtk_interp, gdbtk_file) != TCL_OK)
610/* start-sanitize-tclpro */
611#endif
612/* end-sanitize-tclpro */
613 {
614 char *msg;
929db6e5 615
ca4e7e14
JI
616 /* Force errorInfo to be set up propertly. */
617 Tcl_AddErrorInfo (gdbtk_interp, "");
e0f7db02 618
ca4e7e14 619 msg = Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY);
4f17e6eb 620
ca4e7e14 621 fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
7f6cb62e 622
ca4e7e14
JI
623#ifdef _WIN32
624 MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
625#else
626 fputs_unfiltered (msg, gdb_stderr);
627#endif
7f6cb62e 628
ca4e7e14 629 error ("");
7f6cb62e 630 }
ca4e7e14
JI
631/* start-sanitize-tclpro */
632#ifdef TCLPRO_DEBUGGER
633 Tcl_DStringFree(&source_cmd);
7f6cb62e 634 }
ca4e7e14
JI
635#endif
636/* end-sanitize-tclpro */
7f6cb62e 637
ca4e7e14
JI
638#ifdef IDE
639 /* start-sanitize-ide */
640 /* Don't do this until we have initialized. Otherwise, we may get a
641 run command before we are ready for one. */
642 if (ide_run_server_init (gdbtk_interp, h) != TCL_OK)
643 error ("ide_run_server_init failed: %s", gdbtk_interp->result);
644 /* end-sanitize-ide */
645#endif
7f6cb62e 646
ca4e7e14 647 free (gdbtk_file);
7f6cb62e 648
ca4e7e14
JI
649 /* Now source in the filename provided by the --tclcommand option.
650 This is mostly used for the gdbtk testsuite... */
7f6cb62e 651
ca4e7e14
JI
652 if (gdbtk_source_filename != NULL)
653 {
654 char *s = "after idle source ";
655 char *script = concat (s, gdbtk_source_filename, (char *) NULL);
656 Tcl_Eval (gdbtk_interp, script);
657 free (gdbtk_source_filename);
658 free (script);
659 }
660
661
662 discard_cleanups (old_chain);
7f6cb62e
KS
663}
664
ca4e7e14
JI
665/* gdbtk_test is used in main.c to validate the -tclcommand option to
666 gdb, which sources in a file of tcl code after idle during the
667 startup procedure. */
668
7f6cb62e
KS
669int
670gdbtk_test (filename)
671 char *filename;
672{
673 if (access (filename, R_OK) != 0)
674 return 0;
675 else
676 gdbtk_source_filename = xstrdup (filename);
677 return 1;
678}
ca4e7e14 679
3f37b696 680/* Come here during initialize_all_files () */
754e5da2
SG
681
682void
683_initialize_gdbtk ()
684{
c5197511
SG
685 if (use_windows)
686 {
687 /* Tell the rest of the world that Gdbtk is now set up. */
754e5da2 688
c5197511 689 init_ui_hook = gdbtk_init;
47792960
KS
690#ifdef __CYGWIN32__
691 (void) FreeConsole ();
692#endif
c5197511 693 }
cb432079
EZ
694#ifdef __CYGWIN32__
695 else
696 {
697 DWORD ft = GetFileType (GetStdHandle (STD_INPUT_HANDLE));
698 void cygwin32_attach_handle_to_fd (char *, int, HANDLE, int, int);
699
700 switch (ft)
701 {
702 case FILE_TYPE_DISK:
703 case FILE_TYPE_CHAR:
704 case FILE_TYPE_PIPE:
705 break;
706 default:
707 AllocConsole();
708 cygwin32_attach_handle_to_fd ("/dev/conin", 0,
709 GetStdHandle (STD_INPUT_HANDLE),
710 1, GENERIC_READ);
711 cygwin32_attach_handle_to_fd ("/dev/conout", 1,
712 GetStdHandle (STD_OUTPUT_HANDLE),
713 0, GENERIC_WRITE);
714 cygwin32_attach_handle_to_fd ("/dev/conout", 2,
715 GetStdHandle (STD_ERROR_HANDLE),
716 0, GENERIC_WRITE);
717 break;
718 }
719 }
720#endif
754e5da2 721}
ca4e7e14
JI
722
723static void
724tk_command (cmd, from_tty)
725 char *cmd;
726 int from_tty;
727{
728 int retval;
729 char *result;
730 struct cleanup *old_chain;
731
732 /* Catch case of no argument, since this will make the tcl interpreter dump core. */
733 if (cmd == NULL)
734 error_no_arg ("tcl command to interpret");
735
736 retval = Tcl_Eval (gdbtk_interp, cmd);
737
738 result = strdup (gdbtk_interp->result);
739
740 old_chain = make_cleanup (free, result);
741
742 if (retval != TCL_OK)
743 error (result);
744
745 printf_unfiltered ("%s\n", result);
746
747 do_cleanups (old_chain);
748}
749
This page took 0.370059 seconds and 4 git commands to generate.