Deleted Added
full compact
session.c (21787) session.c (42664)
1/* session.c -- The user windowing interface to Info. */
1/* session.c -- The user windowing interface to Info.
2 $Id: session.c,v 1.13 1998/02/22 22:38:30 karl Exp $
2
3
3/* This file is part of GNU Info, a program for reading online documentation
4 stored in Info format.
4 Copyright (C) 1993, 96, 97 Free Software Foundation, Inc.
5
5
6 Copyright (C) 1993, 96 Free Software Foundation, Inc.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Written by Brian Fox (bfox@ai.mit.edu). */
23
24#include "info.h"
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 Written by Brian Fox (bfox@ai.mit.edu). */
21
22#include "info.h"
25#if defined (HAVE_SYS_FILE_H)
26#include <sys/file.h>
27#endif /* HAVE_SYS_FILE_H */
28#include <sys/ioctl.h>
23#include <sys/ioctl.h>
29#include <fcntl.h>
30#include <stdlib.h>
31
32#if defined (HAVE_SYS_TIME_H)
33# include <sys/time.h>
34# define HAVE_STRUCT_TIMEVAL
35#endif /* HAVE_SYS_TIME_H */
36
37#if defined (HANDLE_MAN_PAGES)
38# include "man.h"
39#endif
40
41static void info_clear_pending_input (), info_set_pending_input ();
42static void info_handle_pointer ();
43
44/* **************************************************************** */
24
25#if defined (HAVE_SYS_TIME_H)
26# include <sys/time.h>
27# define HAVE_STRUCT_TIMEVAL
28#endif /* HAVE_SYS_TIME_H */
29
30#if defined (HANDLE_MAN_PAGES)
31# include "man.h"
32#endif
33
34static void info_clear_pending_input (), info_set_pending_input ();
35static void info_handle_pointer ();
36
37/* **************************************************************** */
45/* */
46/* Running an Info Session */
47/* */
38/* */
39/* Running an Info Session */
40/* */
48/* **************************************************************** */
49
50/* The place that we are reading input from. */
41/* **************************************************************** */
42
43/* The place that we are reading input from. */
51static FILE *info_input_stream = (FILE *)NULL;
44static FILE *info_input_stream = NULL;
52
53/* The last executed command. */
45
46/* The last executed command. */
54VFunction *info_last_executed_command = (VFunction *)NULL;
47VFunction *info_last_executed_command = NULL;
55
56/* Becomes non-zero when 'q' is typed to an Info window. */
57int quit_info_immediately = 0;
58
59/* Array of structures describing for each window which nodes have been
60 visited in that window. */
48
49/* Becomes non-zero when 'q' is typed to an Info window. */
50int quit_info_immediately = 0;
51
52/* Array of structures describing for each window which nodes have been
53 visited in that window. */
61INFO_WINDOW **info_windows = (INFO_WINDOW **)NULL;
54INFO_WINDOW **info_windows = NULL;
62
63/* Where to add the next window, if we need to add one. */
64static int info_windows_index = 0;
65
55
56/* Where to add the next window, if we need to add one. */
57static int info_windows_index = 0;
58
66/* Number of slots allocated to INFO_WINDOWS. */
59/* Number of slots allocated to `info_windows'. */
67static int info_windows_slots = 0;
68
69void remember_window_and_node (), forget_window_and_nodes ();
70void initialize_info_session (), info_session ();
71void display_startup_message_and_start ();
72
73/* Begin an info session finding the nodes specified by FILENAME and NODENAMES.
74 For each loaded node, create a new window. Always split the largest of the

--- 8 unchanged lines hidden (view full) ---

83
84 for (i = 0; nodenames[i]; i++)
85 {
86 NODE *node;
87
88 node = info_get_node (filename, nodenames[i]);
89
90 if (!node)
60static int info_windows_slots = 0;
61
62void remember_window_and_node (), forget_window_and_nodes ();
63void initialize_info_session (), info_session ();
64void display_startup_message_and_start ();
65
66/* Begin an info session finding the nodes specified by FILENAME and NODENAMES.
67 For each loaded node, create a new window. Always split the largest of the

--- 8 unchanged lines hidden (view full) ---

76
77 for (i = 0; nodenames[i]; i++)
78 {
79 NODE *node;
80
81 node = info_get_node (filename, nodenames[i]);
82
83 if (!node)
91 break;
84 break;
92
93 /* If this is the first node, initialize the info session. */
94 if (!window)
85
86 /* If this is the first node, initialize the info session. */
87 if (!window)
95 {
96 initialize_info_session (node);
97 window = active_window;
98 }
88 {
89 initialize_info_session (node, 1);
90 window = active_window;
91 }
99 else
92 else
100 {
101 /* Find the largest window in WINDOWS, and make that be the active
102 one. Then split it and add our window and node to the list
103 of remembered windows and nodes. Then tile the windows. */
104 register WINDOW *win, *largest = (WINDOW *)NULL;
105 int max_height = 0;
93 {
94 /* Find the largest window in WINDOWS, and make that be the active
95 one. Then split it and add our window and node to the list
96 of remembered windows and nodes. Then tile the windows. */
97 register WINDOW *win, *largest = (WINDOW *)NULL;
98 int max_height = 0;
106
99
107 for (win = windows; win; win = win->next)
108 if (win->height > max_height)
109 {
110 max_height = win->height;
111 largest = win;
112 }
100 for (win = windows; win; win = win->next)
101 if (win->height > max_height)
102 {
103 max_height = win->height;
104 largest = win;
105 }
113
106
114 if (!largest)
115 {
116 display_update_display (windows);
117 info_error (CANT_FIND_WIND);
118 info_session ();
119 exit (0);
120 }
107 if (!largest)
108 {
109 display_update_display (windows);
110 info_error (CANT_FIND_WIND);
111 info_session ();
112 exit (0);
113 }
121
114
122 active_window = largest;
123 window = window_make_window (node);
124 if (window)
125 {
126 window_tile_windows (TILE_INTERNALS);
127 remember_window_and_node (window, node);
128 }
129 else
130 {
131 display_update_display (windows);
132 info_error (WIN_TOO_SMALL);
133 info_session ();
134 exit (0);
135 }
136 }
115 active_window = largest;
116 window = window_make_window (node);
117 if (window)
118 {
119 window_tile_windows (TILE_INTERNALS);
120 remember_window_and_node (window, node);
121 }
122 else
123 {
124 display_update_display (windows);
125 info_error (WIN_TOO_SMALL);
126 info_session ();
127 exit (0);
128 }
129 }
137 }
138 display_startup_message_and_start ();
139}
140
141/* Start an info session with INITIAL_NODE, and an error message in the echo
142 area made from FORMAT and ARG. */
143void
144begin_info_session_with_error (initial_node, format, arg)
145 NODE *initial_node;
146 char *format;
147 void *arg;
148{
130 }
131 display_startup_message_and_start ();
132}
133
134/* Start an info session with INITIAL_NODE, and an error message in the echo
135 area made from FORMAT and ARG. */
136void
137begin_info_session_with_error (initial_node, format, arg)
138 NODE *initial_node;
139 char *format;
140 void *arg;
141{
149 initialize_info_session (initial_node);
142 initialize_info_session (initial_node, 1);
150 info_error (format, arg, (void *)NULL);
151 info_session ();
152}
153
154/* Start an info session with INITIAL_NODE. */
155void
156begin_info_session (initial_node)
157 NODE *initial_node;
158{
143 info_error (format, arg, (void *)NULL);
144 info_session ();
145}
146
147/* Start an info session with INITIAL_NODE. */
148void
149begin_info_session (initial_node)
150 NODE *initial_node;
151{
159 initialize_info_session (initial_node);
152 initialize_info_session (initial_node, 1);
160 display_startup_message_and_start ();
161}
162
163void
164display_startup_message_and_start ()
165{
166 char *format;
167
168 format = replace_in_documentation
153 display_startup_message_and_start ();
154}
155
156void
157display_startup_message_and_start ()
158{
159 char *format;
160
161 format = replace_in_documentation
169 ("Welcome to Info version %s. \"\\[get-help-window]\" for help, \"\\[menu-item]\" for menu item.");
162 (_("Welcome to Info version %s. \"\\[get-help-window]\" for help, \"\\[menu-item]\" for menu item."));
170
171 window_message_in_echo_area (format, version_string ());
172 info_session ();
173}
174
175/* Run an info session with an already initialized window and node. */
176void
177info_session ()
178{
163
164 window_message_in_echo_area (format, version_string ());
165 info_session ();
166}
167
168/* Run an info session with an already initialized window and node. */
169void
170info_session ()
171{
179 terminal_prep_terminal ();
180 display_update_display (windows);
172 display_update_display (windows);
181 info_last_executed_command = (VFunction *)NULL;
173 info_last_executed_command = NULL;
182 info_read_and_dispatch ();
183 /* On program exit, leave the cursor at the bottom of the window, and
184 restore the terminal I/O. */
185 terminal_goto_xy (0, screenheight - 1);
186 terminal_clear_to_eol ();
187 fflush (stdout);
188 terminal_unprep_terminal ();
189 close_dribble_file ();

--- 8 unchanged lines hidden (view full) ---

198 int done;
199 done = 0;
200
201 while (!done && !quit_info_immediately)
202 {
203 int lk;
204
205 /* If we haven't just gone up or down a line, there is no
174 info_read_and_dispatch ();
175 /* On program exit, leave the cursor at the bottom of the window, and
176 restore the terminal I/O. */
177 terminal_goto_xy (0, screenheight - 1);
178 terminal_clear_to_eol ();
179 fflush (stdout);
180 terminal_unprep_terminal ();
181 close_dribble_file ();

--- 8 unchanged lines hidden (view full) ---

190 int done;
191 done = 0;
192
193 while (!done && !quit_info_immediately)
194 {
195 int lk;
196
197 /* If we haven't just gone up or down a line, there is no
206 goal column for this window. */
198 goal column for this window. */
207 if ((info_last_executed_command != info_next_line) &&
199 if ((info_last_executed_command != info_next_line) &&
208 (info_last_executed_command != info_prev_line))
209 active_window->goal_column = -1;
200 (info_last_executed_command != info_prev_line))
201 active_window->goal_column = -1;
210
211 if (echo_area_is_active)
202
203 if (echo_area_is_active)
212 {
213 lk = echo_area_last_command_was_kill;
214 echo_area_prep_read ();
215 }
204 {
205 lk = echo_area_last_command_was_kill;
206 echo_area_prep_read ();
207 }
216
217 if (!info_any_buffered_input_p ())
208
209 if (!info_any_buffered_input_p ())
218 display_update_display (windows);
210 display_update_display (windows);
219
220 display_cursor_at_point (active_window);
221 info_initialize_numeric_arg ();
222
223 initialize_keyseq ();
224 key = info_get_input_char ();
225
226 /* No errors yet. We just read a character, that's all. Only clear
211
212 display_cursor_at_point (active_window);
213 info_initialize_numeric_arg ();
214
215 initialize_keyseq ();
216 key = info_get_input_char ();
217
218 /* No errors yet. We just read a character, that's all. Only clear
227 the echo_area if it is not currently active. */
219 the echo_area if it is not currently active. */
228 if (!echo_area_is_active)
220 if (!echo_area_is_active)
229 window_clear_echo_area ();
221 window_clear_echo_area ();
230
231 info_error_was_printed = 0;
232
233 /* Do the selected command. */
234 info_dispatch_on_key (key, active_window->keymap);
235
236 if (echo_area_is_active)
222
223 info_error_was_printed = 0;
224
225 /* Do the selected command. */
226 info_dispatch_on_key (key, active_window->keymap);
227
228 if (echo_area_is_active)
237 {
238 /* Echo area commands that do killing increment the value of
239 ECHO_AREA_LAST_COMMAND_WAS_KILL. Thus, if there is no
240 change in the value of this variable, the last command
241 executed was not a kill command. */
242 if (lk == echo_area_last_command_was_kill)
243 echo_area_last_command_was_kill = 0;
229 {
230 /* Echo area commands that do killing increment the value of
231 ECHO_AREA_LAST_COMMAND_WAS_KILL. Thus, if there is no
232 change in the value of this variable, the last command
233 executed was not a kill command. */
234 if (lk == echo_area_last_command_was_kill)
235 echo_area_last_command_was_kill = 0;
244
236
245 if (ea_last_executed_command == ea_newline ||
246 info_aborted_echo_area)
247 {
248 ea_last_executed_command = (VFunction *)NULL;
249 done = 1;
250 }
237 if (ea_last_executed_command == ea_newline ||
238 info_aborted_echo_area)
239 {
240 ea_last_executed_command = (VFunction *)NULL;
241 done = 1;
242 }
251
243
252 if (info_last_executed_command == info_quit)
253 quit_info_immediately = 1;
254 }
244 if (info_last_executed_command == info_quit)
245 quit_info_immediately = 1;
246 }
255 else if (info_last_executed_command == info_quit)
247 else if (info_last_executed_command == info_quit)
256 done = 1;
248 done = 1;
257 }
258}
259
260/* Found in signals.c */
261extern void initialize_info_signal_handler ();
262
263/* Initialize the first info session by starting the terminal, window,
249 }
250}
251
252/* Found in signals.c */
253extern void initialize_info_signal_handler ();
254
255/* Initialize the first info session by starting the terminal, window,
264 and display systems. */
256 and display systems. If CLEAR_SCREEN is 0, don't clear the screen. */
265void
257void
266initialize_info_session (node)
258initialize_info_session (node, clear_screen)
267 NODE *node;
259 NODE *node;
260 int clear_screen;
268{
261{
269 char *getenv (), *term_name;
270
271 term_name = getenv ("TERM");
262 char *term_name = getenv ("TERM");
272 terminal_initialize_terminal (term_name);
273
274 if (terminal_is_dumb_p)
275 {
276 if (!term_name)
263 terminal_initialize_terminal (term_name);
264
265 if (terminal_is_dumb_p)
266 {
267 if (!term_name)
277 term_name = "dumb";
268 term_name = "dumb";
278
279 info_error (TERM_TOO_DUMB, term_name);
280 exit (1);
281 }
282
269
270 info_error (TERM_TOO_DUMB, term_name);
271 exit (1);
272 }
273
283 terminal_clear_screen ();
274 if (clear_screen)
275 {
276 terminal_prep_terminal ();
277 terminal_clear_screen ();
278 }
279
284 initialize_info_keymaps ();
285 window_initialize_windows (screenwidth, screenheight);
286 initialize_info_signal_handler ();
287 display_initialize_display (screenwidth, screenheight);
288 info_set_node_of_window (active_window, node);
289
290 /* Tell the window system how to notify us when a window needs to be
291 asynchronously deleted (e.g., user resizes window very small). */
292 window_deletion_notifier = forget_window_and_nodes;
293
280 initialize_info_keymaps ();
281 window_initialize_windows (screenwidth, screenheight);
282 initialize_info_signal_handler ();
283 display_initialize_display (screenwidth, screenheight);
284 info_set_node_of_window (active_window, node);
285
286 /* Tell the window system how to notify us when a window needs to be
287 asynchronously deleted (e.g., user resizes window very small). */
288 window_deletion_notifier = forget_window_and_nodes;
289
294 /* If input has not been redirected yet, make it come from STDIN. */
290 /* If input has not been redirected yet, make it come from unbuffered
291 standard input. */
295 if (!info_input_stream)
292 if (!info_input_stream)
296 info_input_stream = stdin;
293 {
294 setbuf(stdin, NULL);
295 info_input_stream = stdin;
296 }
297
298 info_windows_initialized_p = 1;
299}
300
301/* Tell Info that input is coming from the file FILENAME. */
302void
303info_set_input_from_file (filename)
304 char *filename;

--- 52 unchanged lines hidden (view full) ---

357 }
358}
359
360void
361remember_window_and_node (window, node)
362 WINDOW *window;
363 NODE *node;
364{
297
298 info_windows_initialized_p = 1;
299}
300
301/* Tell Info that input is coming from the file FILENAME. */
302void
303info_set_input_from_file (filename)
304 char *filename;

--- 52 unchanged lines hidden (view full) ---

357 }
358}
359
360void
361remember_window_and_node (window, node)
362 WINDOW *window;
363 NODE *node;
364{
365 INFO_WINDOW *info_win;
366
367 /* See if we already have this window in our list. */
365 /* See if we already have this window in our list. */
368 info_win = get_info_window_of_window (window);
366 INFO_WINDOW *info_win = get_info_window_of_window (window);
369
370 /* If the window wasn't already on our list, then make a new entry. */
371 if (!info_win)
372 {
373 info_win = (INFO_WINDOW *)xmalloc (sizeof (INFO_WINDOW));
374 info_win->window = window;
375 info_win->nodes = (NODE **)NULL;
376 info_win->pagetops = (int *)NULL;
377 info_win->points = (long *)NULL;
378 info_win->current = 0;
379 info_win->nodes_index = 0;
380 info_win->nodes_slots = 0;
381
382 add_pointer_to_array (info_win, info_windows_index, info_windows,
367
368 /* If the window wasn't already on our list, then make a new entry. */
369 if (!info_win)
370 {
371 info_win = (INFO_WINDOW *)xmalloc (sizeof (INFO_WINDOW));
372 info_win->window = window;
373 info_win->nodes = (NODE **)NULL;
374 info_win->pagetops = (int *)NULL;
375 info_win->points = (long *)NULL;
376 info_win->current = 0;
377 info_win->nodes_index = 0;
378 info_win->nodes_slots = 0;
379
380 add_pointer_to_array (info_win, info_windows_index, info_windows,
383 info_windows_slots, 10, INFO_WINDOW *);
381 info_windows_slots, 10, INFO_WINDOW *);
384 }
385
386 /* If this node, the current pagetop, and the current point are the
382 }
383
384 /* If this node, the current pagetop, and the current point are the
387 same as the last saved node and pagetop, don't really add this to
388 the list of history nodes. */
389 {
390 int ni = info_win->nodes_index - 1;
385 same as the current saved node and pagetop, don't really add this to
386 the list of history nodes. This may happen only at the very
387 beginning of the program, I'm not sure. --karl */
388 if (info_win->nodes
389 && info_win->current >= 0
390 && info_win->nodes[info_win->current]->contents == node->contents
391 && info_win->pagetops[info_win->current] == window->pagetop
392 && info_win->points[info_win->current] == window->point)
393 return;
391
394
392 if ((ni != -1) &&
393 (info_win->nodes[ni]->contents == node->contents) &&
394 (info_win->pagetops[ni] == window->pagetop) &&
395 (info_win->points[ni] == window->point))
396 return;
397 }
398
399 /* Remember this node, the currently displayed pagetop, and the current
400 location of point in this window. Because we are updating pagetops
401 and points as well as nodes, it is more efficient to avoid the
402 add_pointer_to_array macro here. */
403 if (info_win->nodes_index + 2 >= info_win->nodes_slots)
404 {
395 /* Remember this node, the currently displayed pagetop, and the current
396 location of point in this window. Because we are updating pagetops
397 and points as well as nodes, it is more efficient to avoid the
398 add_pointer_to_array macro here. */
399 if (info_win->nodes_index + 2 >= info_win->nodes_slots)
400 {
405 info_win->nodes = (NODE **)
406 xrealloc (info_win->nodes,
407 (info_win->nodes_slots += 20) * sizeof (NODE *));
408
409 info_win->pagetops = (int *)
410 xrealloc (info_win->pagetops, info_win->nodes_slots * sizeof (int));
411
412 info_win->points = (long *)
413 xrealloc (info_win->points, info_win->nodes_slots * sizeof (long));
401 info_win->nodes_slots += 20;
402 info_win->nodes = (NODE **) xrealloc (info_win->nodes,
403 info_win->nodes_slots * sizeof (NODE *));
404 info_win->pagetops = (int *) xrealloc (info_win->pagetops,
405 info_win->nodes_slots * sizeof (int));
406 info_win->points = (long *) xrealloc (info_win->points,
407 info_win->nodes_slots * sizeof (long));
414 }
415
416 info_win->nodes[info_win->nodes_index] = node;
417 info_win->pagetops[info_win->nodes_index] = window->pagetop;
418 info_win->points[info_win->nodes_index] = window->point;
419 info_win->current = info_win->nodes_index++;
408 }
409
410 info_win->nodes[info_win->nodes_index] = node;
411 info_win->pagetops[info_win->nodes_index] = window->pagetop;
412 info_win->points[info_win->nodes_index] = window->point;
413 info_win->current = info_win->nodes_index++;
420 info_win->nodes[info_win->nodes_index] = (NODE *)NULL;
414 info_win->nodes[info_win->nodes_index] = NULL;
421 info_win->pagetops[info_win->nodes_index] = 0;
422 info_win->points[info_win->nodes_index] = 0;
423}
424
425#define DEBUG_FORGET_WINDOW_AND_NODES
426#if defined (DEBUG_FORGET_WINDOW_AND_NODES)
427static void
428consistency_check_info_windows ()
429{
430 register int i;
415 info_win->pagetops[info_win->nodes_index] = 0;
416 info_win->points[info_win->nodes_index] = 0;
417}
418
419#define DEBUG_FORGET_WINDOW_AND_NODES
420#if defined (DEBUG_FORGET_WINDOW_AND_NODES)
421static void
422consistency_check_info_windows ()
423{
424 register int i;
431 INFO_WINDOW *info_win;
432
433 for (i = 0; i < info_windows_index; i++)
434 {
435 WINDOW *win;
436
437 for (win = windows; win; win = win->next)
425
426 for (i = 0; i < info_windows_index; i++)
427 {
428 WINDOW *win;
429
430 for (win = windows; win; win = win->next)
438 if (win == info_windows[i]->window)
439 break;
431 if (win == info_windows[i]->window)
432 break;
440
441 if (!win)
433
434 if (!win)
442 abort ();
435 abort ();
443 }
444}
445#endif /* DEBUG_FORGET_WINDOW_AND_NODES */
446
447/* Remove WINDOW and its associated list of nodes from INFO_WINDOWS. */
448void
449forget_window_and_nodes (window)
450 WINDOW *window;

--- 4 unchanged lines hidden (view full) ---

455 for (i = 0; info_windows && (info_win = info_windows[i]); i++)
456 if (info_win->window == window)
457 break;
458
459 /* If we found the window to forget, then do so. */
460 if (info_win)
461 {
462 while (i < info_windows_index)
436 }
437}
438#endif /* DEBUG_FORGET_WINDOW_AND_NODES */
439
440/* Remove WINDOW and its associated list of nodes from INFO_WINDOWS. */
441void
442forget_window_and_nodes (window)
443 WINDOW *window;

--- 4 unchanged lines hidden (view full) ---

448 for (i = 0; info_windows && (info_win = info_windows[i]); i++)
449 if (info_win->window == window)
450 break;
451
452 /* If we found the window to forget, then do so. */
453 if (info_win)
454 {
455 while (i < info_windows_index)
463 {
464 info_windows[i] = info_windows[i + 1];
465 i++;
466 }
456 {
457 info_windows[i] = info_windows[i + 1];
458 i++;
459 }
467
468 info_windows_index--;
469 info_windows[info_windows_index] = (INFO_WINDOW *)NULL;
470
471 if (info_win->nodes)
460
461 info_windows_index--;
462 info_windows[info_windows_index] = (INFO_WINDOW *)NULL;
463
464 if (info_win->nodes)
472 {
473 /* Free the node structures which held onto internal node contents
474 here. This doesn't free the contents; we have a garbage collector
475 which does that. */
476 for (i = 0; info_win->nodes[i]; i++)
477 if (internal_info_node_p (info_win->nodes[i]))
478 free (info_win->nodes[i]);
479 free (info_win->nodes);
465 {
466 /* Free the node structures which held onto internal node contents
467 here. This doesn't free the contents; we have a garbage collector
468 which does that. */
469 for (i = 0; info_win->nodes[i]; i++)
470 if (internal_info_node_p (info_win->nodes[i]))
471 free (info_win->nodes[i]);
472 free (info_win->nodes);
480
473
481 maybe_free (info_win->pagetops);
482 maybe_free (info_win->points);
483 }
474 maybe_free (info_win->pagetops);
475 maybe_free (info_win->points);
476 }
484
485 free (info_win);
486 }
487#if defined (DEBUG_FORGET_WINDOW_AND_NODES)
488 consistency_check_info_windows ();
489#endif /* DEBUG_FORGET_WINDOW_AND_NODES */
490}
491

--- 14 unchanged lines hidden (view full) ---

506 /* If doing auto-footnote display/undisplay, show the footnotes belonging
507 to this window's node. */
508 if (auto_footnotes_p)
509 info_get_or_remove_footnotes (window);
510}
511
512
513/* **************************************************************** */
477
478 free (info_win);
479 }
480#if defined (DEBUG_FORGET_WINDOW_AND_NODES)
481 consistency_check_info_windows ();
482#endif /* DEBUG_FORGET_WINDOW_AND_NODES */
483}
484

--- 14 unchanged lines hidden (view full) ---

499 /* If doing auto-footnote display/undisplay, show the footnotes belonging
500 to this window's node. */
501 if (auto_footnotes_p)
502 info_get_or_remove_footnotes (window);
503}
504
505
506/* **************************************************************** */
514/* */
515/* Info Movement Commands */
516/* */
507/* */
508/* Info Movement Commands */
509/* */
517/* **************************************************************** */
518
519/* Change the pagetop of WINDOW to DESIRED_TOP, perhaps scrolling the screen
520 to do so. */
521void
522set_window_pagetop (window, desired_top)
523 WINDOW *window;
524 int desired_top;

--- 27 unchanged lines hidden (view full) ---

552 than 10 % of the window's height. */
553 if (old_pagetop < desired_top)
554 {
555 int start, end, amount;
556
557 amount = desired_top - old_pagetop;
558
559 if ((amount >= window->height) ||
510/* **************************************************************** */
511
512/* Change the pagetop of WINDOW to DESIRED_TOP, perhaps scrolling the screen
513 to do so. */
514void
515set_window_pagetop (window, desired_top)
516 WINDOW *window;
517 int desired_top;

--- 27 unchanged lines hidden (view full) ---

545 than 10 % of the window's height. */
546 if (old_pagetop < desired_top)
547 {
548 int start, end, amount;
549
550 amount = desired_top - old_pagetop;
551
552 if ((amount >= window->height) ||
560 (((window->height - amount) * 10) < window->height))
561 return;
553 (((window->height - amount) * 10) < window->height))
554 return;
562
563 start = amount + window->first_row;
564 end = window->height + window->first_row;
565
566 display_scroll_display (start, end, -amount);
567 }
568 else
569 {
570 int start, end, amount;
571
572 amount = old_pagetop - desired_top;
573
574 if ((amount >= window->height) ||
555
556 start = amount + window->first_row;
557 end = window->height + window->first_row;
558
559 display_scroll_display (start, end, -amount);
560 }
561 else
562 {
563 int start, end, amount;
564
565 amount = old_pagetop - desired_top;
566
567 if ((amount >= window->height) ||
575 (((window->height - amount) * 10) < window->height))
576 return;
568 (((window->height - amount) * 10) < window->height))
569 return;
577
578 start = window->first_row;
579 end = (window->first_row + window->height) - amount;
580 display_scroll_display (start, end, amount);
581 }
582}
583
584/* Immediately make WINDOW->point visible on the screen, and move the

--- 31 unchanged lines hidden (view full) ---

616 {
617 info_error (CANT_FIND_POINT);
618 }
619 else
620 {
621 int goal;
622
623 if (new >= window->line_count || new < 0)
570
571 start = window->first_row;
572 end = (window->first_row + window->height) - amount;
573 display_scroll_display (start, end, amount);
574 }
575}
576
577/* Immediately make WINDOW->point visible on the screen, and move the

--- 31 unchanged lines hidden (view full) ---

609 {
610 info_error (CANT_FIND_POINT);
611 }
612 else
613 {
614 int goal;
615
616 if (new >= window->line_count || new < 0)
624 return;
617 return;
625
626 goal = window_get_goal_column (window);
627 window->goal_column = goal;
628
629 window->point = window->line_starts[new] - window->node->contents;
630 window->point += window_chars_to_goal (window->line_starts[new], goal);
631 info_show_point (window);
632 }
633}
634
635/* Move WINDOW's point down to the next line if possible. */
618
619 goal = window_get_goal_column (window);
620 window->goal_column = goal;
621
622 window->point = window->line_starts[new] - window->node->contents;
623 window->point += window_chars_to_goal (window->line_starts[new], goal);
624 info_show_point (window);
625 }
626}
627
628/* Move WINDOW's point down to the next line if possible. */
636DECLARE_INFO_COMMAND (info_next_line, "Move down to the next line")
629DECLARE_INFO_COMMAND (info_next_line, _("Move down to the next line"))
637{
638 int old_line, new_line;
639
640 if (count < 0)
641 info_prev_line (window, -count, key);
642 else
643 {
644 old_line = window_line_of_point (window);
645 new_line = old_line + count;
646 move_to_new_line (old_line, new_line, window);
647 }
648}
649
650/* Move WINDOW's point up to the previous line if possible. */
630{
631 int old_line, new_line;
632
633 if (count < 0)
634 info_prev_line (window, -count, key);
635 else
636 {
637 old_line = window_line_of_point (window);
638 new_line = old_line + count;
639 move_to_new_line (old_line, new_line, window);
640 }
641}
642
643/* Move WINDOW's point up to the previous line if possible. */
651DECLARE_INFO_COMMAND (info_prev_line, "Move up to the previous line")
644DECLARE_INFO_COMMAND (info_prev_line, _("Move up to the previous line"))
652{
653 int old_line, new_line;
654
655 if (count < 0)
656 info_next_line (window, -count, key);
657 else
658 {
659 old_line = window_line_of_point (window);
660 new_line = old_line - count;
661 move_to_new_line (old_line, new_line, window);
662 }
663}
664
665/* Move WINDOW's point to the end of the true line. */
645{
646 int old_line, new_line;
647
648 if (count < 0)
649 info_next_line (window, -count, key);
650 else
651 {
652 old_line = window_line_of_point (window);
653 new_line = old_line - count;
654 move_to_new_line (old_line, new_line, window);
655 }
656}
657
658/* Move WINDOW's point to the end of the true line. */
666DECLARE_INFO_COMMAND (info_end_of_line, "Move to the end of the line")
659DECLARE_INFO_COMMAND (info_end_of_line, _("Move to the end of the line"))
667{
668 register int point, len;
669 register char *buffer;
670
671 buffer = window->node->contents;
672 len = window->node->nodelen;
673
674 for (point = window->point;
675 (point < len) && (buffer[point] != '\n');
676 point++);
677
678 if (point != window->point)
679 {
680 window->point = point;
681 info_show_point (window);
682 }
683}
684
685/* Move WINDOW's point to the beginning of the true line. */
660{
661 register int point, len;
662 register char *buffer;
663
664 buffer = window->node->contents;
665 len = window->node->nodelen;
666
667 for (point = window->point;
668 (point < len) && (buffer[point] != '\n');
669 point++);
670
671 if (point != window->point)
672 {
673 window->point = point;
674 info_show_point (window);
675 }
676}
677
678/* Move WINDOW's point to the beginning of the true line. */
686DECLARE_INFO_COMMAND (info_beginning_of_line, "Move to the start of the line")
679DECLARE_INFO_COMMAND (info_beginning_of_line, _("Move to the start of the line"))
687{
688 register int point;
689 register char *buffer;
690
691 buffer = window->node->contents;
692 point = window->point;
693
694 for (; (point) && (buffer[point - 1] != '\n'); point--);
695
696 /* If at a line start alreay, do nothing. */
697 if (point != window->point)
698 {
699 window->point = point;
700 info_show_point (window);
701 }
702}
703
704/* Move point forward in the node. */
680{
681 register int point;
682 register char *buffer;
683
684 buffer = window->node->contents;
685 point = window->point;
686
687 for (; (point) && (buffer[point - 1] != '\n'); point--);
688
689 /* If at a line start alreay, do nothing. */
690 if (point != window->point)
691 {
692 window->point = point;
693 info_show_point (window);
694 }
695}
696
697/* Move point forward in the node. */
705DECLARE_INFO_COMMAND (info_forward_char, "Move forward a character")
698DECLARE_INFO_COMMAND (info_forward_char, _("Move forward a character"))
706{
707 if (count < 0)
708 info_backward_char (window, -count, key);
709 else
710 {
711 window->point += count;
712
713 if (window->point >= window->node->nodelen)
699{
700 if (count < 0)
701 info_backward_char (window, -count, key);
702 else
703 {
704 window->point += count;
705
706 if (window->point >= window->node->nodelen)
714 window->point = window->node->nodelen - 1;
707 window->point = window->node->nodelen - 1;
715
716 info_show_point (window);
717 }
718}
719
720/* Move point backward in the node. */
708
709 info_show_point (window);
710 }
711}
712
713/* Move point backward in the node. */
721DECLARE_INFO_COMMAND (info_backward_char, "Move backward a character")
714DECLARE_INFO_COMMAND (info_backward_char, _("Move backward a character"))
722{
723 if (count < 0)
724 info_forward_char (window, -count, key);
725 else
726 {
727 window->point -= count;
728
729 if (window->point < 0)
715{
716 if (count < 0)
717 info_forward_char (window, -count, key);
718 else
719 {
720 window->point -= count;
721
722 if (window->point < 0)
730 window->point = 0;
723 window->point = 0;
731
732 info_show_point (window);
733 }
734}
735
736#define alphabetic(c) (islower (c) || isupper (c) || isdigit (c))
737
738/* Move forward a word in this node. */
724
725 info_show_point (window);
726 }
727}
728
729#define alphabetic(c) (islower (c) || isupper (c) || isdigit (c))
730
731/* Move forward a word in this node. */
739DECLARE_INFO_COMMAND (info_forward_word, "Move forward a word")
732DECLARE_INFO_COMMAND (info_forward_word, _("Move forward a word"))
740{
741 long point;
742 char *buffer;
743 int end, c;
744
745 if (count < 0)
746 {
747 info_backward_word (window, -count, key);
748 return;
749 }
750
751 point = window->point;
752 buffer = window->node->contents;
753 end = window->node->nodelen;
754
755 while (count)
756 {
757 if (point + 1 >= end)
733{
734 long point;
735 char *buffer;
736 int end, c;
737
738 if (count < 0)
739 {
740 info_backward_word (window, -count, key);
741 return;
742 }
743
744 point = window->point;
745 buffer = window->node->contents;
746 end = window->node->nodelen;
747
748 while (count)
749 {
750 if (point + 1 >= end)
758 return;
751 return;
759
760 /* If we are not in a word, move forward until we are in one.
752
753 /* If we are not in a word, move forward until we are in one.
761 Then, move forward until we hit a non-alphabetic character. */
754 Then, move forward until we hit a non-alphabetic character. */
762 c = buffer[point];
763
764 if (!alphabetic (c))
755 c = buffer[point];
756
757 if (!alphabetic (c))
765 {
766 while (++point < end)
767 {
768 c = buffer[point];
769 if (alphabetic (c))
770 break;
771 }
772 }
758 {
759 while (++point < end)
760 {
761 c = buffer[point];
762 if (alphabetic (c))
763 break;
764 }
765 }
773
774 if (point >= end) return;
775
776 while (++point < end)
766
767 if (point >= end) return;
768
769 while (++point < end)
777 {
778 c = buffer[point];
779 if (!alphabetic (c))
780 break;
781 }
770 {
771 c = buffer[point];
772 if (!alphabetic (c))
773 break;
774 }
782 --count;
783 }
784 window->point = point;
785 info_show_point (window);
786}
787
775 --count;
776 }
777 window->point = point;
778 info_show_point (window);
779}
780
788DECLARE_INFO_COMMAND (info_backward_word, "Move backward a word")
781DECLARE_INFO_COMMAND (info_backward_word, _("Move backward a word"))
789{
790 long point;
791 char *buffer;
792 int c;
793
794 if (count < 0)
795 {
796 info_forward_word (window, -count, key);
797 return;
798 }
799
800 buffer = window->node->contents;
801 point = window->point;
802
803 while (count)
804 {
805 if (point == 0)
782{
783 long point;
784 char *buffer;
785 int c;
786
787 if (count < 0)
788 {
789 info_forward_word (window, -count, key);
790 return;
791 }
792
793 buffer = window->node->contents;
794 point = window->point;
795
796 while (count)
797 {
798 if (point == 0)
806 break;
799 break;
807
808 /* Like info_forward_word (), except that we look at the
800
801 /* Like info_forward_word (), except that we look at the
809 characters just before point. */
802 characters just before point. */
810
811 c = buffer[point - 1];
812
813 if (!alphabetic (c))
803
804 c = buffer[point - 1];
805
806 if (!alphabetic (c))
814 {
815 while (--point)
816 {
817 c = buffer[point - 1];
818 if (alphabetic (c))
819 break;
820 }
821 }
807 {
808 while (--point)
809 {
810 c = buffer[point - 1];
811 if (alphabetic (c))
812 break;
813 }
814 }
822
823 while (point)
815
816 while (point)
824 {
825 c = buffer[point - 1];
826 if (!alphabetic (c))
827 break;
828 else
829 --point;
830 }
817 {
818 c = buffer[point - 1];
819 if (!alphabetic (c))
820 break;
821 else
822 --point;
823 }
831 --count;
832 }
833 window->point = point;
834 info_show_point (window);
835}
836
837/* Here is a list of time counter names which correspond to ordinal numbers.
838 It is used to print "once" instead of "1". */

--- 15 unchanged lines hidden (view full) ---

854
855 td_buffer[0] = '\0';
856
857 for (i = 0; counter_names[i]; i++)
858 if (count == i)
859 break;
860
861 if (counter_names[i])
824 --count;
825 }
826 window->point = point;
827 info_show_point (window);
828}
829
830/* Here is a list of time counter names which correspond to ordinal numbers.
831 It is used to print "once" instead of "1". */

--- 15 unchanged lines hidden (view full) ---

847
848 td_buffer[0] = '\0';
849
850 for (i = 0; counter_names[i]; i++)
851 if (count == i)
852 break;
853
854 if (counter_names[i])
862 sprintf (td_buffer, "%s%s", counter_names[i], count > 2 ? " times" : "");
855 sprintf (td_buffer, "%s%s", counter_names[i], count > 2 ? _(" times") : "");
863 else
856 else
864 sprintf (td_buffer, "%d times", count);
857 sprintf (td_buffer, _("%d times"), count);
865
866 return (td_buffer);
867}
868
869/* Variable controlling the behaviour of default scrolling when you are
870 already at the bottom of a node. Possible values are defined in session.h.
871 The meanings are:
872
858
859 return (td_buffer);
860}
861
862/* Variable controlling the behaviour of default scrolling when you are
863 already at the bottom of a node. Possible values are defined in session.h.
864 The meanings are:
865
873 IS_Continuous Try to get first menu item, or failing that, the
874 "Next:" pointer, or failing that, the "Up:" and
875 "Next:" of the up.
876 IS_NextOnly Try to get "Next:" menu item.
877 IS_PageOnly Simply give up at the bottom of a node. */
866 IS_Continuous Try to get first menu item, or failing that, the
867 "Next:" pointer, or failing that, the "Up:" and
868 "Next:" of the up.
869 IS_NextOnly Try to get "Next:" menu item.
870 IS_PageOnly Simply give up at the bottom of a node. */
878
879int info_scroll_behaviour = IS_Continuous;
880
881/* Choices used by the completer when reading a value for the user-visible
882 variable "scroll-behaviour". */
883char *info_scroll_choices[] = {
884 "Continuous", "Next Only", "Page Only", (char *)NULL
885};

--- 8 unchanged lines hidden (view full) ---

894 {
895 case IS_PageOnly:
896 info_error (AT_NODE_BOTTOM);
897 break;
898
899 case IS_NextOnly:
900 info_next_label_of_node (window->node);
901 if (!info_parsed_nodename && !info_parsed_filename)
871
872int info_scroll_behaviour = IS_Continuous;
873
874/* Choices used by the completer when reading a value for the user-visible
875 variable "scroll-behaviour". */
876char *info_scroll_choices[] = {
877 "Continuous", "Next Only", "Page Only", (char *)NULL
878};

--- 8 unchanged lines hidden (view full) ---

887 {
888 case IS_PageOnly:
889 info_error (AT_NODE_BOTTOM);
890 break;
891
892 case IS_NextOnly:
893 info_next_label_of_node (window->node);
894 if (!info_parsed_nodename && !info_parsed_filename)
902 info_error ("No \"Next\" pointer for this node.");
895 info_error (_("No \"Next\" pointer for this node."));
903 else
896 else
904 {
905 window_message_in_echo_area ("Following \"Next\" node...");
906 info_handle_pointer ("Next", window);
907 }
897 {
898 window_message_in_echo_area (_("Following \"Next\" node..."));
899 info_handle_pointer (_("Next"), window);
900 }
908 break;
909
910 case IS_Continuous:
911 {
901 break;
902
903 case IS_Continuous:
904 {
912 /* First things first. If this node contains a menu, move down
913 into the menu. */
914 {
915 REFERENCE **menu;
905 /* First things first. If this node contains a menu, move down
906 into the menu. */
907 {
908 REFERENCE **menu;
916
909
917 menu = info_menu_of_node (window->node);
910 menu = info_menu_of_node (window->node);
918
911
919 if (menu)
920 {
921 info_free_references (menu);
922 window_message_in_echo_area ("Selecting first menu item...");
923 info_menu_digit (window, 1, '1');
924 return;
925 }
926 }
912 if (menu)
913 {
914 info_free_references (menu);
915 window_message_in_echo_area (_("Selecting first menu item..."));
916 info_menu_digit (window, 1, '1');
917 return;
918 }
919 }
927
920
928 /* Okay, this node does not contain a menu. If it contains a
929 "Next:" pointer, use that. */
930 info_next_label_of_node (window->node);
931 if (info_label_was_found)
932 {
933 window_message_in_echo_area ("Selecting \"Next\" node...");
934 info_handle_pointer ("Next", window);
935 return;
936 }
921 /* Okay, this node does not contain a menu. If it contains a
922 "Next:" pointer, use that. */
923 info_next_label_of_node (window->node);
924 if (info_label_was_found)
925 {
926 window_message_in_echo_area (_("Selecting \"Next\" node..."));
927 info_handle_pointer (_("Next"), window);
928 return;
929 }
937
930
938 /* Okay, there wasn't a "Next:" for this node. Move "Up:" until we
939 can move "Next:". If that isn't possible, complain that there
940 are no more nodes. */
941 {
942 int up_counter, old_current;
943 INFO_WINDOW *info_win;
931 /* Okay, there wasn't a "Next:" for this node. Move "Up:" until we
932 can move "Next:". If that isn't possible, complain that there
933 are no more nodes. */
934 {
935 int up_counter, old_current;
936 INFO_WINDOW *info_win;
944
937
945 /* Remember the current node and location. */
946 info_win = get_info_window_of_window (window);
947 old_current = info_win->current;
938 /* Remember the current node and location. */
939 info_win = get_info_window_of_window (window);
940 old_current = info_win->current;
948
941
949 /* Back up through the "Up:" pointers until we have found a "Next:"
950 that isn't the same as the first menu item found in that node. */
951 up_counter = 0;
952 while (!info_error_was_printed)
953 {
954 info_up_label_of_node (window->node);
955 if (info_label_was_found)
956 {
957 info_handle_pointer ("Up", window);
958 if (info_error_was_printed)
959 continue;
942 /* Back up through the "Up:" pointers until we have found a "Next:"
943 that isn't the same as the first menu item found in that node. */
944 up_counter = 0;
945 while (!info_error_was_printed)
946 {
947 info_up_label_of_node (window->node);
948 if (info_label_was_found)
949 {
950 info_handle_pointer (_("Up"), window);
951 if (info_error_was_printed)
952 continue;
960
953
961 up_counter++;
954 up_counter++;
962
955
963 info_next_label_of_node (window->node);
956 info_next_label_of_node (window->node);
964
957
965 /* If no "Next" pointer, keep backing up. */
966 if (!info_label_was_found)
967 continue;
958 /* If no "Next" pointer, keep backing up. */
959 if (!info_label_was_found)
960 continue;
968
961
969 /* If this node's first menu item is the same as this node's
970 Next pointer, keep backing up. */
971 if (!info_parsed_filename)
972 {
973 REFERENCE **menu;
974 char *next_nodename;
962 /* If this node's first menu item is the same as this node's
963 Next pointer, keep backing up. */
964 if (!info_parsed_filename)
965 {
966 REFERENCE **menu;
967 char *next_nodename;
975
968
976 /* Remember the name of the Next node, since reading
977 the menu can overwrite the contents of the
978 info_parsed_xxx strings. */
979 next_nodename = strdup (info_parsed_nodename);
969 /* Remember the name of the Next node, since reading
970 the menu can overwrite the contents of the
971 info_parsed_xxx strings. */
972 next_nodename = xstrdup (info_parsed_nodename);
980
973
981 menu = info_menu_of_node (window->node);
982 if (menu &&
983 (strcmp
984 (menu[0]->nodename, next_nodename) == 0))
985 {
986 info_free_references (menu);
987 free (next_nodename);
988 continue;
989 }
990 else
991 {
992 /* Restore the world to where it was before
993 reading the menu contents. */
994 info_free_references (menu);
995 free (next_nodename);
996 info_next_label_of_node (window->node);
997 }
998 }
974 menu = info_menu_of_node (window->node);
975 if (menu &&
976 (strcmp
977 (menu[0]->nodename, next_nodename) == 0))
978 {
979 info_free_references (menu);
980 free (next_nodename);
981 continue;
982 }
983 else
984 {
985 /* Restore the world to where it was before
986 reading the menu contents. */
987 info_free_references (menu);
988 free (next_nodename);
989 info_next_label_of_node (window->node);
990 }
991 }
999
992
1000 /* This node has a "Next" pointer, and it is not the
1001 same as the first menu item found in this node. */
1002 window_message_in_echo_area
1003 ("Moving \"Up\" %s, then \"Next\".",
1004 times_description (up_counter));
993 /* This node has a "Next" pointer, and it is not the
994 same as the first menu item found in this node. */
995 window_message_in_echo_area
996 ("Moving \"Up\" %s, then \"Next\".",
997 times_description (up_counter));
1005
998
1006 info_handle_pointer ("Next", window);
1007 return;
1008 }
1009 else
1010 {
1011 /* No more "Up" pointers. Print an error, and call it
1012 quits. */
1013 register int i;
999 info_handle_pointer (_("Next"), window);
1000 return;
1001 }
1002 else
1003 {
1004 /* No more "Up" pointers. Print an error, and call it
1005 quits. */
1006 register int i;
1014
1007
1015 for (i = 0; i < up_counter; i++)
1016 {
1017 info_win->nodes_index--;
1018 free (info_win->nodes[info_win->nodes_index]);
1019 info_win->nodes[info_win->nodes_index] = (NODE *)NULL;
1020 }
1021 info_win->current = old_current;
1022 window->node = info_win->nodes[old_current];
1023 window->pagetop = info_win->pagetops[old_current];
1024 window->point = info_win->points[old_current];
1025 recalculate_line_starts (window);
1026 window->flags |= W_UpdateWindow;
1027 info_error ("No more nodes.");
1028 }
1029 }
1030 }
1031 break;
1008 for (i = 0; i < up_counter; i++)
1009 {
1010 info_win->nodes_index--;
1011 free (info_win->nodes[info_win->nodes_index]);
1012 info_win->nodes[info_win->nodes_index] = (NODE *)NULL;
1013 }
1014 info_win->current = old_current;
1015 window->node = info_win->nodes[old_current];
1016 window->pagetop = info_win->pagetops[old_current];
1017 window->point = info_win->points[old_current];
1018 recalculate_line_starts (window);
1019 window->flags |= W_UpdateWindow;
1020 info_error (_("No more nodes."));
1021 }
1022 }
1023 }
1024 break;
1032 }
1033 }
1034}
1035
1036/* Move Prev, Up or error in WINDOW depending on BEHAVIOUR. */
1037static void
1038backward_move_node_structure (window, behaviour)
1039 WINDOW *window;
1040 int behaviour;
1041{
1042 switch (behaviour)
1043 {
1044 case IS_PageOnly:
1045 info_error (AT_NODE_TOP);
1046 break;
1047
1048 case IS_NextOnly:
1049 info_prev_label_of_node (window->node);
1050 if (!info_parsed_nodename && !info_parsed_filename)
1025 }
1026 }
1027}
1028
1029/* Move Prev, Up or error in WINDOW depending on BEHAVIOUR. */
1030static void
1031backward_move_node_structure (window, behaviour)
1032 WINDOW *window;
1033 int behaviour;
1034{
1035 switch (behaviour)
1036 {
1037 case IS_PageOnly:
1038 info_error (AT_NODE_TOP);
1039 break;
1040
1041 case IS_NextOnly:
1042 info_prev_label_of_node (window->node);
1043 if (!info_parsed_nodename && !info_parsed_filename)
1051 info_error ("No \"Prev\" for this node.");
1044 info_error (_("No \"Prev\" for this node."));
1052 else
1045 else
1053 {
1054 window_message_in_echo_area ("Moving \"Prev\" in this window.");
1055 info_handle_pointer ("Prev", window);
1056 }
1046 {
1047 window_message_in_echo_area (_("Moving \"Prev\" in this window."));
1048 info_handle_pointer (_("Prev"), window);
1049 }
1057 break;
1058
1059 case IS_Continuous:
1060 info_prev_label_of_node (window->node);
1061
1062 if (!info_parsed_nodename && !info_parsed_filename)
1050 break;
1051
1052 case IS_Continuous:
1053 info_prev_label_of_node (window->node);
1054
1055 if (!info_parsed_nodename && !info_parsed_filename)
1063 {
1064 info_up_label_of_node (window->node);
1065 if (!info_parsed_nodename && !info_parsed_filename)
1066 info_error ("No \"Prev\" or \"Up\" for this node.");
1067 else
1068 {
1069 window_message_in_echo_area ("Moving \"Up\" in this window.");
1070 info_handle_pointer ("Up", window);
1071 }
1072 }
1056 {
1057 info_up_label_of_node (window->node);
1058 if (!info_parsed_nodename && !info_parsed_filename)
1059 info_error (_("No \"Prev\" or \"Up\" for this node."));
1060 else
1061 {
1062 window_message_in_echo_area (_("Moving \"Up\" in this window."));
1063 info_handle_pointer (_("Up"), window);
1064 }
1065 }
1073 else
1066 else
1074 {
1075 REFERENCE **menu;
1076 int inhibit_menu_traversing = 0;
1067 {
1068 REFERENCE **menu;
1069 int inhibit_menu_traversing = 0;
1077
1070
1078 /* Watch out! If this node's Prev is the same as the Up, then
1079 move Up. Otherwise, we could move Prev, and then to the last
1080 menu item in the Prev. This would cause the user to loop
1081 through a subsection of the info file. */
1082 if (!info_parsed_filename && info_parsed_nodename)
1083 {
1084 char *pnode;
1071 /* Watch out! If this node's Prev is the same as the Up, then
1072 move Up. Otherwise, we could move Prev, and then to the last
1073 menu item in the Prev. This would cause the user to loop
1074 through a subsection of the info file. */
1075 if (!info_parsed_filename && info_parsed_nodename)
1076 {
1077 char *pnode;
1085
1078
1086 pnode = strdup (info_parsed_nodename);
1087 info_up_label_of_node (window->node);
1079 pnode = xstrdup (info_parsed_nodename);
1080 info_up_label_of_node (window->node);
1088
1081
1089 if (!info_parsed_filename && info_parsed_nodename &&
1090 strcmp (info_parsed_nodename, pnode) == 0)
1091 {
1092 /* The nodes are the same. Inhibit moving to the last
1093 menu item. */
1094 free (pnode);
1095 inhibit_menu_traversing = 1;
1096 }
1097 else
1098 {
1099 free (pnode);
1100 info_prev_label_of_node (window->node);
1101 }
1102 }
1082 if (!info_parsed_filename && info_parsed_nodename &&
1083 strcmp (info_parsed_nodename, pnode) == 0)
1084 {
1085 /* The nodes are the same. Inhibit moving to the last
1086 menu item. */
1087 free (pnode);
1088 inhibit_menu_traversing = 1;
1089 }
1090 else
1091 {
1092 free (pnode);
1093 info_prev_label_of_node (window->node);
1094 }
1095 }
1103
1096
1104 /* Move to the previous node. If this node now contains a menu,
1105 and we have not inhibited movement to it, move to the node
1106 corresponding to the last menu item. */
1107 window_message_in_echo_area ("Moving \"Prev\" in this window.");
1108 info_handle_pointer ("Prev", window);
1097 /* Move to the previous node. If this node now contains a menu,
1098 and we have not inhibited movement to it, move to the node
1099 corresponding to the last menu item. */
1100 window_message_in_echo_area (_("Moving \"Prev\" in this window."));
1101 info_handle_pointer (_("Prev"), window);
1109
1102
1110 if (!inhibit_menu_traversing)
1111 {
1112 while (!info_error_was_printed &&
1113 (menu = info_menu_of_node (window->node)))
1114 {
1115 info_free_references (menu);
1116 window_message_in_echo_area
1117 ("Moving to \"Prev\"'s last menu item.");
1118 info_menu_digit (window, 1, '0');
1119 }
1120 }
1121 }
1103 if (!inhibit_menu_traversing)
1104 {
1105 while (!info_error_was_printed &&
1106 (menu = info_menu_of_node (window->node)))
1107 {
1108 info_free_references (menu);
1109 window_message_in_echo_area
1110 (_("Moving to \"Prev\"'s last menu item."));
1111 info_menu_digit (window, 1, '0');
1112 }
1113 }
1114 }
1122 break;
1123 }
1124}
1125
1126/* Move continuously forward through the node structure of this info file. */
1127DECLARE_INFO_COMMAND (info_global_next_node,
1115 break;
1116 }
1117}
1118
1119/* Move continuously forward through the node structure of this info file. */
1120DECLARE_INFO_COMMAND (info_global_next_node,
1128 "Move forwards or down through node structure")
1121 _("Move forwards or down through node structure"))
1129{
1130 if (count < 0)
1131 info_global_prev_node (window, -count, key);
1132 else
1133 {
1134 while (count && !info_error_was_printed)
1122{
1123 if (count < 0)
1124 info_global_prev_node (window, -count, key);
1125 else
1126 {
1127 while (count && !info_error_was_printed)
1135 {
1136 forward_move_node_structure (window, IS_Continuous);
1137 count--;
1138 }
1128 {
1129 forward_move_node_structure (window, IS_Continuous);
1130 count--;
1131 }
1139 }
1140}
1141
1142/* Move continuously backward through the node structure of this info file. */
1143DECLARE_INFO_COMMAND (info_global_prev_node,
1132 }
1133}
1134
1135/* Move continuously backward through the node structure of this info file. */
1136DECLARE_INFO_COMMAND (info_global_prev_node,
1144 "Move backwards or up through node structure")
1137 _("Move backwards or up through node structure"))
1145{
1146 if (count < 0)
1147 info_global_next_node (window, -count, key);
1148 else
1149 {
1150 while (count && !info_error_was_printed)
1138{
1139 if (count < 0)
1140 info_global_next_node (window, -count, key);
1141 else
1142 {
1143 while (count && !info_error_was_printed)
1151 {
1152 backward_move_node_structure (window, IS_Continuous);
1153 count--;
1154 }
1144 {
1145 backward_move_node_structure (window, IS_Continuous);
1146 count--;
1147 }
1155 }
1156}
1157
1158/* Show the next screen of WINDOW's node. */
1148 }
1149}
1150
1151/* Show the next screen of WINDOW's node. */
1159DECLARE_INFO_COMMAND (info_scroll_forward, "Scroll forward in this window")
1152DECLARE_INFO_COMMAND (info_scroll_forward, _("Scroll forward in this window"))
1160{
1161 if (count < 0)
1162 info_scroll_backward (window, -count, key);
1163 else
1164 {
1165 int desired_top;
1166
1167 /* Without an explicit numeric argument, scroll the bottom two
1153{
1154 if (count < 0)
1155 info_scroll_backward (window, -count, key);
1156 else
1157 {
1158 int desired_top;
1159
1160 /* Without an explicit numeric argument, scroll the bottom two
1168 lines to the top of this window, Or, if at bottom of window,
1169 and the user wishes to scroll through nodes get the "Next" node
1170 for this window. */
1161 lines to the top of this window, Or, if at bottom of window,
1162 and the user wishes to scroll through nodes get the "Next" node
1163 for this window. */
1171 if (!info_explicit_arg && count == 1)
1164 if (!info_explicit_arg && count == 1)
1172 {
1173 desired_top = window->pagetop + (window->height - 2);
1165 {
1166 desired_top = window->pagetop + (window->height - 2);
1174
1167
1175 /* If there are no more lines to scroll here, error, or get
1176 another node, depending on INFO_SCROLL_BEHAVIOUR. */
1177 if (desired_top > window->line_count)
1178 {
1179 int behaviour = info_scroll_behaviour;
1168 /* If there are no more lines to scroll here, error, or get
1169 another node, depending on INFO_SCROLL_BEHAVIOUR. */
1170 if (desired_top > window->line_count)
1171 {
1172 int behaviour = info_scroll_behaviour;
1180
1173
1181 /* Here is a hack. If the key being used is not SPC, do the
1182 PageOnly behaviour. */
1183 if (key != SPC && key != DEL)
1184 behaviour = IS_PageOnly;
1174 /* Here is a hack. If the key being used is not SPC, do the
1175 PageOnly behaviour. */
1176 if (key != SPC && key != DEL)
1177 behaviour = IS_PageOnly;
1185
1178
1186 forward_move_node_structure (window, behaviour);
1187 return;
1188 }
1189 }
1179 forward_move_node_structure (window, behaviour);
1180 return;
1181 }
1182 }
1190 else
1183 else
1191 desired_top = window->pagetop + count;
1184 desired_top = window->pagetop + count;
1192
1193 if (desired_top >= window->line_count)
1185
1186 if (desired_top >= window->line_count)
1194 desired_top = window->line_count - 2;
1187 desired_top = window->line_count - 2;
1195
1196 if (window->pagetop > desired_top)
1188
1189 if (window->pagetop > desired_top)
1197 return;
1190 return;
1198 else
1191 else
1199 set_window_pagetop (window, desired_top);
1192 set_window_pagetop (window, desired_top);
1200 }
1201}
1202
1203/* Show the previous screen of WINDOW's node. */
1193 }
1194}
1195
1196/* Show the previous screen of WINDOW's node. */
1204DECLARE_INFO_COMMAND (info_scroll_backward, "Scroll backward in this window")
1197DECLARE_INFO_COMMAND (info_scroll_backward, _("Scroll backward in this window"))
1205{
1206 if (count < 0)
1207 info_scroll_forward (window, -count, key);
1208 else
1209 {
1210 int desired_top;
1211
1212 /* Without an explicit numeric argument, scroll the top two lines
1198{
1199 if (count < 0)
1200 info_scroll_forward (window, -count, key);
1201 else
1202 {
1203 int desired_top;
1204
1205 /* Without an explicit numeric argument, scroll the top two lines
1213 to the bottom of this window, or move to the previous, or Up'th
1214 node. */
1206 to the bottom of this window, or move to the previous, or Up'th
1207 node. */
1215 if (!info_explicit_arg && count == 1)
1208 if (!info_explicit_arg && count == 1)
1216 {
1217 desired_top = window->pagetop - (window->height - 2);
1209 {
1210 desired_top = window->pagetop - (window->height - 2);
1218
1211
1219 if ((desired_top < 0) && (window->pagetop == 0))
1220 {
1221 int behaviour = info_scroll_behaviour;
1212 if ((desired_top < 0) && (window->pagetop == 0))
1213 {
1214 int behaviour = info_scroll_behaviour;
1222
1215
1223 /* Same kind of hack as in info_scroll_forward. If the key
1224 used to invoke this command is not DEL, do only the PageOnly
1225 behaviour. */
1226 if (key != DEL && key != SPC)
1227 behaviour = IS_PageOnly;
1216 /* Same kind of hack as in info_scroll_forward. If the key
1217 used to invoke this command is not DEL, do only the PageOnly
1218 behaviour. */
1219 if (key != DEL && key != SPC)
1220 behaviour = IS_PageOnly;
1228
1221
1229 backward_move_node_structure (window, behaviour);
1230 return;
1231 }
1232 }
1222 backward_move_node_structure (window, behaviour);
1223 return;
1224 }
1225 }
1233 else
1226 else
1234 desired_top = window->pagetop - count;
1227 desired_top = window->pagetop - count;
1235
1236 if (desired_top < 0)
1228
1229 if (desired_top < 0)
1237 desired_top = 0;
1230 desired_top = 0;
1238
1239 set_window_pagetop (window, desired_top);
1240 }
1241}
1242
1243/* Move to the beginning of the node. */
1231
1232 set_window_pagetop (window, desired_top);
1233 }
1234}
1235
1236/* Move to the beginning of the node. */
1244DECLARE_INFO_COMMAND (info_beginning_of_node, "Move to the start of this node")
1237DECLARE_INFO_COMMAND (info_beginning_of_node, _("Move to the start of this node"))
1245{
1246 window->pagetop = window->point = 0;
1247 window->flags |= W_UpdateWindow;
1248}
1249
1250/* Move to the end of the node. */
1238{
1239 window->pagetop = window->point = 0;
1240 window->flags |= W_UpdateWindow;
1241}
1242
1243/* Move to the end of the node. */
1251DECLARE_INFO_COMMAND (info_end_of_node, "Move to the end of this node")
1244DECLARE_INFO_COMMAND (info_end_of_node, _("Move to the end of this node"))
1252{
1253 window->point = window->node->nodelen - 1;
1254 info_show_point (window);
1255}
1256
1257/* **************************************************************** */
1245{
1246 window->point = window->node->nodelen - 1;
1247 info_show_point (window);
1248}
1249
1250/* **************************************************************** */
1258/* */
1259/* Commands for Manipulating Windows */
1260/* */
1251/* */
1252/* Commands for Manipulating Windows */
1253/* */
1261/* **************************************************************** */
1262
1263/* Make the next window in the chain be the active window. */
1254/* **************************************************************** */
1255
1256/* Make the next window in the chain be the active window. */
1264DECLARE_INFO_COMMAND (info_next_window, "Select the next window")
1257DECLARE_INFO_COMMAND (info_next_window, _("Select the next window"))
1265{
1266 if (count < 0)
1267 {
1268 info_prev_window (window, -count, key);
1269 return;
1270 }
1271
1272 /* If no other window, error now. */
1273 if (!windows->next && !echo_area_is_active)
1274 {
1275 info_error (ONE_WINDOW);
1276 return;
1277 }
1278
1279 while (count--)
1280 {
1281 if (window->next)
1258{
1259 if (count < 0)
1260 {
1261 info_prev_window (window, -count, key);
1262 return;
1263 }
1264
1265 /* If no other window, error now. */
1266 if (!windows->next && !echo_area_is_active)
1267 {
1268 info_error (ONE_WINDOW);
1269 return;
1270 }
1271
1272 while (count--)
1273 {
1274 if (window->next)
1282 window = window->next;
1275 window = window->next;
1283 else
1276 else
1284 {
1285 if (window == the_echo_area || !echo_area_is_active)
1286 window = windows;
1287 else
1288 window = the_echo_area;
1289 }
1277 {
1278 if (window == the_echo_area || !echo_area_is_active)
1279 window = windows;
1280 else
1281 window = the_echo_area;
1282 }
1290 }
1291
1292 if (active_window != window)
1293 {
1294 if (auto_footnotes_p)
1283 }
1284
1285 if (active_window != window)
1286 {
1287 if (auto_footnotes_p)
1295 info_get_or_remove_footnotes (window);
1288 info_get_or_remove_footnotes (window);
1296
1297 window->flags |= W_UpdateWindow;
1298 active_window = window;
1299 }
1300}
1301
1302/* Make the previous window in the chain be the active window. */
1289
1290 window->flags |= W_UpdateWindow;
1291 active_window = window;
1292 }
1293}
1294
1295/* Make the previous window in the chain be the active window. */
1303DECLARE_INFO_COMMAND (info_prev_window, "Select the previous window")
1296DECLARE_INFO_COMMAND (info_prev_window, _("Select the previous window"))
1304{
1305 if (count < 0)
1306 {
1307 info_next_window (window, -count, key);
1308 return;
1309 }
1310
1311 /* Only one window? */
1312
1313 if (!windows->next && !echo_area_is_active)
1314 {
1315 info_error (ONE_WINDOW);
1316 return;
1317 }
1318
1319 while (count--)
1320 {
1321 /* If we are in the echo area, or if the echo area isn't active and we
1297{
1298 if (count < 0)
1299 {
1300 info_next_window (window, -count, key);
1301 return;
1302 }
1303
1304 /* Only one window? */
1305
1306 if (!windows->next && !echo_area_is_active)
1307 {
1308 info_error (ONE_WINDOW);
1309 return;
1310 }
1311
1312 while (count--)
1313 {
1314 /* If we are in the echo area, or if the echo area isn't active and we
1322 are in the first window, find the last window in the chain. */
1315 are in the first window, find the last window in the chain. */
1323 if (window == the_echo_area ||
1316 if (window == the_echo_area ||
1324 (window == windows && !echo_area_is_active))
1325 {
1326 register WINDOW *win, *last;
1317 (window == windows && !echo_area_is_active))
1318 {
1319 register WINDOW *win, *last;
1327
1320
1328 for (win = windows; win; win = win->next)
1329 last = win;
1321 for (win = windows; win; win = win->next)
1322 last = win;
1330
1323
1331 window = last;
1332 }
1324 window = last;
1325 }
1333 else
1326 else
1334 {
1335 if (window == windows)
1336 window = the_echo_area;
1337 else
1338 window = window->prev;
1339 }
1327 {
1328 if (window == windows)
1329 window = the_echo_area;
1330 else
1331 window = window->prev;
1332 }
1340 }
1341
1342 if (active_window != window)
1343 {
1344 if (auto_footnotes_p)
1333 }
1334
1335 if (active_window != window)
1336 {
1337 if (auto_footnotes_p)
1345 info_get_or_remove_footnotes (window);
1338 info_get_or_remove_footnotes (window);
1346
1347 window->flags |= W_UpdateWindow;
1348 active_window = window;
1349 }
1350}
1351
1352/* Split WINDOW into two windows, both showing the same node. If we
1353 are automatically tiling windows, re-tile after the split. */
1339
1340 window->flags |= W_UpdateWindow;
1341 active_window = window;
1342 }
1343}
1344
1345/* Split WINDOW into two windows, both showing the same node. If we
1346 are automatically tiling windows, re-tile after the split. */
1354DECLARE_INFO_COMMAND (info_split_window, "Split the current window")
1347DECLARE_INFO_COMMAND (info_split_window, _("Split the current window"))
1355{
1356 WINDOW *split, *old_active;
1357 int pagetop;
1358
1359 /* Remember the current pagetop of the window being split. If it doesn't
1360 change, we can scroll its contents around after the split. */
1361 pagetop = window->pagetop;
1362

--- 7 unchanged lines hidden (view full) ---

1370 {
1371 info_error (WIN_TOO_SMALL);
1372 }
1373 else
1374 {
1375#if defined (SPLIT_BEFORE_ACTIVE)
1376 /* Try to scroll the old window into its new postion. */
1377 if (pagetop == window->pagetop)
1348{
1349 WINDOW *split, *old_active;
1350 int pagetop;
1351
1352 /* Remember the current pagetop of the window being split. If it doesn't
1353 change, we can scroll its contents around after the split. */
1354 pagetop = window->pagetop;
1355

--- 7 unchanged lines hidden (view full) ---

1363 {
1364 info_error (WIN_TOO_SMALL);
1365 }
1366 else
1367 {
1368#if defined (SPLIT_BEFORE_ACTIVE)
1369 /* Try to scroll the old window into its new postion. */
1370 if (pagetop == window->pagetop)
1378 {
1379 int start, end, amount;
1371 {
1372 int start, end, amount;
1380
1373
1381 start = split->first_row;
1382 end = start + window->height;
1383 amount = split->height + 1;
1384 display_scroll_display (start, end, amount);
1385 }
1374 start = split->first_row;
1375 end = start + window->height;
1376 amount = split->height + 1;
1377 display_scroll_display (start, end, amount);
1378 }
1386#else /* !SPLIT_BEFORE_ACTIVE */
1387 /* Make sure point still appears in the active window. */
1388 info_show_point (window);
1389#endif /* !SPLIT_BEFORE_ACTIVE */
1390
1391 /* If the window just split was one internal to Info, try to display
1379#else /* !SPLIT_BEFORE_ACTIVE */
1380 /* Make sure point still appears in the active window. */
1381 info_show_point (window);
1382#endif /* !SPLIT_BEFORE_ACTIVE */
1383
1384 /* If the window just split was one internal to Info, try to display
1392 something else in it. */
1385 something else in it. */
1393 if (internal_info_node_p (split->node))
1386 if (internal_info_node_p (split->node))
1394 {
1395 register int i, j;
1396 INFO_WINDOW *iw;
1397 NODE *node = (NODE *)NULL;
1398 char *filename;
1387 {
1388 register int i, j;
1389 INFO_WINDOW *iw;
1390 NODE *node = (NODE *)NULL;
1391 char *filename;
1399
1392
1400 for (i = 0; iw = info_windows[i]; i++)
1401 {
1402 for (j = 0; j < iw->nodes_index; j++)
1403 if (!internal_info_node_p (iw->nodes[j]))
1404 {
1405 if (iw->nodes[j]->parent)
1406 filename = iw->nodes[j]->parent;
1407 else
1408 filename = iw->nodes[j]->filename;
1393 for (i = 0; (iw = info_windows[i]); i++)
1394 {
1395 for (j = 0; j < iw->nodes_index; j++)
1396 if (!internal_info_node_p (iw->nodes[j]))
1397 {
1398 if (iw->nodes[j]->parent)
1399 filename = iw->nodes[j]->parent;
1400 else
1401 filename = iw->nodes[j]->filename;
1409
1402
1410 node = info_get_node (filename, iw->nodes[j]->nodename);
1411 if (node)
1412 {
1413 window_set_node_of_window (split, node);
1414 i = info_windows_index - 1;
1415 break;
1416 }
1417 }
1418 }
1419 }
1403 node = info_get_node (filename, iw->nodes[j]->nodename);
1404 if (node)
1405 {
1406 window_set_node_of_window (split, node);
1407 i = info_windows_index - 1;
1408 break;
1409 }
1410 }
1411 }
1412 }
1420 split->pagetop = window->pagetop;
1421
1422 if (auto_tiling_p)
1413 split->pagetop = window->pagetop;
1414
1415 if (auto_tiling_p)
1423 window_tile_windows (DONT_TILE_INTERNALS);
1416 window_tile_windows (DONT_TILE_INTERNALS);
1424 else
1417 else
1425 window_adjust_pagetop (split);
1418 window_adjust_pagetop (split);
1426
1427 remember_window_and_node (split, split->node);
1428 }
1429}
1430
1431/* Delete WINDOW, forgetting the list of last visited nodes. If we are
1432 automatically displaying footnotes, show or remove the footnotes
1433 window. If we are automatically tiling windows, re-tile after the
1434 deletion. */
1419
1420 remember_window_and_node (split, split->node);
1421 }
1422}
1423
1424/* Delete WINDOW, forgetting the list of last visited nodes. If we are
1425 automatically displaying footnotes, show or remove the footnotes
1426 window. If we are automatically tiling windows, re-tile after the
1427 deletion. */
1435DECLARE_INFO_COMMAND (info_delete_window, "Delete the current window")
1428DECLARE_INFO_COMMAND (info_delete_window, _("Delete the current window"))
1436{
1437 if (!windows->next)
1438 {
1439 info_error (CANT_KILL_LAST);
1440 }
1441 else if (window->flags & W_WindowIsPerm)
1442 {
1429{
1430 if (!windows->next)
1431 {
1432 info_error (CANT_KILL_LAST);
1433 }
1434 else if (window->flags & W_WindowIsPerm)
1435 {
1443 info_error ("Cannot delete a permanent window");
1436 info_error (_("Cannot delete a permanent window"));
1444 }
1445 else
1446 {
1447 info_delete_window_internal (window);
1448
1449 if (auto_footnotes_p)
1437 }
1438 else
1439 {
1440 info_delete_window_internal (window);
1441
1442 if (auto_footnotes_p)
1450 info_get_or_remove_footnotes (active_window);
1443 info_get_or_remove_footnotes (active_window);
1451
1452 if (auto_tiling_p)
1444
1445 if (auto_tiling_p)
1453 window_tile_windows (DONT_TILE_INTERNALS);
1446 window_tile_windows (DONT_TILE_INTERNALS);
1454 }
1455}
1456
1457/* Do the physical deletion of WINDOW, and forget this window and
1458 associated nodes. */
1459void
1460info_delete_window_internal (window)
1461 WINDOW *window;
1462{
1463 if (windows->next && ((window->flags & W_WindowIsPerm) == 0))
1464 {
1465 /* We not only delete the window from the display, we forget it from
1447 }
1448}
1449
1450/* Do the physical deletion of WINDOW, and forget this window and
1451 associated nodes. */
1452void
1453info_delete_window_internal (window)
1454 WINDOW *window;
1455{
1456 if (windows->next && ((window->flags & W_WindowIsPerm) == 0))
1457 {
1458 /* We not only delete the window from the display, we forget it from
1466 our list of remembered windows. */
1459 our list of remembered windows. */
1467 forget_window_and_nodes (window);
1468 window_delete_window (window);
1469
1470 if (echo_area_is_active)
1460 forget_window_and_nodes (window);
1461 window_delete_window (window);
1462
1463 if (echo_area_is_active)
1471 echo_area_inform_of_deleted_window (window);
1464 echo_area_inform_of_deleted_window (window);
1472 }
1473}
1474
1475/* Just keep WINDOW, deleting all others. */
1465 }
1466}
1467
1468/* Just keep WINDOW, deleting all others. */
1476DECLARE_INFO_COMMAND (info_keep_one_window, "Delete all other windows")
1469DECLARE_INFO_COMMAND (info_keep_one_window, _("Delete all other windows"))
1477{
1470{
1478 int num_deleted; /* The number of windows we deleted. */
1471 int num_deleted; /* The number of windows we deleted. */
1479 int pagetop, start, end;
1480
1481 /* Remember a few things about this window. We may be able to speed up
1482 redisplay later by scrolling its contents. */
1483 pagetop = window->pagetop;
1484 start = window->first_row;
1485 end = start + window->height;
1486
1487 num_deleted = 0;
1488
1489 while (1)
1490 {
1491 WINDOW *win;
1492
1493 /* Find an eligible window and delete it. If no eligible windows
1472 int pagetop, start, end;
1473
1474 /* Remember a few things about this window. We may be able to speed up
1475 redisplay later by scrolling its contents. */
1476 pagetop = window->pagetop;
1477 start = window->first_row;
1478 end = start + window->height;
1479
1480 num_deleted = 0;
1481
1482 while (1)
1483 {
1484 WINDOW *win;
1485
1486 /* Find an eligible window and delete it. If no eligible windows
1494 are found, we are done. A window is eligible for deletion if
1495 is it not permanent, and it is not WINDOW. */
1487 are found, we are done. A window is eligible for deletion if
1488 is it not permanent, and it is not WINDOW. */
1496 for (win = windows; win; win = win->next)
1489 for (win = windows; win; win = win->next)
1497 if (win != window && ((win->flags & W_WindowIsPerm) == 0))
1498 break;
1490 if (win != window && ((win->flags & W_WindowIsPerm) == 0))
1491 break;
1499
1500 if (!win)
1492
1493 if (!win)
1501 break;
1494 break;
1502
1503 info_delete_window_internal (win);
1504 num_deleted++;
1505 }
1506
1507 /* Scroll the contents of this window into the right place so that the
1508 user doesn't have to wait any longer than necessary for redisplay. */
1509 if (num_deleted)

--- 4 unchanged lines hidden (view full) ---

1514 amount -= (window->pagetop - pagetop);
1515 display_scroll_display (start, end, amount);
1516 }
1517
1518 window->flags |= W_UpdateWindow;
1519}
1520
1521/* Scroll the "other" window of WINDOW. */
1495
1496 info_delete_window_internal (win);
1497 num_deleted++;
1498 }
1499
1500 /* Scroll the contents of this window into the right place so that the
1501 user doesn't have to wait any longer than necessary for redisplay. */
1502 if (num_deleted)

--- 4 unchanged lines hidden (view full) ---

1507 amount -= (window->pagetop - pagetop);
1508 display_scroll_display (start, end, amount);
1509 }
1510
1511 window->flags |= W_UpdateWindow;
1512}
1513
1514/* Scroll the "other" window of WINDOW. */
1522DECLARE_INFO_COMMAND (info_scroll_other_window, "Scroll the other window")
1515DECLARE_INFO_COMMAND (info_scroll_other_window, _("Scroll the other window"))
1523{
1524 WINDOW *other;
1525
1526 /* If only one window, give up. */
1527 if (!windows->next)
1528 {
1529 info_error (ONE_WINDOW);
1530 return;
1531 }
1532
1533 other = window->next;
1534
1535 if (!other)
1536 other = window->prev;
1537
1538 info_scroll_forward (other, count, key);
1539}
1540
1541/* Change the size of WINDOW by AMOUNT. */
1516{
1517 WINDOW *other;
1518
1519 /* If only one window, give up. */
1520 if (!windows->next)
1521 {
1522 info_error (ONE_WINDOW);
1523 return;
1524 }
1525
1526 other = window->next;
1527
1528 if (!other)
1529 other = window->prev;
1530
1531 info_scroll_forward (other, count, key);
1532}
1533
1534/* Change the size of WINDOW by AMOUNT. */
1542DECLARE_INFO_COMMAND (info_grow_window, "Grow (or shrink) this window")
1535DECLARE_INFO_COMMAND (info_grow_window, _("Grow (or shrink) this window"))
1543{
1544 window_change_window_height (window, count);
1545}
1546
1547/* When non-zero, tiling takes place automatically when info_split_window
1548 is called. */
1549int auto_tiling_p = 0;
1550
1551/* Tile all of the visible windows. */
1552DECLARE_INFO_COMMAND (info_tile_windows,
1536{
1537 window_change_window_height (window, count);
1538}
1539
1540/* When non-zero, tiling takes place automatically when info_split_window
1541 is called. */
1542int auto_tiling_p = 0;
1543
1544/* Tile all of the visible windows. */
1545DECLARE_INFO_COMMAND (info_tile_windows,
1553 "Divide the available screen space among the visible windows")
1546 _("Divide the available screen space among the visible windows"))
1554{
1555 window_tile_windows (TILE_INTERNALS);
1556}
1557
1558/* Toggle the state of this window's wrapping of lines. */
1559DECLARE_INFO_COMMAND (info_toggle_wrap,
1547{
1548 window_tile_windows (TILE_INTERNALS);
1549}
1550
1551/* Toggle the state of this window's wrapping of lines. */
1552DECLARE_INFO_COMMAND (info_toggle_wrap,
1560 "Toggle the state of line wrapping in the current window")
1553 _("Toggle the state of line wrapping in the current window"))
1561{
1562 window_toggle_wrap (window);
1563}
1564
1565/* **************************************************************** */
1554{
1555 window_toggle_wrap (window);
1556}
1557
1558/* **************************************************************** */
1566/* */
1567/* Info Node Commands */
1568/* */
1559/* */
1560/* Info Node Commands */
1561/* */
1569/* **************************************************************** */
1570
1571/* Using WINDOW for various defaults, select the node referenced by ENTRY
1572 in it. If the node is selected, the window and node are remembered. */
1573void
1574info_select_reference (window, entry)
1575 WINDOW *window;
1576 REFERENCE *entry;

--- 5 unchanged lines hidden (view full) ---

1582
1583 filename = entry->filename;
1584 if (!filename)
1585 filename = window->node->parent;
1586 if (!filename)
1587 filename = window->node->filename;
1588
1589 if (filename)
1562/* **************************************************************** */
1563
1564/* Using WINDOW for various defaults, select the node referenced by ENTRY
1565 in it. If the node is selected, the window and node are remembered. */
1566void
1567info_select_reference (window, entry)
1568 WINDOW *window;
1569 REFERENCE *entry;

--- 5 unchanged lines hidden (view full) ---

1575
1576 filename = entry->filename;
1577 if (!filename)
1578 filename = window->node->parent;
1579 if (!filename)
1580 filename = window->node->filename;
1581
1582 if (filename)
1590 filename = strdup (filename);
1583 filename = xstrdup (filename);
1591
1592 if (entry->nodename)
1584
1585 if (entry->nodename)
1593 nodename = strdup (entry->nodename);
1586 nodename = xstrdup (entry->nodename);
1594 else
1587 else
1595 nodename = strdup ("Top");
1588 nodename = xstrdup ("Top");
1596
1597 node = info_get_node (filename, nodename);
1598
1599 /* Try something a little weird. If the node couldn't be found, and the
1600 reference was of the form "foo::", see if the entry->label can be found
1601 as a file, with a node of "Top". */
1602 if (!node)
1603 {
1604 if (info_recent_file_error)
1589
1590 node = info_get_node (filename, nodename);
1591
1592 /* Try something a little weird. If the node couldn't be found, and the
1593 reference was of the form "foo::", see if the entry->label can be found
1594 as a file, with a node of "Top". */
1595 if (!node)
1596 {
1597 if (info_recent_file_error)
1605 file_system_error = strdup (info_recent_file_error);
1598 file_system_error = xstrdup (info_recent_file_error);
1606
1607 if (entry->nodename && (strcmp (entry->nodename, entry->label) == 0))
1599
1600 if (entry->nodename && (strcmp (entry->nodename, entry->label) == 0))
1608 {
1609 node = info_get_node (entry->label, "Top");
1610 if (!node && info_recent_file_error)
1611 {
1612 maybe_free (file_system_error);
1613 file_system_error = strdup (info_recent_file_error);
1614 }
1615 }
1601 {
1602 node = info_get_node (entry->label, "Top");
1603 if (!node && info_recent_file_error)
1604 {
1605 maybe_free (file_system_error);
1606 file_system_error = xstrdup (info_recent_file_error);
1607 }
1608 }
1616 }
1617
1618 if (!node)
1619 {
1620 if (file_system_error)
1609 }
1610
1611 if (!node)
1612 {
1613 if (file_system_error)
1621 info_error (file_system_error);
1614 info_error (file_system_error);
1622 else
1615 else
1623 info_error (CANT_FIND_NODE, nodename);
1616 info_error (CANT_FIND_NODE, nodename);
1624 }
1625
1626 maybe_free (file_system_error);
1627 maybe_free (filename);
1628 maybe_free (nodename);
1629
1630 if (node)
1631 {

--- 33 unchanged lines hidden (view full) ---

1665 if (info_parsed_filename || info_parsed_nodename)
1666 {
1667 char *filename, *nodename;
1668 NODE *node;
1669
1670 filename = nodename = (char *)NULL;
1671
1672 if (info_parsed_filename)
1617 }
1618
1619 maybe_free (file_system_error);
1620 maybe_free (filename);
1621 maybe_free (nodename);
1622
1623 if (node)
1624 {

--- 33 unchanged lines hidden (view full) ---

1658 if (info_parsed_filename || info_parsed_nodename)
1659 {
1660 char *filename, *nodename;
1661 NODE *node;
1662
1663 filename = nodename = (char *)NULL;
1664
1665 if (info_parsed_filename)
1673 filename = strdup (info_parsed_filename);
1666 filename = xstrdup (info_parsed_filename);
1674 else
1667 else
1675 {
1676 if (window->node->parent)
1677 filename = strdup (window->node->parent);
1678 else if (window->node->filename)
1679 filename = strdup (window->node->filename);
1680 }
1668 {
1669 if (window->node->parent)
1670 filename = xstrdup (window->node->parent);
1671 else if (window->node->filename)
1672 filename = xstrdup (window->node->filename);
1673 }
1681
1682 if (info_parsed_nodename)
1674
1675 if (info_parsed_nodename)
1683 nodename = strdup (info_parsed_nodename);
1676 nodename = xstrdup (info_parsed_nodename);
1684 else
1677 else
1685 nodename = strdup ("Top");
1678 nodename = xstrdup ("Top");
1686
1687 node = info_get_node (filename, nodename);
1688
1689 if (node)
1679
1680 node = info_get_node (filename, nodename);
1681
1682 if (node)
1690 {
1691 INFO_WINDOW *info_win;
1683 {
1684 INFO_WINDOW *info_win;
1692
1685
1693 info_win = get_info_window_of_window (window);
1694 if (info_win)
1695 {
1696 info_win->pagetops[info_win->current] = window->pagetop;
1697 info_win->points[info_win->current] = window->point;
1698 }
1699 set_remembered_pagetop_and_point (window);
1700 info_set_node_of_window (window, node);
1701 }
1686 info_win = get_info_window_of_window (window);
1687 if (info_win)
1688 {
1689 info_win->pagetops[info_win->current] = window->pagetop;
1690 info_win->points[info_win->current] = window->point;
1691 }
1692 set_remembered_pagetop_and_point (window);
1693 info_set_node_of_window (window, node);
1694 }
1702 else
1695 else
1703 {
1704 if (info_recent_file_error)
1705 info_error (info_recent_file_error);
1706 else
1707 info_error (CANT_FILE_NODE, filename, nodename);
1708 }
1696 {
1697 if (info_recent_file_error)
1698 info_error (info_recent_file_error);
1699 else
1700 info_error (CANT_FILE_NODE, filename, nodename);
1701 }
1709
1710 free (filename);
1711 free (nodename);
1712 }
1713 else
1714 {
1715 info_error (NO_POINTER, label);
1716 }
1717}
1718
1719/* Make WINDOW display the "Next:" node of the node currently being
1720 displayed. */
1702
1703 free (filename);
1704 free (nodename);
1705 }
1706 else
1707 {
1708 info_error (NO_POINTER, label);
1709 }
1710}
1711
1712/* Make WINDOW display the "Next:" node of the node currently being
1713 displayed. */
1721DECLARE_INFO_COMMAND (info_next_node, "Select the `Next' node")
1714DECLARE_INFO_COMMAND (info_next_node, _("Select the `Next' node"))
1722{
1723 info_next_label_of_node (window->node);
1715{
1716 info_next_label_of_node (window->node);
1724 info_handle_pointer ("Next", window);
1717 info_handle_pointer (_("Next"), window);
1725}
1726
1727/* Make WINDOW display the "Prev:" node of the node currently being
1728 displayed. */
1718}
1719
1720/* Make WINDOW display the "Prev:" node of the node currently being
1721 displayed. */
1729DECLARE_INFO_COMMAND (info_prev_node, "Select the `Prev' node")
1722DECLARE_INFO_COMMAND (info_prev_node, _("Select the `Prev' node"))
1730{
1731 info_prev_label_of_node (window->node);
1723{
1724 info_prev_label_of_node (window->node);
1732 info_handle_pointer ("Prev", window);
1725 info_handle_pointer (_("Prev"), window);
1733}
1734
1735/* Make WINDOW display the "Up:" node of the node currently being
1736 displayed. */
1726}
1727
1728/* Make WINDOW display the "Up:" node of the node currently being
1729 displayed. */
1737DECLARE_INFO_COMMAND (info_up_node, "Select the `Up' node")
1730DECLARE_INFO_COMMAND (info_up_node, _("Select the `Up' node"))
1738{
1739 info_up_label_of_node (window->node);
1731{
1732 info_up_label_of_node (window->node);
1740 info_handle_pointer ("Up", window);
1733 info_handle_pointer (_("Up"), window);
1741}
1742
1743/* Make WINDOW display the last node of this info file. */
1734}
1735
1736/* Make WINDOW display the last node of this info file. */
1744DECLARE_INFO_COMMAND (info_last_node, "Select the last node in this file")
1737DECLARE_INFO_COMMAND (info_last_node, _("Select the last node in this file"))
1745{
1746 register int i;
1747 FILE_BUFFER *fb = file_buffer_of_window (window);
1748 NODE *node = (NODE *)NULL;
1749
1750 if (fb && fb->tags)
1751 {
1752 for (i = 0; fb->tags[i]; i++);
1753 node = info_get_node (fb->filename, fb->tags[i - 1]->nodename);
1754 }
1755
1756 if (!node)
1738{
1739 register int i;
1740 FILE_BUFFER *fb = file_buffer_of_window (window);
1741 NODE *node = (NODE *)NULL;
1742
1743 if (fb && fb->tags)
1744 {
1745 for (i = 0; fb->tags[i]; i++);
1746 node = info_get_node (fb->filename, fb->tags[i - 1]->nodename);
1747 }
1748
1749 if (!node)
1757 info_error ("This window has no additional nodes");
1750 info_error (_("This window has no additional nodes"));
1758 else
1759 {
1760 set_remembered_pagetop_and_point (window);
1761 info_set_node_of_window (window, node);
1762 }
1763}
1764
1765/* Make WINDOW display the first node of this info file. */
1751 else
1752 {
1753 set_remembered_pagetop_and_point (window);
1754 info_set_node_of_window (window, node);
1755 }
1756}
1757
1758/* Make WINDOW display the first node of this info file. */
1766DECLARE_INFO_COMMAND (info_first_node, "Select the first node in this file")
1759DECLARE_INFO_COMMAND (info_first_node, _("Select the first node in this file"))
1767{
1768 FILE_BUFFER *fb = file_buffer_of_window (window);
1769 NODE *node = (NODE *)NULL;
1770
1771 if (fb && fb->tags)
1772 node = info_get_node (fb->filename, fb->tags[0]->nodename);
1773
1774 if (!node)
1760{
1761 FILE_BUFFER *fb = file_buffer_of_window (window);
1762 NODE *node = (NODE *)NULL;
1763
1764 if (fb && fb->tags)
1765 node = info_get_node (fb->filename, fb->tags[0]->nodename);
1766
1767 if (!node)
1775 info_error ("This window has no additional nodes");
1768 info_error (_("This window has no additional nodes"));
1776 else
1777 {
1778 set_remembered_pagetop_and_point (window);
1779 info_set_node_of_window (window, node);
1780 }
1781}
1782
1769 else
1770 {
1771 set_remembered_pagetop_and_point (window);
1772 info_set_node_of_window (window, node);
1773 }
1774}
1775
1783/* Make WINDOW display the previous node displayed in this window. */
1784DECLARE_INFO_COMMAND (info_history_node,
1785 "Select the most recently selected node")
1786{
1787 INFO_WINDOW *info_win;
1788
1789 /* Find the INFO_WINDOW which contains WINDOW. */
1790 info_win = get_info_window_of_window (window);
1791
1792 if (!info_win)
1793 {
1794 info_error ("Requested window is not present!");
1795 return;
1796 }
1797
1798 set_remembered_pagetop_and_point (window);
1799 if (!info_win->current)
1800 {
1801 if (info_win->nodes_index > 1)
1802 {
1803 window_message_in_echo_area
1804 ("Now wrapped around to beginning of history.");
1805 info_win->current = info_win->nodes_index;
1806 }
1807 else
1808 {
1809 info_error ("No earlier nodes in this window.");
1810 return;
1811 }
1812 }
1813
1814 info_win->current--;
1815 window_set_node_of_window (window, info_win->nodes[info_win->current]);
1816 window->pagetop = info_win->pagetops[info_win->current];
1817 window->point = info_win->points[info_win->current];
1818 window->flags |= W_UpdateWindow;
1819 if (auto_footnotes_p)
1820 info_get_or_remove_footnotes (window);
1821}
1822
1823/* Select the last menu item in WINDOW->node. */
1824DECLARE_INFO_COMMAND (info_last_menu_item,
1776/* Select the last menu item in WINDOW->node. */
1777DECLARE_INFO_COMMAND (info_last_menu_item,
1825 "Select the last item in this node's menu")
1778 _("Select the last item in this node's menu"))
1826{
1827 info_menu_digit (window, 1, '0');
1828}
1829
1830/* Use KEY (a digit) to select the Nth menu item in WINDOW->node. */
1779{
1780 info_menu_digit (window, 1, '0');
1781}
1782
1783/* Use KEY (a digit) to select the Nth menu item in WINDOW->node. */
1831DECLARE_INFO_COMMAND (info_menu_digit, "Select this menu item")
1784DECLARE_INFO_COMMAND (info_menu_digit, _("Select this menu item"))
1832{
1833 register int i, item;
1834 register REFERENCE *entry, **menu;
1835
1836 menu = info_menu_of_node (window->node);
1837
1838 if (!menu)
1839 {

--- 4 unchanged lines hidden (view full) ---

1844 /* We have the menu. See if there are this many items in it. */
1845 item = key - '0';
1846
1847 /* Special case. Item "0" is the last item in this menu. */
1848 if (item == 0)
1849 for (i = 0; menu[i + 1]; i++);
1850 else
1851 {
1785{
1786 register int i, item;
1787 register REFERENCE *entry, **menu;
1788
1789 menu = info_menu_of_node (window->node);
1790
1791 if (!menu)
1792 {

--- 4 unchanged lines hidden (view full) ---

1797 /* We have the menu. See if there are this many items in it. */
1798 item = key - '0';
1799
1800 /* Special case. Item "0" is the last item in this menu. */
1801 if (item == 0)
1802 for (i = 0; menu[i + 1]; i++);
1803 else
1804 {
1852 for (i = 0; entry = menu[i]; i++)
1853 if (i == item - 1)
1854 break;
1805 for (i = 0; (entry = menu[i]); i++)
1806 if (i == item - 1)
1807 break;
1855 }
1856
1857 if (menu[i])
1858 info_select_reference (window, menu[i]);
1859 else
1808 }
1809
1810 if (menu[i])
1811 info_select_reference (window, menu[i]);
1812 else
1860 info_error ("There aren't %d items in this menu.", item);
1813 info_error (_("There aren't %d items in this menu."), item);
1861
1862 info_free_references (menu);
1863 return;
1864}
1865
1866/* Read a menu or followed reference from the user defaulting to the
1867 reference found on the current line, and select that node. The
1868 reading is done with completion. BUILDER is the function used

--- 10 unchanged lines hidden (view full) ---

1879 REFERENCE **menu, *entry, *defentry = (REFERENCE *)NULL;
1880 char *line;
1881
1882 menu = (*builder) (window->node);
1883
1884 if (!menu)
1885 {
1886 if (builder == info_menu_of_node)
1814
1815 info_free_references (menu);
1816 return;
1817}
1818
1819/* Read a menu or followed reference from the user defaulting to the
1820 reference found on the current line, and select that node. The
1821 reading is done with completion. BUILDER is the function used

--- 10 unchanged lines hidden (view full) ---

1832 REFERENCE **menu, *entry, *defentry = (REFERENCE *)NULL;
1833 char *line;
1834
1835 menu = (*builder) (window->node);
1836
1837 if (!menu)
1838 {
1839 if (builder == info_menu_of_node)
1887 info_error (NO_MENU_NODE);
1840 info_error (NO_MENU_NODE);
1888 else
1841 else
1889 info_error (NO_XREF_NODE);
1842 info_error (NO_XREF_NODE);
1890 return;
1891 }
1892
1893 /* Default the selected reference to the one which is on the line that
1894 point is in. */
1895 {
1896 REFERENCE **refs = (REFERENCE **)NULL;
1897 int point_line;
1898
1899 point_line = window_line_of_point (window);
1900
1901 if (point_line != -1)
1902 {
1843 return;
1844 }
1845
1846 /* Default the selected reference to the one which is on the line that
1847 point is in. */
1848 {
1849 REFERENCE **refs = (REFERENCE **)NULL;
1850 int point_line;
1851
1852 point_line = window_line_of_point (window);
1853
1854 if (point_line != -1)
1855 {
1903 SEARCH_BINDING binding;
1856 SEARCH_BINDING binding;
1904
1857
1905 binding.buffer = window->node->contents;
1906 binding.start = window->line_starts[point_line] - binding.buffer;
1907 if (window->line_starts[point_line + 1])
1908 binding.end = window->line_starts[point_line + 1] - binding.buffer;
1909 else
1910 binding.end = window->node->nodelen;
1911 binding.flags = 0;
1858 binding.buffer = window->node->contents;
1859 binding.start = window->line_starts[point_line] - binding.buffer;
1860 if (window->line_starts[point_line + 1])
1861 binding.end = window->line_starts[point_line + 1] - binding.buffer;
1862 else
1863 binding.end = window->node->nodelen;
1864 binding.flags = 0;
1912
1865
1913 if (builder == info_menu_of_node)
1914 {
1915 if (point_line)
1916 {
1917 binding.start--;
1918 refs = info_menu_items (&binding);
1919 }
1920 }
1921 else
1922 {
1866 if (builder == info_menu_of_node)
1867 {
1868 if (point_line)
1869 {
1870 binding.start--;
1871 refs = info_menu_items (&binding);
1872 }
1873 }
1874 else
1875 {
1923#if defined (HANDLE_MAN_PAGES)
1876#if defined (HANDLE_MAN_PAGES)
1924 if (window->node->flags & N_IsManPage)
1925 refs = manpage_xrefs_in_binding (window->node, &binding);
1926 else
1877 if (window->node->flags & N_IsManPage)
1878 refs = manpage_xrefs_in_binding (window->node, &binding);
1879 else
1927#endif /* HANDLE_MAN_PAGES */
1880#endif /* HANDLE_MAN_PAGES */
1928 refs = info_xrefs (&binding);
1929 }
1881 refs = info_xrefs (&binding);
1882 }
1930
1883
1931 if (refs)
1932 {
1933 if ((strcmp (refs[0]->label, "Menu") != 0) ||
1934 (builder == info_xrefs_of_node))
1935 {
1936 int which = 0;
1884 if (refs)
1885 {
1886 if ((strcmp (refs[0]->label, "Menu") != 0) ||
1887 (builder == info_xrefs_of_node))
1888 {
1889 int which = 0;
1937
1890
1938 /* Find the closest reference to point. */
1939 if (builder == info_xrefs_of_node)
1940 {
1941 int closest = -1;
1891 /* Find the closest reference to point. */
1892 if (builder == info_xrefs_of_node)
1893 {
1894 int closest = -1;
1942
1895
1943 for (; refs[which]; which++)
1944 {
1945 if ((window->point >= refs[which]->start) &&
1946 (window->point <= refs[which]->end))
1947 {
1948 closest = which;
1949 break;
1950 }
1951 else if (window->point < refs[which]->start)
1952 {
1953 break;
1954 }
1955 }
1956 if (closest == -1)
1957 which--;
1958 else
1959 which = closest;
1960 }
1896 for (; refs[which]; which++)
1897 {
1898 if ((window->point >= refs[which]->start) &&
1899 (window->point <= refs[which]->end))
1900 {
1901 closest = which;
1902 break;
1903 }
1904 else if (window->point < refs[which]->start)
1905 {
1906 break;
1907 }
1908 }
1909 if (closest == -1)
1910 which--;
1911 else
1912 which = closest;
1913 }
1961
1914
1962 defentry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
1963 defentry->label = strdup (refs[which]->label);
1964 defentry->filename = refs[which]->filename;
1965 defentry->nodename = refs[which]->nodename;
1915 defentry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
1916 defentry->label = xstrdup (refs[which]->label);
1917 defentry->filename = refs[which]->filename;
1918 defentry->nodename = refs[which]->nodename;
1966
1919
1967 if (defentry->filename)
1968 defentry->filename = strdup (defentry->filename);
1969 if (defentry->nodename)
1970 defentry->nodename = strdup (defentry->nodename);
1971 }
1972 info_free_references (refs);
1973 }
1920 if (defentry->filename)
1921 defentry->filename = xstrdup (defentry->filename);
1922 if (defentry->nodename)
1923 defentry->nodename = xstrdup (defentry->nodename);
1924 }
1925 info_free_references (refs);
1926 }
1974 }
1975 }
1976
1977 /* If we are going to ask the user a question, do it now. */
1978 if (ask_p)
1979 {
1980 char *prompt;
1981
1982 /* Build the prompt string. */
1983 if (defentry)
1927 }
1928 }
1929
1930 /* If we are going to ask the user a question, do it now. */
1931 if (ask_p)
1932 {
1933 char *prompt;
1934
1935 /* Build the prompt string. */
1936 if (defentry)
1984 prompt = (char *)xmalloc (20 + strlen (defentry->label));
1937 prompt = (char *)xmalloc (20 + strlen (defentry->label));
1985 else
1938 else
1986 prompt = (char *)xmalloc (20);
1939 prompt = (char *)xmalloc (20);
1987
1988 if (builder == info_menu_of_node)
1940
1941 if (builder == info_menu_of_node)
1989 {
1990 if (defentry)
1991 sprintf (prompt, "Menu item (%s): ", defentry->label);
1992 else
1993 sprintf (prompt, "Menu item: ");
1994 }
1942 {
1943 if (defentry)
1944 sprintf (prompt, _("Menu item (%s): "), defentry->label);
1945 else
1946 sprintf (prompt, _("Menu item: "));
1947 }
1995 else
1948 else
1996 {
1997 if (defentry)
1998 sprintf (prompt, "Follow xref (%s): ", defentry->label);
1999 else
2000 sprintf (prompt, "Follow xref: ");
2001 }
1949 {
1950 if (defentry)
1951 sprintf (prompt, _("Follow xref (%s): "), defentry->label);
1952 else
1953 sprintf (prompt, _("Follow xref: "));
1954 }
2002
2003 line = info_read_completing_in_echo_area (window, prompt, menu);
2004 free (prompt);
2005
2006 window = active_window;
2007
2008 /* User aborts, just quit. */
2009 if (!line)
1955
1956 line = info_read_completing_in_echo_area (window, prompt, menu);
1957 free (prompt);
1958
1959 window = active_window;
1960
1961 /* User aborts, just quit. */
1962 if (!line)
2010 {
2011 maybe_free (defentry);
2012 info_free_references (menu);
2013 info_abort_key (window, 0, 0);
2014 return;
2015 }
1963 {
1964 maybe_free (defentry);
1965 info_free_references (menu);
1966 info_abort_key (window, 0, 0);
1967 return;
1968 }
2016
2017 /* If we had a default and the user accepted it, use that. */
2018 if (!*line)
1969
1970 /* If we had a default and the user accepted it, use that. */
1971 if (!*line)
2019 {
2020 free (line);
2021 if (defentry)
2022 line = strdup (defentry->label);
2023 else
2024 line = (char *)NULL;
2025 }
1972 {
1973 free (line);
1974 if (defentry)
1975 line = xstrdup (defentry->label);
1976 else
1977 line = (char *)NULL;
1978 }
2026 }
2027 else
2028 {
2029 /* Not going to ask any questions. If we have a default entry, use
1979 }
1980 else
1981 {
1982 /* Not going to ask any questions. If we have a default entry, use
2030 that, otherwise return. */
1983 that, otherwise return. */
2031 if (!defentry)
1984 if (!defentry)
2032 return;
1985 return;
2033 else
1986 else
2034 line = strdup (defentry->label);
1987 line = xstrdup (defentry->label);
2035 }
2036
2037 if (line)
2038 {
2039 /* Find the selected label in the references. */
2040 entry = info_get_labeled_reference (line, menu);
2041
2042 if (!entry && defentry)
1988 }
1989
1990 if (line)
1991 {
1992 /* Find the selected label in the references. */
1993 entry = info_get_labeled_reference (line, menu);
1994
1995 if (!entry && defentry)
2043 info_error ("The reference disappeared! (%s).", line);
1996 info_error (_("The reference disappeared! (%s)."), line);
2044 else
1997 else
2045 {
2046 NODE *orig;
1998 {
1999 NODE *orig;
2047
2000
2048 orig = window->node;
2049 info_select_reference (window, entry);
2050 if ((builder == info_xrefs_of_node) && (window->node != orig))
2051 {
2052 long offset;
2053 long start;
2001 orig = window->node;
2002 info_select_reference (window, entry);
2003 if ((builder == info_xrefs_of_node) && (window->node != orig))
2004 {
2005 long offset;
2006 long start;
2054
2007
2055 if (window->line_count > 0)
2056 start = window->line_starts[1] - window->node->contents;
2057 else
2058 start = 0;
2008 if (window->line_count > 0)
2009 start = window->line_starts[1] - window->node->contents;
2010 else
2011 start = 0;
2059
2012
2060 offset =
2061 info_target_search_node (window->node, entry->label, start);
2013 offset =
2014 info_target_search_node (window->node, entry->label, start);
2062
2015
2063 if (offset != -1)
2064 {
2065 window->point = offset;
2066 window_adjust_pagetop (window);
2067 }
2068 }
2069 }
2016 if (offset != -1)
2017 {
2018 window->point = offset;
2019 window_adjust_pagetop (window);
2020 }
2021 }
2022 }
2070
2071 free (line);
2072 if (defentry)
2023
2024 free (line);
2025 if (defentry)
2073 {
2074 free (defentry->label);
2075 maybe_free (defentry->filename);
2076 maybe_free (defentry->nodename);
2077 free (defentry);
2078 }
2026 {
2027 free (defentry->label);
2028 maybe_free (defentry->filename);
2029 maybe_free (defentry->nodename);
2030 free (defentry);
2031 }
2079 }
2080
2081 info_free_references (menu);
2082
2083 if (!info_error_was_printed)
2084 window_clear_echo_area ();
2085}
2086
2087/* Read a line (with completion) which is the name of a menu item,
2088 and select that item. */
2032 }
2033
2034 info_free_references (menu);
2035
2036 if (!info_error_was_printed)
2037 window_clear_echo_area ();
2038}
2039
2040/* Read a line (with completion) which is the name of a menu item,
2041 and select that item. */
2089DECLARE_INFO_COMMAND (info_menu_item, "Read a menu item and select its node")
2042DECLARE_INFO_COMMAND (info_menu_item, _("Read a menu item and select its node"))
2090{
2091 info_menu_or_ref_item (window, count, key, info_menu_of_node, 1);
2092}
2093
2094/* Read a line (with completion) which is the name of a reference to
2095 follow, and select the node. */
2096DECLARE_INFO_COMMAND
2043{
2044 info_menu_or_ref_item (window, count, key, info_menu_of_node, 1);
2045}
2046
2047/* Read a line (with completion) which is the name of a reference to
2048 follow, and select the node. */
2049DECLARE_INFO_COMMAND
2097 (info_xref_item, "Read a footnote or cross reference and select its node")
2050 (info_xref_item, _("Read a footnote or cross reference and select its node"))
2098{
2099 info_menu_or_ref_item (window, count, key, info_xrefs_of_node, 1);
2100}
2101
2102/* Position the cursor at the start of this node's menu. */
2051{
2052 info_menu_or_ref_item (window, count, key, info_xrefs_of_node, 1);
2053}
2054
2055/* Position the cursor at the start of this node's menu. */
2103DECLARE_INFO_COMMAND (info_find_menu, "Move to the start of this node's menu")
2056DECLARE_INFO_COMMAND (info_find_menu, _("Move to the start of this node's menu"))
2104{
2105 SEARCH_BINDING binding;
2106 long position;
2107
2108 binding.buffer = window->node->contents;
2109 binding.start = 0;
2110 binding.end = window->node->nodelen;
2111 binding.flags = S_FoldCase | S_SkipDest;

--- 7 unchanged lines hidden (view full) ---

2119 window->point = position;
2120 window_adjust_pagetop (window);
2121 window->flags |= W_UpdateWindow;
2122 }
2123}
2124
2125/* Visit as many menu items as is possible, each in a separate window. */
2126DECLARE_INFO_COMMAND (info_visit_menu,
2057{
2058 SEARCH_BINDING binding;
2059 long position;
2060
2061 binding.buffer = window->node->contents;
2062 binding.start = 0;
2063 binding.end = window->node->nodelen;
2064 binding.flags = S_FoldCase | S_SkipDest;

--- 7 unchanged lines hidden (view full) ---

2072 window->point = position;
2073 window_adjust_pagetop (window);
2074 window->flags |= W_UpdateWindow;
2075 }
2076}
2077
2078/* Visit as many menu items as is possible, each in a separate window. */
2079DECLARE_INFO_COMMAND (info_visit_menu,
2127 "Visit as many menu items at once as possible")
2080 _("Visit as many menu items at once as possible"))
2128{
2129 register int i;
2130 REFERENCE *entry, **menu;
2131
2132 menu = info_menu_of_node (window->node);
2133
2134 if (!menu)
2135 info_error (NO_MENU_NODE);
2136
2137 for (i = 0; (!info_error_was_printed) && (entry = menu[i]); i++)
2138 {
2139 WINDOW *new;
2140
2141 new = window_make_window (window->node);
2142 window_tile_windows (TILE_INTERNALS);
2143
2144 if (!new)
2081{
2082 register int i;
2083 REFERENCE *entry, **menu;
2084
2085 menu = info_menu_of_node (window->node);
2086
2087 if (!menu)
2088 info_error (NO_MENU_NODE);
2089
2090 for (i = 0; (!info_error_was_printed) && (entry = menu[i]); i++)
2091 {
2092 WINDOW *new;
2093
2094 new = window_make_window (window->node);
2095 window_tile_windows (TILE_INTERNALS);
2096
2097 if (!new)
2145 info_error (WIN_TOO_SMALL);
2098 info_error (WIN_TOO_SMALL);
2146 else
2099 else
2147 {
2148 active_window = new;
2149 info_select_reference (new, entry);
2150 }
2100 {
2101 active_window = new;
2102 info_select_reference (new, entry);
2103 }
2151 }
2152}
2153
2154/* Read a line of input which is a node name, and go to that node. */
2104 }
2105}
2106
2107/* Read a line of input which is a node name, and go to that node. */
2155DECLARE_INFO_COMMAND (info_goto_node, "Read a node name and select it")
2108DECLARE_INFO_COMMAND (info_goto_node, _("Read a node name and select it"))
2156{
2157 char *line;
2109{
2110 char *line;
2158 NODE *node;
2159
2160#define GOTO_COMPLETES
2161#if defined (GOTO_COMPLETES)
2162 /* Build a completion list of all of the known nodes. */
2163 {
2164 register int fbi, i;
2165 FILE_BUFFER *current;
2166 REFERENCE **items = (REFERENCE **)NULL;
2167 int items_index = 0;
2168 int items_slots = 0;
2169
2170 current = file_buffer_of_window (window);
2171
2172 for (fbi = 0; info_loaded_files && info_loaded_files[fbi]; fbi++)
2173 {
2111
2112#define GOTO_COMPLETES
2113#if defined (GOTO_COMPLETES)
2114 /* Build a completion list of all of the known nodes. */
2115 {
2116 register int fbi, i;
2117 FILE_BUFFER *current;
2118 REFERENCE **items = (REFERENCE **)NULL;
2119 int items_index = 0;
2120 int items_slots = 0;
2121
2122 current = file_buffer_of_window (window);
2123
2124 for (fbi = 0; info_loaded_files && info_loaded_files[fbi]; fbi++)
2125 {
2174 FILE_BUFFER *fb;
2175 REFERENCE *entry;
2176 int this_is_the_current_fb;
2126 FILE_BUFFER *fb;
2127 REFERENCE *entry;
2128 int this_is_the_current_fb;
2177
2129
2178 fb = info_loaded_files[fbi];
2179 this_is_the_current_fb = (current == fb);
2130 fb = info_loaded_files[fbi];
2131 this_is_the_current_fb = (current == fb);
2180
2132
2181 entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
2182 entry->filename = entry->nodename = (char *)NULL;
2183 entry->label = (char *)xmalloc (4 + strlen (fb->filename));
2184 sprintf (entry->label, "(%s)*", fb->filename);
2133 entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
2134 entry->filename = entry->nodename = (char *)NULL;
2135 entry->label = (char *)xmalloc (4 + strlen (fb->filename));
2136 sprintf (entry->label, "(%s)*", fb->filename);
2185
2137
2186 add_pointer_to_array
2187 (entry, items_index, items, items_slots, 10, REFERENCE *);
2138 add_pointer_to_array
2139 (entry, items_index, items, items_slots, 10, REFERENCE *);
2188
2140
2189 if (fb->tags)
2190 {
2191 for (i = 0; fb->tags[i]; i++)
2192 {
2193 entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
2194 entry->filename = entry->nodename = (char *)NULL;
2195 entry->label = (char *) xmalloc
2196 (4 + strlen (fb->filename) + strlen (fb->tags[i]->nodename));
2197 sprintf (entry->label, "(%s)%s",
2198 fb->filename, fb->tags[i]->nodename);
2141 if (fb->tags)
2142 {
2143 for (i = 0; fb->tags[i]; i++)
2144 {
2145 entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
2146 entry->filename = entry->nodename = (char *)NULL;
2147 entry->label = (char *) xmalloc
2148 (4 + strlen (fb->filename) + strlen (fb->tags[i]->nodename));
2149 sprintf (entry->label, "(%s)%s",
2150 fb->filename, fb->tags[i]->nodename);
2199
2151
2200 add_pointer_to_array
2201 (entry, items_index, items, items_slots, 100, REFERENCE *);
2202 }
2152 add_pointer_to_array
2153 (entry, items_index, items, items_slots, 100, REFERENCE *);
2154 }
2203
2155
2204 if (this_is_the_current_fb)
2205 {
2206 for (i = 0; fb->tags[i]; i++)
2207 {
2208 entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
2209 entry->filename = entry->nodename = (char *)NULL;
2210 entry->label = strdup (fb->tags[i]->nodename);
2211 add_pointer_to_array (entry, items_index, items,
2212 items_slots, 100, REFERENCE *);
2213 }
2214 }
2215 }
2156 if (this_is_the_current_fb)
2157 {
2158 for (i = 0; fb->tags[i]; i++)
2159 {
2160 entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
2161 entry->filename = entry->nodename = (char *)NULL;
2162 entry->label = xstrdup (fb->tags[i]->nodename);
2163 add_pointer_to_array (entry, items_index, items,
2164 items_slots, 100, REFERENCE *);
2165 }
2166 }
2167 }
2216 }
2168 }
2217 line = info_read_maybe_completing (window, "Goto Node: ", items);
2169 line = info_read_maybe_completing (window, _("Goto Node: "), items);
2218 info_free_references (items);
2219 }
2220#else /* !GOTO_COMPLETES */
2170 info_free_references (items);
2171 }
2172#else /* !GOTO_COMPLETES */
2221 line = info_read_in_echo_area (window, "Goto Node: ");
2173 line = info_read_in_echo_area (window, _("Goto Node: "));
2222#endif /* !GOTO_COMPLETES */
2223
2224 /* If the user aborted, quit now. */
2225 if (!line)
2226 {
2227 info_abort_key (window, 0, 0);
2228 return;
2229 }

--- 4 unchanged lines hidden (view full) ---

2234 info_parse_and_select (line, window);
2235
2236 free (line);
2237 if (!info_error_was_printed)
2238 window_clear_echo_area ();
2239}
2240
2241#if defined (HANDLE_MAN_PAGES)
2174#endif /* !GOTO_COMPLETES */
2175
2176 /* If the user aborted, quit now. */
2177 if (!line)
2178 {
2179 info_abort_key (window, 0, 0);
2180 return;
2181 }

--- 4 unchanged lines hidden (view full) ---

2186 info_parse_and_select (line, window);
2187
2188 free (line);
2189 if (!info_error_was_printed)
2190 window_clear_echo_area ();
2191}
2192
2193#if defined (HANDLE_MAN_PAGES)
2242DECLARE_INFO_COMMAND (info_man, "Read a manpage reference and select it")
2194DECLARE_INFO_COMMAND (info_man, _("Read a manpage reference and select it"))
2243{
2244 char *line;
2195{
2196 char *line;
2245 NODE *node;
2246
2197
2247 line = info_read_in_echo_area (window, "Get Manpage: ");
2198 line = info_read_in_echo_area (window, _("Get Manpage: "));
2248
2249 if (!line)
2250 {
2251 info_abort_key (window, 0, 0);
2252 return;
2253 }
2254
2255 canonicalize_whitespace (line);
2256
2257 if (*line)
2258 {
2259 char *goto_command;
2260
2261 goto_command = (char *)xmalloc
2199
2200 if (!line)
2201 {
2202 info_abort_key (window, 0, 0);
2203 return;
2204 }
2205
2206 canonicalize_whitespace (line);
2207
2208 if (*line)
2209 {
2210 char *goto_command;
2211
2212 goto_command = (char *)xmalloc
2262 (4 + strlen (MANPAGE_FILE_BUFFER_NAME) + strlen (line));
2213 (4 + strlen (MANPAGE_FILE_BUFFER_NAME) + strlen (line));
2263
2264 sprintf (goto_command, "(%s)%s", MANPAGE_FILE_BUFFER_NAME, line);
2265
2266 info_parse_and_select (goto_command, window);
2267 free (goto_command);
2268 }
2269
2270 free (line);
2271 if (!info_error_was_printed)
2272 window_clear_echo_area ();
2273}
2274#endif /* HANDLE_MAN_PAGES */
2275
2276/* Move to the "Top" node in this file. */
2214
2215 sprintf (goto_command, "(%s)%s", MANPAGE_FILE_BUFFER_NAME, line);
2216
2217 info_parse_and_select (goto_command, window);
2218 free (goto_command);
2219 }
2220
2221 free (line);
2222 if (!info_error_was_printed)
2223 window_clear_echo_area ();
2224}
2225#endif /* HANDLE_MAN_PAGES */
2226
2227/* Move to the "Top" node in this file. */
2277DECLARE_INFO_COMMAND (info_top_node, "Select the node `Top' in this file")
2228DECLARE_INFO_COMMAND (info_top_node, _("Select the node `Top' in this file"))
2278{
2229{
2279 info_parse_and_select ("Top", window);
2230 info_parse_and_select (_("Top"), window);
2280}
2281
2282/* Move to the node "(dir)Top". */
2231}
2232
2233/* Move to the node "(dir)Top". */
2283DECLARE_INFO_COMMAND (info_dir_node, "Select the node `(dir)'")
2234DECLARE_INFO_COMMAND (info_dir_node, _("Select the node `(dir)'"))
2284{
2285 info_parse_and_select ("(dir)Top", window);
2286}
2287
2235{
2236 info_parse_and_select ("(dir)Top", window);
2237}
2238
2288/* Try to delete the current node appearing in this window, showing the most
2289 recently selected node in this window. */
2290DECLARE_INFO_COMMAND (info_kill_node, "Kill this node")
2239
2240/* Read the name of a node to kill. The list of available nodes comes
2241 from the nodes appearing in the current window configuration. */
2242static char *
2243read_nodename_to_kill (window)
2244 WINDOW *window;
2291{
2245{
2292 register int iw, i;
2293 register INFO_WINDOW *info_win;
2294 char *nodename = (char *)NULL;
2295 NODE *temp = (NODE *)NULL;
2246 int iw;
2247 char *nodename;
2248 INFO_WINDOW *info_win;
2249 REFERENCE **menu = NULL;
2250 int menu_index = 0, menu_slots = 0;
2251 char *default_nodename = xstrdup (active_window->node->nodename);
2252 char *prompt = xmalloc (40 + strlen (default_nodename));
2296
2253
2297 /* Read the name of a node to kill. The list of available nodes comes
2298 from the nodes appearing in the current window configuration. */
2299 {
2300 REFERENCE **menu = (REFERENCE **)NULL;
2301 int menu_index = 0, menu_slots = 0;
2302 char *default_nodename, *prompt;
2254 sprintf (prompt, _("Kill node (%s): "), default_nodename);
2303
2255
2304 for (iw = 0; info_win = info_windows[iw]; iw++)
2305 {
2306 REFERENCE *entry;
2256 for (iw = 0; (info_win = info_windows[iw]); iw++)
2257 {
2258 REFERENCE *entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
2259 entry->label = xstrdup (info_win->window->node->nodename);
2260 entry->filename = entry->nodename = (char *)NULL;
2307
2261
2308 entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
2309 entry->label = strdup (info_win->window->node->nodename);
2310 entry->filename = entry->nodename = (char *)NULL;
2262 add_pointer_to_array (entry, menu_index, menu, menu_slots, 10,
2263 REFERENCE *);
2264 }
2311
2265
2312 add_pointer_to_array
2313 (entry, menu_index, menu, menu_slots, 10, REFERENCE *);
2314 }
2266 nodename = info_read_completing_in_echo_area (window, prompt, menu);
2267 free (prompt);
2268 info_free_references (menu);
2269 if (nodename && !*nodename)
2270 {
2271 free (nodename);
2272 nodename = default_nodename;
2273 }
2274 else
2275 free (default_nodename);
2315
2276
2316 default_nodename = strdup (active_window->node->nodename);
2317 prompt = (char *)xmalloc (40 + strlen (default_nodename));
2318 sprintf (prompt, "Kill node (%s): ", default_nodename);
2277 return nodename;
2278}
2319
2279
2320 nodename = info_read_completing_in_echo_area (window, prompt, menu);
2321 free (prompt);
2322 info_free_references (menu);
2323 if (nodename && !*nodename)
2324 {
2325 free (nodename);
2326 nodename = default_nodename;
2327 }
2328 else
2329 free (default_nodename);
2330 }
2331
2280
2281/* Delete NODENAME from this window, showing the most
2282 recently selected node in this window. */
2283static void
2284kill_node (window, nodename)
2285 WINDOW *window;
2286 char *nodename;
2287{
2288 int iw, i;
2289 INFO_WINDOW *info_win;
2290 NODE *temp;
2291
2332 /* If there is no nodename to kill, quit now. */
2333 if (!nodename)
2334 {
2335 info_abort_key (window, 0, 0);
2336 return;
2337 }
2338
2339 /* If there is a nodename, find it in our window list. */
2292 /* If there is no nodename to kill, quit now. */
2293 if (!nodename)
2294 {
2295 info_abort_key (window, 0, 0);
2296 return;
2297 }
2298
2299 /* If there is a nodename, find it in our window list. */
2340 for (iw = 0; info_win = info_windows[iw]; iw++)
2300 for (iw = 0; (info_win = info_windows[iw]); iw++)
2341 if (strcmp (nodename, info_win->nodes[info_win->current]->nodename) == 0)
2342 break;
2343
2344 if (!info_win)
2345 {
2346 if (*nodename)
2301 if (strcmp (nodename, info_win->nodes[info_win->current]->nodename) == 0)
2302 break;
2303
2304 if (!info_win)
2305 {
2306 if (*nodename)
2347 info_error ("Cannot kill the node `%s'", nodename);
2307 info_error (_("Cannot kill node `%s'"), nodename);
2348 else
2308 else
2349 window_clear_echo_area ();
2309 window_clear_echo_area ();
2350
2351 return;
2352 }
2353
2354 /* If there are no more nodes left anywhere to view, complain and exit. */
2355 if (info_windows_index == 1 && info_windows[0]->nodes_index == 1)
2356 {
2310
2311 return;
2312 }
2313
2314 /* If there are no more nodes left anywhere to view, complain and exit. */
2315 if (info_windows_index == 1 && info_windows[0]->nodes_index == 1)
2316 {
2357 info_error ("Cannot kill the last node");
2317 info_error (_("Cannot kill the last node"));
2358 return;
2359 }
2360
2318 return;
2319 }
2320
2361 /* INFO_WIN contains the node that the user wants to stop viewing.
2362 Delete this node from the list of nodes previously shown in this
2363 window. */
2321 /* INFO_WIN contains the node that the user wants to stop viewing. Delete
2322 this node from the list of nodes previously shown in this window. */
2364 for (i = info_win->current; i < info_win->nodes_index; i++)
2365 info_win->nodes[i] = info_win->nodes[i++];
2366
2367 /* There is one less node in this window's history list. */
2368 info_win->nodes_index--;
2369
2370 /* Make this window show the most recent history node. */
2371 info_win->current = info_win->nodes_index - 1;
2372
2373 /* If there aren't any nodes left in this window, steal one from the
2374 next window. */
2375 if (info_win->current < 0)
2376 {
2377 INFO_WINDOW *stealer;
2378 int which, pagetop;
2379 long point;
2380
2381 if (info_windows[iw + 1])
2323 for (i = info_win->current; i < info_win->nodes_index; i++)
2324 info_win->nodes[i] = info_win->nodes[i++];
2325
2326 /* There is one less node in this window's history list. */
2327 info_win->nodes_index--;
2328
2329 /* Make this window show the most recent history node. */
2330 info_win->current = info_win->nodes_index - 1;
2331
2332 /* If there aren't any nodes left in this window, steal one from the
2333 next window. */
2334 if (info_win->current < 0)
2335 {
2336 INFO_WINDOW *stealer;
2337 int which, pagetop;
2338 long point;
2339
2340 if (info_windows[iw + 1])
2382 stealer = info_windows[iw + 1];
2341 stealer = info_windows[iw + 1];
2383 else
2342 else
2384 stealer = info_windows[0];
2343 stealer = info_windows[0];
2385
2386 /* If the node being displayed in the next window is not the most
2344
2345 /* If the node being displayed in the next window is not the most
2387 recently loaded one, get the most recently loaded one. */
2346 recently loaded one, get the most recently loaded one. */
2388 if ((stealer->nodes_index - 1) != stealer->current)
2347 if ((stealer->nodes_index - 1) != stealer->current)
2389 which = stealer->nodes_index - 1;
2348 which = stealer->nodes_index - 1;
2390
2391 /* Else, if there is another node behind the stealers current node,
2349
2350 /* Else, if there is another node behind the stealers current node,
2392 use that one. */
2351 use that one. */
2393 else if (stealer->current > 0)
2352 else if (stealer->current > 0)
2394 which = stealer->current - 1;
2353 which = stealer->current - 1;
2395
2396 /* Else, just use the node appearing in STEALER's window. */
2397 else
2354
2355 /* Else, just use the node appearing in STEALER's window. */
2356 else
2398 which = stealer->current;
2357 which = stealer->current;
2399
2400 /* Copy this node. */
2401 {
2358
2359 /* Copy this node. */
2360 {
2402 NODE *copy;
2361 NODE *copy = xmalloc (sizeof (NODE));
2362
2363 temp = stealer->nodes[which];
2364 point = stealer->points[which];
2365 pagetop = stealer->pagetops[which];
2403
2366
2404 temp = stealer->nodes[which];
2405 point = stealer->points[which];
2406 pagetop = stealer->pagetops[which];
2367 copy->filename = temp->filename;
2368 copy->parent = temp->parent;
2369 copy->nodename = temp->nodename;
2370 copy->contents = temp->contents;
2371 copy->nodelen = temp->nodelen;
2372 copy->flags = temp->flags;
2407
2373
2408 copy = (NODE *)xmalloc (sizeof (NODE));
2409 copy->filename = temp->filename;
2410 copy->parent = temp->parent;
2411 copy->nodename = temp->nodename;
2412 copy->contents = temp->contents;
2413 copy->nodelen = temp->nodelen;
2414 copy->flags = temp->flags;
2415
2416 temp = copy;
2374 temp = copy;
2417 }
2418
2419 window_set_node_of_window (info_win->window, temp);
2420 window->point = point;
2421 window->pagetop = pagetop;
2422 remember_window_and_node (info_win->window, temp);
2423 }
2424 else
2425 {
2426 temp = info_win->nodes[info_win->current];
2427 window_set_node_of_window (info_win->window, temp);
2428 }
2375 }
2376
2377 window_set_node_of_window (info_win->window, temp);
2378 window->point = point;
2379 window->pagetop = pagetop;
2380 remember_window_and_node (info_win->window, temp);
2381 }
2382 else
2383 {
2384 temp = info_win->nodes[info_win->current];
2385 window_set_node_of_window (info_win->window, temp);
2386 }
2387
2429 if (!info_error_was_printed)
2430 window_clear_echo_area ();
2388 if (!info_error_was_printed)
2389 window_clear_echo_area ();
2390
2391 if (auto_footnotes_p)
2392 info_get_or_remove_footnotes (window);
2431}
2432
2393}
2394
2395/* Kill current node, thus going back one in the node history. I (karl)
2396 do not think this is completely correct yet, because of the
2397 window-changing stuff in kill_node, but it's a lot better than the
2398 previous implementation, which did not account for nodes being
2399 visited twice at all. */
2400DECLARE_INFO_COMMAND (info_history_node,
2401 _("Select the most recently selected node"))
2402{
2403 kill_node (window, active_window->node->nodename);
2404}
2405
2406/* Kill named node. */
2407DECLARE_INFO_COMMAND (info_kill_node, _("Kill this node"))
2408{
2409 char *nodename = read_nodename_to_kill (window);
2410 kill_node (window, nodename);
2411}
2412
2413
2433/* Read the name of a file and select the entire file. */
2414/* Read the name of a file and select the entire file. */
2434DECLARE_INFO_COMMAND (info_view_file, "Read the name of a file and select it")
2415DECLARE_INFO_COMMAND (info_view_file, _("Read the name of a file and select it"))
2435{
2436 char *line;
2437
2416{
2417 char *line;
2418
2438 line = info_read_in_echo_area (window, "Find file: ");
2419 line = info_read_in_echo_area (window, _("Find file: "));
2439 if (!line)
2440 {
2441 info_abort_key (active_window, 1, 0);
2442 return;
2443 }
2444
2445 if (*line)
2446 {
2447 NODE *node;
2448
2449 node = info_get_node (line, "*");
2450 if (!node)
2420 if (!line)
2421 {
2422 info_abort_key (active_window, 1, 0);
2423 return;
2424 }
2425
2426 if (*line)
2427 {
2428 NODE *node;
2429
2430 node = info_get_node (line, "*");
2431 if (!node)
2451 {
2452 if (info_recent_file_error)
2453 info_error (info_recent_file_error);
2454 else
2455 info_error ("Cannot find \"%s\".", line);
2456 }
2432 {
2433 if (info_recent_file_error)
2434 info_error (info_recent_file_error);
2435 else
2436 info_error (_("Cannot find \"%s\"."), line);
2437 }
2457 else
2438 else
2458 {
2459 set_remembered_pagetop_and_point (active_window);
2460 info_set_node_of_window (window, node);
2461 }
2439 {
2440 set_remembered_pagetop_and_point (active_window);
2441 info_set_node_of_window (window, node);
2442 }
2462 free (line);
2463 }
2464
2465 if (!info_error_was_printed)
2466 window_clear_echo_area ();
2467}
2468
2469/* **************************************************************** */
2443 free (line);
2444 }
2445
2446 if (!info_error_was_printed)
2447 window_clear_echo_area ();
2448}
2449
2450/* **************************************************************** */
2470/* */
2471/* Dumping and Printing Nodes */
2472/* */
2451/* */
2452/* Dumping and Printing Nodes */
2453/* */
2473/* **************************************************************** */
2474
2475#define VERBOSE_NODE_DUMPING
2476static void write_node_to_stream ();
2477static void dump_node_to_stream ();
2478static void initialize_dumping ();
2479
2480/* Dump the nodes specified by FILENAME and NODENAMES to the file named

--- 13 unchanged lines hidden (view full) ---

2494 filename of "-" means to dump the nodes to stdout. */
2495 if (strcmp (output_filename, "-") == 0)
2496 output_stream = stdout;
2497 else
2498 output_stream = fopen (output_filename, "w");
2499
2500 if (!output_stream)
2501 {
2454/* **************************************************************** */
2455
2456#define VERBOSE_NODE_DUMPING
2457static void write_node_to_stream ();
2458static void dump_node_to_stream ();
2459static void initialize_dumping ();
2460
2461/* Dump the nodes specified by FILENAME and NODENAMES to the file named

--- 13 unchanged lines hidden (view full) ---

2475 filename of "-" means to dump the nodes to stdout. */
2476 if (strcmp (output_filename, "-") == 0)
2477 output_stream = stdout;
2478 else
2479 output_stream = fopen (output_filename, "w");
2480
2481 if (!output_stream)
2482 {
2502 info_error ("Could not create output file \"%s\".", output_filename);
2483 info_error (_("Could not create output file \"%s\"."), output_filename);
2503 return;
2504 }
2505
2506 /* Print each node to stream. */
2507 initialize_dumping ();
2508 for (i = 0; nodenames[i]; i++)
2509 dump_node_to_stream (filename, nodenames[i], output_stream, dump_subnodes);
2510
2511 if (output_stream != stdout)
2512 fclose (output_stream);
2513
2514#if defined (VERBOSE_NODE_DUMPING)
2484 return;
2485 }
2486
2487 /* Print each node to stream. */
2488 initialize_dumping ();
2489 for (i = 0; nodenames[i]; i++)
2490 dump_node_to_stream (filename, nodenames[i], output_stream, dump_subnodes);
2491
2492 if (output_stream != stdout)
2493 fclose (output_stream);
2494
2495#if defined (VERBOSE_NODE_DUMPING)
2515 info_error ("Done.");
2496 info_error (_("Done."));
2516#endif /* VERBOSE_NODE_DUMPING */
2517}
2518
2519/* A place to remember already dumped nodes. */
2520static char **dumped_already = (char **)NULL;
2521static int dumped_already_index = 0;
2522static int dumped_already_slots = 0;
2523

--- 15 unchanged lines hidden (view full) ---

2539 register int i;
2540 NODE *node;
2541
2542 node = info_get_node (filename, nodename);
2543
2544 if (!node)
2545 {
2546 if (info_recent_file_error)
2497#endif /* VERBOSE_NODE_DUMPING */
2498}
2499
2500/* A place to remember already dumped nodes. */
2501static char **dumped_already = (char **)NULL;
2502static int dumped_already_index = 0;
2503static int dumped_already_slots = 0;
2504

--- 15 unchanged lines hidden (view full) ---

2520 register int i;
2521 NODE *node;
2522
2523 node = info_get_node (filename, nodename);
2524
2525 if (!node)
2526 {
2527 if (info_recent_file_error)
2547 info_error (info_recent_file_error);
2528 info_error (info_recent_file_error);
2548 else
2529 else
2549 {
2550 if (filename && *nodename != '(')
2551 info_error
2552 (CANT_FILE_NODE, filename_non_directory (filename), nodename);
2553 else
2554 info_error (CANT_FIND_NODE, nodename);
2555 }
2530 {
2531 if (filename && *nodename != '(')
2532 info_error
2533 (CANT_FILE_NODE, filename_non_directory (filename), nodename);
2534 else
2535 info_error (CANT_FIND_NODE, nodename);
2536 }
2556 return;
2557 }
2558
2559 /* If we have already dumped this node, don't dump it again. */
2560 for (i = 0; i < dumped_already_index; i++)
2561 if (strcmp (node->nodename, dumped_already[i]) == 0)
2562 {
2537 return;
2538 }
2539
2540 /* If we have already dumped this node, don't dump it again. */
2541 for (i = 0; i < dumped_already_index; i++)
2542 if (strcmp (node->nodename, dumped_already[i]) == 0)
2543 {
2563 free (node);
2564 return;
2544 free (node);
2545 return;
2565 }
2566 add_pointer_to_array (node->nodename, dumped_already_index, dumped_already,
2546 }
2547 add_pointer_to_array (node->nodename, dumped_already_index, dumped_already,
2567 dumped_already_slots, 50, char *);
2548 dumped_already_slots, 50, char *);
2568
2569#if defined (VERBOSE_NODE_DUMPING)
2570 /* Maybe we should print some information about the node being output. */
2571 if (node->filename)
2549
2550#if defined (VERBOSE_NODE_DUMPING)
2551 /* Maybe we should print some information about the node being output. */
2552 if (node->filename)
2572 info_error ("Writing node \"(%s)%s\"...",
2573 filename_non_directory (node->filename), node->nodename);
2553 info_error (_("Writing node \"(%s)%s\"..."),
2554 filename_non_directory (node->filename), node->nodename);
2574 else
2555 else
2575 info_error ("Writing node \"%s\"...", node->nodename);
2556 info_error (_("Writing node \"%s\"..."), node->nodename);
2576#endif /* VERBOSE_NODE_DUMPING */
2577
2578 write_node_to_stream (node, stream);
2579
2580 /* If we are dumping subnodes, get the list of menu items in this node,
2581 and dump each one recursively. */
2582 if (dump_subnodes)
2583 {
2584 REFERENCE **menu = (REFERENCE **)NULL;
2585
2586 /* If this node is an Index, do not dump the menu references. */
2587 if (string_in_line ("Index", node->nodename) == -1)
2557#endif /* VERBOSE_NODE_DUMPING */
2558
2559 write_node_to_stream (node, stream);
2560
2561 /* If we are dumping subnodes, get the list of menu items in this node,
2562 and dump each one recursively. */
2563 if (dump_subnodes)
2564 {
2565 REFERENCE **menu = (REFERENCE **)NULL;
2566
2567 /* If this node is an Index, do not dump the menu references. */
2568 if (string_in_line ("Index", node->nodename) == -1)
2588 menu = info_menu_of_node (node);
2569 menu = info_menu_of_node (node);
2589
2590 if (menu)
2570
2571 if (menu)
2591 {
2592 for (i = 0; menu[i]; i++)
2593 {
2594 /* We don't dump Info files which are different than the
2595 current one. */
2596 if (!menu[i]->filename)
2597 dump_node_to_stream
2598 (filename, menu[i]->nodename, stream, dump_subnodes);
2599 }
2600 info_free_references (menu);
2601 }
2572 {
2573 for (i = 0; menu[i]; i++)
2574 {
2575 /* We don't dump Info files which are different than the
2576 current one. */
2577 if (!menu[i]->filename)
2578 dump_node_to_stream
2579 (filename, menu[i]->nodename, stream, dump_subnodes);
2580 }
2581 info_free_references (menu);
2582 }
2602 }
2603
2604 free (node);
2605}
2606
2607/* Dump NODE to FILENAME. If DUMP_SUBNODES is non-zero, recursively dump
2608 the nodes which appear in the menu of each node dumped. */
2609void

--- 9 unchanged lines hidden (view full) ---

2619 filename of "-" means to dump the nodes to stdout. */
2620 if (strcmp (filename, "-") == 0)
2621 output_stream = stdout;
2622 else
2623 output_stream = fopen (filename, "w");
2624
2625 if (!output_stream)
2626 {
2583 }
2584
2585 free (node);
2586}
2587
2588/* Dump NODE to FILENAME. If DUMP_SUBNODES is non-zero, recursively dump
2589 the nodes which appear in the menu of each node dumped. */
2590void

--- 9 unchanged lines hidden (view full) ---

2600 filename of "-" means to dump the nodes to stdout. */
2601 if (strcmp (filename, "-") == 0)
2602 output_stream = stdout;
2603 else
2604 output_stream = fopen (filename, "w");
2605
2606 if (!output_stream)
2607 {
2627 info_error ("Could not create output file \"%s\".", filename);
2608 info_error (_("Could not create output file \"%s\"."), filename);
2628 return;
2629 }
2630
2631 if (node->parent)
2632 nodes_filename = node->parent;
2633 else
2634 nodes_filename = node->filename;
2635
2636 initialize_dumping ();
2637 dump_node_to_stream
2638 (nodes_filename, node->nodename, output_stream, dump_subnodes);
2639
2640 if (output_stream != stdout)
2641 fclose (output_stream);
2642
2643#if defined (VERBOSE_NODE_DUMPING)
2609 return;
2610 }
2611
2612 if (node->parent)
2613 nodes_filename = node->parent;
2614 else
2615 nodes_filename = node->filename;
2616
2617 initialize_dumping ();
2618 dump_node_to_stream
2619 (nodes_filename, node->nodename, output_stream, dump_subnodes);
2620
2621 if (output_stream != stdout)
2622 fclose (output_stream);
2623
2624#if defined (VERBOSE_NODE_DUMPING)
2644 info_error ("Done.");
2625 info_error (_("Done."));
2645#endif /* VERBOSE_NODE_DUMPING */
2646}
2647
2648#if !defined (DEFAULT_INFO_PRINT_COMMAND)
2649# define DEFAULT_INFO_PRINT_COMMAND "lpr"
2650#endif /* !DEFAULT_INFO_PRINT_COMMAND */
2651
2652DECLARE_INFO_COMMAND (info_print_node,
2626#endif /* VERBOSE_NODE_DUMPING */
2627}
2628
2629#if !defined (DEFAULT_INFO_PRINT_COMMAND)
2630# define DEFAULT_INFO_PRINT_COMMAND "lpr"
2631#endif /* !DEFAULT_INFO_PRINT_COMMAND */
2632
2633DECLARE_INFO_COMMAND (info_print_node,
2653 "Pipe the contents of this node through INFO_PRINT_COMMAND")
2634 _("Pipe the contents of this node through INFO_PRINT_COMMAND"))
2654{
2655 print_node (window->node);
2656}
2657
2658/* Print NODE on a printer piping it into INFO_PRINT_COMMAND. */
2659void
2660print_node (node)
2661 NODE *node;
2662{
2635{
2636 print_node (window->node);
2637}
2638
2639/* Print NODE on a printer piping it into INFO_PRINT_COMMAND. */
2640void
2641print_node (node)
2642 NODE *node;
2643{
2663 char *print_command, *getenv ();
2664 FILE *printer_pipe;
2644 FILE *printer_pipe;
2645 char *print_command = getenv ("INFO_PRINT_COMMAND");
2665
2646
2666 print_command = getenv ("INFO_PRINT_COMMAND");
2667
2668 if (!print_command || !*print_command)
2669 print_command = DEFAULT_INFO_PRINT_COMMAND;
2670
2671 printer_pipe = popen (print_command, "w");
2672
2673 if (!printer_pipe)
2674 {
2647 if (!print_command || !*print_command)
2648 print_command = DEFAULT_INFO_PRINT_COMMAND;
2649
2650 printer_pipe = popen (print_command, "w");
2651
2652 if (!printer_pipe)
2653 {
2675 info_error ("Cannot open pipe to \"%s\".", print_command);
2654 info_error (_("Cannot open pipe to \"%s\"."), print_command);
2676 return;
2677 }
2678
2679#if defined (VERBOSE_NODE_DUMPING)
2680 /* Maybe we should print some information about the node being output. */
2681 if (node->filename)
2655 return;
2656 }
2657
2658#if defined (VERBOSE_NODE_DUMPING)
2659 /* Maybe we should print some information about the node being output. */
2660 if (node->filename)
2682 info_error ("Printing node \"(%s)%s\"...",
2683 filename_non_directory (node->filename), node->nodename);
2661 info_error (_("Printing node \"(%s)%s\"..."),
2662 filename_non_directory (node->filename), node->nodename);
2684 else
2663 else
2685 info_error ("Printing node \"%s\"...", node->nodename);
2664 info_error (_("Printing node \"%s\"..."), node->nodename);
2686#endif /* VERBOSE_NODE_DUMPING */
2687
2688 write_node_to_stream (node, printer_pipe);
2689 pclose (printer_pipe);
2690
2691#if defined (VERBOSE_NODE_DUMPING)
2665#endif /* VERBOSE_NODE_DUMPING */
2666
2667 write_node_to_stream (node, printer_pipe);
2668 pclose (printer_pipe);
2669
2670#if defined (VERBOSE_NODE_DUMPING)
2692 info_error ("Done.");
2671 info_error (_("Done."));
2693#endif /* VERBOSE_NODE_DUMPING */
2694}
2695
2696static void
2697write_node_to_stream (node, stream)
2698 NODE *node;
2699 FILE *stream;
2700{
2701 fwrite (node->contents, 1, node->nodelen, stream);
2702}
2703
2704/* **************************************************************** */
2672#endif /* VERBOSE_NODE_DUMPING */
2673}
2674
2675static void
2676write_node_to_stream (node, stream)
2677 NODE *node;
2678 FILE *stream;
2679{
2680 fwrite (node->contents, 1, node->nodelen, stream);
2681}
2682
2683/* **************************************************************** */
2705/* */
2706/* Info Searching Commands */
2707/* */
2684/* */
2685/* Info Searching Commands */
2686/* */
2708/* **************************************************************** */
2709
2710/* Variable controlling the garbage collection of files briefly visited
2711 during searches. Such files are normally gc'ed, unless they were
2712 compressed to begin with. If this variable is non-zero, it says
2713 to gc even those file buffer contents which had to be uncompressed. */
2714int gc_compressed_files = 0;
2715

--- 58 unchanged lines hidden (view full) ---

2774 binding.flags |= S_SkipDest;
2775
2776 offset = search (string, &binding);
2777
2778 if (offset != -1 && window)
2779 {
2780 set_remembered_pagetop_and_point (window);
2781 if (window->node != node)
2687/* **************************************************************** */
2688
2689/* Variable controlling the garbage collection of files briefly visited
2690 during searches. Such files are normally gc'ed, unless they were
2691 compressed to begin with. If this variable is non-zero, it says
2692 to gc even those file buffer contents which had to be uncompressed. */
2693int gc_compressed_files = 0;
2694

--- 58 unchanged lines hidden (view full) ---

2753 binding.flags |= S_SkipDest;
2754
2755 offset = search (string, &binding);
2756
2757 if (offset != -1 && window)
2758 {
2759 set_remembered_pagetop_and_point (window);
2760 if (window->node != node)
2782 window_set_node_of_window (window, node);
2761 window_set_node_of_window (window, node);
2783 window->point = offset;
2784 window_adjust_pagetop (window);
2785 }
2786 return (offset);
2787}
2788
2789/* Search NODE, looking for the largest possible match of STRING. Start the
2790 search at START. Return the absolute position of the match, or -1, if
2791 no part of the string could be found. */
2792long
2793info_target_search_node (node, string, start)
2794 NODE *node;
2795 char *string;
2796 long start;
2797{
2798 register int i;
2799 long offset;
2800 char *target;
2801
2762 window->point = offset;
2763 window_adjust_pagetop (window);
2764 }
2765 return (offset);
2766}
2767
2768/* Search NODE, looking for the largest possible match of STRING. Start the
2769 search at START. Return the absolute position of the match, or -1, if
2770 no part of the string could be found. */
2771long
2772info_target_search_node (node, string, start)
2773 NODE *node;
2774 char *string;
2775 long start;
2776{
2777 register int i;
2778 long offset;
2779 char *target;
2780
2802 target = strdup (string);
2781 target = xstrdup (string);
2803 i = strlen (target);
2804
2805 /* Try repeatedly searching for this string while removing words from
2806 the end of it. */
2807 while (i)
2808 {
2809 target[i] = '\0';
2810 offset = info_search_in_node (target, node, start, (WINDOW *)NULL, 1);
2811
2812 if (offset != -1)
2782 i = strlen (target);
2783
2784 /* Try repeatedly searching for this string while removing words from
2785 the end of it. */
2786 while (i)
2787 {
2788 target[i] = '\0';
2789 offset = info_search_in_node (target, node, start, (WINDOW *)NULL, 1);
2790
2791 if (offset != -1)
2813 break;
2792 break;
2814
2815 /* Delete the last word from TARGET. */
2816 for (; i && (!whitespace (target[i]) && (target[i] != ',')); i--);
2817 }
2818 free (target);
2819 return (offset);
2820}
2821

--- 17 unchanged lines hidden (view full) ---

2839 file_buffer = file_buffer_of_window (window);
2840 initial_nodename = window->node->nodename;
2841
2842 if ((info_last_executed_command == info_search) &&
2843 (last_searched_for_string) &&
2844 (strcmp (last_searched_for_string, string) == 0))
2845 {
2846 ret = info_search_in_node
2793
2794 /* Delete the last word from TARGET. */
2795 for (; i && (!whitespace (target[i]) && (target[i] != ',')); i--);
2796 }
2797 free (target);
2798 return (offset);
2799}
2800

--- 17 unchanged lines hidden (view full) ---

2818 file_buffer = file_buffer_of_window (window);
2819 initial_nodename = window->node->nodename;
2820
2821 if ((info_last_executed_command == info_search) &&
2822 (last_searched_for_string) &&
2823 (strcmp (last_searched_for_string, string) == 0))
2824 {
2825 ret = info_search_in_node
2847 (string, window->node, window->point + dir, window, dir);
2826 (string, window->node, window->point + dir, window, dir);
2848 }
2849 else
2850 {
2851 ret = info_search_in_node
2827 }
2828 else
2829 {
2830 ret = info_search_in_node
2852 (string, window->node, window->point, window, dir);
2831 (string, window->node, window->point, window, dir);
2853 }
2854
2855 maybe_free (last_searched_for_string);
2832 }
2833
2834 maybe_free (last_searched_for_string);
2856 last_searched_for_string = strdup (string);
2835 last_searched_for_string = xstrdup (string);
2857
2858 if (ret != -1)
2859 {
2860 /* We won! */
2861 if (!echo_area_is_active && !isearch_is_active)
2836
2837 if (ret != -1)
2838 {
2839 /* We won! */
2840 if (!echo_area_is_active && !isearch_is_active)
2862 window_clear_echo_area ();
2841 window_clear_echo_area ();
2863 return (0);
2864 }
2865
2866 /* The string wasn't found in the current node. Search through the
2867 window's file buffer, iff the current node is not "*". */
2868 if (!file_buffer || (strcmp (initial_nodename, "*") == 0))
2869 return (-1);
2870

--- 4 unchanged lines hidden (view full) ---

2875 {
2876 register int current_tag, number_of_tags;
2877 char *last_subfile;
2878 TAG *tag;
2879
2880 /* Find number of tags and current tag. */
2881 last_subfile = (char *)NULL;
2882 for (i = 0; file_buffer->tags[i]; i++)
2842 return (0);
2843 }
2844
2845 /* The string wasn't found in the current node. Search through the
2846 window's file buffer, iff the current node is not "*". */
2847 if (!file_buffer || (strcmp (initial_nodename, "*") == 0))
2848 return (-1);
2849

--- 4 unchanged lines hidden (view full) ---

2854 {
2855 register int current_tag, number_of_tags;
2856 char *last_subfile;
2857 TAG *tag;
2858
2859 /* Find number of tags and current tag. */
2860 last_subfile = (char *)NULL;
2861 for (i = 0; file_buffer->tags[i]; i++)
2883 if (strcmp (initial_nodename, file_buffer->tags[i]->nodename) == 0)
2884 {
2885 current_tag = i;
2886 last_subfile = file_buffer->tags[i]->filename;
2887 }
2862 if (strcmp (initial_nodename, file_buffer->tags[i]->nodename) == 0)
2863 {
2864 current_tag = i;
2865 last_subfile = file_buffer->tags[i]->filename;
2866 }
2888
2889 number_of_tags = i;
2890
2891 /* If there is no last_subfile, our tag wasn't found. */
2892 if (!last_subfile)
2867
2868 number_of_tags = i;
2869
2870 /* If there is no last_subfile, our tag wasn't found. */
2871 if (!last_subfile)
2893 return (-1);
2872 return (-1);
2894
2895 /* Search through subsequent nodes, wrapping around to the top
2873
2874 /* Search through subsequent nodes, wrapping around to the top
2896 of the info file until we find the string or return to this
2897 window's node and point. */
2875 of the info file until we find the string or return to this
2876 window's node and point. */
2898 while (1)
2877 while (1)
2899 {
2900 NODE *node;
2878 {
2879 NODE *node;
2901
2880
2902 /* Allow C-g to quit the search, failing it if pressed. */
2903 return_if_control_g (-1);
2881 /* Allow C-g to quit the search, failing it if pressed. */
2882 return_if_control_g (-1);
2904
2883
2905 current_tag += dir;
2884 current_tag += dir;
2906
2885
2907 if (current_tag < 0)
2908 current_tag = number_of_tags - 1;
2909 else if (current_tag == number_of_tags)
2910 current_tag = 0;
2886 if (current_tag < 0)
2887 current_tag = number_of_tags - 1;
2888 else if (current_tag == number_of_tags)
2889 current_tag = 0;
2911
2890
2912 tag = file_buffer->tags[current_tag];
2891 tag = file_buffer->tags[current_tag];
2913
2892
2914 if (!echo_area_is_active && (last_subfile != tag->filename))
2915 {
2916 window_message_in_echo_area
2917 ("Searching subfile \"%s\"...",
2918 filename_non_directory (tag->filename));
2893 if (!echo_area_is_active && (last_subfile != tag->filename))
2894 {
2895 window_message_in_echo_area
2896 (_("Searching subfile \"%s\"..."),
2897 filename_non_directory (tag->filename));
2919
2898
2920 last_subfile = tag->filename;
2921 }
2899 last_subfile = tag->filename;
2900 }
2922
2901
2923 node = info_get_node (file_buffer->filename, tag->nodename);
2902 node = info_get_node (file_buffer->filename, tag->nodename);
2924
2903
2925 if (!node)
2926 {
2927 /* If not doing i-search... */
2928 if (!echo_area_is_active)
2929 {
2930 if (info_recent_file_error)
2931 info_error (info_recent_file_error);
2932 else
2933 info_error (CANT_FILE_NODE,
2934 filename_non_directory (file_buffer->filename),
2935 tag->nodename);
2936 }
2937 return (-1);
2938 }
2904 if (!node)
2905 {
2906 /* If not doing i-search... */
2907 if (!echo_area_is_active)
2908 {
2909 if (info_recent_file_error)
2910 info_error (info_recent_file_error);
2911 else
2912 info_error (CANT_FILE_NODE,
2913 filename_non_directory (file_buffer->filename),
2914 tag->nodename);
2915 }
2916 return (-1);
2917 }
2939
2918
2940 if (dir < 0)
2941 start = tag->nodelen;
2919 if (dir < 0)
2920 start = tag->nodelen;
2942
2921
2943 ret =
2944 info_search_in_node (string, node, start, window, dir);
2922 ret =
2923 info_search_in_node (string, node, start, window, dir);
2945
2924
2946 /* Did we find the string in this node? */
2947 if (ret != -1)
2948 {
2949 /* Yes! We win. */
2950 remember_window_and_node (window, node);
2951 if (!echo_area_is_active)
2952 window_clear_echo_area ();
2953 return (0);
2954 }
2925 /* Did we find the string in this node? */
2926 if (ret != -1)
2927 {
2928 /* Yes! We win. */
2929 remember_window_and_node (window, node);
2930 if (!echo_area_is_active)
2931 window_clear_echo_area ();
2932 return (0);
2933 }
2955
2934
2956 /* No. Free this node, and make sure that we haven't passed
2957 our starting point. */
2958 free (node);
2935 /* No. Free this node, and make sure that we haven't passed
2936 our starting point. */
2937 free (node);
2959
2938
2960 if (strcmp (initial_nodename, tag->nodename) == 0)
2961 return (-1);
2962 }
2939 if (strcmp (initial_nodename, tag->nodename) == 0)
2940 return (-1);
2941 }
2963 }
2964 return (-1);
2965}
2966
2942 }
2943 return (-1);
2944}
2945
2967DECLARE_INFO_COMMAND (info_search, "Read a string and search for it")
2946DECLARE_INFO_COMMAND (info_search, _("Read a string and search for it"))
2968{
2969 char *line, *prompt;
2970 int result, old_pagetop;
2971 int direction;
2972
2973 if (count < 0)
2974 direction = -1;
2975 else
2976 direction = 1;
2977
2978 /* Read a string from the user, defaulting the search to SEARCH_STRING. */
2979 if (!search_string)
2980 {
2981 search_string = (char *)xmalloc (search_string_size = 100);
2982 search_string[0] = '\0';
2983 }
2984
2985 prompt = (char *)xmalloc (50 + strlen (search_string));
2986
2947{
2948 char *line, *prompt;
2949 int result, old_pagetop;
2950 int direction;
2951
2952 if (count < 0)
2953 direction = -1;
2954 else
2955 direction = 1;
2956
2957 /* Read a string from the user, defaulting the search to SEARCH_STRING. */
2958 if (!search_string)
2959 {
2960 search_string = (char *)xmalloc (search_string_size = 100);
2961 search_string[0] = '\0';
2962 }
2963
2964 prompt = (char *)xmalloc (50 + strlen (search_string));
2965
2987 sprintf (prompt, "%s for string [%s]: ",
2988 direction < 0 ? "Search backward" : "Search",
2989 search_string);
2966 sprintf (prompt, _("%s for string [%s]: "),
2967 direction < 0 ? _("Search backward") : _("Search"),
2968 search_string);
2990
2991 line = info_read_in_echo_area (window, prompt);
2992 free (prompt);
2993
2994 if (!line)
2995 {
2996 info_abort_key ();
2997 return;
2998 }
2999
3000 if (*line)
3001 {
3002 if (strlen (line) + 1 > search_string_size)
2969
2970 line = info_read_in_echo_area (window, prompt);
2971 free (prompt);
2972
2973 if (!line)
2974 {
2975 info_abort_key ();
2976 return;
2977 }
2978
2979 if (*line)
2980 {
2981 if (strlen (line) + 1 > search_string_size)
3003 search_string = (char *)
3004 xrealloc (search_string, (search_string_size += 50 + strlen (line)));
2982 search_string = (char *)
2983 xrealloc (search_string, (search_string_size += 50 + strlen (line)));
3005
3006 strcpy (search_string, line);
3007 search_string_index = strlen (line);
3008 free (line);
3009 }
3010
3011 old_pagetop = active_window->pagetop;
3012 result = info_search_internal (search_string, active_window, direction);
3013
3014 if (result != 0 && !info_error_was_printed)
2984
2985 strcpy (search_string, line);
2986 search_string_index = strlen (line);
2987 free (line);
2988 }
2989
2990 old_pagetop = active_window->pagetop;
2991 result = info_search_internal (search_string, active_window, direction);
2992
2993 if (result != 0 && !info_error_was_printed)
3015 info_error ("Search failed.");
2994 info_error (_("Search failed."));
3016 else if (old_pagetop != active_window->pagetop)
3017 {
3018 int new_pagetop;
3019
3020 new_pagetop = active_window->pagetop;
3021 active_window->pagetop = old_pagetop;
3022 set_window_pagetop (active_window, new_pagetop);
3023 if (auto_footnotes_p)
2995 else if (old_pagetop != active_window->pagetop)
2996 {
2997 int new_pagetop;
2998
2999 new_pagetop = active_window->pagetop;
3000 active_window->pagetop = old_pagetop;
3001 set_window_pagetop (active_window, new_pagetop);
3002 if (auto_footnotes_p)
3024 info_get_or_remove_footnotes (active_window);
3003 info_get_or_remove_footnotes (active_window);
3025 }
3026
3027 /* Perhaps free the unreferenced file buffers that were searched, but
3028 not retained. */
3029 info_gc_file_buffers ();
3030}
3031
3032/* **************************************************************** */
3004 }
3005
3006 /* Perhaps free the unreferenced file buffers that were searched, but
3007 not retained. */
3008 info_gc_file_buffers ();
3009}
3010
3011/* **************************************************************** */
3033/* */
3034/* Incremental Searching */
3035/* */
3012/* */
3013/* Incremental Searching */
3014/* */
3036/* **************************************************************** */
3037
3038static void incremental_search ();
3039
3040DECLARE_INFO_COMMAND (isearch_forward,
3015/* **************************************************************** */
3016
3017static void incremental_search ();
3018
3019DECLARE_INFO_COMMAND (isearch_forward,
3041 "Search interactively for a string as you type it")
3020 _("Search interactively for a string as you type it"))
3042{
3043 incremental_search (window, count, key);
3044}
3045
3046DECLARE_INFO_COMMAND (isearch_backward,
3021{
3022 incremental_search (window, count, key);
3023}
3024
3025DECLARE_INFO_COMMAND (isearch_backward,
3047 "Search interactively for a string as you type it")
3026 _("Search interactively for a string as you type it"))
3048{
3049 incremental_search (window, -count, key);
3050}
3051
3052/* Incrementally search for a string as it is typed. */
3053/* The last accepted incremental search string. */
3054static char *last_isearch_accepted = (char *)NULL;
3055
3056/* The current incremental search string. */
3057static char *isearch_string = (char *)NULL;
3058static int isearch_string_index = 0;
3059static int isearch_string_size = 0;
3060static unsigned char isearch_terminate_search_key = ESC;
3061
3062/* Structure defining the current state of an incremental search. */
3063typedef struct {
3027{
3028 incremental_search (window, -count, key);
3029}
3030
3031/* Incrementally search for a string as it is typed. */
3032/* The last accepted incremental search string. */
3033static char *last_isearch_accepted = (char *)NULL;
3034
3035/* The current incremental search string. */
3036static char *isearch_string = (char *)NULL;
3037static int isearch_string_index = 0;
3038static int isearch_string_size = 0;
3039static unsigned char isearch_terminate_search_key = ESC;
3040
3041/* Structure defining the current state of an incremental search. */
3042typedef struct {
3064 WINDOW_STATE_DECL; /* The node, pagetop and point. */
3065 int search_index; /* Offset of the last char in the search string. */
3066 int direction; /* The direction that this search is heading in. */
3067 int failing; /* Whether or not this search failed. */
3043 WINDOW_STATE_DECL; /* The node, pagetop and point. */
3044 int search_index; /* Offset of the last char in the search string. */
3045 int direction; /* The direction that this search is heading in. */
3046 int failing; /* Whether or not this search failed. */
3068} SEARCH_STATE;
3069
3070/* Array of search states. */
3071static SEARCH_STATE **isearch_states = (SEARCH_STATE **)NULL;
3072static int isearch_states_index = 0;
3073static int isearch_states_slots = 0;
3074
3075/* Push the state of this search. */

--- 6 unchanged lines hidden (view full) ---

3082
3083 state = (SEARCH_STATE *)xmalloc (sizeof (SEARCH_STATE));
3084 window_get_state (window, state);
3085 state->search_index = search_index;
3086 state->direction = direction;
3087 state->failing = failing;
3088
3089 add_pointer_to_array (state, isearch_states_index, isearch_states,
3047} SEARCH_STATE;
3048
3049/* Array of search states. */
3050static SEARCH_STATE **isearch_states = (SEARCH_STATE **)NULL;
3051static int isearch_states_index = 0;
3052static int isearch_states_slots = 0;
3053
3054/* Push the state of this search. */

--- 6 unchanged lines hidden (view full) ---

3061
3062 state = (SEARCH_STATE *)xmalloc (sizeof (SEARCH_STATE));
3063 window_get_state (window, state);
3064 state->search_index = search_index;
3065 state->direction = direction;
3066 state->failing = failing;
3067
3068 add_pointer_to_array (state, isearch_states_index, isearch_states,
3090 isearch_states_slots, 20, SEARCH_STATE *);
3069 isearch_states_slots, 20, SEARCH_STATE *);
3091}
3092
3093/* Pop the state of this search to WINDOW, SEARCH_INDEX, and DIRECTION. */
3094static void
3095pop_isearch (window, search_index, direction, failing)
3096 WINDOW *window;
3097 int *search_index, *direction, *failing;
3098{

--- 34 unchanged lines hidden (view full) ---

3133 unsigned char *string;
3134 int failing_p;
3135{
3136 register int i;
3137 char *prefix, *prompt, *p_rep;
3138 int prompt_len, p_rep_index, p_rep_size;
3139
3140 if (dir < 0)
3070}
3071
3072/* Pop the state of this search to WINDOW, SEARCH_INDEX, and DIRECTION. */
3073static void
3074pop_isearch (window, search_index, direction, failing)
3075 WINDOW *window;
3076 int *search_index, *direction, *failing;
3077{

--- 34 unchanged lines hidden (view full) ---

3112 unsigned char *string;
3113 int failing_p;
3114{
3115 register int i;
3116 char *prefix, *prompt, *p_rep;
3117 int prompt_len, p_rep_index, p_rep_size;
3118
3119 if (dir < 0)
3141 prefix = "I-search backward: ";
3120 prefix = _("I-search backward: ");
3142 else
3121 else
3143 prefix = "I-search: ";
3122 prefix = _("I-search: ");
3144
3145 p_rep_index = p_rep_size = 0;
3146 p_rep = (char *)NULL;
3147 for (i = 0; string[i]; i++)
3148 {
3149 char *rep;
3150
3151 switch (string[i])
3123
3124 p_rep_index = p_rep_size = 0;
3125 p_rep = (char *)NULL;
3126 for (i = 0; string[i]; i++)
3127 {
3128 char *rep;
3129
3130 switch (string[i])
3152 {
3153 case ' ': rep = " "; break;
3154 case LFD: rep = "\\n"; break;
3155 case TAB: rep = "\\t"; break;
3156 default:
3157 rep = pretty_keyname (string[i]);
3158 }
3131 {
3132 case ' ': rep = " "; break;
3133 case LFD: rep = "\\n"; break;
3134 case TAB: rep = "\\t"; break;
3135 default:
3136 rep = pretty_keyname (string[i]);
3137 }
3159 if ((p_rep_index + strlen (rep) + 1) >= p_rep_size)
3138 if ((p_rep_index + strlen (rep) + 1) >= p_rep_size)
3160 p_rep = (char *)xrealloc (p_rep, p_rep_size += 100);
3139 p_rep = (char *)xrealloc (p_rep, p_rep_size += 100);
3161
3162 strcpy (p_rep + p_rep_index, rep);
3163 p_rep_index += strlen (rep);
3164 }
3165
3166 prompt_len = strlen (prefix) + p_rep_index + 20;
3167 prompt = (char *)xmalloc (prompt_len);
3140
3141 strcpy (p_rep + p_rep_index, rep);
3142 p_rep_index += strlen (rep);
3143 }
3144
3145 prompt_len = strlen (prefix) + p_rep_index + 20;
3146 prompt = (char *)xmalloc (prompt_len);
3168 sprintf (prompt, "%s%s%s", failing_p ? "Failing " : "", prefix,
3169 p_rep ? p_rep : "");
3147 sprintf (prompt, "%s%s%s", failing_p ? _("Failing ") : "", prefix,
3148 p_rep ? p_rep : "");
3170
3171 window_message_in_echo_area ("%s", prompt);
3172 maybe_free (p_rep);
3173 free (prompt);
3174 display_cursor_at_point (active_window);
3175}
3176
3177static void

--- 26 unchanged lines hidden (view full) ---

3204 isearch_is_active = 1;
3205
3206 while (isearch_is_active)
3207 {
3208 VFunction *func = (VFunction *)NULL;
3209 int quoted = 0;
3210
3211 /* If a recent display was interrupted, then do the redisplay now if
3149
3150 window_message_in_echo_area ("%s", prompt);
3151 maybe_free (p_rep);
3152 free (prompt);
3153 display_cursor_at_point (active_window);
3154}
3155
3156static void

--- 26 unchanged lines hidden (view full) ---

3183 isearch_is_active = 1;
3184
3185 while (isearch_is_active)
3186 {
3187 VFunction *func = (VFunction *)NULL;
3188 int quoted = 0;
3189
3190 /* If a recent display was interrupted, then do the redisplay now if
3212 it is convenient. */
3191 it is convenient. */
3213 if (!info_any_buffered_input_p () && display_was_interrupted_p)
3192 if (!info_any_buffered_input_p () && display_was_interrupted_p)
3214 {
3215 display_update_one_window (window);
3216 display_cursor_at_point (active_window);
3217 }
3193 {
3194 display_update_one_window (window);
3195 display_cursor_at_point (active_window);
3196 }
3218
3219 /* Read a character and dispatch on it. */
3220 key = info_get_input_char ();
3221 window_get_state (window, &mystate);
3222
3223 if (key == DEL)
3197
3198 /* Read a character and dispatch on it. */
3199 key = info_get_input_char ();
3200 window_get_state (window, &mystate);
3201
3202 if (key == DEL)
3224 {
3225 /* User wants to delete one level of search? */
3226 if (!isearch_states_index)
3227 {
3228 terminal_ring_bell ();
3229 continue;
3230 }
3231 else
3232 {
3233 pop_isearch
3234 (window, &isearch_string_index, &dir, &search_result);
3235 isearch_string[isearch_string_index] = '\0';
3236 show_isearch_prompt (dir, isearch_string, search_result);
3237 goto after_search;
3238 }
3239 }
3203 {
3204 /* User wants to delete one level of search? */
3205 if (!isearch_states_index)
3206 {
3207 terminal_ring_bell ();
3208 continue;
3209 }
3210 else
3211 {
3212 pop_isearch
3213 (window, &isearch_string_index, &dir, &search_result);
3214 isearch_string[isearch_string_index] = '\0';
3215 show_isearch_prompt (dir, isearch_string, search_result);
3216 goto after_search;
3217 }
3218 }
3240 else if (key == Control ('q'))
3219 else if (key == Control ('q'))
3241 {
3242 key = info_get_input_char ();
3243 quoted = 1;
3244 }
3220 {
3221 key = info_get_input_char ();
3222 quoted = 1;
3223 }
3245
3246 /* We are about to search again, or quit. Save the current search. */
3247 push_isearch (window, isearch_string_index, dir, search_result);
3248
3249 if (quoted)
3224
3225 /* We are about to search again, or quit. Save the current search. */
3226 push_isearch (window, isearch_string_index, dir, search_result);
3227
3228 if (quoted)
3250 goto insert_and_search;
3229 goto insert_and_search;
3251
3252 if (!Meta_p (key) || (ISO_Latin_p && key < 160))
3230
3231 if (!Meta_p (key) || (ISO_Latin_p && key < 160))
3253 {
3254 func = window->keymap[key].function;
3232 {
3233 func = window->keymap[key].function;
3255
3234
3256 /* If this key invokes an incremental search, then this means that
3257 we will either search again in the same direction, search
3258 again in the reverse direction, or insert the last search
3259 string that was accepted through incremental searching. */
3260 if (func == isearch_forward || func == isearch_backward)
3261 {
3262 if ((func == isearch_forward && dir > 0) ||
3263 (func == isearch_backward && dir < 0))
3264 {
3265 /* If the user has typed no characters, then insert the
3266 last successful search into the current search string. */
3267 if (isearch_string_index == 0)
3268 {
3269 /* Of course, there must be something to insert. */
3270 if (last_isearch_accepted)
3271 {
3272 if (strlen (last_isearch_accepted) + 1 >=
3273 isearch_string_size)
3274 isearch_string = (char *)
3275 xrealloc (isearch_string,
3276 isearch_string_size += 10 +
3277 strlen (last_isearch_accepted));
3278 strcpy (isearch_string, last_isearch_accepted);
3279 isearch_string_index = strlen (isearch_string);
3280 goto search_now;
3281 }
3282 else
3283 continue;
3284 }
3285 else
3286 {
3287 /* Search again in the same direction. This means start
3288 from a new place if the last search was successful. */
3289 if (search_result == 0)
3290 window->point += dir;
3291 }
3292 }
3293 else
3294 {
3295 /* Reverse the direction of the search. */
3296 dir = -dir;
3297 }
3298 }
3299 else if (isprint (key) || func == (VFunction *)NULL)
3300 {
3301 insert_and_search:
3235 /* If this key invokes an incremental search, then this means that
3236 we will either search again in the same direction, search
3237 again in the reverse direction, or insert the last search
3238 string that was accepted through incremental searching. */
3239 if (func == isearch_forward || func == isearch_backward)
3240 {
3241 if ((func == isearch_forward && dir > 0) ||
3242 (func == isearch_backward && dir < 0))
3243 {
3244 /* If the user has typed no characters, then insert the
3245 last successful search into the current search string. */
3246 if (isearch_string_index == 0)
3247 {
3248 /* Of course, there must be something to insert. */
3249 if (last_isearch_accepted)
3250 {
3251 if (strlen (last_isearch_accepted) + 1 >=
3252 isearch_string_size)
3253 isearch_string = (char *)
3254 xrealloc (isearch_string,
3255 isearch_string_size += 10 +
3256 strlen (last_isearch_accepted));
3257 strcpy (isearch_string, last_isearch_accepted);
3258 isearch_string_index = strlen (isearch_string);
3259 goto search_now;
3260 }
3261 else
3262 continue;
3263 }
3264 else
3265 {
3266 /* Search again in the same direction. This means start
3267 from a new place if the last search was successful. */
3268 if (search_result == 0)
3269 window->point += dir;
3270 }
3271 }
3272 else
3273 {
3274 /* Reverse the direction of the search. */
3275 dir = -dir;
3276 }
3277 }
3278 else if (isprint (key) || func == (VFunction *)NULL)
3279 {
3280 insert_and_search:
3302
3281
3303 if (isearch_string_index + 2 >= isearch_string_size)
3304 isearch_string = (char *)xrealloc
3305 (isearch_string, isearch_string_size += 100);
3282 if (isearch_string_index + 2 >= isearch_string_size)
3283 isearch_string = (char *)xrealloc
3284 (isearch_string, isearch_string_size += 100);
3306
3285
3307 isearch_string[isearch_string_index++] = key;
3308 isearch_string[isearch_string_index] = '\0';
3309 goto search_now;
3310 }
3311 else if (func == info_abort_key)
3312 {
3313 /* If C-g pressed, and the search is failing, pop the search
3314 stack back to the last unfailed search. */
3315 if (isearch_states_index && (search_result != 0))
3316 {
3317 terminal_ring_bell ();
3318 while (isearch_states_index && (search_result != 0))
3319 pop_isearch
3320 (window, &isearch_string_index, &dir, &search_result);
3321 isearch_string[isearch_string_index] = '\0';
3322 show_isearch_prompt (dir, isearch_string, search_result);
3323 continue;
3324 }
3325 else
3326 goto exit_search;
3327 }
3328 else
3329 goto exit_search;
3330 }
3286 isearch_string[isearch_string_index++] = key;
3287 isearch_string[isearch_string_index] = '\0';
3288 goto search_now;
3289 }
3290 else if (func == info_abort_key)
3291 {
3292 /* If C-g pressed, and the search is failing, pop the search
3293 stack back to the last unfailed search. */
3294 if (isearch_states_index && (search_result != 0))
3295 {
3296 terminal_ring_bell ();
3297 while (isearch_states_index && (search_result != 0))
3298 pop_isearch
3299 (window, &isearch_string_index, &dir, &search_result);
3300 isearch_string[isearch_string_index] = '\0';
3301 show_isearch_prompt (dir, isearch_string, search_result);
3302 continue;
3303 }
3304 else
3305 goto exit_search;
3306 }
3307 else
3308 goto exit_search;
3309 }
3331 else
3310 else
3332 {
3333 exit_search:
3334 /* The character is not printable, or it has a function which is
3335 non-null. Exit the search, remembering the search string. If
3336 the key is not the same as the isearch_terminate_search_key,
3337 then push it into pending input. */
3338 if (isearch_string_index && func != info_abort_key)
3339 {
3340 maybe_free (last_isearch_accepted);
3341 last_isearch_accepted = strdup (isearch_string);
3342 }
3311 {
3312 exit_search:
3313 /* The character is not printable, or it has a function which is
3314 non-null. Exit the search, remembering the search string. If
3315 the key is not the same as the isearch_terminate_search_key,
3316 then push it into pending input. */
3317 if (isearch_string_index && func != info_abort_key)
3318 {
3319 maybe_free (last_isearch_accepted);
3320 last_isearch_accepted = xstrdup (isearch_string);
3321 }
3343
3322
3344 if (key != isearch_terminate_search_key)
3345 info_set_pending_input (key);
3323 if (key != isearch_terminate_search_key)
3324 info_set_pending_input (key);
3346
3325
3347 if (func == info_abort_key)
3348 {
3349 if (isearch_states_index)
3350 window_set_state (window, &orig_state);
3351 }
3326 if (func == info_abort_key)
3327 {
3328 if (isearch_states_index)
3329 window_set_state (window, &orig_state);
3330 }
3352
3331
3353 if (!echo_area_is_active)
3354 window_clear_echo_area ();
3332 if (!echo_area_is_active)
3333 window_clear_echo_area ();
3355
3334
3356 if (auto_footnotes_p)
3357 info_get_or_remove_footnotes (active_window);
3335 if (auto_footnotes_p)
3336 info_get_or_remove_footnotes (active_window);
3358
3337
3359 isearch_is_active = 0;
3360 continue;
3361 }
3338 isearch_is_active = 0;
3339 continue;
3340 }
3362
3363 /* Search for the contents of isearch_string. */
3364 search_now:
3365 show_isearch_prompt (dir, isearch_string, search_result);
3366
3367 if (search_result == 0)
3341
3342 /* Search for the contents of isearch_string. */
3343 search_now:
3344 show_isearch_prompt (dir, isearch_string, search_result);
3345
3346 if (search_result == 0)
3368 {
3369 /* Check to see if the current search string is right here. If
3370 we are looking at it, then don't bother calling the search
3371 function. */
3372 if (((dir < 0) &&
3373 (strncasecmp (window->node->contents + window->point,
3374 isearch_string, isearch_string_index) == 0)) ||
3375 ((dir > 0) &&
3376 ((window->point - isearch_string_index) >= 0) &&
3377 (strncasecmp (window->node->contents +
3378 (window->point - (isearch_string_index - 1)),
3379 isearch_string, isearch_string_index) == 0)))
3380 {
3381 if (dir > 0)
3382 window->point++;
3383 }
3384 else
3385 search_result = info_search_internal (isearch_string, window, dir);
3386 }
3347 {
3348 /* Check to see if the current search string is right here. If
3349 we are looking at it, then don't bother calling the search
3350 function. */
3351 if (((dir < 0) &&
3352 (strncasecmp (window->node->contents + window->point,
3353 isearch_string, isearch_string_index) == 0)) ||
3354 ((dir > 0) &&
3355 ((window->point - isearch_string_index) >= 0) &&
3356 (strncasecmp (window->node->contents +
3357 (window->point - (isearch_string_index - 1)),
3358 isearch_string, isearch_string_index) == 0)))
3359 {
3360 if (dir > 0)
3361 window->point++;
3362 }
3363 else
3364 search_result = info_search_internal (isearch_string, window, dir);
3365 }
3387
3388 /* If this search failed, and we didn't already have a failed search,
3366
3367 /* If this search failed, and we didn't already have a failed search,
3389 then ring the terminal bell. */
3368 then ring the terminal bell. */
3390 if (search_result != 0 && last_search_result == 0)
3369 if (search_result != 0 && last_search_result == 0)
3391 terminal_ring_bell ();
3370 terminal_ring_bell ();
3392
3393 after_search:
3394 show_isearch_prompt (dir, isearch_string, search_result);
3395
3396 if (search_result == 0)
3371
3372 after_search:
3373 show_isearch_prompt (dir, isearch_string, search_result);
3374
3375 if (search_result == 0)
3397 {
3398 if ((mystate.node == window->node) &&
3399 (mystate.pagetop != window->pagetop))
3400 {
3401 int newtop = window->pagetop;
3402 window->pagetop = mystate.pagetop;
3403 set_window_pagetop (window, newtop);
3404 }
3405 display_update_one_window (window);
3406 display_cursor_at_point (window);
3407 }
3376 {
3377 if ((mystate.node == window->node) &&
3378 (mystate.pagetop != window->pagetop))
3379 {
3380 int newtop = window->pagetop;
3381 window->pagetop = mystate.pagetop;
3382 set_window_pagetop (window, newtop);
3383 }
3384 display_update_one_window (window);
3385 display_cursor_at_point (window);
3386 }
3408
3409 last_search_result = search_result;
3410 }
3411
3412 /* Free the memory used to remember each search state. */
3413 free_isearch_states ();
3414
3415 /* Perhaps GC some file buffers. */

--- 13 unchanged lines hidden (view full) ---

3429{
3430 register int fb_index, iw_index, i;
3431 register FILE_BUFFER *fb;
3432 register INFO_WINDOW *iw;
3433
3434 if (!info_loaded_files)
3435 return;
3436
3387
3388 last_search_result = search_result;
3389 }
3390
3391 /* Free the memory used to remember each search state. */
3392 free_isearch_states ();
3393
3394 /* Perhaps GC some file buffers. */

--- 13 unchanged lines hidden (view full) ---

3408{
3409 register int fb_index, iw_index, i;
3410 register FILE_BUFFER *fb;
3411 register INFO_WINDOW *iw;
3412
3413 if (!info_loaded_files)
3414 return;
3415
3437 for (fb_index = 0; fb = info_loaded_files[fb_index]; fb_index++)
3416 for (fb_index = 0; (fb = info_loaded_files[fb_index]); fb_index++)
3438 {
3439 int fb_referenced_p = 0;
3440
3441 /* If already gc-ed, do nothing. */
3442 if (!fb->contents)
3417 {
3418 int fb_referenced_p = 0;
3419
3420 /* If already gc-ed, do nothing. */
3421 if (!fb->contents)
3443 continue;
3422 continue;
3444
3445 /* If this file had to be uncompressed, check to see if we should
3423
3424 /* If this file had to be uncompressed, check to see if we should
3446 gc it. This means that the user-variable "gc-compressed-files"
3447 is non-zero. */
3425 gc it. This means that the user-variable "gc-compressed-files"
3426 is non-zero. */
3448 if ((fb->flags & N_IsCompressed) && !gc_compressed_files)
3427 if ((fb->flags & N_IsCompressed) && !gc_compressed_files)
3449 continue;
3428 continue;
3450
3451 /* If this file's contents are not gc-able, move on. */
3452 if (fb->flags & N_CannotGC)
3429
3430 /* If this file's contents are not gc-able, move on. */
3431 if (fb->flags & N_CannotGC)
3453 continue;
3432 continue;
3454
3455 /* Check each INFO_WINDOW to see if it has any nodes which reference
3433
3434 /* Check each INFO_WINDOW to see if it has any nodes which reference
3456 this file. */
3457 for (iw_index = 0; iw = info_windows[iw_index]; iw_index++)
3458 {
3459 for (i = 0; iw->nodes && iw->nodes[i]; i++)
3460 {
3461 if ((strcmp (fb->fullpath, iw->nodes[i]->filename) == 0) ||
3462 (strcmp (fb->filename, iw->nodes[i]->filename) == 0))
3463 {
3464 fb_referenced_p = 1;
3465 break;
3466 }
3467 }
3468 }
3435 this file. */
3436 for (iw_index = 0; (iw = info_windows[iw_index]); iw_index++)
3437 {
3438 for (i = 0; iw->nodes && iw->nodes[i]; i++)
3439 {
3440 if ((strcmp (fb->fullpath, iw->nodes[i]->filename) == 0) ||
3441 (strcmp (fb->filename, iw->nodes[i]->filename) == 0))
3442 {
3443 fb_referenced_p = 1;
3444 break;
3445 }
3446 }
3447 }
3469
3470 /* If this file buffer wasn't referenced, free its contents. */
3471 if (!fb_referenced_p)
3448
3449 /* If this file buffer wasn't referenced, free its contents. */
3450 if (!fb_referenced_p)
3472 {
3473 free (fb->contents);
3474 fb->contents = (char *)NULL;
3475 }
3451 {
3452 free (fb->contents);
3453 fb->contents = (char *)NULL;
3454 }
3476 }
3477}
3478
3479/* **************************************************************** */
3455 }
3456}
3457
3458/* **************************************************************** */
3480/* */
3481/* Traversing and Selecting References */
3482/* */
3459/* */
3460/* Traversing and Selecting References */
3461/* */
3483/* **************************************************************** */
3484
3485/* Move to the next or previous cross reference in this node. */
3486static void
3487info_move_to_xref (window, count, key, dir)
3488 WINDOW *window;
3489 int count;
3490 unsigned char key;

--- 18 unchanged lines hidden (view full) ---

3509 /* FIRSTMENU may point directly to the line defining the menu. Skip that
3510 and go directly to the first item. */
3511
3512 if (firstmenu != -1)
3513 {
3514 char *text = node->contents + firstmenu;
3515
3516 if (strncmp (text, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)) == 0)
3462/* **************************************************************** */
3463
3464/* Move to the next or previous cross reference in this node. */
3465static void
3466info_move_to_xref (window, count, key, dir)
3467 WINDOW *window;
3468 int count;
3469 unsigned char key;

--- 18 unchanged lines hidden (view full) ---

3488 /* FIRSTMENU may point directly to the line defining the menu. Skip that
3489 and go directly to the first item. */
3490
3491 if (firstmenu != -1)
3492 {
3493 char *text = node->contents + firstmenu;
3494
3495 if (strncmp (text, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)) == 0)
3517 firstmenu = info_search_in_node
3518 (INFO_MENU_ENTRY_LABEL, node, firstmenu + dir, (WINDOW *)NULL, dir);
3496 firstmenu = info_search_in_node
3497 (INFO_MENU_ENTRY_LABEL, node, firstmenu + dir, (WINDOW *)NULL, dir);
3519 }
3520
3521 firstxref =
3522 info_search_in_node (INFO_XREF_LABEL, node, start, (WINDOW *)NULL, dir);
3523
3524#if defined (HANDLE_MAN_PAGES)
3525 if ((firstxref == -1) && (node->flags & N_IsManPage))
3526 {
3527 firstxref = locate_manpage_xref (node, start, dir);
3528 }
3529#endif /* HANDLE_MAN_PAGES */
3530
3531 if (firstmenu == -1 && firstxref == -1)
3532 {
3498 }
3499
3500 firstxref =
3501 info_search_in_node (INFO_XREF_LABEL, node, start, (WINDOW *)NULL, dir);
3502
3503#if defined (HANDLE_MAN_PAGES)
3504 if ((firstxref == -1) && (node->flags & N_IsManPage))
3505 {
3506 firstxref = locate_manpage_xref (node, start, dir);
3507 }
3508#endif /* HANDLE_MAN_PAGES */
3509
3510 if (firstmenu == -1 && firstxref == -1)
3511 {
3533 info_error ("No cross references in this node.");
3512 info_error (_("No cross references in this node."));
3534 return;
3535 }
3536
3537 /* There is at least one cross reference or menu entry in this node.
3538 Try hard to find the next available one. */
3539
3540 nextmenu = info_search_in_node
3541 (INFO_MENU_ENTRY_LABEL, node, window->point + dir, (WINDOW *)NULL, dir);

--- 7 unchanged lines hidden (view full) ---

3549#endif /* HANDLE_MAN_PAGES */
3550
3551 /* Ignore "Menu:" as a menu item. */
3552 if (nextmenu != -1)
3553 {
3554 char *text = node->contents + nextmenu;
3555
3556 if (strncmp (text, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)) == 0)
3513 return;
3514 }
3515
3516 /* There is at least one cross reference or menu entry in this node.
3517 Try hard to find the next available one. */
3518
3519 nextmenu = info_search_in_node
3520 (INFO_MENU_ENTRY_LABEL, node, window->point + dir, (WINDOW *)NULL, dir);

--- 7 unchanged lines hidden (view full) ---

3528#endif /* HANDLE_MAN_PAGES */
3529
3530 /* Ignore "Menu:" as a menu item. */
3531 if (nextmenu != -1)
3532 {
3533 char *text = node->contents + nextmenu;
3534
3535 if (strncmp (text, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)) == 0)
3557 nextmenu = info_search_in_node
3558 (INFO_MENU_ENTRY_LABEL, node, nextmenu + dir, (WINDOW *)NULL, dir);
3536 nextmenu = info_search_in_node
3537 (INFO_MENU_ENTRY_LABEL, node, nextmenu + dir, (WINDOW *)NULL, dir);
3559 }
3560
3561 /* If there is both a next menu entry, and a next xref entry, choose the
3562 one which occurs first. Otherwise, select the one which actually
3563 appears in this node following point. */
3564 if (nextmenu != -1 && nextxref != -1)
3565 {
3566 if (((dir == 1) && (nextmenu < nextxref)) ||
3538 }
3539
3540 /* If there is both a next menu entry, and a next xref entry, choose the
3541 one which occurs first. Otherwise, select the one which actually
3542 appears in this node following point. */
3543 if (nextmenu != -1 && nextxref != -1)
3544 {
3545 if (((dir == 1) && (nextmenu < nextxref)) ||
3567 ((dir == -1) && (nextmenu > nextxref)))
3568 placement = nextmenu + 1;
3546 ((dir == -1) && (nextmenu > nextxref)))
3547 placement = nextmenu + 1;
3569 else
3548 else
3570 placement = nextxref;
3549 placement = nextxref;
3571 }
3572 else if (nextmenu != -1)
3573 placement = nextmenu + 1;
3574 else if (nextxref != -1)
3575 placement = nextxref;
3576
3577 /* If there was neither a menu or xref entry appearing in this node after
3578 point, choose the first menu or xref entry appearing in this node. */
3579 if (placement == -1)
3580 {
3581 if (firstmenu != -1 && firstxref != -1)
3550 }
3551 else if (nextmenu != -1)
3552 placement = nextmenu + 1;
3553 else if (nextxref != -1)
3554 placement = nextxref;
3555
3556 /* If there was neither a menu or xref entry appearing in this node after
3557 point, choose the first menu or xref entry appearing in this node. */
3558 if (placement == -1)
3559 {
3560 if (firstmenu != -1 && firstxref != -1)
3582 {
3583 if (((dir == 1) && (firstmenu < firstxref)) ||
3584 ((dir == -1) && (firstmenu > firstxref)))
3585 placement = firstmenu + 1;
3586 else
3587 placement = firstxref;
3588 }
3561 {
3562 if (((dir == 1) && (firstmenu < firstxref)) ||
3563 ((dir == -1) && (firstmenu > firstxref)))
3564 placement = firstmenu + 1;
3565 else
3566 placement = firstxref;
3567 }
3589 else if (firstmenu != -1)
3568 else if (firstmenu != -1)
3590 placement = firstmenu + 1;
3569 placement = firstmenu + 1;
3591 else
3570 else
3592 placement = firstxref;
3571 placement = firstxref;
3593 }
3594 window->point = placement;
3595 window_adjust_pagetop (window);
3596 window->flags |= W_UpdateWindow;
3597}
3598
3599DECLARE_INFO_COMMAND (info_move_to_prev_xref,
3572 }
3573 window->point = placement;
3574 window_adjust_pagetop (window);
3575 window->flags |= W_UpdateWindow;
3576}
3577
3578DECLARE_INFO_COMMAND (info_move_to_prev_xref,
3600 "Move to the previous cross reference")
3579 _("Move to the previous cross reference"))
3601{
3602 if (count < 0)
3603 info_move_to_prev_xref (window, -count, key);
3604 else
3605 info_move_to_xref (window, count, key, -1);
3606}
3607
3608DECLARE_INFO_COMMAND (info_move_to_next_xref,
3580{
3581 if (count < 0)
3582 info_move_to_prev_xref (window, -count, key);
3583 else
3584 info_move_to_xref (window, count, key, -1);
3585}
3586
3587DECLARE_INFO_COMMAND (info_move_to_next_xref,
3609 "Move to the next cross reference")
3588 _("Move to the next cross reference"))
3610{
3611 if (count < 0)
3612 info_move_to_next_xref (window, -count, key);
3613 else
3614 info_move_to_xref (window, count, key, 1);
3615}
3616
3617/* Select the menu item or reference that appears on this line. */
3618DECLARE_INFO_COMMAND (info_select_reference_this_line,
3589{
3590 if (count < 0)
3591 info_move_to_next_xref (window, -count, key);
3592 else
3593 info_move_to_xref (window, count, key, 1);
3594}
3595
3596/* Select the menu item or reference that appears on this line. */
3597DECLARE_INFO_COMMAND (info_select_reference_this_line,
3619 "Select reference or menu item appearing on this line")
3598 _("Select reference or menu item appearing on this line"))
3620{
3621 char *line;
3622 NODE *orig;
3623
3624 line = window->line_starts[window_line_of_point (window)];
3625 orig = window->node;
3626
3627 /* If this line contains a menu item, select that one. */
3628 if (strncmp ("* ", line, 2) == 0)
3629 info_menu_or_ref_item (window, count, key, info_menu_of_node, 0);
3630 else
3631 info_menu_or_ref_item (window, count, key, info_xrefs_of_node, 0);
3632}
3633
3634/* **************************************************************** */
3599{
3600 char *line;
3601 NODE *orig;
3602
3603 line = window->line_starts[window_line_of_point (window)];
3604 orig = window->node;
3605
3606 /* If this line contains a menu item, select that one. */
3607 if (strncmp ("* ", line, 2) == 0)
3608 info_menu_or_ref_item (window, count, key, info_menu_of_node, 0);
3609 else
3610 info_menu_or_ref_item (window, count, key, info_xrefs_of_node, 0);
3611}
3612
3613/* **************************************************************** */
3635/* */
3636/* Miscellaneous Info Commands */
3637/* */
3614/* */
3615/* Miscellaneous Info Commands */
3616/* */
3638/* **************************************************************** */
3639
3640/* What to do when C-g is pressed in a window. */
3617/* **************************************************************** */
3618
3619/* What to do when C-g is pressed in a window. */
3641DECLARE_INFO_COMMAND (info_abort_key, "Cancel current operation")
3620DECLARE_INFO_COMMAND (info_abort_key, _("Cancel current operation"))
3642{
3643 /* If error printing doesn't oridinarily ring the bell, do it now,
3644 since C-g always rings the bell. Otherwise, let the error printer
3645 do it. */
3646 if (!info_error_rings_bell_p)
3647 terminal_ring_bell ();
3621{
3622 /* If error printing doesn't oridinarily ring the bell, do it now,
3623 since C-g always rings the bell. Otherwise, let the error printer
3624 do it. */
3625 if (!info_error_rings_bell_p)
3626 terminal_ring_bell ();
3648 info_error ("Quit");
3627 info_error (_("Quit"));
3649
3650 info_initialize_numeric_arg ();
3651 info_clear_pending_input ();
3652 info_last_executed_command = (VFunction *)NULL;
3653}
3654
3655/* Move the cursor to the desired line of the window. */
3656DECLARE_INFO_COMMAND (info_move_to_window_line,
3628
3629 info_initialize_numeric_arg ();
3630 info_clear_pending_input ();
3631 info_last_executed_command = (VFunction *)NULL;
3632}
3633
3634/* Move the cursor to the desired line of the window. */
3635DECLARE_INFO_COMMAND (info_move_to_window_line,
3657 "Move to the cursor to a specific line of the window")
3636 _("Move to the cursor to a specific line of the window"))
3658{
3659 int line;
3660
3661 /* With no numeric argument of any kind, default to the center line. */
3662 if (!info_explicit_arg && count == 1)
3663 line = (window->height / 2) + window->pagetop;
3664 else
3665 {
3666 if (count < 0)
3637{
3638 int line;
3639
3640 /* With no numeric argument of any kind, default to the center line. */
3641 if (!info_explicit_arg && count == 1)
3642 line = (window->height / 2) + window->pagetop;
3643 else
3644 {
3645 if (count < 0)
3667 line = (window->height + count) + window->pagetop;
3646 line = (window->height + count) + window->pagetop;
3668 else
3647 else
3669 line = window->pagetop + count;
3648 line = window->pagetop + count;
3670 }
3671
3672 /* If the line doesn't appear in this window, make it do so. */
3673 if ((line - window->pagetop) >= window->height)
3674 line = window->pagetop + (window->height - 1);
3675
3676 /* If the line is too small, make it fit. */
3677 if (line < window->pagetop)
3678 line = window->pagetop;
3679
3680 /* If the selected line is past the bottom of the node, force it back. */
3681 if (line >= window->line_count)
3682 line = window->line_count - 1;
3683
3684 window->point = (window->line_starts[line] - window->node->contents);
3685}
3686
3687/* Clear the screen and redraw its contents. Given a numeric argument,
3688 move the line the cursor is on to the COUNT'th line of the window. */
3649 }
3650
3651 /* If the line doesn't appear in this window, make it do so. */
3652 if ((line - window->pagetop) >= window->height)
3653 line = window->pagetop + (window->height - 1);
3654
3655 /* If the line is too small, make it fit. */
3656 if (line < window->pagetop)
3657 line = window->pagetop;
3658
3659 /* If the selected line is past the bottom of the node, force it back. */
3660 if (line >= window->line_count)
3661 line = window->line_count - 1;
3662
3663 window->point = (window->line_starts[line] - window->node->contents);
3664}
3665
3666/* Clear the screen and redraw its contents. Given a numeric argument,
3667 move the line the cursor is on to the COUNT'th line of the window. */
3689DECLARE_INFO_COMMAND (info_redraw_display, "Redraw the display")
3668DECLARE_INFO_COMMAND (info_redraw_display, _("Redraw the display"))
3690{
3691 if ((!info_explicit_arg && count == 1) || echo_area_is_active)
3692 {
3693 terminal_clear_screen ();
3694 display_clear_display (the_display);
3695 window_mark_chain (windows, W_UpdateWindow);
3696 display_update_display (windows);
3697 }
3698 else
3699 {
3700 int desired_line, point_line;
3701 int new_pagetop;
3702
3703 point_line = window_line_of_point (window) - window->pagetop;
3704
3705 if (count < 0)
3669{
3670 if ((!info_explicit_arg && count == 1) || echo_area_is_active)
3671 {
3672 terminal_clear_screen ();
3673 display_clear_display (the_display);
3674 window_mark_chain (windows, W_UpdateWindow);
3675 display_update_display (windows);
3676 }
3677 else
3678 {
3679 int desired_line, point_line;
3680 int new_pagetop;
3681
3682 point_line = window_line_of_point (window) - window->pagetop;
3683
3684 if (count < 0)
3706 desired_line = window->height + count;
3685 desired_line = window->height + count;
3707 else
3686 else
3708 desired_line = count;
3687 desired_line = count;
3709
3710 if (desired_line < 0)
3688
3689 if (desired_line < 0)
3711 desired_line = 0;
3690 desired_line = 0;
3712
3713 if (desired_line >= window->height)
3691
3692 if (desired_line >= window->height)
3714 desired_line = window->height - 1;
3693 desired_line = window->height - 1;
3715
3716 if (desired_line == point_line)
3694
3695 if (desired_line == point_line)
3717 return;
3696 return;
3718
3719 new_pagetop = window->pagetop + (point_line - desired_line);
3720
3721 set_window_pagetop (window, new_pagetop);
3722 }
3723}
3724/* This command does nothing. It is the fact that a key is bound to it
3725 that has meaning. See the code at the top of info_session (). */
3697
3698 new_pagetop = window->pagetop + (point_line - desired_line);
3699
3700 set_window_pagetop (window, new_pagetop);
3701 }
3702}
3703/* This command does nothing. It is the fact that a key is bound to it
3704 that has meaning. See the code at the top of info_session (). */
3726DECLARE_INFO_COMMAND (info_quit, "Quit using Info")
3705DECLARE_INFO_COMMAND (info_quit, _("Quit using Info"))
3727{}
3728
3729
3730/* **************************************************************** */
3706{}
3707
3708
3709/* **************************************************************** */
3731/* */
3732/* Reading Keys and Dispatching on Them */
3733/* */
3710/* */
3711/* Reading Keys and Dispatching on Them */
3712/* */
3734/* **************************************************************** */
3735
3736/* Declaration only. Special cased in info_dispatch_on_key (). */
3737DECLARE_INFO_COMMAND (info_do_lowercase_version, "")
3738{}
3739
3740static void
3741dispatch_error (keyseq)
3742 char *keyseq;
3743{
3744 char *rep;
3745
3746 rep = pretty_keyseq (keyseq);
3747
3748 if (!echo_area_is_active)
3713/* **************************************************************** */
3714
3715/* Declaration only. Special cased in info_dispatch_on_key (). */
3716DECLARE_INFO_COMMAND (info_do_lowercase_version, "")
3717{}
3718
3719static void
3720dispatch_error (keyseq)
3721 char *keyseq;
3722{
3723 char *rep;
3724
3725 rep = pretty_keyseq (keyseq);
3726
3727 if (!echo_area_is_active)
3749 info_error ("Unknown command (%s).", rep);
3728 info_error (_("Unknown command (%s)."), rep);
3750 else
3751 {
3752 char *temp;
3753
3729 else
3730 {
3731 char *temp;
3732
3754 temp = (char *)xmalloc (1 + strlen (rep) + strlen ("\"\" is invalid"));
3733 temp = (char *)xmalloc (1 + strlen (rep) + strlen (_("\"\" is invalid")));
3755
3734
3756 sprintf (temp, "\"%s\" is invalid", rep);
3735 sprintf (temp, _("\"%s\" is invalid"), rep);
3757 terminal_ring_bell ();
3758 inform_in_echo_area (temp);
3759 free (temp);
3760 }
3761}
3762
3763/* Keeping track of key sequences. */
3764static char *info_keyseq = (char *)NULL;

--- 29 unchanged lines hidden (view full) ---

3794{
3795 register int i;
3796
3797 keyseq_rep[0] = '\0';
3798
3799 for (i = 0; keyseq[i]; i++)
3800 {
3801 sprintf (keyseq_rep + strlen (keyseq_rep), "%s%s",
3736 terminal_ring_bell ();
3737 inform_in_echo_area (temp);
3738 free (temp);
3739 }
3740}
3741
3742/* Keeping track of key sequences. */
3743static char *info_keyseq = (char *)NULL;

--- 29 unchanged lines hidden (view full) ---

3773{
3774 register int i;
3775
3776 keyseq_rep[0] = '\0';
3777
3778 for (i = 0; keyseq[i]; i++)
3779 {
3780 sprintf (keyseq_rep + strlen (keyseq_rep), "%s%s",
3802 strlen (keyseq_rep) ? " " : "",
3803 pretty_keyname (keyseq[i]));
3781 strlen (keyseq_rep) ? " " : "",
3782 pretty_keyname (keyseq[i]));
3804 }
3805
3806 return (keyseq_rep);
3807}
3808
3809/* Display the current value of info_keyseq. If argument EXPECTING is
3810 non-zero, input is expected to be read after the key sequence is
3811 displayed, so add an additional prompting character to the sequence. */

--- 16 unchanged lines hidden (view full) ---

3828 }
3829 info_keyseq_displayed_p = 1;
3830}
3831
3832/* Called by interactive commands to read a keystroke. */
3833unsigned char
3834info_get_another_input_char ()
3835{
3783 }
3784
3785 return (keyseq_rep);
3786}
3787
3788/* Display the current value of info_keyseq. If argument EXPECTING is
3789 non-zero, input is expected to be read after the key sequence is
3790 displayed, so add an additional prompting character to the sequence. */

--- 16 unchanged lines hidden (view full) ---

3807 }
3808 info_keyseq_displayed_p = 1;
3809}
3810
3811/* Called by interactive commands to read a keystroke. */
3812unsigned char
3813info_get_another_input_char ()
3814{
3836 int ready = 0;
3815 int ready = !info_keyseq_displayed_p; /* ready if new and pending key */
3837
3838 /* If there isn't any input currently available, then wait a
3839 moment looking for input. If we don't get it fast enough,
3840 prompt a little bit with the current key sequence. */
3816
3817 /* If there isn't any input currently available, then wait a
3818 moment looking for input. If we don't get it fast enough,
3819 prompt a little bit with the current key sequence. */
3841 if (!info_keyseq_displayed_p &&
3842 !info_any_buffered_input_p () &&
3843 !info_input_pending_p ())
3820 if (!info_keyseq_displayed_p)
3844 {
3821 {
3822 ready = 1;
3823 if (!info_any_buffered_input_p () &&
3824 !info_input_pending_p ())
3825 {
3845#if defined (FD_SET)
3826#if defined (FD_SET)
3846 struct timeval timer;
3847 fd_set readfds;
3827 struct timeval timer;
3828 fd_set readfds;
3848
3829
3849 FD_ZERO (&readfds);
3850 FD_SET (fileno (info_input_stream), &readfds);
3851 timer.tv_sec = 0;
3852 timer.tv_usec = 0;
3853 ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
3830 FD_ZERO (&readfds);
3831 FD_SET (fileno (info_input_stream), &readfds);
3832 timer.tv_sec = 1;
3833 timer.tv_usec = 750;
3834 ready = select (fileno(info_input_stream)+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
3835#else
3836 ready = 0;
3854#endif /* FD_SET */
3837#endif /* FD_SET */
3838 }
3855 }
3856
3857 if (!ready)
3858 display_info_keyseq (1);
3859
3860 return (info_get_input_char ());
3861}
3862
3863/* Do the command associated with KEY in MAP. If the associated command is
3864 really a keymap, then read another key, and dispatch into that map. */
3865void
3866info_dispatch_on_key (key, map)
3867 unsigned char key;
3868 Keymap map;
3869{
3870 if (Meta_p (key) && (!ISO_Latin_p || map[key].function != ea_insert))
3871 {
3872 if (map[ESC].type == ISKMAP)
3839 }
3840
3841 if (!ready)
3842 display_info_keyseq (1);
3843
3844 return (info_get_input_char ());
3845}
3846
3847/* Do the command associated with KEY in MAP. If the associated command is
3848 really a keymap, then read another key, and dispatch into that map. */
3849void
3850info_dispatch_on_key (key, map)
3851 unsigned char key;
3852 Keymap map;
3853{
3854 if (Meta_p (key) && (!ISO_Latin_p || map[key].function != ea_insert))
3855 {
3856 if (map[ESC].type == ISKMAP)
3873 {
3874 map = (Keymap)map[ESC].function;
3875 add_char_to_keyseq (ESC);
3876 key = UnMeta (key);
3877 info_dispatch_on_key (key, map);
3878 }
3857 {
3858 map = (Keymap)map[ESC].function;
3859 add_char_to_keyseq (ESC);
3860 key = UnMeta (key);
3861 info_dispatch_on_key (key, map);
3862 }
3879 else
3863 else
3880 {
3881 dispatch_error (info_keyseq);
3882 }
3864 {
3865 dispatch_error (info_keyseq);
3866 }
3883 return;
3884 }
3885
3886 switch (map[key].type)
3887 {
3888 case ISFUNC:
3889 {
3867 return;
3868 }
3869
3870 switch (map[key].type)
3871 {
3872 case ISFUNC:
3873 {
3890 VFunction *func;
3874 VFunction *func;
3891
3875
3892 func = map[key].function;
3893 if (func != (VFunction *)NULL)
3894 {
3895 /* Special case info_do_lowercase_version (). */
3896 if (func == info_do_lowercase_version)
3897 {
3898 info_dispatch_on_key (tolower (key), map);
3899 return;
3900 }
3876 func = map[key].function;
3877 if (func != (VFunction *)NULL)
3878 {
3879 /* Special case info_do_lowercase_version (). */
3880 if (func == info_do_lowercase_version)
3881 {
3882 info_dispatch_on_key (tolower (key), map);
3883 return;
3884 }
3901
3885
3902 add_char_to_keyseq (key);
3886 add_char_to_keyseq (key);
3903
3887
3904 if (info_keyseq_displayed_p)
3905 display_info_keyseq (0);
3888 if (info_keyseq_displayed_p)
3889 display_info_keyseq (0);
3906
3890
3907 {
3908 WINDOW *where;
3891 {
3892 WINDOW *where;
3909
3893
3910 where = active_window;
3911 (*map[key].function)
3912 (active_window, info_numeric_arg * info_numeric_arg_sign, key);
3894 where = active_window;
3895 (*map[key].function)
3896 (active_window, info_numeric_arg * info_numeric_arg_sign, key);
3913
3897
3914 /* If we have input pending, then the last command was a prefix
3915 command. Don't change the value of the last function vars.
3916 Otherwise, remember the last command executed in the var
3917 appropriate to the window in which it was executed. */
3918 if (!info_input_pending_p ())
3919 {
3920 if (where == the_echo_area)
3921 ea_last_executed_command = map[key].function;
3922 else
3923 info_last_executed_command = map[key].function;
3924 }
3925 }
3926 }
3927 else
3928 {
3929 add_char_to_keyseq (key);
3930 dispatch_error (info_keyseq);
3931 return;
3932 }
3898 /* If we have input pending, then the last command was a prefix
3899 command. Don't change the value of the last function vars.
3900 Otherwise, remember the last command executed in the var
3901 appropriate to the window in which it was executed. */
3902 if (!info_input_pending_p ())
3903 {
3904 if (where == the_echo_area)
3905 ea_last_executed_command = map[key].function;
3906 else
3907 info_last_executed_command = map[key].function;
3908 }
3909 }
3910 }
3911 else
3912 {
3913 add_char_to_keyseq (key);
3914 dispatch_error (info_keyseq);
3915 return;
3916 }
3933 }
3934 break;
3935
3936 case ISKMAP:
3937 add_char_to_keyseq (key);
3938 if (map[key].function != (VFunction *)NULL)
3917 }
3918 break;
3919
3920 case ISKMAP:
3921 add_char_to_keyseq (key);
3922 if (map[key].function != (VFunction *)NULL)
3939 {
3940 unsigned char newkey;
3923 {
3924 unsigned char newkey;
3941
3925
3942 newkey = info_get_another_input_char ();
3943 info_dispatch_on_key (newkey, (Keymap)map[key].function);
3944 }
3926 newkey = info_get_another_input_char ();
3927 info_dispatch_on_key (newkey, (Keymap)map[key].function);
3928 }
3945 else
3929 else
3946 {
3947 dispatch_error (info_keyseq);
3948 return;
3949 }
3930 {
3931 dispatch_error (info_keyseq);
3932 return;
3933 }
3950 break;
3951 }
3952}
3953
3954/* **************************************************************** */
3934 break;
3935 }
3936}
3937
3938/* **************************************************************** */
3955/* */
3956/* Numeric Arguments */
3957/* */
3939/* */
3940/* Numeric Arguments */
3941/* */
3958/* **************************************************************** */
3959
3960/* Handle C-u style numeric args, as well as M--, and M-digits. */
3961
3962/* Non-zero means that an explicit argument has been passed to this
3963 command, as in C-u C-v. */
3964int info_explicit_arg = 0;
3965
3966/* The sign of the numeric argument. */
3967int info_numeric_arg_sign = 1;
3968
3969/* The value of the argument itself. */
3970int info_numeric_arg = 1;
3971
3972/* Add the current digit to the argument in progress. */
3973DECLARE_INFO_COMMAND (info_add_digit_to_numeric_arg,
3942/* **************************************************************** */
3943
3944/* Handle C-u style numeric args, as well as M--, and M-digits. */
3945
3946/* Non-zero means that an explicit argument has been passed to this
3947 command, as in C-u C-v. */
3948int info_explicit_arg = 0;
3949
3950/* The sign of the numeric argument. */
3951int info_numeric_arg_sign = 1;
3952
3953/* The value of the argument itself. */
3954int info_numeric_arg = 1;
3955
3956/* Add the current digit to the argument in progress. */
3957DECLARE_INFO_COMMAND (info_add_digit_to_numeric_arg,
3974 "Add this digit to the current numeric argument")
3958 _("Add this digit to the current numeric argument"))
3975{
3976 info_numeric_arg_digit_loop (window, 0, key);
3977}
3978
3979/* C-u, universal argument. Multiply the current argument by 4.
3980 Read a key. If the key has nothing to do with arguments, then
3981 dispatch on it. If the key is the abort character then abort. */
3982DECLARE_INFO_COMMAND (info_universal_argument,
3959{
3960 info_numeric_arg_digit_loop (window, 0, key);
3961}
3962
3963/* C-u, universal argument. Multiply the current argument by 4.
3964 Read a key. If the key has nothing to do with arguments, then
3965 dispatch on it. If the key is the abort character then abort. */
3966DECLARE_INFO_COMMAND (info_universal_argument,
3983 "Start (or multiply by 4) the current numeric argument")
3967 _("Start (or multiply by 4) the current numeric argument"))
3984{
3985 info_numeric_arg *= 4;
3986 info_numeric_arg_digit_loop (window, 0, 0);
3987}
3988
3989/* Create a default argument. */
3990void
3991info_initialize_numeric_arg ()
3992{
3993 info_numeric_arg = info_numeric_arg_sign = 1;
3994 info_explicit_arg = 0;
3995}
3996
3997DECLARE_INFO_COMMAND (info_numeric_arg_digit_loop,
3968{
3969 info_numeric_arg *= 4;
3970 info_numeric_arg_digit_loop (window, 0, 0);
3971}
3972
3973/* Create a default argument. */
3974void
3975info_initialize_numeric_arg ()
3976{
3977 info_numeric_arg = info_numeric_arg_sign = 1;
3978 info_explicit_arg = 0;
3979}
3980
3981DECLARE_INFO_COMMAND (info_numeric_arg_digit_loop,
3998 "Internally used by \\[universal-argument]")
3982 _("Internally used by \\[universal-argument]"))
3999{
4000 unsigned char pure_key;
4001 Keymap keymap = window->keymap;
4002
4003 while (1)
4004 {
4005 if (key)
3983{
3984 unsigned char pure_key;
3985 Keymap keymap = window->keymap;
3986
3987 while (1)
3988 {
3989 if (key)
4006 pure_key = key;
3990 pure_key = key;
4007 else
3991 else
4008 {
4009 if (display_was_interrupted_p && !info_any_buffered_input_p ())
4010 display_update_display (windows);
3992 {
3993 if (display_was_interrupted_p && !info_any_buffered_input_p ())
3994 display_update_display (windows);
4011
3995
4012 if (active_window != the_echo_area)
4013 display_cursor_at_point (active_window);
3996 if (active_window != the_echo_area)
3997 display_cursor_at_point (active_window);
4014
3998
4015 pure_key = key = info_get_another_input_char ();
3999 pure_key = key = info_get_another_input_char ();
4016
4000
4017 if (Meta_p (key))
4018 add_char_to_keyseq (ESC);
4001 if (Meta_p (key))
4002 add_char_to_keyseq (ESC);
4019
4003
4020 add_char_to_keyseq (UnMeta (key));
4021 }
4004 add_char_to_keyseq (UnMeta (key));
4005 }
4022
4023 if (Meta_p (key))
4006
4007 if (Meta_p (key))
4024 key = UnMeta (key);
4008 key = UnMeta (key);
4025
4026 if (keymap[key].type == ISFUNC &&
4009
4010 if (keymap[key].type == ISFUNC &&
4027 keymap[key].function == info_universal_argument)
4028 {
4029 info_numeric_arg *= 4;
4030 key = 0;
4031 continue;
4032 }
4011 keymap[key].function == info_universal_argument)
4012 {
4013 info_numeric_arg *= 4;
4014 key = 0;
4015 continue;
4016 }
4033
4034 if (isdigit (key))
4017
4018 if (isdigit (key))
4035 {
4036 if (info_explicit_arg)
4037 info_numeric_arg = (info_numeric_arg * 10) + (key - '0');
4038 else
4039 info_numeric_arg = (key - '0');
4040 info_explicit_arg = 1;
4041 }
4019 {
4020 if (info_explicit_arg)
4021 info_numeric_arg = (info_numeric_arg * 10) + (key - '0');
4022 else
4023 info_numeric_arg = (key - '0');
4024 info_explicit_arg = 1;
4025 }
4042 else
4026 else
4043 {
4044 if (key == '-' && !info_explicit_arg)
4045 {
4046 info_numeric_arg_sign = -1;
4047 info_numeric_arg = 1;
4048 }
4049 else
4050 {
4051 info_keyseq_index--;
4052 info_dispatch_on_key (pure_key, keymap);
4053 return;
4054 }
4055 }
4027 {
4028 if (key == '-' && !info_explicit_arg)
4029 {
4030 info_numeric_arg_sign = -1;
4031 info_numeric_arg = 1;
4032 }
4033 else
4034 {
4035 info_keyseq_index--;
4036 info_dispatch_on_key (pure_key, keymap);
4037 return;
4038 }
4039 }
4056 key = 0;
4057 }
4058}
4059
4060/* **************************************************************** */
4040 key = 0;
4041 }
4042}
4043
4044/* **************************************************************** */
4061/* */
4062/* Input Character Buffering */
4063/* */
4045/* */
4046/* Input Character Buffering */
4047/* */
4064/* **************************************************************** */
4065
4066/* Character waiting to be read next. */
4067static int pending_input_character = 0;
4068
4069/* How to make there be no pending input. */
4070static void
4071info_clear_pending_input ()

--- 32 unchanged lines hidden (view full) ---

4104 {
4105 push_index = pop_index;
4106 info_set_pending_input (Control ('g'));
4107 }
4108 else
4109 {
4110 info_input_buffer[push_index++] = key;
4111 if (push_index >= sizeof (info_input_buffer))
4048/* **************************************************************** */
4049
4050/* Character waiting to be read next. */
4051static int pending_input_character = 0;
4052
4053/* How to make there be no pending input. */
4054static void
4055info_clear_pending_input ()

--- 32 unchanged lines hidden (view full) ---

4088 {
4089 push_index = pop_index;
4090 info_set_pending_input (Control ('g'));
4091 }
4092 else
4093 {
4094 info_input_buffer[push_index++] = key;
4095 if (push_index >= sizeof (info_input_buffer))
4112 push_index = 0;
4096 push_index = 0;
4113 }
4114}
4115
4116/* Return the amount of space available in INFO_INPUT_BUFFER for new chars. */
4117static int
4118info_input_buffer_space_available ()
4119{
4120 if (pop_index > push_index)

--- 22 unchanged lines hidden (view full) ---

4143
4144int
4145info_any_buffered_input_p ()
4146{
4147 info_gather_typeahead ();
4148 return (push_index != pop_index);
4149}
4150
4097 }
4098}
4099
4100/* Return the amount of space available in INFO_INPUT_BUFFER for new chars. */
4101static int
4102info_input_buffer_space_available ()
4103{
4104 if (pop_index > push_index)

--- 22 unchanged lines hidden (view full) ---

4127
4128int
4129info_any_buffered_input_p ()
4130{
4131 info_gather_typeahead ();
4132 return (push_index != pop_index);
4133}
4134
4151/* Push KEY into the *front* of the input buffer. Returns non-zero if
4152 successful, zero if there is no space left in the buffer. */
4153static int
4154info_replace_key_to_typeahead (key)
4155 unsigned char key;
4156{
4157 if (info_input_buffer_space_available ())
4158 {
4159 pop_index--;
4160 if (pop_index < 0)
4161 pop_index = sizeof (info_input_buffer) - 1;
4162 info_input_buffer[pop_index] = key;
4163 return (1);
4164 }
4165 return (0);
4166}
4167
4168/* If characters are available to be read, then read them and stuff them into
4169 info_input_buffer. Otherwise, do nothing. */
4170void
4171info_gather_typeahead ()
4172{
4173 register int i = 0;
4174 int tty, space_avail;
4175 long chars_avail;

--- 8 unchanged lines hidden (view full) ---

4184#if defined (FIONREAD)
4185 {
4186 ioctl (tty, FIONREAD, &chars_avail);
4187
4188 if (chars_avail > space_avail)
4189 chars_avail = space_avail;
4190
4191 if (chars_avail)
4135/* If characters are available to be read, then read them and stuff them into
4136 info_input_buffer. Otherwise, do nothing. */
4137void
4138info_gather_typeahead ()
4139{
4140 register int i = 0;
4141 int tty, space_avail;
4142 long chars_avail;

--- 8 unchanged lines hidden (view full) ---

4151#if defined (FIONREAD)
4152 {
4153 ioctl (tty, FIONREAD, &chars_avail);
4154
4155 if (chars_avail > space_avail)
4156 chars_avail = space_avail;
4157
4158 if (chars_avail)
4192 read (tty, &input[0], chars_avail);
4159 chars_avail = read (tty, &input[0], chars_avail);
4193 }
4194#else /* !FIONREAD */
4195# if defined (O_NDELAY)
4196 {
4197 int flags;
4198
4199 flags = fcntl (tty, F_GETFL, 0);
4200

--- 25 unchanged lines hidden (view full) ---

4226 if (pending_input_character)
4227 {
4228 keystroke = pending_input_character;
4229 pending_input_character = 0;
4230 }
4231 else if (info_get_key_from_typeahead (&keystroke) == 0)
4232 {
4233 int rawkey;
4160 }
4161#else /* !FIONREAD */
4162# if defined (O_NDELAY)
4163 {
4164 int flags;
4165
4166 flags = fcntl (tty, F_GETFL, 0);
4167

--- 25 unchanged lines hidden (view full) ---

4193 if (pending_input_character)
4194 {
4195 keystroke = pending_input_character;
4196 pending_input_character = 0;
4197 }
4198 else if (info_get_key_from_typeahead (&keystroke) == 0)
4199 {
4200 int rawkey;
4201 unsigned char c;
4202 int tty = fileno (info_input_stream);
4234
4203
4235 rawkey = getc (info_input_stream);
4204 /* Using stream I/O causes FIONREAD etc to fail to work
4205 so unless someone can find a portable way of finding
4206 out how many characters are currently buffered, we
4207 should stay with away from stream I/O.
4208 --Egil Kvaleberg <egilk@sn.no>, January 1997. */
4209#ifdef EINTR
4210 /* Keep reading if we got EINTR, so that we don't just exit.
4211 --Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>,
4212 22 Dec 1997. */
4213 {
4214 int n;
4215 do
4216 n = read (tty, &c, 1);
4217 while (n == -1 && errno == EINTR);
4218 rawkey = n == 1 ? c : EOF;
4219 }
4220#else
4221 rawkey = (read (tty, &c, 1) == 1) ? c : EOF;
4222#endif
4223
4236 keystroke = rawkey;
4237
4238 if (rawkey == EOF)
4224 keystroke = rawkey;
4225
4226 if (rawkey == EOF)
4239 {
4240 if (info_input_stream != stdin)
4241 {
4242 fclose (info_input_stream);
4243 info_input_stream = stdin;
4244 display_inhibited = 0;
4245 display_update_display (windows);
4246 display_cursor_at_point (active_window);
4247 rawkey = getc (info_input_stream);
4248 keystroke = rawkey;
4249 }
4227 {
4228 if (info_input_stream != stdin)
4229 {
4230 fclose (info_input_stream);
4231 info_input_stream = stdin;
4232 display_inhibited = 0;
4233 display_update_display (windows);
4234 display_cursor_at_point (active_window);
4235 rawkey = (read (tty, &c, 1) == 1) ? c : EOF;
4236 keystroke = rawkey;
4237 }
4250
4238
4251 if (rawkey == EOF)
4252 {
4253 terminal_unprep_terminal ();
4254 close_dribble_file ();
4255 exit (0);
4256 }
4257 }
4239 if (rawkey == EOF)
4240 {
4241 terminal_unprep_terminal ();
4242 close_dribble_file ();
4243 exit (0);
4244 }
4245 }
4258 }
4259
4260 if (info_dribble_file)
4261 dribble (keystroke);
4262
4246 }
4247
4248 if (info_dribble_file)
4249 dribble (keystroke);
4250
4263 return (keystroke);
4251 return keystroke;
4264}
4252}