OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [tui/] [tui-hooks.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* GDB hooks for TUI.
2
 
3
   Copyright 2001, 2002 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 2 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
23
   "defs.h" should be included first.  Unfortunatly some systems
24
   (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
25
   and they clash with "bfd.h"'s definiton of true/false.  The correct
26
   fix is to remove true/false from "bfd.h", however, until that
27
   happens, hack around it by including "config.h" and <curses.h>
28
   first.  */
29
 
30
#include "config.h"
31
#ifdef HAVE_NCURSES_H
32
#include <ncurses.h>
33
#else
34
#ifdef HAVE_CURSES_H
35
#include <curses.h>
36
#endif
37
#endif
38
 
39
#include "defs.h"
40
#include "symtab.h"
41
#include "inferior.h"
42
#include "command.h"
43
#include "bfd.h"
44
#include "symfile.h"
45
#include "objfiles.h"
46
#include "target.h"
47
#include "gdbcore.h"
48
#include "event-loop.h"
49
#include "event-top.h"
50
#include "frame.h"
51
#include "breakpoint.h"
52
#include "gdb-events.h"
53
#include "ui-out.h"
54
#include "top.h"
55
#include <readline/readline.h>
56
#include <unistd.h>
57
#include <fcntl.h>
58
 
59
#include "tui.h"
60
#include "tuiData.h"
61
#include "tuiLayout.h"
62
#include "tuiIO.h"
63
#include "tuiRegs.h"
64
#include "tuiWin.h"
65
#include "tuiStack.h"
66
#include "tuiDataWin.h"
67
#include "tuiSourceWin.h"
68
 
69
int tui_target_has_run = 0;
70
 
71
static void (* tui_target_new_objfile_chain) (struct objfile*);
72
extern void (*selected_frame_level_changed_hook) (int);
73
static void tui_event_loop (void);
74
static void tui_command_loop (void);
75
 
76
static void
77
tui_new_objfile_hook (struct objfile* objfile)
78
{
79
  if (tui_active)
80
    tui_display_main ();
81
 
82
  if (tui_target_new_objfile_chain)
83
    tui_target_new_objfile_chain (objfile);
84
}
85
 
86
static int
87
tui_query_hook (const char * msg, va_list argp)
88
{
89
  int retval;
90
  int ans2;
91
  int answer;
92
 
93
  /* Automatically answer "yes" if input is not from a terminal.  */
94
  if (!input_from_terminal_p ())
95
    return 1;
96
 
97
  echo ();
98
  while (1)
99
    {
100
      wrap_here ("");           /* Flush any buffered output */
101
      gdb_flush (gdb_stdout);
102
 
103
      vfprintf_filtered (gdb_stdout, msg, argp);
104
      printf_filtered ("(y or n) ");
105
 
106
      wrap_here ("");
107
      gdb_flush (gdb_stdout);
108
 
109
      answer = tui_getc (stdin);
110
      clearerr (stdin);         /* in case of C-d */
111
      if (answer == EOF)        /* C-d */
112
        {
113
          retval = 1;
114
          break;
115
        }
116
      /* Eat rest of input line, to EOF or newline */
117
      if (answer != '\n')
118
        do
119
          {
120
            ans2 = tui_getc (stdin);
121
            clearerr (stdin);
122
          }
123
        while (ans2 != EOF && ans2 != '\n' && ans2 != '\r');
124
 
125
      if (answer >= 'a')
126
        answer -= 040;
127
      if (answer == 'Y')
128
        {
129
          retval = 1;
130
          break;
131
        }
132
      if (answer == 'N')
133
        {
134
          retval = 0;
135
          break;
136
        }
137
      printf_filtered ("Please answer y or n.\n");
138
    }
139
  noecho ();
140
  return retval;
141
}
142
 
143
/* Prevent recursion of registers_changed_hook().  */
144
static int tui_refreshing_registers = 0;
145
 
146
static void
147
tui_registers_changed_hook (void)
148
{
149
  struct frame_info *fi;
150
 
151
  fi = selected_frame;
152
  if (fi && tui_refreshing_registers == 0)
153
    {
154
      tui_refreshing_registers = 1;
155
#if 0
156
      tuiCheckDataValues (fi);
157
#endif
158
      tui_refreshing_registers = 0;
159
    }
160
}
161
 
162
static void
163
tui_register_changed_hook (int regno)
164
{
165
  struct frame_info *fi;
166
 
167
  fi = selected_frame;
168
  if (fi && tui_refreshing_registers == 0)
169
    {
170
      tui_refreshing_registers = 1;
171
      tuiCheckDataValues (fi);
172
      tui_refreshing_registers = 0;
173
    }
174
}
175
 
176
/* Breakpoint creation hook.
177
   Update the screen to show the new breakpoint.  */
178
static void
179
tui_event_create_breakpoint (int number)
180
{
181
  tui_update_all_breakpoint_info ();
182
}
183
 
184
/* Breakpoint deletion hook.
185
   Refresh the screen to update the breakpoint marks.  */
186
static void
187
tui_event_delete_breakpoint (int number)
188
{
189
  tui_update_all_breakpoint_info ();
190
}
191
 
192
static void
193
tui_event_modify_breakpoint (int number)
194
{
195
  tui_update_all_breakpoint_info ();
196
}
197
 
198
static void
199
tui_event_default (int number)
200
{
201
  ;
202
}
203
 
204
static struct gdb_events *tui_old_event_hooks;
205
 
206
static struct gdb_events tui_event_hooks =
207
{
208
  tui_event_create_breakpoint,
209
  tui_event_delete_breakpoint,
210
  tui_event_modify_breakpoint,
211
  tui_event_default,
212
  tui_event_default,
213
  tui_event_default
214
};
215
 
216
/* Called when going to wait for the target.
217
   Leave curses mode and setup program mode.  */
218
static ptid_t
219
tui_target_wait_hook (ptid_t pid, struct target_waitstatus *status)
220
{
221
  ptid_t res;
222
 
223
  /* Leave tui mode (optional).  */
224
#if 0
225
  if (tui_active)
226
    {
227
      target_terminal_ours ();
228
      endwin ();
229
      target_terminal_inferior ();
230
    }
231
#endif
232
  tui_target_has_run = 1;
233
  res = target_wait (pid, status);
234
 
235
  if (tui_active)
236
    {
237
      /* TODO: need to refresh (optional).  */
238
    }
239
  return res;
240
}
241
 
242
/* The selected frame has changed.  This is happens after a target
243
   stop or when the user explicitly changes the frame (up/down/thread/...).  */
244
static void
245
tui_selected_frame_level_changed_hook (int level)
246
{
247
  struct frame_info *fi;
248
 
249
  fi = selected_frame;
250
  /* Ensure that symbols for this frame are read in.  Also, determine the
251
     source language of this frame, and switch to it if desired.  */
252
  if (fi)
253
    {
254
      struct symtab *s;
255
 
256
      s = find_pc_symtab (fi->pc);
257
      /* elz: this if here fixes the problem with the pc not being displayed
258
         in the tui asm layout, with no debug symbols. The value of s
259
         would be 0 here, and select_source_symtab would abort the
260
         command by calling the 'error' function */
261
      if (s)
262
        select_source_symtab (s);
263
 
264
      /* Display the frame position (even if there is no symbols).  */
265
      tuiShowFrameInfo (fi);
266
 
267
      /* Refresh the register window if it's visible.  */
268
      if (tui_is_window_visible (DATA_WIN))
269
        {
270
          tui_refreshing_registers = 1;
271
          tuiCheckDataValues (fi);
272
          tui_refreshing_registers = 0;
273
        }
274
    }
275
}
276
 
277
/* Called from print_frame_info to list the line we stopped in.  */
278
static void
279
tui_print_frame_info_listing_hook (struct symtab *s, int line,
280
                                   int stopline, int noerror)
281
{
282
  select_source_symtab (s);
283
  tuiShowFrameInfo (selected_frame);
284
}
285
 
286
/* Called when the target process died or is detached.
287
   Update the status line.  */
288
static void
289
tui_detach_hook (void)
290
{
291
  tuiShowFrameInfo (0);
292
  tui_display_main ();
293
}
294
 
295
/* Install the TUI specific hooks.  */
296
void
297
tui_install_hooks (void)
298
{
299
  target_wait_hook = tui_target_wait_hook;
300
  selected_frame_level_changed_hook = tui_selected_frame_level_changed_hook;
301
  print_frame_info_listing_hook = tui_print_frame_info_listing_hook;
302
 
303
  query_hook = tui_query_hook;
304
 
305
  /* Install the event hooks.  */
306
  tui_old_event_hooks = set_gdb_event_hooks (&tui_event_hooks);
307
 
308
  registers_changed_hook = tui_registers_changed_hook;
309
  register_changed_hook = tui_register_changed_hook;
310
  detach_hook = tui_detach_hook;
311
}
312
 
313
/* Remove the TUI specific hooks.  */
314
void
315
tui_remove_hooks (void)
316
{
317
  target_wait_hook = 0;
318
  selected_frame_level_changed_hook = 0;
319
  print_frame_info_listing_hook = 0;
320
  query_hook = 0;
321
  registers_changed_hook = 0;
322
  register_changed_hook = 0;
323
  detach_hook = 0;
324
 
325
  /* Restore the previous event hooks.  */
326
  set_gdb_event_hooks (tui_old_event_hooks);
327
}
328
 
329
/* Cleanup the tui before exiting.  */
330
static void
331
tui_exit (void)
332
{
333
  /* Disable the tui.  Curses mode is left leaving the screen
334
     in a clean state (see endwin()).  */
335
  tui_disable ();
336
}
337
 
338
/* Initialize all the necessary variables, start the event loop,
339
   register readline, and stdin, start the loop. */
340
static void
341
tui_command_loop (void)
342
{
343
  int length;
344
  char *a_prompt;
345
  char *gdb_prompt = get_prompt ();
346
 
347
  /* If we are using readline, set things up and display the first
348
     prompt, otherwise just print the prompt. */
349
  if (async_command_editing_p)
350
    {
351
      /* Tell readline what the prompt to display is and what function it
352
         will need to call after a whole line is read. This also displays
353
         the first prompt. */
354
      length = strlen (PREFIX (0)) + strlen (gdb_prompt) + strlen (SUFFIX (0)) + 1;
355
      a_prompt = (char *) xmalloc (length);
356
      strcpy (a_prompt, PREFIX (0));
357
      strcat (a_prompt, gdb_prompt);
358
      strcat (a_prompt, SUFFIX (0));
359
      rl_callback_handler_install (a_prompt, input_handler);
360
    }
361
  else
362
    display_gdb_prompt (0);
363
 
364
  /* Now it's time to start the event loop. */
365
  tui_event_loop ();
366
}
367
 
368
/* Start up the event loop. This is the entry point to the event loop
369
   from the command loop. */
370
 
371
static void
372
tui_event_loop (void)
373
{
374
  /* Loop until there is nothing to do. This is the entry point to the
375
     event loop engine. gdb_do_one_event, called via catch_errors()
376
     will process one event for each invocation.  It blocks waits for
377
     an event and then processes it.  >0 when an event is processed, 0
378
     when catch_errors() caught an error and <0 when there are no
379
     longer any event sources registered. */
380
  while (1)
381
    {
382
      int result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL);
383
      if (result < 0)
384
        break;
385
 
386
      /* Update gdb output according to TUI mode.  Since catch_errors
387
         preserves the uiout from changing, this must be done at top
388
         level of event loop.  */
389
      if (tui_active)
390
        uiout = tui_out;
391
      else
392
        uiout = tui_old_uiout;
393
 
394
      if (result == 0)
395
        {
396
          /* FIXME: this should really be a call to a hook that is
397
             interface specific, because interfaces can display the
398
             prompt in their own way. */
399
          display_gdb_prompt (0);
400
          /* This call looks bizarre, but it is required.  If the user
401
             entered a command that caused an error,
402
             after_char_processing_hook won't be called from
403
             rl_callback_read_char_wrapper.  Using a cleanup there
404
             won't work, since we want this function to be called
405
             after a new prompt is printed.  */
406
          if (after_char_processing_hook)
407
            (*after_char_processing_hook) ();
408
          /* Maybe better to set a flag to be checked somewhere as to
409
             whether display the prompt or not. */
410
        }
411
    }
412
 
413
  /* We are done with the event loop. There are no more event sources
414
     to listen to.  So we exit GDB. */
415
  return;
416
}
417
 
418
/* Initialize the tui by installing several gdb hooks, initializing
419
   the tui IO and preparing the readline with the kind binding.  */
420
static void
421
tui_init_hook (char *argv0)
422
{
423
  /* Don't enable the TUI if a specific interpreter is installed.  */
424
  if (interpreter_p)
425
    return;
426
 
427
  /* Install exit handler to leave the screen in a good shape.  */
428
  atexit (tui_exit);
429
 
430
  initializeStaticData ();
431
 
432
  /* Install the permanent hooks.  */
433
  tui_target_new_objfile_chain = target_new_objfile_hook;
434
  target_new_objfile_hook = tui_new_objfile_hook;
435
 
436
  tui_initialize_io ();
437
  tui_initialize_readline ();
438
 
439
  /* Tell gdb to use the tui_command_loop as the main loop. */
440
  command_loop_hook = tui_command_loop;
441
 
442
  /* Decide in which mode to start using GDB (based on -tui).  */
443
  if (tui_version)
444
    {
445
      tui_enable ();
446
    }
447
}
448
 
449
/* Initialize the tui.  */
450
void
451
_initialize_tui (void)
452
{
453
  /* Setup initialization hook.  */
454
  init_ui_hook = tui_init_hook;
455
}
456
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.