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