* stabsread.c (get_substring): Declare second arg as int.
[deliverable/binutils-gdb.git] / gdb / gdbtk.c
CommitLineData
4604b34c 1/* Tcl/Tk interface routines.
1a57cd09 2 Copyright 1994, 1995, 1996 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"
754e5da2
SG
30#include <tcl.h>
31#include <tk.h>
73d3dbd4 32#ifdef ANSI_PROTOTYPES
85c613aa
C
33#include <stdarg.h>
34#else
cd2df226 35#include <varargs.h>
85c613aa 36#endif
cd2df226
SG
37#include <signal.h>
38#include <fcntl.h>
8532893d 39#include <unistd.h>
86db943c
SG
40#include <setjmp.h>
41#include "top.h"
736a82e7 42#include <sys/ioctl.h>
2b576293 43#include "gdb_string.h"
09722039 44#include "dis-asm.h"
6131622e
SG
45#include <stdio.h>
46#include "gdbcmd.h"
736a82e7
SG
47
48#ifndef FIOASYNC
546b8ca7
SG
49#include <sys/stropts.h>
50#endif
754e5da2 51
8b3f9ed6 52/* Some versions (1.3.79, 1.3.81) of Linux don't support SIOCSPGRP the way
3f37b696 53 gdbtk wants to use it... */
8b3f9ed6
MM
54#ifdef __linux__
55#undef SIOCSPGRP
56#endif
57
b607efe7
FF
58static void null_routine PARAMS ((int));
59static void gdbtk_flush PARAMS ((FILE *));
60static void gdbtk_fputs PARAMS ((const char *, FILE *));
61static int gdbtk_query PARAMS ((const char *, va_list));
62static char *gdbtk_readline PARAMS ((char *));
63static void gdbtk_init PARAMS ((void));
64static void tk_command_loop PARAMS ((void));
65static void gdbtk_call_command PARAMS ((struct cmd_list_element *, char *, int));
66static int gdbtk_wait PARAMS ((int, struct target_waitstatus *));
67static void x_event PARAMS ((int));
68static void gdbtk_interactive PARAMS ((void));
69static void cleanup_init PARAMS ((int));
70static void tk_command PARAMS ((char *, int));
71static int gdb_disassemble PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
72static int compare_lines PARAMS ((const PTR, const PTR));
73static int gdbtk_dis_asm_read_memory PARAMS ((bfd_vma, bfd_byte *, int, disassemble_info *));
74static int gdb_stop PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
75static int gdb_listfiles PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
76static int call_wrapper PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
77static int gdb_cmd PARAMS ((ClientData, Tcl_Interp *, int, char *argv[]));
78static int gdb_fetch_registers PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
79static void gdbtk_readline_end PARAMS ((void));
80static int gdb_changed_register_list PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
81static void register_changed_p PARAMS ((int, void *));
82static int gdb_get_breakpoint_list PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
83static int gdb_get_breakpoint_info PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
84static void breakpoint_notify PARAMS ((struct breakpoint *, const char *));
85static void gdbtk_create_breakpoint PARAMS ((struct breakpoint *));
86static void gdbtk_delete_breakpoint PARAMS ((struct breakpoint *));
87static void gdbtk_modify_breakpoint PARAMS ((struct breakpoint *));
88static int gdb_loc PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
89static int gdb_eval PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
90static int gdb_sourcelines PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
91static int map_arg_registers PARAMS ((int, char *[], void (*) (int, void *), void *));
92static void get_register_name PARAMS ((int, void *));
93static int gdb_regnames PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
94static void get_register PARAMS ((int, void *));
95
754e5da2 96/* Handle for TCL interpreter */
fda6fadc 97
754e5da2
SG
98static Tcl_Interp *interp = NULL;
99
100/* Handle for TK main window */
fda6fadc 101
754e5da2
SG
102static Tk_Window mainWindow = NULL;
103
479f0f18
SG
104static int x_fd; /* X network socket */
105
fda6fadc
SS
106/* This variable is true when the inferior is running. Although it's
107 possible to disable most input from widgets and thus prevent
108 attempts to do anything while the inferior is running, any commands
109 that get through - even a simple memory read - are Very Bad, and
110 may cause GDB to crash or behave strangely. So, this variable
111 provides an extra layer of defense. */
09722039 112
fda6fadc
SS
113static int running_now;
114
115/* This variable determines where memory used for disassembly is read from.
116 If > 0, then disassembly comes from the exec file rather than the
117 target (which might be at the other end of a slow serial link). If
118 == 0 then disassembly comes from target. If < 0 disassembly is
119 automatically switched to the target if it's an inferior process,
120 otherwise the exec file is used. */
09722039
SG
121
122static int disassemble_from_exec = -1;
123
8c19daa1
SG
124/* Supply malloc calls for tcl/tk. */
125
126char *
127Tcl_Malloc (size)
128 unsigned int size;
129{
130 return xmalloc (size);
131}
132
133char *
134Tcl_Realloc (ptr, size)
135 char *ptr;
136 unsigned int size;
137{
138 return xrealloc (ptr, size);
139}
140
141void
142Tcl_Free(ptr)
143 char *ptr;
144{
145 free (ptr);
146}
147
754e5da2
SG
148static void
149null_routine(arg)
150 int arg;
151{
152}
153
546b8ca7
SG
154/* The following routines deal with stdout/stderr data, which is created by
155 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
156 lowest level of these routines and capture all output from the rest of GDB.
157 Normally they present their data to tcl via callbacks to the following tcl
158 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
159 in turn call tk routines to update the display.
86db943c 160
546b8ca7
SG
161 Under some circumstances, you may want to collect the output so that it can
162 be returned as the value of a tcl procedure. This can be done by
163 surrounding the output routines with calls to start_saving_output and
164 finish_saving_output. The saved data can then be retrieved with
165 get_saved_output (but this must be done before the call to
166 finish_saving_output). */
86db943c 167
546b8ca7 168/* Dynamic string header for stdout. */
86db943c 169
6131622e 170static Tcl_DString *result_ptr;
754e5da2 171\f
754e5da2
SG
172static void
173gdbtk_flush (stream)
174 FILE *stream;
175{
6131622e 176#if 0
86db943c
SG
177 /* Force immediate screen update */
178
754e5da2 179 Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
6131622e 180#endif
754e5da2
SG
181}
182
8532893d 183static void
86db943c 184gdbtk_fputs (ptr, stream)
8532893d 185 const char *ptr;
86db943c 186 FILE *stream;
8532893d 187{
fda6fadc 188
6131622e 189 if (result_ptr)
45f90c50 190 Tcl_DStringAppend (result_ptr, (char *)ptr, -1);
6131622e 191 else
86db943c 192 {
6131622e 193 Tcl_DString str;
86db943c 194
6131622e 195 Tcl_DStringInit (&str);
8532893d 196
6131622e 197 Tcl_DStringAppend (&str, "gdbtk_tcl_fputs", -1);
45f90c50 198 Tcl_DStringAppendElement (&str, (char *)ptr);
8532893d 199
6131622e
SG
200 Tcl_Eval (interp, Tcl_DStringValue (&str));
201 Tcl_DStringFree (&str);
202 }
8532893d
SG
203}
204
754e5da2 205static int
85c613aa 206gdbtk_query (query, args)
b607efe7 207 const char *query;
754e5da2
SG
208 va_list args;
209{
4e327047
TT
210 char buf[200], *merge[2];
211 char *command;
754e5da2
SG
212 long val;
213
6131622e 214 vsprintf (buf, query, args);
4e327047
TT
215 merge[0] = "gdbtk_tcl_query";
216 merge[1] = buf;
217 command = Tcl_Merge (2, merge);
218 Tcl_Eval (interp, command);
219 free (command);
754e5da2
SG
220
221 val = atol (interp->result);
222 return val;
223}
41756e56
FF
224
225/* VARARGS */
226static void
227#ifdef ANSI_PROTOTYPES
228gdbtk_readline_begin (char *format, ...)
229#else
230gdbtk_readline_begin (va_alist)
231 va_dcl
232#endif
233{
234 va_list args;
235 char buf[200], *merge[2];
236 char *command;
237
238#ifdef ANSI_PROTOTYPES
239 va_start (args, format);
240#else
241 char *format;
242 va_start (args);
243 format = va_arg (args, char *);
244#endif
245
246 vsprintf (buf, format, args);
247 merge[0] = "gdbtk_tcl_readline_begin";
248 merge[1] = buf;
249 command = Tcl_Merge (2, merge);
250 Tcl_Eval (interp, command);
251 free (command);
252}
253
254static char *
255gdbtk_readline (prompt)
256 char *prompt;
257{
258 char *merge[2];
259 char *command;
260
261 merge[0] = "gdbtk_tcl_readline";
262 merge[1] = prompt;
263 command = Tcl_Merge (2, merge);
264 if (Tcl_Eval (interp, command) == TCL_OK)
265 {
266 return (strdup (interp -> result));
267 }
268 else
269 {
270 gdbtk_fputs (interp -> result, gdb_stdout);
271 gdbtk_fputs ("\n", gdb_stdout);
272 return (NULL);
273 }
274}
275
276static void
277gdbtk_readline_end ()
278{
279 Tcl_Eval (interp, "gdbtk_tcl_readline_end");
280}
281
754e5da2 282\f
6131622e 283static void
73d3dbd4 284#ifdef ANSI_PROTOTYPES
85c613aa
C
285dsprintf_append_element (Tcl_DString *dsp, char *format, ...)
286#else
6131622e
SG
287dsprintf_append_element (va_alist)
288 va_dcl
85c613aa 289#endif
6131622e
SG
290{
291 va_list args;
85c613aa
C
292 char buf[1024];
293
73d3dbd4 294#ifdef ANSI_PROTOTYPES
85c613aa
C
295 va_start (args, format);
296#else
6131622e
SG
297 Tcl_DString *dsp;
298 char *format;
6131622e
SG
299
300 va_start (args);
6131622e
SG
301 dsp = va_arg (args, Tcl_DString *);
302 format = va_arg (args, char *);
85c613aa 303#endif
6131622e
SG
304
305 vsprintf (buf, format, args);
306
307 Tcl_DStringAppendElement (dsp, buf);
308}
309
310static int
311gdb_get_breakpoint_list (clientData, interp, argc, argv)
312 ClientData clientData;
313 Tcl_Interp *interp;
314 int argc;
315 char *argv[];
316{
317 struct breakpoint *b;
318 extern struct breakpoint *breakpoint_chain;
319
320 if (argc != 1)
321 error ("wrong # args");
322
323 for (b = breakpoint_chain; b; b = b->next)
324 if (b->type == bp_breakpoint)
325 dsprintf_append_element (result_ptr, "%d", b->number);
326
327 return TCL_OK;
328}
329
330static int
331gdb_get_breakpoint_info (clientData, interp, argc, argv)
332 ClientData clientData;
333 Tcl_Interp *interp;
334 int argc;
335 char *argv[];
336{
337 struct symtab_and_line sal;
338 static char *bptypes[] = {"breakpoint", "hardware breakpoint", "until",
339 "finish", "watchpoint", "hardware watchpoint",
340 "read watchpoint", "access watchpoint",
341 "longjmp", "longjmp resume", "step resume",
342 "through sigtramp", "watchpoint scope",
343 "call dummy" };
344 static char *bpdisp[] = {"delete", "disable", "donttouch"};
345 struct command_line *cmd;
346 int bpnum;
347 struct breakpoint *b;
348 extern struct breakpoint *breakpoint_chain;
349
350 if (argc != 2)
351 error ("wrong # args");
352
353 bpnum = atoi (argv[1]);
354
355 for (b = breakpoint_chain; b; b = b->next)
356 if (b->number == bpnum)
357 break;
358
9468f8aa 359 if (!b || b->type != bp_breakpoint)
6131622e
SG
360 error ("Breakpoint #%d does not exist", bpnum);
361
6131622e
SG
362 sal = find_pc_line (b->address, 0);
363
364 Tcl_DStringAppendElement (result_ptr, symtab_to_filename (sal.symtab));
365 dsprintf_append_element (result_ptr, "%d", sal.line);
366 dsprintf_append_element (result_ptr, "0x%lx", b->address);
367 Tcl_DStringAppendElement (result_ptr, bptypes[b->type]);
368 Tcl_DStringAppendElement (result_ptr, b->enable == enabled ? "1" : "0");
369 Tcl_DStringAppendElement (result_ptr, bpdisp[b->disposition]);
370 dsprintf_append_element (result_ptr, "%d", b->silent);
371 dsprintf_append_element (result_ptr, "%d", b->ignore_count);
372
373 Tcl_DStringStartSublist (result_ptr);
374 for (cmd = b->commands; cmd; cmd = cmd->next)
375 Tcl_DStringAppendElement (result_ptr, cmd->line);
376 Tcl_DStringEndSublist (result_ptr);
377
378 Tcl_DStringAppendElement (result_ptr, b->cond_string);
379
380 dsprintf_append_element (result_ptr, "%d", b->thread);
381 dsprintf_append_element (result_ptr, "%d", b->hit_count);
382
383 return TCL_OK;
384}
385
754e5da2
SG
386static void
387breakpoint_notify(b, action)
388 struct breakpoint *b;
389 const char *action;
390{
6131622e 391 char buf[100];
754e5da2
SG
392 int v;
393
394 if (b->type != bp_breakpoint)
395 return;
396
4e327047
TT
397 /* We ensure that ACTION contains no special Tcl characters, so we
398 can do this. */
6131622e 399 sprintf (buf, "gdbtk_tcl_breakpoint %s %d", action, b->number);
754e5da2 400
6131622e 401 v = Tcl_Eval (interp, buf);
754e5da2
SG
402
403 if (v != TCL_OK)
404 {
546b8ca7
SG
405 gdbtk_fputs (interp->result, gdb_stdout);
406 gdbtk_fputs ("\n", gdb_stdout);
754e5da2 407 }
754e5da2
SG
408}
409
410static void
411gdbtk_create_breakpoint(b)
412 struct breakpoint *b;
413{
6131622e 414 breakpoint_notify (b, "create");
754e5da2
SG
415}
416
417static void
418gdbtk_delete_breakpoint(b)
419 struct breakpoint *b;
420{
6131622e 421 breakpoint_notify (b, "delete");
754e5da2
SG
422}
423
424static void
6131622e 425gdbtk_modify_breakpoint(b)
754e5da2
SG
426 struct breakpoint *b;
427{
6131622e 428 breakpoint_notify (b, "modify");
754e5da2
SG
429}
430\f
431/* This implements the TCL command `gdb_loc', which returns a list consisting
432 of the source and line number associated with the current pc. */
433
434static int
435gdb_loc (clientData, interp, argc, argv)
436 ClientData clientData;
437 Tcl_Interp *interp;
438 int argc;
439 char *argv[];
440{
441 char *filename;
754e5da2
SG
442 struct symtab_and_line sal;
443 char *funcname;
8532893d 444 CORE_ADDR pc;
754e5da2
SG
445
446 if (argc == 1)
447 {
1dfc8dfb 448 pc = selected_frame ? selected_frame->pc : stop_pc;
754e5da2
SG
449 sal = find_pc_line (pc, 0);
450 }
451 else if (argc == 2)
452 {
754e5da2 453 struct symtabs_and_lines sals;
8532893d 454 int nelts;
754e5da2
SG
455
456 sals = decode_line_spec (argv[1], 1);
457
8532893d
SG
458 nelts = sals.nelts;
459 sal = sals.sals[0];
460 free (sals.sals);
461
754e5da2 462 if (sals.nelts != 1)
6131622e 463 error ("Ambiguous line spec");
754e5da2 464
8532893d 465 pc = sal.pc;
754e5da2
SG
466 }
467 else
6131622e 468 error ("wrong # args");
754e5da2 469
754e5da2 470 if (sal.symtab)
6131622e 471 Tcl_DStringAppendElement (result_ptr, sal.symtab->filename);
754e5da2 472 else
6131622e 473 Tcl_DStringAppendElement (result_ptr, "");
8532893d
SG
474
475 find_pc_partial_function (pc, &funcname, NULL, NULL);
6131622e 476 Tcl_DStringAppendElement (result_ptr, funcname);
8532893d 477
637b1661 478 filename = symtab_to_filename (sal.symtab);
6131622e 479 Tcl_DStringAppendElement (result_ptr, filename);
8532893d 480
9468f8aa 481 dsprintf_append_element (result_ptr, "%d", sal.line); /* line number */
754e5da2 482
9468f8aa 483 dsprintf_append_element (result_ptr, "0x%lx", pc); /* PC */
8532893d 484
754e5da2
SG
485 return TCL_OK;
486}
487\f
09722039
SG
488/* This implements the TCL command `gdb_eval'. */
489
490static int
491gdb_eval (clientData, interp, argc, argv)
492 ClientData clientData;
493 Tcl_Interp *interp;
494 int argc;
495 char *argv[];
496{
497 struct expression *expr;
498 struct cleanup *old_chain;
499 value_ptr val;
500
501 if (argc != 2)
6131622e 502 error ("wrong # args");
09722039
SG
503
504 expr = parse_expression (argv[1]);
505
506 old_chain = make_cleanup (free_current_contents, &expr);
507
508 val = evaluate_expression (expr);
509
09722039
SG
510 val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), VALUE_ADDRESS (val),
511 gdb_stdout, 0, 0, 0, 0);
09722039
SG
512
513 do_cleanups (old_chain);
514
515 return TCL_OK;
516}
517\f
5b21fb68
SG
518/* This implements the TCL command `gdb_sourcelines', which returns a list of
519 all of the lines containing executable code for the specified source file
520 (ie: lines where you can put breakpoints). */
521
522static int
523gdb_sourcelines (clientData, interp, argc, argv)
524 ClientData clientData;
525 Tcl_Interp *interp;
526 int argc;
527 char *argv[];
528{
529 struct symtab *symtab;
530 struct linetable_entry *le;
531 int nlines;
5b21fb68
SG
532
533 if (argc != 2)
6131622e 534 error ("wrong # args");
5b21fb68
SG
535
536 symtab = lookup_symtab (argv[1]);
537
538 if (!symtab)
6131622e 539 error ("No such file");
5b21fb68
SG
540
541 /* If there's no linetable, or no entries, then we are done. */
542
543 if (!symtab->linetable
544 || symtab->linetable->nitems == 0)
545 {
6131622e 546 Tcl_DStringAppendElement (result_ptr, "");
5b21fb68
SG
547 return TCL_OK;
548 }
549
550 le = symtab->linetable->item;
551 nlines = symtab->linetable->nitems;
552
553 for (;nlines > 0; nlines--, le++)
554 {
555 /* If the pc of this line is the same as the pc of the next line, then
556 just skip it. */
557 if (nlines > 1
558 && le->pc == (le + 1)->pc)
559 continue;
560
9468f8aa 561 dsprintf_append_element (result_ptr, "%d", le->line);
5b21fb68
SG
562 }
563
564 return TCL_OK;
565}
566\f
746d1df4
SG
567static int
568map_arg_registers (argc, argv, func, argp)
569 int argc;
570 char *argv[];
6131622e 571 void (*func) PARAMS ((int regnum, void *argp));
746d1df4
SG
572 void *argp;
573{
574 int regnum;
575
576 /* Note that the test for a valid register must include checking the
577 reg_names array because NUM_REGS may be allocated for the union of the
578 register sets within a family of related processors. In this case, the
579 trailing entries of reg_names will change depending upon the particular
580 processor being debugged. */
581
582 if (argc == 0) /* No args, just do all the regs */
583 {
584 for (regnum = 0;
585 regnum < NUM_REGS
586 && reg_names[regnum] != NULL
587 && *reg_names[regnum] != '\000';
588 regnum++)
589 func (regnum, argp);
590
591 return TCL_OK;
592 }
593
594 /* Else, list of register #s, just do listed regs */
595 for (; argc > 0; argc--, argv++)
596 {
597 regnum = atoi (*argv);
598
599 if (regnum >= 0
600 && regnum < NUM_REGS
601 && reg_names[regnum] != NULL
602 && *reg_names[regnum] != '\000')
603 func (regnum, argp);
604 else
6131622e 605 error ("bad register number");
746d1df4
SG
606 }
607
608 return TCL_OK;
609}
610
6131622e 611static void
746d1df4
SG
612get_register_name (regnum, argp)
613 int regnum;
614 void *argp; /* Ignored */
615{
6131622e 616 Tcl_DStringAppendElement (result_ptr, reg_names[regnum]);
746d1df4
SG
617}
618
5b21fb68
SG
619/* This implements the TCL command `gdb_regnames', which returns a list of
620 all of the register names. */
621
622static int
623gdb_regnames (clientData, interp, argc, argv)
624 ClientData clientData;
625 Tcl_Interp *interp;
626 int argc;
627 char *argv[];
628{
746d1df4
SG
629 argc--;
630 argv++;
631
b607efe7 632 return map_arg_registers (argc, argv, get_register_name, NULL);
746d1df4
SG
633}
634
746d1df4
SG
635#ifndef REGISTER_CONVERTIBLE
636#define REGISTER_CONVERTIBLE(x) (0 != 0)
637#endif
638
639#ifndef REGISTER_CONVERT_TO_VIRTUAL
640#define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
641#endif
642
643#ifndef INVALID_FLOAT
644#define INVALID_FLOAT(x, y) (0 != 0)
645#endif
646
6131622e 647static void
746d1df4 648get_register (regnum, fp)
6131622e 649 int regnum;
746d1df4
SG
650 void *fp;
651{
652 char raw_buffer[MAX_REGISTER_RAW_SIZE];
653 char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
654 int format = (int)fp;
655
656 if (read_relative_register_raw_bytes (regnum, raw_buffer))
657 {
6131622e 658 Tcl_DStringAppendElement (result_ptr, "Optimized out");
746d1df4
SG
659 return;
660 }
661
746d1df4
SG
662 /* Convert raw data to virtual format if necessary. */
663
664 if (REGISTER_CONVERTIBLE (regnum))
665 {
666 REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
667 raw_buffer, virtual_buffer);
668 }
669 else
670 memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
671
3d9f68c0
FF
672 if (format == 'r')
673 {
674 int j;
675 printf_filtered ("0x");
676 for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++)
677 {
678 register int idx = TARGET_BYTE_ORDER == BIG_ENDIAN ? j
679 : REGISTER_RAW_SIZE (regnum) - 1 - j;
680 printf_filtered ("%02x", (unsigned char)raw_buffer[idx]);
681 }
682 }
683 else
684 val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0,
685 gdb_stdout, format, 1, 0, Val_pretty_default);
746d1df4 686
6131622e 687 Tcl_DStringAppend (result_ptr, " ", -1);
746d1df4
SG
688}
689
690static int
691gdb_fetch_registers (clientData, interp, argc, argv)
692 ClientData clientData;
693 Tcl_Interp *interp;
694 int argc;
695 char *argv[];
696{
697 int format;
698
699 if (argc < 2)
6131622e 700 error ("wrong # args");
5b21fb68 701
746d1df4
SG
702 argc--;
703 argv++;
5b21fb68 704
746d1df4
SG
705 argc--;
706 format = **argv++;
707
b607efe7 708 return map_arg_registers (argc, argv, get_register, (void *) format);
746d1df4
SG
709}
710
711/* This contains the previous values of the registers, since the last call to
712 gdb_changed_register_list. */
713
714static char old_regs[REGISTER_BYTES];
715
6131622e 716static void
746d1df4 717register_changed_p (regnum, argp)
6131622e 718 int regnum;
746d1df4
SG
719 void *argp; /* Ignored */
720{
721 char raw_buffer[MAX_REGISTER_RAW_SIZE];
746d1df4
SG
722
723 if (read_relative_register_raw_bytes (regnum, raw_buffer))
724 return;
725
726 if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
727 REGISTER_RAW_SIZE (regnum)) == 0)
728 return;
729
fda6fadc 730 /* Found a changed register. Save new value and return its number. */
746d1df4
SG
731
732 memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
733 REGISTER_RAW_SIZE (regnum));
734
9468f8aa 735 dsprintf_append_element (result_ptr, "%d", regnum);
746d1df4
SG
736}
737
738static int
739gdb_changed_register_list (clientData, interp, argc, argv)
740 ClientData clientData;
741 Tcl_Interp *interp;
742 int argc;
743 char *argv[];
744{
746d1df4
SG
745 argc--;
746 argv++;
747
748 return map_arg_registers (argc, argv, register_changed_p, NULL);
5b21fb68
SG
749}
750\f
fda6fadc 751/* This implements the TCL command `gdb_cmd', which sends its argument into
754e5da2
SG
752 the GDB command scanner. */
753
754static int
755gdb_cmd (clientData, interp, argc, argv)
756 ClientData clientData;
757 Tcl_Interp *interp;
758 int argc;
759 char *argv[];
760{
754e5da2 761 if (argc != 2)
6131622e 762 error ("wrong # args");
754e5da2 763
fda6fadc
SS
764 if (running_now)
765 return TCL_OK;
766
86db943c 767 execute_command (argv[1], 1);
479f0f18 768
754e5da2 769 bpstat_do_actions (&stop_bpstat);
754e5da2 770
754e5da2
SG
771 return TCL_OK;
772}
773
86db943c
SG
774/* This routine acts as a top-level for all GDB code called by tcl/Tk. It
775 handles cleanups, and calls to return_to_top_level (usually via error).
776 This is necessary in order to prevent a longjmp out of the bowels of Tk,
777 possibly leaving things in a bad state. Since this routine can be called
778 recursively, it needs to save and restore the contents of the jmp_buf as
779 necessary. */
780
781static int
782call_wrapper (clientData, interp, argc, argv)
783 ClientData clientData;
784 Tcl_Interp *interp;
785 int argc;
786 char *argv[];
787{
788 int val;
789 struct cleanup *saved_cleanup_chain;
790 Tcl_CmdProc *func;
791 jmp_buf saved_error_return;
6131622e
SG
792 Tcl_DString result, *old_result_ptr;
793
794 Tcl_DStringInit (&result);
795 old_result_ptr = result_ptr;
796 result_ptr = &result;
86db943c
SG
797
798 func = (Tcl_CmdProc *)clientData;
799 memcpy (saved_error_return, error_return, sizeof (jmp_buf));
800
801 saved_cleanup_chain = save_cleanups ();
802
803 if (!setjmp (error_return))
804 val = func (clientData, interp, argc, argv);
805 else
806 {
807 val = TCL_ERROR; /* Flag an error for TCL */
808
86db943c
SG
809 gdb_flush (gdb_stderr); /* Flush error output */
810
09722039
SG
811 gdb_flush (gdb_stdout); /* Sometimes error output comes here as well */
812
fda6fadc
SS
813 /* In case of an error, we may need to force the GUI into idle
814 mode because gdbtk_call_command may have bombed out while in
815 the command routine. */
86db943c 816
4e327047 817 Tcl_Eval (interp, "gdbtk_tcl_idle");
86db943c
SG
818 }
819
820 do_cleanups (ALL_CLEANUPS);
821
822 restore_cleanups (saved_cleanup_chain);
823
824 memcpy (error_return, saved_error_return, sizeof (jmp_buf));
825
6131622e
SG
826 Tcl_DStringResult (interp, &result);
827 result_ptr = old_result_ptr;
828
86db943c
SG
829 return val;
830}
831
754e5da2
SG
832static int
833gdb_listfiles (clientData, interp, argc, argv)
834 ClientData clientData;
835 Tcl_Interp *interp;
836 int argc;
837 char *argv[];
838{
754e5da2
SG
839 struct objfile *objfile;
840 struct partial_symtab *psymtab;
546b8ca7 841 struct symtab *symtab;
754e5da2
SG
842
843 ALL_PSYMTABS (objfile, psymtab)
6131622e 844 Tcl_DStringAppendElement (result_ptr, psymtab->filename);
754e5da2 845
546b8ca7 846 ALL_SYMTABS (objfile, symtab)
6131622e 847 Tcl_DStringAppendElement (result_ptr, symtab->filename);
546b8ca7 848
754e5da2
SG
849 return TCL_OK;
850}
479f0f18
SG
851
852static int
853gdb_stop (clientData, interp, argc, argv)
854 ClientData clientData;
855 Tcl_Interp *interp;
856 int argc;
857 char *argv[];
858{
6c27841f 859 target_stop ();
546b8ca7
SG
860
861 return TCL_OK;
479f0f18 862}
09722039
SG
863\f
864/* This implements the TCL command `gdb_disassemble'. */
479f0f18 865
09722039
SG
866static int
867gdbtk_dis_asm_read_memory (memaddr, myaddr, len, info)
868 bfd_vma memaddr;
869 bfd_byte *myaddr;
870 int len;
871 disassemble_info *info;
872{
873 extern struct target_ops exec_ops;
874 int res;
875
876 errno = 0;
877 res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops);
878
879 if (res == len)
880 return 0;
881 else
882 if (errno == 0)
883 return EIO;
884 else
885 return errno;
886}
887
888/* We need a different sort of line table from the normal one cuz we can't
889 depend upon implicit line-end pc's for lines. This is because of the
890 reordering we are about to do. */
891
892struct my_line_entry {
893 int line;
894 CORE_ADDR start_pc;
895 CORE_ADDR end_pc;
896};
897
898static int
899compare_lines (mle1p, mle2p)
900 const PTR mle1p;
901 const PTR mle2p;
902{
903 struct my_line_entry *mle1, *mle2;
904 int val;
905
906 mle1 = (struct my_line_entry *) mle1p;
907 mle2 = (struct my_line_entry *) mle2p;
908
909 val = mle1->line - mle2->line;
910
911 if (val != 0)
912 return val;
913
914 return mle1->start_pc - mle2->start_pc;
915}
916
917static int
918gdb_disassemble (clientData, interp, argc, argv)
919 ClientData clientData;
920 Tcl_Interp *interp;
921 int argc;
922 char *argv[];
923{
924 CORE_ADDR pc, low, high;
925 int mixed_source_and_assembly;
fc941258
DE
926 static disassemble_info di;
927 static int di_initialized;
928
929 if (! di_initialized)
930 {
91550191
SG
931 INIT_DISASSEMBLE_INFO_NO_ARCH (di, gdb_stdout,
932 (fprintf_ftype) fprintf_unfiltered);
caeec767 933 di.flavour = bfd_target_unknown_flavour;
fc941258
DE
934 di.memory_error_func = dis_asm_memory_error;
935 di.print_address_func = dis_asm_print_address;
936 di_initialized = 1;
937 }
09722039 938
91550191
SG
939 di.mach = tm_print_insn_info.mach;
940 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
941 tm_print_insn_info.endian = BFD_ENDIAN_BIG;
942 else
943 tm_print_insn_info.endian = BFD_ENDIAN_LITTLE;
944
09722039 945 if (argc != 3 && argc != 4)
6131622e 946 error ("wrong # args");
09722039
SG
947
948 if (strcmp (argv[1], "source") == 0)
949 mixed_source_and_assembly = 1;
950 else if (strcmp (argv[1], "nosource") == 0)
951 mixed_source_and_assembly = 0;
952 else
6131622e 953 error ("First arg must be 'source' or 'nosource'");
09722039
SG
954
955 low = parse_and_eval_address (argv[2]);
956
957 if (argc == 3)
958 {
959 if (find_pc_partial_function (low, NULL, &low, &high) == 0)
6131622e 960 error ("No function contains specified address");
09722039
SG
961 }
962 else
963 high = parse_and_eval_address (argv[3]);
964
965 /* If disassemble_from_exec == -1, then we use the following heuristic to
966 determine whether or not to do disassembly from target memory or from the
967 exec file:
968
969 If we're debugging a local process, read target memory, instead of the
970 exec file. This makes disassembly of functions in shared libs work
971 correctly.
972
973 Else, we're debugging a remote process, and should disassemble from the
fda6fadc 974 exec file for speed. However, this is no good if the target modifies its
09722039
SG
975 code (for relocation, or whatever).
976 */
977
978 if (disassemble_from_exec == -1)
979 if (strcmp (target_shortname, "child") == 0
d7c4766c
SS
980 || strcmp (target_shortname, "procfs") == 0
981 || strcmp (target_shortname, "vxprocess") == 0)
09722039
SG
982 disassemble_from_exec = 0; /* It's a child process, read inferior mem */
983 else
984 disassemble_from_exec = 1; /* It's remote, read the exec file */
985
986 if (disassemble_from_exec)
a76ef70a
SG
987 di.read_memory_func = gdbtk_dis_asm_read_memory;
988 else
989 di.read_memory_func = dis_asm_read_memory;
09722039
SG
990
991 /* If just doing straight assembly, all we need to do is disassemble
992 everything between low and high. If doing mixed source/assembly, we've
993 got a totally different path to follow. */
994
995 if (mixed_source_and_assembly)
996 { /* Come here for mixed source/assembly */
997 /* The idea here is to present a source-O-centric view of a function to
998 the user. This means that things are presented in source order, with
999 (possibly) out of order assembly immediately following. */
1000 struct symtab *symtab;
1001 struct linetable_entry *le;
1002 int nlines;
c81a3fa9 1003 int newlines;
09722039
SG
1004 struct my_line_entry *mle;
1005 struct symtab_and_line sal;
1006 int i;
1007 int out_of_order;
c81a3fa9 1008 int next_line;
09722039
SG
1009
1010 symtab = find_pc_symtab (low); /* Assume symtab is valid for whole PC range */
1011
1012 if (!symtab)
1013 goto assembly_only;
1014
1015/* First, convert the linetable to a bunch of my_line_entry's. */
1016
1017 le = symtab->linetable->item;
1018 nlines = symtab->linetable->nitems;
1019
1020 if (nlines <= 0)
1021 goto assembly_only;
1022
1023 mle = (struct my_line_entry *) alloca (nlines * sizeof (struct my_line_entry));
1024
1025 out_of_order = 0;
1026
c81a3fa9
SG
1027/* Copy linetable entries for this function into our data structure, creating
1028 end_pc's and setting out_of_order as appropriate. */
1029
1030/* First, skip all the preceding functions. */
1031
1032 for (i = 0; i < nlines - 1 && le[i].pc < low; i++) ;
1033
1034/* Now, copy all entries before the end of this function. */
1035
1036 newlines = 0;
1037 for (; i < nlines - 1 && le[i].pc < high; i++)
09722039 1038 {
c81a3fa9
SG
1039 if (le[i].line == le[i + 1].line
1040 && le[i].pc == le[i + 1].pc)
1041 continue; /* Ignore duplicates */
1042
1043 mle[newlines].line = le[i].line;
09722039
SG
1044 if (le[i].line > le[i + 1].line)
1045 out_of_order = 1;
c81a3fa9
SG
1046 mle[newlines].start_pc = le[i].pc;
1047 mle[newlines].end_pc = le[i + 1].pc;
1048 newlines++;
09722039
SG
1049 }
1050
c81a3fa9
SG
1051/* If we're on the last line, and it's part of the function, then we need to
1052 get the end pc in a special way. */
1053
1054 if (i == nlines - 1
1055 && le[i].pc < high)
1056 {
1057 mle[newlines].line = le[i].line;
1058 mle[newlines].start_pc = le[i].pc;
1059 sal = find_pc_line (le[i].pc, 0);
1060 mle[newlines].end_pc = sal.end;
1061 newlines++;
1062 }
09722039
SG
1063
1064/* Now, sort mle by line #s (and, then by addresses within lines). */
1065
1066 if (out_of_order)
c81a3fa9 1067 qsort (mle, newlines, sizeof (struct my_line_entry), compare_lines);
09722039
SG
1068
1069/* Now, for each line entry, emit the specified lines (unless they have been
1070 emitted before), followed by the assembly code for that line. */
1071
c81a3fa9
SG
1072 next_line = 0; /* Force out first line */
1073 for (i = 0; i < newlines; i++)
09722039 1074 {
c81a3fa9
SG
1075/* Print out everything from next_line to the current line. */
1076
1077 if (mle[i].line >= next_line)
09722039 1078 {
c81a3fa9
SG
1079 if (next_line != 0)
1080 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
09722039 1081 else
c81a3fa9
SG
1082 print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
1083
1084 next_line = mle[i].line + 1;
09722039 1085 }
c81a3fa9 1086
09722039
SG
1087 for (pc = mle[i].start_pc; pc < mle[i].end_pc; )
1088 {
1089 QUIT;
1090 fputs_unfiltered (" ", gdb_stdout);
1091 print_address (pc, gdb_stdout);
1092 fputs_unfiltered (":\t ", gdb_stdout);
d039851f 1093 pc += (*tm_print_insn) (pc, &di);
09722039
SG
1094 fputs_unfiltered ("\n", gdb_stdout);
1095 }
1096 }
1097 }
1098 else
1099 {
1100assembly_only:
1101 for (pc = low; pc < high; )
1102 {
1103 QUIT;
1104 fputs_unfiltered (" ", gdb_stdout);
1105 print_address (pc, gdb_stdout);
1106 fputs_unfiltered (":\t ", gdb_stdout);
d039851f 1107 pc += (*tm_print_insn) (pc, &di);
09722039
SG
1108 fputs_unfiltered ("\n", gdb_stdout);
1109 }
1110 }
1111
09722039
SG
1112 gdb_flush (gdb_stdout);
1113
1114 return TCL_OK;
1115}
754e5da2
SG
1116\f
1117static void
1118tk_command (cmd, from_tty)
1119 char *cmd;
1120 int from_tty;
1121{
546b8ca7
SG
1122 int retval;
1123 char *result;
1124 struct cleanup *old_chain;
1125
572977a5
FF
1126 /* Catch case of no argument, since this will make the tcl interpreter dump core. */
1127 if (cmd == NULL)
1128 error_no_arg ("tcl command to interpret");
1129
546b8ca7
SG
1130 retval = Tcl_Eval (interp, cmd);
1131
1132 result = strdup (interp->result);
754e5da2 1133
546b8ca7
SG
1134 old_chain = make_cleanup (free, result);
1135
1136 if (retval != TCL_OK)
1137 error (result);
1138
1139 printf_unfiltered ("%s\n", result);
1140
1141 do_cleanups (old_chain);
754e5da2
SG
1142}
1143
1144static void
1145cleanup_init (ignored)
1146 int ignored;
1147{
1148 if (mainWindow != NULL)
1149 Tk_DestroyWindow (mainWindow);
1150 mainWindow = NULL;
1151
1152 if (interp != NULL)
1153 Tcl_DeleteInterp (interp);
1154 interp = NULL;
1155}
1156
637b1661
SG
1157/* Come here during long calculations to check for GUI events. Usually invoked
1158 via the QUIT macro. */
1159
1160static void
1161gdbtk_interactive ()
1162{
1163 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
1164}
1165
479f0f18
SG
1166/* Come here when there is activity on the X file descriptor. */
1167
1168static void
1169x_event (signo)
1170 int signo;
1171{
1172 /* Process pending events */
1173
1174 while (Tk_DoOneEvent (TK_DONT_WAIT|TK_ALL_EVENTS) != 0);
1175}
1176
1177static int
1178gdbtk_wait (pid, ourstatus)
1179 int pid;
1180 struct target_waitstatus *ourstatus;
1181{
736a82e7
SG
1182 struct sigaction action;
1183 static sigset_t nullsigmask = {0};
1184
1185#ifndef SA_RESTART
1186 /* Needed for SunOS 4.1.x */
1187#define SA_RESTART 0
546b8ca7 1188#endif
479f0f18 1189
736a82e7
SG
1190 action.sa_handler = x_event;
1191 action.sa_mask = nullsigmask;
1192 action.sa_flags = SA_RESTART;
1193 sigaction(SIGIO, &action, NULL);
1194
479f0f18
SG
1195 pid = target_wait (pid, ourstatus);
1196
736a82e7
SG
1197 action.sa_handler = SIG_IGN;
1198 sigaction(SIGIO, &action, NULL);
479f0f18
SG
1199
1200 return pid;
1201}
1202
1203/* This is called from execute_command, and provides a wrapper around
1204 various command routines in a place where both protocol messages and
1205 user input both flow through. Mostly this is used for indicating whether
1206 the target process is running or not.
1207*/
1208
1209static void
1210gdbtk_call_command (cmdblk, arg, from_tty)
1211 struct cmd_list_element *cmdblk;
1212 char *arg;
1213 int from_tty;
1214{
fda6fadc 1215 running_now = 0;
479f0f18
SG
1216 if (cmdblk->class == class_run)
1217 {
fda6fadc 1218 running_now = 1;
4e327047 1219 Tcl_Eval (interp, "gdbtk_tcl_busy");
479f0f18 1220 (*cmdblk->function.cfunc)(arg, from_tty);
4e327047 1221 Tcl_Eval (interp, "gdbtk_tcl_idle");
fda6fadc 1222 running_now = 0;
479f0f18
SG
1223 }
1224 else
1225 (*cmdblk->function.cfunc)(arg, from_tty);
1226}
1227
5bac2b50
FF
1228/* This function is called instead of gdb's internal command loop. This is the
1229 last chance to do anything before entering the main Tk event loop. */
1230
1231static void
1232tk_command_loop ()
1233{
41756e56
FF
1234 extern GDB_FILE *instream;
1235
1236 /* We no longer want to use stdin as the command input stream */
1237 instream = NULL;
5bac2b50
FF
1238 Tcl_Eval (interp, "gdbtk_tcl_preloop");
1239 Tk_MainLoop ();
1240}
1241
754e5da2
SG
1242static void
1243gdbtk_init ()
1244{
1245 struct cleanup *old_chain;
1246 char *gdbtk_filename;
479f0f18 1247 int i;
736a82e7
SG
1248 struct sigaction action;
1249 static sigset_t nullsigmask = {0};
754e5da2
SG
1250
1251 old_chain = make_cleanup (cleanup_init, 0);
1252
1253 /* First init tcl and tk. */
1254
1255 interp = Tcl_CreateInterp ();
1256
1257 if (!interp)
1258 error ("Tcl_CreateInterp failed");
1259
1260 mainWindow = Tk_CreateMainWindow (interp, NULL, "gdb", "Gdb");
1261
1262 if (!mainWindow)
1263 return; /* DISPLAY probably not set */
1264
1265 if (Tcl_Init(interp) != TCL_OK)
1266 error ("Tcl_Init failed: %s", interp->result);
1267
1268 if (Tk_Init(interp) != TCL_OK)
1269 error ("Tk_Init failed: %s", interp->result);
1270
86db943c
SG
1271 Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
1272 Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
1273 Tcl_CreateCommand (interp, "gdb_sourcelines", call_wrapper, gdb_sourcelines,
1274 NULL);
1275 Tcl_CreateCommand (interp, "gdb_listfiles", call_wrapper, gdb_listfiles,
746d1df4 1276 NULL);
86db943c
SG
1277 Tcl_CreateCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
1278 Tcl_CreateCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
1279 Tcl_CreateCommand (interp, "gdb_fetch_registers", call_wrapper,
1280 gdb_fetch_registers, NULL);
1281 Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper,
1282 gdb_changed_register_list, NULL);
09722039
SG
1283 Tcl_CreateCommand (interp, "gdb_disassemble", call_wrapper,
1284 gdb_disassemble, NULL);
1285 Tcl_CreateCommand (interp, "gdb_eval", call_wrapper, gdb_eval, NULL);
6131622e
SG
1286 Tcl_CreateCommand (interp, "gdb_get_breakpoint_list", call_wrapper,
1287 gdb_get_breakpoint_list, NULL);
1288 Tcl_CreateCommand (interp, "gdb_get_breakpoint_info", call_wrapper,
1289 gdb_get_breakpoint_info, NULL);
754e5da2 1290
5bac2b50 1291 command_loop_hook = tk_command_loop;
b607efe7
FF
1292 print_frame_info_listing_hook =
1293 (void (*) PARAMS ((struct symtab *, int, int, int))) null_routine;
09722039
SG
1294 query_hook = gdbtk_query;
1295 flush_hook = gdbtk_flush;
1296 create_breakpoint_hook = gdbtk_create_breakpoint;
1297 delete_breakpoint_hook = gdbtk_delete_breakpoint;
6131622e 1298 modify_breakpoint_hook = gdbtk_modify_breakpoint;
09722039
SG
1299 interactive_hook = gdbtk_interactive;
1300 target_wait_hook = gdbtk_wait;
1301 call_command_hook = gdbtk_call_command;
41756e56
FF
1302 readline_begin_hook = gdbtk_readline_begin;
1303 readline_hook = gdbtk_readline;
1304 readline_end_hook = gdbtk_readline_end;
754e5da2 1305
cd2df226 1306 /* Get the file descriptor for the X server */
479f0f18 1307
cd2df226 1308 x_fd = ConnectionNumber (Tk_Display (mainWindow));
479f0f18
SG
1309
1310 /* Setup for I/O interrupts */
1311
736a82e7
SG
1312 action.sa_mask = nullsigmask;
1313 action.sa_flags = 0;
1314 action.sa_handler = SIG_IGN;
1315 sigaction(SIGIO, &action, NULL);
1316
1317#ifdef FIOASYNC
1318 i = 1;
1319 if (ioctl (x_fd, FIOASYNC, &i))
1320 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
479f0f18 1321
77a89957 1322#ifdef SIOCSPGRP
736a82e7
SG
1323 i = getpid();
1324 if (ioctl (x_fd, SIOCSPGRP, &i))
1325 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
45f90c50
MM
1326
1327#else
1328#ifdef F_SETOWN
1329 i = getpid();
1330 if (fcntl (x_fd, F_SETOWN, i))
1331 perror_with_name ("gdbtk_init: fcntl F_SETOWN failed");
1332#endif /* F_SETOWN */
1333#endif /* !SIOCSPGRP */
546b8ca7
SG
1334#else
1335 if (ioctl (x_fd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
736a82e7
SG
1336 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
1337#endif /* ifndef FIOASYNC */
479f0f18 1338
754e5da2
SG
1339 add_com ("tk", class_obscure, tk_command,
1340 "Send a command directly into tk.");
09722039 1341
09722039
SG
1342 Tcl_LinkVar (interp, "disassemble-from-exec", (char *)&disassemble_from_exec,
1343 TCL_LINK_INT);
1344
1345 /* Load up gdbtk.tcl after all the environment stuff has been setup. */
1346
1347 gdbtk_filename = getenv ("GDBTK_FILENAME");
1348 if (!gdbtk_filename)
1349 if (access ("gdbtk.tcl", R_OK) == 0)
1350 gdbtk_filename = "gdbtk.tcl";
1351 else
1352 gdbtk_filename = GDBTK_FILENAME;
1353
724498fd
SG
1354/* Defer setup of fputs_unfiltered_hook to near the end so that error messages
1355 prior to this point go to stdout/stderr. */
1356
1357 fputs_unfiltered_hook = gdbtk_fputs;
1358
09722039 1359 if (Tcl_EvalFile (interp, gdbtk_filename) != TCL_OK)
724498fd
SG
1360 {
1361 fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
1362
1363 fprintf_unfiltered (stderr, "%s:%d: %s\n", gdbtk_filename,
1364 interp->errorLine, interp->result);
b66051ec
SG
1365
1366 fputs_unfiltered ("Stack trace:\n", gdb_stderr);
1367 fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
1368 error ("");
724498fd 1369 }
09722039
SG
1370
1371 discard_cleanups (old_chain);
754e5da2
SG
1372}
1373
3f37b696 1374/* Come here during initialize_all_files () */
754e5da2
SG
1375
1376void
1377_initialize_gdbtk ()
1378{
c5197511
SG
1379 if (use_windows)
1380 {
1381 /* Tell the rest of the world that Gdbtk is now set up. */
754e5da2 1382
c5197511
SG
1383 init_ui_hook = gdbtk_init;
1384 }
754e5da2 1385}
This page took 0.161523 seconds and 4 git commands to generate.