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