~ubuntu-branches/ubuntu/maverick/texinfo/maverick

« back to all changes in this revision

Viewing changes to info/session.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2005-10-28 15:10:30 UTC
  • mto: (2.1.1 dapper) (3.1.4 hardy)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20051028151030-9nsf2s2k2z3fktjt
Tags: upstream-4.8
ImportĀ upstreamĀ versionĀ 4.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* session.c -- user windowing interface to Info.
2
 
   $Id: session.c,v 1.45 2002/03/02 15:05:04 karl Exp $
 
2
   $Id: session.c,v 1.16 2004/12/14 00:15:36 karl Exp $
3
3
 
4
 
   Copyright (C) 1993, 96, 97, 98, 99, 2000, 01, 02
 
4
   Copyright (C) 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
5
5
   Free Software Foundation, Inc.
6
6
 
7
7
   This program is free software; you can redistribute it and/or modify
18
18
   along with this program; if not, write to the Free Software
19
19
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
20
 
21
 
   Written by Brian Fox (bfox@ai.mit.edu). */
 
21
   Originally written by Brian Fox (bfox@ai.mit.edu). */
22
22
 
23
23
#include "info.h"
 
24
#include "search.h"
24
25
#include <sys/ioctl.h>
25
26
 
26
27
#if defined (HAVE_SYS_TIME_H)
32
33
#  include "man.h"
33
34
#endif
34
35
 
35
 
#ifdef M_XENIX
36
 
/* SCO 3.2v5.0.2 defines but does not correctly declare strncasecmp.
37
 
   Since we use it as a symbol, have to get it right.  --gildea, 1jul99.  */
38
 
extern int strncasecmp (const char *, const char *, size_t);
39
 
#endif
40
 
 
41
 
static void info_clear_pending_input (), info_set_pending_input ();
42
 
static void info_handle_pointer ();
 
36
static void info_clear_pending_input (void);
 
37
static void info_set_pending_input (unsigned char key);
 
38
static void info_handle_pointer (char *label, WINDOW *window);
 
39
static void display_info_keyseq (int expecting_future_input);
 
40
char *node_printed_rep (NODE *node);
43
41
 
44
42
/* **************************************************************** */
45
43
/*                                                                  */
66
64
/* Number of slots allocated to `info_windows'. */
67
65
static int info_windows_slots = 0;
68
66
 
69
 
void remember_window_and_node (), forget_window_and_nodes ();
70
 
void initialize_info_session (), info_session ();
71
 
void display_startup_message_and_start ();
 
67
void remember_window_and_node (WINDOW *window, NODE *node);
 
68
void forget_window_and_nodes (WINDOW *window);
 
69
void display_startup_message_and_start (void);
72
70
 
73
71
/* Begin an info session finding the nodes specified by FILENAME and NODENAMES.
74
72
   For each loaded node, create a new window.  Always split the largest of the
75
73
   available windows. */
76
74
void
77
 
begin_multiple_window_info_session (filename, nodenames)
78
 
     char *filename;
79
 
     char **nodenames;
 
75
begin_multiple_window_info_session (char *filename, char **nodenames)
80
76
{
81
77
  register int i;
82
78
  WINDOW *window = (WINDOW *)NULL;
114
110
          if (!largest)
115
111
            {
116
112
              display_update_display (windows);
117
 
              info_error (msg_cant_find_window);
 
113
              info_error ((char *) msg_cant_find_window, NULL, NULL);
118
114
              info_session ();
119
115
              xexit (0);
120
116
            }
129
125
          else
130
126
            {
131
127
              display_update_display (windows);
132
 
              info_error (msg_win_too_small);
 
128
              info_error ((char *) msg_win_too_small, NULL, NULL);
133
129
              info_session ();
134
130
              xexit (0);
135
131
            }
141
137
/* Start an info session with INITIAL_NODE, and an error message in the echo
142
138
   area made from FORMAT and ARG. */
143
139
void
144
 
begin_info_session_with_error (initial_node, format, arg1, arg2)
145
 
     NODE *initial_node;
146
 
     char *format;
147
 
     void *arg1;
148
 
     void *arg2;
 
140
begin_info_session_with_error (NODE *initial_node, char *format,
 
141
    void *arg1, void *arg2)
149
142
{
150
143
  initialize_info_session (initial_node, 1);
151
144
  info_error (format, arg1, arg2);
154
147
 
155
148
/* Start an info session with INITIAL_NODE. */
156
149
void
157
 
begin_info_session (initial_node)
158
 
     NODE *initial_node;
 
150
begin_info_session (NODE *initial_node)
159
151
{
160
152
  initialize_info_session (initial_node, 1);
161
153
  display_startup_message_and_start ();
162
154
}
163
155
 
164
156
void
165
 
display_startup_message_and_start ()
 
157
display_startup_message_and_start (void)
166
158
{
167
159
  char *format;
168
160
 
169
161
  format = replace_in_documentation
170
 
    (_("Welcome to Info version %s. Type \\[get-help-window] for help, \\[menu-item] for menu item."));
 
162
    ((char *) _("Welcome to Info version %s. Type \\[get-help-window] for help, \\[menu-item] for menu item."),
 
163
     0);
171
164
 
172
 
  window_message_in_echo_area (format, VERSION);
 
165
  window_message_in_echo_area (format, VERSION, NULL);
173
166
  info_session ();
174
167
}
175
168
 
176
169
/* Run an info session with an already initialized window and node. */
177
170
void
178
 
info_session ()
 
171
info_session (void)
179
172
{
180
173
  display_update_display (windows);
181
174
  info_last_executed_command = NULL;
192
185
/* Here is a window-location dependent event loop.  Called from the
193
186
   functions info_session (), and from read_xxx_in_echo_area (). */
194
187
void
195
 
info_read_and_dispatch ()
 
188
info_read_and_dispatch (void)
196
189
{
197
190
  unsigned char key;
198
191
  int done;
200
193
 
201
194
  while (!done && !quit_info_immediately)
202
195
    {
203
 
      int lk;
 
196
      int lk = 0;
204
197
 
205
198
      /* If we haven't just gone up or down a line, there is no
206
199
         goal column for this window. */
207
 
      if ((info_last_executed_command != info_next_line) &&
208
 
          (info_last_executed_command != info_prev_line))
 
200
      if ((info_last_executed_command != (VFunction *) info_next_line) &&
 
201
          (info_last_executed_command != (VFunction *) info_prev_line))
209
202
        active_window->goal_column = -1;
210
203
 
211
204
      if (echo_area_is_active)
242
235
          if (lk == echo_area_last_command_was_kill)
243
236
            echo_area_last_command_was_kill = 0;
244
237
 
245
 
          if (ea_last_executed_command == ea_newline ||
 
238
          if (ea_last_executed_command == (VFunction *) ea_newline ||
246
239
              info_aborted_echo_area)
247
240
            {
248
241
              ea_last_executed_command = (VFunction *)NULL;
249
242
              done = 1;
250
243
            }
251
244
 
252
 
          if (info_last_executed_command == info_quit)
 
245
          if (info_last_executed_command == (VFunction *) info_quit)
253
246
            quit_info_immediately = 1;
254
247
        }
255
 
      else if (info_last_executed_command == info_quit)
 
248
      else if (info_last_executed_command == (VFunction *) info_quit)
256
249
        done = 1;
257
250
    }
258
251
}
259
252
 
260
253
/* Found in signals.c */
261
 
extern void initialize_info_signal_handler ();
 
254
extern void initialize_info_signal_handler (void );
262
255
 
263
256
/* Initialize the first info session by starting the terminal, window,
264
257
   and display systems.  If CLEAR_SCREEN is 0, don't clear the screen.  */
265
258
void
266
 
initialize_info_session (node, clear_screen)
267
 
     NODE *node;
268
 
     int clear_screen;
 
259
initialize_info_session (NODE *node, int clear_screen)
269
260
{
270
261
  char *term_name = getenv ("TERM");
271
262
  terminal_initialize_terminal (term_name);
275
266
      if (!term_name)
276
267
        term_name = "dumb";
277
268
 
278
 
      info_error (msg_term_too_dumb, term_name);
 
269
      info_error ((char *) msg_term_too_dumb, term_name, NULL);
279
270
      xexit (1);
280
271
    }
281
272
 
293
284
 
294
285
  /* Tell the window system how to notify us when a window needs to be
295
286
     asynchronously deleted (e.g., user resizes window very small). */
296
 
  window_deletion_notifier = forget_window_and_nodes;
 
287
  window_deletion_notifier = (VFunction *) forget_window_and_nodes;
297
288
 
298
289
  /* If input has not been redirected yet, make it come from unbuffered
299
290
     standard input. */
308
299
 
309
300
/* Tell Info that input is coming from the file FILENAME. */
310
301
void
311
 
info_set_input_from_file (filename)
312
 
     char *filename;
 
302
info_set_input_from_file (char *filename)
313
303
{
314
304
  FILE *stream;
315
305
 
331
321
 
332
322
/* Return the INFO_WINDOW containing WINDOW, or NULL if there isn't one. */
333
323
static INFO_WINDOW *
334
 
get_info_window_of_window (window)
335
 
     WINDOW *window;
 
324
get_info_window_of_window (WINDOW *window)
336
325
{
337
326
  register int i;
338
327
  INFO_WINDOW *info_win = (INFO_WINDOW *)NULL;
348
337
   values if the window and node are the same as the current one being
349
338
   displayed. */
350
339
void
351
 
set_remembered_pagetop_and_point (window)
352
 
     WINDOW *window;
 
340
set_remembered_pagetop_and_point (WINDOW *window)
353
341
{
354
342
  INFO_WINDOW *info_win;
355
343
 
367
355
}
368
356
 
369
357
void
370
 
remember_window_and_node (window, node)
371
 
     WINDOW *window;
372
 
     NODE *node;
 
358
remember_window_and_node (WINDOW *window, NODE *node)
373
359
{
374
360
  /* See if we already have this window in our list. */
375
361
  INFO_WINDOW *info_win = get_info_window_of_window (window);
428
414
#define DEBUG_FORGET_WINDOW_AND_NODES
429
415
#if defined (DEBUG_FORGET_WINDOW_AND_NODES)
430
416
static void
431
 
consistency_check_info_windows ()
 
417
consistency_check_info_windows (void)
432
418
{
433
419
  register int i;
434
420
 
448
434
 
449
435
/* Remove WINDOW and its associated list of nodes from INFO_WINDOWS. */
450
436
void
451
 
forget_window_and_nodes (window)
452
 
     WINDOW *window;
 
437
forget_window_and_nodes (WINDOW *window)
453
438
{
454
439
  register int i;
455
440
  INFO_WINDOW *info_win = (INFO_WINDOW *)NULL;
496
481
   the footnotes for this window.  If REMEMBER is nonzero, first call
497
482
   set_remembered_pagetop_and_point.  */
498
483
void
499
 
info_set_node_of_window (remember, window, node)
500
 
     int remember;
501
 
     WINDOW *window;
502
 
     NODE *node;
 
484
info_set_node_of_window (int remember, WINDOW *window, NODE *node)
503
485
{
504
486
  if (remember)
505
487
    set_remembered_pagetop_and_point (window);
526
508
/* Change the pagetop of WINDOW to DESIRED_TOP, perhaps scrolling the screen
527
509
   to do so. */
528
510
void
529
 
set_window_pagetop (window, desired_top)
530
 
     WINDOW *window;
531
 
     int desired_top;
 
511
set_window_pagetop (WINDOW *window, int desired_top)
532
512
{
533
513
  int point_line, old_pagetop;
534
514
 
591
571
/* Immediately make WINDOW->point visible on the screen, and move the
592
572
   terminal cursor there. */
593
573
static void
594
 
info_show_point (window)
595
 
     WINDOW *window;
 
574
info_show_point (WINDOW *window)
596
575
{
597
576
  int old_pagetop;
598
577
 
615
594
 
616
595
/* Move WINDOW->point from OLD line index to NEW line index. */
617
596
static void
618
 
move_to_new_line (old, new, window)
619
 
     int old, new;
620
 
     WINDOW *window;
 
597
move_to_new_line (int old, int new, WINDOW *window)
621
598
{
622
599
  if (old == -1)
623
600
    {
624
 
      info_error (msg_cant_find_point);
 
601
      info_error ((char *) msg_cant_find_point, NULL, NULL);
625
602
    }
626
603
  else
627
604
    {
869
846
 
870
847
/* Move to 1st menu item, Next, Up/Next, or error in this window. */
871
848
static void
872
 
forward_move_node_structure (window, behaviour)
873
 
     WINDOW *window;
874
 
     int behaviour;
 
849
forward_move_node_structure (WINDOW *window, int behaviour)
875
850
{
876
851
  switch (behaviour)
877
852
    {
878
853
    case IS_PageOnly:
879
 
      info_error (msg_at_node_bottom);
 
854
      info_error ((char *) msg_at_node_bottom, NULL, NULL);
880
855
      break;
881
856
 
882
857
    case IS_NextOnly:
883
858
      info_next_label_of_node (window->node);
884
859
      if (!info_parsed_nodename && !info_parsed_filename)
885
 
        info_error (msg_no_pointer, _("Next"));
 
860
        info_error ((char *) msg_no_pointer, (char *) _("Next"), NULL);
886
861
      else
887
862
        {
888
 
          window_message_in_echo_area (_("Following Next node..."));
 
863
          window_message_in_echo_area ((char *) _("Following Next node..."),
 
864
              NULL, NULL);
889
865
          info_handle_pointer ("Next", window);
890
866
        }
891
867
      break;
902
878
          if (menu)
903
879
            {
904
880
              info_free_references (menu);
905
 
              window_message_in_echo_area (_("Selecting first menu item..."));
 
881
              window_message_in_echo_area ((char *) _("Selecting first menu item..."),
 
882
                  NULL, NULL);
906
883
              info_menu_digit (window, 1, '1');
907
884
              return;
908
885
            }
913
890
        info_next_label_of_node (window->node);
914
891
        if (INFO_LABEL_FOUND ())
915
892
          {
916
 
            window_message_in_echo_area (_("Selecting Next node..."));
 
893
            window_message_in_echo_area ((char *) _("Selecting Next node..."),
 
894
                NULL, NULL);
917
895
            info_handle_pointer ("Next", window);
918
896
            return;
919
897
          }
983
961
                  /* This node has a "Next" pointer, and it is not the
984
962
                     same as the first menu item found in this node. */
985
963
                  window_message_in_echo_area
986
 
                    (_("Moving Up %d time(s), then Next."),
987
 
                     up_counter);
 
964
                    ((char *) _("Moving Up %d time(s), then Next."),
 
965
                     (void *) (long) up_counter, NULL);
988
966
 
989
967
                  info_handle_pointer ("Next", window);
990
968
                  return;
1007
985
                  window->point = info_win->points[old_current];
1008
986
                  recalculate_line_starts (window);
1009
987
                  window->flags |= W_UpdateWindow;
1010
 
                  info_error (_("No more nodes within this document."));
 
988
                  info_error ((char *) _("No more nodes within this document."),
 
989
                      NULL, NULL);
1011
990
                }
1012
991
            }
1013
992
        }
1018
997
 
1019
998
/* Move Prev, Up or error in WINDOW depending on BEHAVIOUR. */
1020
999
static void
1021
 
backward_move_node_structure (window, behaviour)
1022
 
     WINDOW *window;
1023
 
     int behaviour;
 
1000
backward_move_node_structure (WINDOW *window, int behaviour)
1024
1001
{
1025
1002
  switch (behaviour)
1026
1003
    {
1027
1004
    case IS_PageOnly:
1028
 
      info_error (msg_at_node_top);
 
1005
      info_error ((char *) msg_at_node_top, NULL, NULL);
1029
1006
      break;
1030
1007
 
1031
1008
    case IS_NextOnly:
1032
1009
      info_prev_label_of_node (window->node);
1033
1010
      if (!info_parsed_nodename && !info_parsed_filename)
1034
 
        info_error (_("No `Prev' for this node."));
 
1011
        info_error ((char *) _("No `Prev' for this node."), NULL, NULL);
1035
1012
      else
1036
1013
        {
1037
 
          window_message_in_echo_area (_("Moving Prev in this window."));
 
1014
          window_message_in_echo_area ((char *) _("Moving Prev in this window."),
 
1015
              NULL, NULL);
1038
1016
          info_handle_pointer ("Prev", window);
1039
1017
        }
1040
1018
      break;
1048
1026
          info_up_label_of_node (window->node);
1049
1027
          if (!info_parsed_nodename && (!info_parsed_filename
1050
1028
                                        || is_dir_name (info_parsed_filename)))
1051
 
            info_error (_("No `Prev' or `Up' for this node within this document."));
 
1029
            info_error ((char *)
 
1030
                _("No `Prev' or `Up' for this node within this document."),
 
1031
                NULL, NULL);
1052
1032
          else
1053
1033
            {
1054
 
              window_message_in_echo_area (_("Moving Up in this window."));
 
1034
              window_message_in_echo_area ((char *) _("Moving Up in this window."),
 
1035
                  NULL, NULL);
1055
1036
              info_handle_pointer ("Up", window);
1056
1037
            }
1057
1038
        }
1089
1070
          /* Move to the previous node.  If this node now contains a menu,
1090
1071
             and we have not inhibited movement to it, move to the node
1091
1072
             corresponding to the last menu item. */
1092
 
          window_message_in_echo_area (_("Moving Prev in this window."));
 
1073
          window_message_in_echo_area ((char *) _("Moving Prev in this window."),
 
1074
              NULL, NULL);
1093
1075
          info_handle_pointer ("Prev", window);
1094
1076
 
1095
1077
          if (!inhibit_menu_traversing)
1099
1081
                {
1100
1082
                  info_free_references (menu);
1101
1083
                  window_message_in_echo_area
1102
 
                    (_("Moving to `Prev's last menu item."));
 
1084
                    ((char *) _("Moving to `Prev's last menu item."), NULL, NULL);
1103
1085
                  info_menu_digit (window, 1, '0');
1104
1086
                }
1105
1087
            }
1140
1122
    }
1141
1123
}
1142
1124
 
1143
 
static void _scroll_forward();
1144
 
static void _scroll_backward();
 
1125
static void _scroll_forward(WINDOW *window, int count,
 
1126
    unsigned char key, int behaviour);
 
1127
static void _scroll_backward(WINDOW *window, int count,
 
1128
    unsigned char key, int behaviour);
1145
1129
 
1146
1130
static void
1147
 
_scroll_forward(window, count, key, behaviour)
1148
 
  WINDOW *window;
1149
 
  int count;
1150
 
  unsigned char key;
1151
 
  int behaviour;
 
1131
_scroll_forward(WINDOW *window, int count, unsigned char key, int behaviour)
1152
1132
{
1153
1133
  if (count < 0)
1154
1134
    _scroll_backward (window, -count, key, behaviour);
1188
1168
}
1189
1169
 
1190
1170
static void
1191
 
_scroll_backward(window, count, key, behaviour)
1192
 
  WINDOW *window;
1193
 
  int count;
1194
 
  unsigned char key;
1195
 
  int behaviour;
 
1171
_scroll_backward(WINDOW *window, int count, unsigned char key, int behaviour)
1196
1172
{
1197
1173
  if (count < 0)
1198
1174
    _scroll_forward (window, -count, key, behaviour);
1406
1382
  /* If no other window, error now. */
1407
1383
  if (!windows->next && !echo_area_is_active)
1408
1384
    {
1409
 
      info_error (msg_one_window);
 
1385
      info_error ((char *) msg_one_window, NULL, NULL);
1410
1386
      return;
1411
1387
    }
1412
1388
 
1446
1422
 
1447
1423
  if (!windows->next && !echo_area_is_active)
1448
1424
    {
1449
 
      info_error (msg_one_window);
 
1425
      info_error ((char *) msg_one_window, NULL, NULL);
1450
1426
      return;
1451
1427
    }
1452
1428
 
1457
1433
      if (window == the_echo_area ||
1458
1434
          (window == windows && !echo_area_is_active))
1459
1435
        {
1460
 
          register WINDOW *win, *last;
 
1436
          register WINDOW *win, *last = NULL;
1461
1437
 
1462
1438
          for (win = windows; win; win = win->next)
1463
1439
            last = win;
1502
1478
 
1503
1479
  if (!split)
1504
1480
    {
1505
 
      info_error (msg_win_too_small);
 
1481
      info_error ((char *) msg_win_too_small, NULL, NULL);
1506
1482
    }
1507
1483
  else
1508
1484
    {
1570
1546
{
1571
1547
  if (!windows->next)
1572
1548
    {
1573
 
      info_error (msg_cant_kill_last);
 
1549
      info_error ((char *) msg_cant_kill_last, NULL, NULL);
1574
1550
    }
1575
1551
  else if (window->flags & W_WindowIsPerm)
1576
1552
    {
1577
 
      info_error (_("Cannot delete a permanent window"));
 
1553
      info_error ((char *) _("Cannot delete a permanent window"), NULL, NULL);
1578
1554
    }
1579
1555
  else
1580
1556
    {
1591
1567
/* Do the physical deletion of WINDOW, and forget this window and
1592
1568
   associated nodes. */
1593
1569
void
1594
 
info_delete_window_internal (window)
1595
 
     WINDOW *window;
 
1570
info_delete_window_internal (WINDOW *window)
1596
1571
{
1597
1572
  if (windows->next && ((window->flags & W_WindowIsPerm) == 0))
1598
1573
    {
1660
1635
  /* If only one window, give up. */
1661
1636
  if (!windows->next)
1662
1637
    {
1663
 
      info_error (msg_one_window);
 
1638
      info_error ((char *) msg_one_window, NULL, NULL);
1664
1639
      return;
1665
1640
    }
1666
1641
 
1712
1687
/* Return (FILENAME)NODENAME for NODE, or just NODENAME if NODE's
1713
1688
   filename is not set. */
1714
1689
char *
1715
 
node_printed_rep (node)
1716
 
     NODE *node;
 
1690
node_printed_rep (NODE *node)
1717
1691
{
1718
1692
  char *rep;
1719
1693
 
1734
1708
/* Using WINDOW for various defaults, select the node referenced by ENTRY
1735
1709
   in it.  If the node is selected, the window and node are remembered. */
1736
1710
void
1737
 
info_select_reference (window, entry)
1738
 
     WINDOW *window;
1739
 
     REFERENCE *entry;
 
1711
info_select_reference (WINDOW *window, REFERENCE *entry)
1740
1712
{
1741
1713
  NODE *node;
1742
1714
  char *filename, *nodename, *file_system_error;
1781
1753
  if (!node)
1782
1754
    {
1783
1755
      if (file_system_error)
1784
 
        info_error (file_system_error);
 
1756
        info_error (file_system_error, NULL, NULL);
1785
1757
      else
1786
 
        info_error (msg_cant_find_node, nodename);
 
1758
        info_error ((char *) msg_cant_find_node, nodename, NULL);
1787
1759
    }
1788
1760
 
1789
1761
  maybe_free (file_system_error);
1798
1770
   Select the parsed node in WINDOW and remember it, or error if the node
1799
1771
   couldn't be found. */
1800
1772
static void
1801
 
info_parse_and_select (line, window)
1802
 
     char *line;
1803
 
     WINDOW *window;
 
1773
info_parse_and_select (char *line, WINDOW *window)
1804
1774
{
1805
1775
  REFERENCE entry;
1806
1776
 
1818
1788
   WINDOW.  The node should have been pointed to by the LABEL pointer of
1819
1789
   WINDOW->node. */
1820
1790
static void
1821
 
info_handle_pointer (label, window)
1822
 
     char *label;
1823
 
     WINDOW *window;
 
1791
info_handle_pointer (char *label, WINDOW *window)
1824
1792
{
1825
1793
  if (info_parsed_filename || info_parsed_nodename)
1826
1794
    {
1861
1829
      else
1862
1830
        {
1863
1831
          if (info_recent_file_error)
1864
 
            info_error (info_recent_file_error);
 
1832
            info_error (info_recent_file_error, NULL, NULL);
1865
1833
          else
1866
 
            info_error (msg_cant_file_node, filename, nodename);
 
1834
            info_error ((char *) msg_cant_file_node, filename, nodename);
1867
1835
        }
1868
1836
 
1869
1837
      free (filename);
1871
1839
    }
1872
1840
  else
1873
1841
    {
1874
 
      info_error (msg_no_pointer, label);
 
1842
      info_error ((char *) msg_no_pointer, label, NULL);
1875
1843
    }
1876
1844
}
1877
1845
 
1927
1895
    }
1928
1896
 
1929
1897
  if (!node)
1930
 
    info_error (_("This window has no additional nodes"));
 
1898
    info_error ((char *) _("This window has no additional nodes"), NULL, NULL);
1931
1899
  else
1932
1900
    info_set_node_of_window (1, window, node);
1933
1901
}
1960
1928
    }
1961
1929
 
1962
1930
  if (!node)
1963
 
    info_error (_("This window has no additional nodes"));
 
1931
    info_error ((char *) _("This window has no additional nodes"), NULL, NULL);
1964
1932
  else
1965
1933
    info_set_node_of_window (1, window, node);
1966
1934
}
1976
1944
DECLARE_INFO_COMMAND (info_menu_digit, _("Select this menu item"))
1977
1945
{
1978
1946
  register int i, item;
1979
 
  register REFERENCE *entry, **menu;
 
1947
  register REFERENCE **menu;
1980
1948
 
1981
1949
  menu = info_menu_of_node (window->node);
1982
1950
 
1983
1951
  if (!menu)
1984
1952
    {
1985
 
      info_error (msg_no_menu_node);
 
1953
      info_error ((char *) msg_no_menu_node, NULL, NULL);
1986
1954
      return;
1987
1955
    }
1988
1956
 
1994
1962
    for (i = 0; menu[i + 1]; i++);
1995
1963
  else
1996
1964
    {
1997
 
      for (i = 0; (entry = menu[i]); i++)
 
1965
      for (i = 0; menu[i]; i++)
1998
1966
        if (i == item - 1)
1999
1967
          break;
2000
1968
    }
2001
1969
 
2002
1970
  if (menu[i])
2003
 
    info_select_reference (window, menu[i]);
 
1971
    {
 
1972
      info_select_reference (window, menu[i]);
 
1973
      if (menu[i]->line_number > 0)
 
1974
        info_next_line (window, menu[i]->line_number - 1, key);
 
1975
    }
2004
1976
  else
2005
 
    info_error (_("There aren't %d items in this menu."), item);
 
1977
    info_error ((char *) _("There aren't %d items in this menu."),
 
1978
                (void *) (long) item, NULL);
2006
1979
 
2007
1980
  info_free_references (menu);
2008
1981
  return;
2009
1982
}
2010
1983
 
 
1984
 
 
1985
 
 
1986
/* Return a pointer to the xref in XREF_LIST that is nearest to POS, or
 
1987
   NULL if XREF_LIST is empty.  That is, if POS is within any of the
 
1988
   given xrefs, return that one.  Otherwise, return the one with the
 
1989
   nearest beginning or end.  If there are two that are equidistant,
 
1990
   prefer the one forward.  The return is in newly-allocated memory,
 
1991
   since the caller frees it.
 
1992
   
 
1993
   This is called from info_menu_or_ref_item with XREF_LIST being all
 
1994
   the xrefs in the node, and POS being point.  The ui function that
 
1995
   starts it all off is select-reference-this-line.
 
1996
 
 
1997
   This is not the same logic as in info.el.  Info-get-token prefers
 
1998
   searching backwards to searching forwards, and has a hardwired search
 
1999
   limit of 200 chars (in Emacs 21.2).  */
 
2000
 
 
2001
static REFERENCE **
 
2002
nearest_xref (REFERENCE **xref_list, long int pos)
 
2003
{
 
2004
  int this_xref;
 
2005
  int nearest = -1;
 
2006
  long best_delta = -1;
 
2007
  
 
2008
  for (this_xref = 0; xref_list[this_xref]; this_xref++)
 
2009
    {
 
2010
      long delta;
 
2011
      REFERENCE *xref = xref_list[this_xref];
 
2012
      if (xref->start <= pos && pos <= xref->end)
 
2013
        { /* POS is within this xref, we're done */
 
2014
          nearest = this_xref;
 
2015
          break;
 
2016
        }
 
2017
      
 
2018
      /* See how far POS is from this xref.  Take into account the
 
2019
         `*Note' that begins the xref, since as far as the user is
 
2020
         concerned, that's where it starts.  */
 
2021
      delta = MIN (labs (pos - (xref->start - strlen (INFO_XREF_LABEL))),
 
2022
                   labs (pos - xref->end));
 
2023
      
 
2024
      /* It's the <= instead of < that makes us choose the forward xref
 
2025
         of POS if two are equidistant.  Of course, because of all the
 
2026
         punctuation surrounding xrefs, it's not necessarily obvious
 
2027
         where one ends.  */
 
2028
      if (delta <= best_delta || best_delta < 0)
 
2029
        {
 
2030
          nearest = this_xref;
 
2031
          best_delta = delta;
 
2032
        }
 
2033
    }
 
2034
  
 
2035
  /* Maybe there was no list to search through.  */
 
2036
  if (nearest < 0)
 
2037
    return NULL;
 
2038
  
 
2039
  /* Ok, we have a nearest xref, make a list of it.  */
 
2040
  {
 
2041
    REFERENCE **ret = xmalloc (sizeof (REFERENCE *) * 2);
 
2042
    ret[0] = info_copy_reference (xref_list[nearest]);
 
2043
    ret[1] = NULL;
 
2044
    return ret;
 
2045
  }
 
2046
}
 
2047
 
 
2048
 
2011
2049
/* Read a menu or followed reference from the user defaulting to the
2012
2050
   reference found on the current line, and select that node.  The
2013
2051
   reading is done with completion.  BUILDER is the function used
2014
2052
   to build the list of references.  ASK_P is non-zero if the user
2015
2053
   should be prompted, or zero to select the default item. */
2016
2054
static void
2017
 
info_menu_or_ref_item (window, count, key, builder, ask_p)
2018
 
     WINDOW *window;
2019
 
     int count;
2020
 
     unsigned char key;
2021
 
     REFERENCE **(*builder) ();
2022
 
     int ask_p;
 
2055
info_menu_or_ref_item (WINDOW *window, int count,
 
2056
    unsigned char key, REFERENCE **(*builder) (NODE *node), int ask_p)
2023
2057
{
2024
 
  REFERENCE **menu, *entry, *defentry = (REFERENCE *)NULL;
2025
2058
  char *line;
2026
 
 
2027
 
  menu = (*builder) (window->node);
 
2059
  REFERENCE *entry;
 
2060
  REFERENCE *defentry = NULL;
 
2061
  REFERENCE **menu = (*builder) (window->node);
2028
2062
 
2029
2063
  if (!menu)
2030
2064
    {
2031
2065
      if (builder == info_menu_of_node)
2032
 
        info_error (msg_no_menu_node);
 
2066
        info_error ((char *) msg_no_menu_node, NULL, NULL);
2033
2067
      else
2034
 
        info_error (msg_no_xref_node);
 
2068
        info_error ((char *) msg_no_xref_node, NULL, NULL);
2035
2069
      return;
2036
2070
    }
2037
2071
 
2038
2072
  /* Default the selected reference to the one which is on the line that
2039
2073
     point is in.  */
2040
2074
  {
2041
 
    REFERENCE **refs = (REFERENCE **)NULL;
2042
 
    int point_line;
2043
 
 
2044
 
    point_line = window_line_of_point (window);
 
2075
    REFERENCE **refs = NULL;
 
2076
    int point_line = window_line_of_point (window);
2045
2077
 
2046
2078
    if (point_line != -1)
2047
2079
      {
2070
2102
              refs = manpage_xrefs_in_binding (window->node, &binding);
2071
2103
            else
2072
2104
#endif /* HANDLE_MAN_PAGES */
2073
 
            {
2074
 
              refs = info_xrefs (&binding);
2075
 
              if (!refs && point_line > 0)
2076
 
                {
2077
 
                  /* People get annoyed that Info cannot find an xref
2078
 
                     which starts on a previous line and ends on this
2079
 
                     one.  So if we fail to find a reference on this
2080
 
                     line, let's try the one before.  */
2081
 
                  binding.start =
2082
 
                    window->line_starts[point_line - 1] - binding.buffer;
2083
 
                  refs = info_xrefs (&binding);
2084
 
                }
2085
 
            }
 
2105
              refs = nearest_xref (menu, window->point);
2086
2106
          }
2087
2107
 
2088
 
        if (refs)
 
2108
        if (refs && refs[0])
2089
2109
          {
2090
 
            if ((strcmp (refs[0]->label, "Menu") != 0) ||
2091
 
                (builder == info_xrefs_of_node))
 
2110
            if (strcmp (refs[0]->label, "Menu") != 0
 
2111
                || builder == info_xrefs_of_node)
2092
2112
              {
2093
2113
                int which = 0;
2094
2114
 
2095
 
                /* Find the closest reference to point. */
2096
 
                if (builder == info_xrefs_of_node)
 
2115
                /* For xrefs, find the closest reference to point,
 
2116
                   unless we only have one reference (as we will if
 
2117
                   we've called nearest_xref above).  It would be better
 
2118
                   to have only one piece of code, but the conditions
 
2119
                   when we call this are tangled.  */
 
2120
                if (builder == info_xrefs_of_node && refs[1])
2097
2121
                  {
2098
2122
                    int closest = -1;
2099
2123
 
2100
2124
                    for (; refs[which]; which++)
2101
2125
                      {
2102
 
                        if ((window->point >= refs[which]->start) &&
2103
 
                            (window->point <= refs[which]->end))
 
2126
                        if (window->point >= refs[which]->start
 
2127
                            && window->point <= refs[which]->end)
2104
2128
                          {
2105
2129
                            closest = which;
2106
2130
                            break;
2107
2131
                          }
2108
2132
                        else if (window->point < refs[which]->start)
2109
 
                          {
2110
 
                            break;
2111
 
                          }
 
2133
                          break;
2112
2134
                      }
2113
 
                    if (closest == -1)
2114
 
                      which--;
2115
 
                    else
2116
 
                      which = closest;
 
2135
                    if (which > 0)
 
2136
                      {
 
2137
                        if (closest == -1)
 
2138
                          which--;
 
2139
                        else
 
2140
                          which = closest;
 
2141
                      }
2117
2142
                  }
2118
2143
 
2119
2144
                defentry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
2120
2145
                defentry->label = xstrdup (refs[which]->label);
2121
2146
                defentry->filename = refs[which]->filename;
2122
2147
                defentry->nodename = refs[which]->nodename;
 
2148
                defentry->line_number = refs[which]->line_number;
2123
2149
 
2124
2150
                if (defentry->filename)
2125
2151
                  defentry->filename = xstrdup (defentry->filename);
2137
2163
      char *prompt;
2138
2164
 
2139
2165
      /* Build the prompt string. */
2140
 
      if (defentry)
2141
 
        prompt = (char *)xmalloc (20 + strlen (defentry->label));
2142
 
      else
2143
 
        prompt = (char *)xmalloc (20);
2144
 
 
2145
2166
      if (builder == info_menu_of_node)
2146
2167
        {
2147
2168
          if (defentry)
2148
 
            sprintf (prompt, _("Menu item (%s): "), defentry->label);
 
2169
            {
 
2170
              prompt = xmalloc (strlen (defentry->label)
 
2171
                                + strlen (_("Menu item (%s): ")));
 
2172
              sprintf (prompt, _("Menu item (%s): "), defentry->label);
 
2173
            }
2149
2174
          else
2150
 
            sprintf (prompt, _("Menu item: "));
 
2175
            prompt = xstrdup (_("Menu item: "));
2151
2176
        }
2152
2177
      else
2153
2178
        {
2154
2179
          if (defentry)
2155
 
            sprintf (prompt, _("Follow xref (%s): "), defentry->label);
 
2180
            {
 
2181
              prompt = xmalloc (strlen (defentry->label)
 
2182
                                + strlen (_("Follow xref (%s): ")));
 
2183
              sprintf (prompt, _("Follow xref (%s): "), defentry->label);
 
2184
            }
2156
2185
          else
2157
 
            sprintf (prompt, _("Follow xref: "));
 
2186
            prompt = xstrdup (_("Follow xref: "));
2158
2187
        }
2159
2188
 
2160
2189
      line = info_read_completing_in_echo_area (window, prompt, menu);
2232
2261
        }
2233
2262
 
2234
2263
      if (!entry && defentry)
2235
 
        info_error (_("The reference disappeared! (%s)."), line);
 
2264
        info_error ((char *) _("The reference disappeared! (%s)."), line, NULL);
2236
2265
      else
2237
2266
        {
2238
2267
          NODE *orig = window->node;
2239
2268
          info_select_reference (window, entry);
 
2269
 
2240
2270
          if (builder == info_xrefs_of_node && window->node != orig
2241
2271
              && !(window->node->flags & N_FromAnchor))
2242
2272
            { /* Search for this reference in the node.  */
2257
2287
                  window_adjust_pagetop (window);
2258
2288
                }
2259
2289
            }
 
2290
 
 
2291
            if (entry->line_number > 0)
 
2292
              /* next_line starts at line 1?  Anyway, the -1 makes it
 
2293
                 move to the right line.  */
 
2294
              info_next_line (window, entry->line_number - 1, key);
2260
2295
        }
2261
2296
 
2262
2297
      free (line);
2304
2339
  position = search (INFO_MENU_LABEL, &binding);
2305
2340
 
2306
2341
  if (position == -1)
2307
 
    info_error (msg_no_menu_node);
 
2342
    info_error ((char *) msg_no_menu_node, NULL, NULL);
2308
2343
  else
2309
2344
    {
2310
2345
      window->point = position;
2323
2358
  menu = info_menu_of_node (window->node);
2324
2359
 
2325
2360
  if (!menu)
2326
 
    info_error (msg_no_menu_node);
 
2361
    info_error ((char *) msg_no_menu_node, NULL, NULL);
2327
2362
 
2328
2363
  for (i = 0; (!info_error_was_printed) && (entry = menu[i]); i++)
2329
2364
    {
2333
2368
      window_tile_windows (TILE_INTERNALS);
2334
2369
 
2335
2370
      if (!new)
2336
 
        info_error (msg_win_too_small);
 
2371
        info_error ((char *) msg_win_too_small, NULL, NULL);
2337
2372
      else
2338
2373
        {
2339
2374
          active_window = new;
2398
2433
              }
2399
2434
          }
2400
2435
      }
2401
 
    line = info_read_maybe_completing (window, _("Goto node: "), items);
 
2436
    line = info_read_maybe_completing (window, (char *) _("Goto node: "),
 
2437
        items);
2402
2438
    info_free_references (items);
2403
2439
  }
2404
2440
#else /* !GOTO_COMPLETES */
2405
 
  line = info_read_in_echo_area (window, _("Goto node: "));
 
2441
  line = info_read_in_echo_area (window, (char *) _("Goto node: "));
2406
2442
#endif /* !GOTO_COMPLETES */
2407
2443
 
2408
2444
  /* If the user aborted, quit now. */
2430
2466
   will be NULL.  */
2431
2467
 
2432
2468
NODE *
2433
 
info_follow_menus (initial_node, menus, errstr, errarg1, errarg2)
2434
 
     NODE *initial_node;
2435
 
     char **menus;
2436
 
     char **errstr, **errarg1, **errarg2;
 
2469
info_follow_menus (NODE *initial_node, char **menus,
 
2470
    const char **errstr, char **errarg1, char **errarg2)
2437
2471
{
2438
2472
  NODE *node = NULL;
2439
2473
  *errstr = *errarg1 = *errarg2 = NULL;
2488
2522
              if (strcasecmp (entry->label, arg) == 0)
2489
2523
                break;
2490
2524
              else
2491
 
                if (strncasecmp (entry->label, arg, strlen (arg)) == 0)
 
2525
                if ((best_guess == -1)
 
2526
                    && (strncasecmp (entry->label, arg, strlen (arg)) == 0))
2492
2527
                  best_guess = i;
2493
2528
            }
2494
2529
 
2566
2601
   Return array terminated with NULL.  */
2567
2602
 
2568
2603
static char **
2569
 
split_list_of_nodenames (str)
2570
 
     char *str;
 
2604
split_list_of_nodenames (char *str)
2571
2605
{
2572
2606
  unsigned len = 2;
2573
2607
  char **nodes = xmalloc (len * sizeof (char *));
2596
2630
DECLARE_INFO_COMMAND (info_menu_sequence,
2597
2631
   _("Read a list of menus starting from dir and follow them"))
2598
2632
{
2599
 
  char *line = info_read_in_echo_area (window, _("Follow menus: "));
 
2633
  char *line = info_read_in_echo_area (window, (char *) _("Follow menus: "));
2600
2634
 
2601
2635
  /* If the user aborted, quit now. */
2602
2636
  if (!line)
2609
2643
 
2610
2644
  if (*line)
2611
2645
    {
2612
 
      char *errstr, *errarg1, *errarg2;
 
2646
      const char *errstr;
 
2647
      char *errarg1, *errarg2;
2613
2648
      NODE *dir_node = info_get_node (NULL, NULL);
2614
2649
      char **nodes = split_list_of_nodenames (line);
2615
 
      NODE *node;
 
2650
      NODE *node = NULL;
2616
2651
 
2617
2652
      /* If DIR_NODE is NULL, they might be reading a file directly,
2618
2653
         like in "info -d . -f ./foo".  Try using "Top" instead.  */
2628
2663
      /* If we still cannot find the starting point, give up.
2629
2664
         We cannot allow a NULL pointer inside info_follow_menus.  */
2630
2665
      if (!dir_node)
2631
 
        info_error (msg_cant_find_node, "Top");
 
2666
        info_error ((char *) msg_cant_find_node, "Top", NULL);
2632
2667
      else
2633
 
        node
2634
 
          = info_follow_menus (dir_node, nodes, &errstr, &errarg1, &errarg2);
 
2668
        node = info_follow_menus (dir_node, nodes, &errstr, &errarg1, &errarg2);
2635
2669
 
2636
2670
      free (nodes);
2637
2671
      if (!errstr)
2638
2672
        info_set_node_of_window (1, window, node);
2639
2673
      else
2640
 
        info_error (errstr, errarg1, errarg2);
 
2674
        info_error ((char *) errstr, errarg1, errarg2);
2641
2675
    }
2642
2676
 
2643
2677
  free (line);
2650
2684
   or NULL if there's nothing in this menu seems to fit the bill.
2651
2685
   If EXACT is non-zero, allow only exact matches.  */
2652
2686
static REFERENCE *
2653
 
entry_in_menu (arg, menu, exact)
2654
 
     char *arg;
2655
 
     REFERENCE **menu;
2656
 
     int exact;
 
2687
entry_in_menu (char *arg, REFERENCE **menu, int exact)
2657
2688
{
2658
2689
  REFERENCE *entry;
2659
2690
 
2687
2718
   invocation info and its command-line options, by looking for menu
2688
2719
   items and chains of menu items with characteristic names.  */
2689
2720
void
2690
 
info_intuit_options_node (window, initial_node, program)
2691
 
     WINDOW *window;
2692
 
     NODE *initial_node;
2693
 
     char *program;
 
2721
info_intuit_options_node (WINDOW *window, NODE *initial_node, char *program)
2694
2722
{
2695
2723
  /* The list of node names typical for GNU manuals where the program
2696
2724
     usage and specifically the command-line arguments are described.
2725
2753
     in the menu hierarchy...  */
2726
2754
  for (node = initial_node; node; initial_node = node)
2727
2755
    {
2728
 
      REFERENCE *entry;
 
2756
      REFERENCE *entry = NULL;
2729
2757
 
2730
2758
      /* Build and return a list of the menu items in this node. */
2731
2759
      menu = info_menu_of_node (initial_node);
2738
2766
      /* Look for node names typical for usage nodes in this menu.  */
2739
2767
      for (try_node = invocation_nodes; *try_node; try_node++)
2740
2768
        {
2741
 
          char nodename[200];
 
2769
          char *nodename;
2742
2770
 
 
2771
          nodename = xmalloc (strlen (program) + strlen (*try_node));
2743
2772
          sprintf (nodename, *try_node, program);
2744
2773
          /* The last resort "%s" is dangerous, so we restrict it
2745
2774
             to exact matches here.  */
2746
2775
          entry = entry_in_menu (nodename, menu,
2747
2776
                                 strcmp (*try_node, "%s") == 0);
 
2777
          free (nodename);
2748
2778
          if (entry)
2749
2779
            break;
2750
2780
        }
2772
2802
/* Given a name of an Info file, find the name of the package it
2773
2803
   describes by removing the leading directories and extensions.  */
2774
2804
char *
2775
 
program_name_from_file_name (file_name)
2776
 
     char *file_name;
 
2805
program_name_from_file_name (char *file_name)
2777
2806
{
2778
2807
  int i;
2779
2808
  char *program_name = xstrdup (filename_non_directory (file_name));
2796
2825
DECLARE_INFO_COMMAND (info_goto_invocation_node,
2797
2826
                      _("Find the node describing program invocation"))
2798
2827
{
2799
 
  char *invocation_prompt = _("Find Invocation node of [%s]: ");
 
2828
  const char *invocation_prompt = _("Find Invocation node of [%s]: ");
2800
2829
  char *program_name, *line;
2801
2830
  char *default_program_name, *prompt, *file_name;
2802
2831
  NODE *top_node;
2814
2843
  free (prompt);
2815
2844
  if (!line)
2816
2845
    {
2817
 
      info_abort_key ();
 
2846
      info_abort_key (window, 0, 0);
2818
2847
      return;
2819
2848
    }
2820
2849
  if (*line)
2826
2855
     from the Top node.  */
2827
2856
  top_node = info_get_node (file_name, NULL);
2828
2857
  if (!top_node)
2829
 
    info_error (msg_cant_find_node, "Top");
 
2858
    info_error ((char *) msg_cant_find_node, "Top", NULL);
2830
2859
 
2831
2860
  info_intuit_options_node (window, top_node, program_name);
2832
2861
  free (line);
2838
2867
{
2839
2868
  char *line;
2840
2869
 
2841
 
  line = info_read_in_echo_area (window, _("Get Manpage: "));
 
2870
  line = info_read_in_echo_area (window, (char *) _("Get Manpage: "));
2842
2871
 
2843
2872
  if (!line)
2844
2873
    {
2883
2912
/* Read the name of a node to kill.  The list of available nodes comes
2884
2913
   from the nodes appearing in the current window configuration. */
2885
2914
static char *
2886
 
read_nodename_to_kill (window)
2887
 
     WINDOW *window;
 
2915
read_nodename_to_kill (WINDOW *window)
2888
2916
{
2889
2917
  int iw;
2890
2918
  char *nodename;
2892
2920
  REFERENCE **menu = NULL;
2893
2921
  int menu_index = 0, menu_slots = 0;
2894
2922
  char *default_nodename = xstrdup (active_window->node->nodename);
2895
 
  char *prompt = xmalloc (40 + strlen (default_nodename));
 
2923
  char *prompt = xmalloc (strlen (_("Kill node (%s): ")) + strlen (default_nodename));
2896
2924
 
2897
2925
  sprintf (prompt, _("Kill node (%s): "), default_nodename);
2898
2926
 
2924
2952
/* Delete NODENAME from this window, showing the most
2925
2953
   recently selected node in this window. */
2926
2954
static void
2927
 
kill_node (window, nodename)
2928
 
     WINDOW *window;
2929
 
     char *nodename;
 
2955
kill_node (WINDOW *window, char *nodename)
2930
2956
{
2931
2957
  int iw, i;
2932
2958
  INFO_WINDOW *info_win;
2948
2974
  if (!info_win)
2949
2975
    {
2950
2976
      if (*nodename)
2951
 
        info_error (_("Cannot kill node `%s'"), nodename);
 
2977
        info_error ((char *) _("Cannot kill node `%s'"), nodename, NULL);
2952
2978
      else
2953
2979
        window_clear_echo_area ();
2954
2980
 
2958
2984
  /* If there are no more nodes left anywhere to view, complain and exit. */
2959
2985
  if (info_windows_index == 1 && info_windows[0]->nodes_index == 1)
2960
2986
    {
2961
 
      info_error (_("Cannot kill the last node"));
 
2987
      info_error ((char *) _("Cannot kill the last node"), NULL, NULL);
2962
2988
      return;
2963
2989
    }
2964
2990
 
3062
3088
{
3063
3089
  char *line;
3064
3090
 
3065
 
  line = info_read_in_echo_area (window, _("Find file: "));
 
3091
  line = info_read_in_echo_area (window, (char *) _("Find file: "));
3066
3092
  if (!line)
3067
3093
    {
3068
3094
      info_abort_key (active_window, 1, 0);
3077
3103
      if (!node)
3078
3104
        {
3079
3105
          if (info_recent_file_error)
3080
 
            info_error (info_recent_file_error);
 
3106
            info_error (info_recent_file_error, NULL, NULL);
3081
3107
          else
3082
 
            info_error (_("Cannot find `%s'."), line);
 
3108
            info_error ((char *) _("Cannot find `%s'."), line, NULL);
3083
3109
        }
3084
3110
      else
3085
3111
        info_set_node_of_window (1, window, node);
3098
3124
/* **************************************************************** */
3099
3125
 
3100
3126
#define VERBOSE_NODE_DUMPING
3101
 
static void write_node_to_stream ();
3102
 
static void dump_node_to_stream ();
3103
 
static void initialize_dumping ();
 
3127
static void write_node_to_stream (NODE *node, FILE *stream);
 
3128
static void dump_node_to_stream (char *filename, char *nodename,
 
3129
    FILE *stream, int dump_subnodes);
 
3130
static void initialize_dumping (void);
3104
3131
 
3105
3132
/* Dump the nodes specified by FILENAME and NODENAMES to the file named
3106
3133
   in OUTPUT_FILENAME.  If DUMP_SUBNODES is non-zero, recursively dump
3107
3134
   the nodes which appear in the menu of each node dumped. */
3108
3135
void
3109
 
dump_nodes_to_file (filename, nodenames, output_filename, dump_subnodes)
3110
 
     char *filename;
3111
 
     char **nodenames;
3112
 
     char *output_filename;
3113
 
     int dump_subnodes;
 
3136
dump_nodes_to_file (char *filename, char **nodenames,
 
3137
    char *output_filename, int dump_subnodes)
3114
3138
{
3115
3139
  register int i;
3116
3140
  FILE *output_stream;
3124
3148
 
3125
3149
  if (!output_stream)
3126
3150
    {
3127
 
      info_error (_("Could not create output file `%s'."), output_filename);
 
3151
      info_error ((char *) _("Could not create output file `%s'."),
 
3152
          output_filename, NULL);
3128
3153
      return;
3129
3154
    }
3130
3155
 
3137
3162
    fclose (output_stream);
3138
3163
 
3139
3164
#if defined (VERBOSE_NODE_DUMPING)
3140
 
  info_error (_("Done."));
 
3165
  info_error ((char *) _("Done."), NULL, NULL);
3141
3166
#endif /* VERBOSE_NODE_DUMPING */
3142
3167
}
3143
3168
 
3147
3172
static int dumped_already_slots = 0;
3148
3173
 
3149
3174
static void
3150
 
initialize_dumping ()
 
3175
initialize_dumping (void)
3151
3176
{
3152
3177
  dumped_already_index = 0;
3153
3178
}
3156
3181
   If DUMP_SUBNODES is non-zero, recursively dump the nodes which appear
3157
3182
   in the menu of each node dumped. */
3158
3183
static void
3159
 
dump_node_to_stream (filename, nodename, stream, dump_subnodes)
3160
 
     char *filename, *nodename;
3161
 
     FILE *stream;
3162
 
     int dump_subnodes;
 
3184
dump_node_to_stream (char *filename, char *nodename,
 
3185
    FILE *stream, int dump_subnodes)
3163
3186
{
3164
3187
  register int i;
3165
3188
  NODE *node;
3169
3192
  if (!node)
3170
3193
    {
3171
3194
      if (info_recent_file_error)
3172
 
        info_error (info_recent_file_error);
 
3195
        info_error (info_recent_file_error, NULL, NULL);
3173
3196
      else
3174
3197
        {
3175
3198
          if (filename && *nodename != '(')
3176
 
            info_error (msg_cant_file_node, filename_non_directory (filename),
3177
 
                        nodename);
 
3199
            info_error ((char *) msg_cant_file_node,
 
3200
                filename_non_directory (filename),
 
3201
                nodename);
3178
3202
          else
3179
 
            info_error (msg_cant_find_node, nodename);
 
3203
            info_error ((char *) msg_cant_find_node, nodename, NULL);
3180
3204
        }
3181
3205
      return;
3182
3206
    }
3193
3217
 
3194
3218
#if defined (VERBOSE_NODE_DUMPING)
3195
3219
  /* Maybe we should print some information about the node being output. */
3196
 
  info_error (_("Writing node %s..."), node_printed_rep (node));
 
3220
  info_error ((char *) _("Writing node %s..."), node_printed_rep (node), NULL);
3197
3221
#endif /* VERBOSE_NODE_DUMPING */
3198
3222
 
3199
3223
  write_node_to_stream (node, stream);
3228
3252
/* Dump NODE to FILENAME.  If DUMP_SUBNODES is non-zero, recursively dump
3229
3253
   the nodes which appear in the menu of each node dumped. */
3230
3254
void
3231
 
dump_node_to_file (node, filename, dump_subnodes)
3232
 
     NODE *node;
3233
 
     char *filename;
3234
 
     int dump_subnodes;
 
3255
dump_node_to_file (NODE *node, char *filename, int dump_subnodes)
3235
3256
{
3236
3257
  FILE *output_stream;
3237
3258
  char *nodes_filename;
3245
3266
 
3246
3267
  if (!output_stream)
3247
3268
    {
3248
 
      info_error (_("Could not create output file `%s'."), filename);
 
3269
      info_error ((char *) _("Could not create output file `%s'."), filename,
 
3270
          NULL);
3249
3271
      return;
3250
3272
    }
3251
3273
 
3262
3284
    fclose (output_stream);
3263
3285
 
3264
3286
#if defined (VERBOSE_NODE_DUMPING)
3265
 
  info_error (_("Done."));
 
3287
  info_error ((char *) _("Done."), NULL, NULL);
3266
3288
#endif /* VERBOSE_NODE_DUMPING */
3267
3289
}
3268
3290
 
3278
3300
 
3279
3301
/* Print NODE on a printer piping it into INFO_PRINT_COMMAND. */
3280
3302
void
3281
 
print_node (node)
3282
 
     NODE *node;
 
3303
print_node (NODE *node)
3283
3304
{
3284
3305
  FILE *printer_pipe;
3285
3306
  char *print_command = getenv ("INFO_PRINT_COMMAND");
3307
3328
 
3308
3329
  if (!printer_pipe)
3309
3330
    {
3310
 
      info_error (_("Cannot open pipe to `%s'."), print_command);
 
3331
      info_error ((char *) _("Cannot open pipe to `%s'."), print_command, NULL);
3311
3332
      return;
3312
3333
    }
3313
3334
 
3314
3335
#if defined (VERBOSE_NODE_DUMPING)
3315
3336
  /* Maybe we should print some information about the node being output. */
3316
 
  info_error (_("Printing node %s..."), node_printed_rep (node));
 
3337
  info_error ((char *) _("Printing node %s..."), node_printed_rep (node), NULL);
3317
3338
#endif /* VERBOSE_NODE_DUMPING */
3318
3339
 
3319
3340
  write_node_to_stream (node, printer_pipe);
3323
3344
    fclose (printer_pipe);
3324
3345
 
3325
3346
#if defined (VERBOSE_NODE_DUMPING)
3326
 
  info_error (_("Done."));
 
3347
  info_error ((char *) _("Done."), NULL, NULL);
3327
3348
#endif /* VERBOSE_NODE_DUMPING */
3328
3349
}
3329
3350
 
3330
3351
static void
3331
 
write_node_to_stream (node, stream)
3332
 
     NODE *node;
3333
 
     FILE *stream;
 
3352
write_node_to_stream (NODE *node, FILE *stream)
3334
3353
{
3335
3354
  fwrite (node->contents, 1, node->nodelen, stream);
3336
3355
}
3347
3366
   to gc even those file buffer contents which had to be uncompressed. */
3348
3367
int gc_compressed_files = 0;
3349
3368
 
3350
 
static void info_gc_file_buffers ();
3351
 
static void info_search_1 ();
 
3369
static void info_gc_file_buffers (void);
 
3370
static void info_search_1 (WINDOW *window, int count,
 
3371
    unsigned char key, int case_sensitive, int ask_for_string);
3352
3372
 
3353
3373
static char *search_string = (char *)NULL;
3354
 
static int search_string_index = 0;
3355
3374
static int search_string_size = 0;
3356
3375
static int isearch_is_active = 0;
3357
3376
 
3360
3379
 
3361
3380
/* Return the file buffer which belongs to WINDOW's node. */
3362
3381
FILE_BUFFER *
3363
 
file_buffer_of_window (window)
3364
 
     WINDOW *window;
 
3382
file_buffer_of_window (WINDOW *window)
3365
3383
{
3366
3384
  /* If this window has no node, then it has no file buffer. */
3367
3385
  if (!window->node)
3383
3401
   DIR says which direction to search in.  If it is positive, search
3384
3402
   forward, else backwards. */
3385
3403
long
3386
 
info_search_in_node (string, node, start, window, dir, case_sensitive)
3387
 
     char *string;
3388
 
     NODE *node;
3389
 
     long start;
3390
 
     WINDOW *window;
3391
 
     int dir, case_sensitive;
 
3404
info_search_in_node (char *string, NODE *node, long int start,
 
3405
    WINDOW *window, int dir, int case_sensitive)
3392
3406
{
3393
3407
  SEARCH_BINDING binding;
3394
3408
  long offset;
3430
3444
   search at START.  Return the absolute position of the match, or -1, if
3431
3445
   no part of the string could be found. */
3432
3446
long
3433
 
info_target_search_node (node, string, start)
3434
 
     NODE *node;
3435
 
     char *string;
3436
 
     long start;
 
3447
info_target_search_node (NODE *node, char *string, long int start)
3437
3448
{
3438
3449
  register int i;
3439
 
  long offset;
 
3450
  long offset = 0;
3440
3451
  char *target;
3441
3452
 
3442
3453
  target = xstrdup (string);
3465
3476
   If the search fails, return non-zero, else zero.  Side-effect window
3466
3477
   leaving the node and point where the string was found current. */
3467
3478
static int
3468
 
info_search_internal (string, window, dir, case_sensitive)
3469
 
     char *string;
3470
 
     WINDOW *window;
3471
 
     int dir, case_sensitive;
 
3479
info_search_internal (char *string, WINDOW *window,
 
3480
    int dir, int case_sensitive)
3472
3481
{
3473
3482
  register int i;
3474
3483
  FILE_BUFFER *file_buffer;
3505
3514
     file's node list. */
3506
3515
  if (file_buffer->tags)
3507
3516
    {
3508
 
      register int current_tag, number_of_tags;
 
3517
      register int current_tag = 0, number_of_tags;
3509
3518
      char *last_subfile;
3510
3519
      TAG *tag;
3511
3520
 
3555
3564
          if (!echo_area_is_active && (last_subfile != tag->filename))
3556
3565
            {
3557
3566
              window_message_in_echo_area
3558
 
                (_("Searching subfile %s ..."),
3559
 
                 filename_non_directory (tag->filename));
 
3567
                ((char *) _("Searching subfile %s ..."),
 
3568
                 filename_non_directory (tag->filename), NULL);
3560
3569
 
3561
3570
              last_subfile = tag->filename;
3562
3571
            }
3569
3578
              if (!echo_area_is_active)
3570
3579
                {
3571
3580
                  if (info_recent_file_error)
3572
 
                    info_error (info_recent_file_error);
 
3581
                    info_error (info_recent_file_error, NULL, NULL);
3573
3582
                  else
3574
 
                    info_error (msg_cant_file_node,
 
3583
                    info_error ((char *) msg_cant_file_node,
3575
3584
                                filename_non_directory (file_buffer->filename),
3576
3585
                                tag->nodename);
3577
3586
                }
3630
3639
}
3631
3640
 
3632
3641
static void
3633
 
info_search_1 (window, count, key, case_sensitive, ask_for_string)
3634
 
     WINDOW *window;
3635
 
     int count;
3636
 
     unsigned char key;
3637
 
     int case_sensitive;
3638
 
     int ask_for_string;
 
3642
info_search_1 (WINDOW *window, int count, unsigned char key,
 
3643
    int case_sensitive, int ask_for_string)
3639
3644
{
3640
3645
  char *line, *prompt;
3641
3646
  int result, old_pagetop;
3662
3667
 
3663
3668
  if (ask_for_string)
3664
3669
    {
3665
 
      prompt = (char *)xmalloc (50 + strlen (search_string));
 
3670
      prompt = (char *)xmalloc (strlen (_("%s%sfor string [%s]: "))
 
3671
                                + strlen (_("Search backward"))
 
3672
                                + strlen (_("Search"))
 
3673
                                + strlen (_(" case-sensitively "))
 
3674
                                + strlen (_(" "))
 
3675
                                + strlen (search_string));
3666
3676
 
3667
3677
      sprintf (prompt, _("%s%sfor string [%s]: "),
3668
3678
               direction < 0 ? _("Search backward") : _("Search"),
3674
3684
 
3675
3685
      if (!line)
3676
3686
        {
3677
 
          info_abort_key ();
 
3687
          info_abort_key (window, 0, 0);
3678
3688
          return;
3679
3689
        }
3680
3690
 
3681
3691
      if (*line)
3682
3692
        {
3683
 
          if (strlen (line) + 1 > search_string_size)
 
3693
          if (strlen (line) + 1 > (unsigned int) search_string_size)
3684
3694
            search_string = (char *) xrealloc
3685
3695
              (search_string, (search_string_size += 50 + strlen (line)));
3686
3696
 
3687
3697
          strcpy (search_string, line);
3688
 
          search_string_index = strlen (line);
3689
3698
          free (line);
3690
3699
        }
3691
3700
    }
3706
3715
                                   active_window, direction, case_sensitive);
3707
3716
 
3708
3717
  if (result != 0 && !info_error_was_printed)
3709
 
    info_error (_("Search failed."));
 
3718
    info_error ((char *) _("Search failed."), NULL, NULL);
3710
3719
  else if (old_pagetop != active_window->pagetop)
3711
3720
    {
3712
3721
      int new_pagetop;
3727
3736
                      _("Repeat last search in the same direction"))
3728
3737
{
3729
3738
  if (!last_search_direction)
3730
 
    info_error (_("No previous search string"));
 
3739
    info_error ((char *) _("No previous search string"), NULL, NULL);
3731
3740
  else
3732
3741
    info_search_1 (window, last_search_direction * count,
3733
3742
                   key, last_search_case_sensitive, 0);
3737
3746
                      _("Repeat last search in the reverse direction"))
3738
3747
{
3739
3748
  if (!last_search_direction)
3740
 
    info_error (_("No previous search string"));
 
3749
    info_error ((char *) _("No previous search string"), NULL, NULL);
3741
3750
  else
3742
3751
    info_search_1 (window, -last_search_direction * count,
3743
3752
                   key, last_search_case_sensitive, 0);
3749
3758
/*                                                                  */
3750
3759
/* **************************************************************** */
3751
3760
 
3752
 
static void incremental_search ();
 
3761
static void incremental_search (WINDOW *window, int count,
 
3762
    unsigned char ignore);
3753
3763
 
3754
3764
DECLARE_INFO_COMMAND (isearch_forward,
3755
3765
                      _("Search interactively for a string as you type it"))
3773
3783
static int isearch_string_size = 0;
3774
3784
static unsigned char isearch_terminate_search_key = ESC;
3775
3785
 
3776
 
/* Structure defining the current state of an incremental search. */
3777
 
typedef struct {
3778
 
  WINDOW_STATE_DECL;    /* The node, pagetop and point. */
3779
 
  int search_index;     /* Offset of the last char in the search string. */
3780
 
  int direction;        /* The direction that this search is heading in. */
3781
 
  int failing;          /* Whether or not this search failed. */
3782
 
} SEARCH_STATE;
3783
 
 
3784
3786
/* Array of search states. */
3785
3787
static SEARCH_STATE **isearch_states = (SEARCH_STATE **)NULL;
3786
3788
static int isearch_states_index = 0;
3788
3790
 
3789
3791
/* Push the state of this search. */
3790
3792
static void
3791
 
push_isearch (window, search_index, direction, failing)
3792
 
     WINDOW *window;
3793
 
     int search_index, direction, failing;
 
3793
push_isearch (WINDOW *window, int search_index, int direction, int failing)
3794
3794
{
3795
3795
  SEARCH_STATE *state;
3796
3796
 
3806
3806
 
3807
3807
/* Pop the state of this search to WINDOW, SEARCH_INDEX, and DIRECTION. */
3808
3808
static void
3809
 
pop_isearch (window, search_index, direction, failing)
3810
 
     WINDOW *window;
3811
 
     int *search_index, *direction, *failing;
 
3809
pop_isearch (WINDOW *window, int *search_index, int *direction, int *failing)
3812
3810
{
3813
3811
  SEARCH_STATE *state;
3814
3812
 
3828
3826
 
3829
3827
/* Free the memory used by isearch_states. */
3830
3828
static void
3831
 
free_isearch_states ()
 
3829
free_isearch_states (void)
3832
3830
{
3833
3831
  register int i;
3834
3832
 
3842
3840
 
3843
3841
/* Display the current search in the echo area. */
3844
3842
static void
3845
 
show_isearch_prompt (dir, string, failing_p)
3846
 
     int dir;
3847
 
     unsigned char *string;
3848
 
     int failing_p;
 
3843
show_isearch_prompt (int dir, unsigned char *string, int failing_p)
3849
3844
{
3850
3845
  register int i;
3851
 
  char *prefix, *prompt, *p_rep;
3852
 
  int prompt_len, p_rep_index, p_rep_size;
 
3846
  const char *prefix;
 
3847
  char *prompt, *p_rep;
 
3848
  unsigned int prompt_len, p_rep_index, p_rep_size;
3853
3849
 
3854
3850
  if (dir < 0)
3855
3851
    prefix = _("I-search backward: ");
3877
3873
      p_rep_index += strlen (rep);
3878
3874
    }
3879
3875
 
3880
 
  prompt_len = strlen (prefix) + p_rep_index + 20;
3881
 
  prompt = (char *)xmalloc (prompt_len);
 
3876
  prompt_len = strlen (prefix) + p_rep_index + 1;
 
3877
  if (failing_p)
 
3878
    prompt_len += strlen (_("Failing "));
 
3879
  prompt = xmalloc (prompt_len);
3882
3880
  sprintf (prompt, "%s%s%s", failing_p ? _("Failing ") : "", prefix,
3883
3881
           p_rep ? p_rep : "");
3884
3882
 
3885
 
  window_message_in_echo_area ("%s", prompt);
 
3883
  window_message_in_echo_area ("%s", prompt, NULL);
3886
3884
  maybe_free (p_rep);
3887
3885
  free (prompt);
3888
3886
  display_cursor_at_point (active_window);
3889
3887
}
3890
3888
 
3891
3889
static void
3892
 
incremental_search (window, count, ignore)
3893
 
     WINDOW *window;
3894
 
     int count;
3895
 
     unsigned char ignore;
 
3890
incremental_search (WINDOW *window, int count, unsigned char ignore)
3896
3891
{
3897
3892
  unsigned char key;
3898
3893
  int last_search_result, search_result, dir;
3915
3910
 
3916
3911
  /* Show the search string in the echo area. */
3917
3912
  isearch_string[isearch_string_index] = '\0';
3918
 
  show_isearch_prompt (dir, isearch_string, search_result);
 
3913
  show_isearch_prompt (dir, (unsigned char *) isearch_string, search_result);
3919
3914
 
3920
3915
  isearch_is_active = 1;
3921
3916
 
3936
3931
      key = info_get_input_char ();
3937
3932
      window_get_state (window, &mystate);
3938
3933
 
3939
 
      if (key == DEL)
 
3934
      if (key == DEL || key == Control ('h'))
3940
3935
        {
3941
3936
          /* User wants to delete one level of search? */
3942
3937
          if (!isearch_states_index)
3949
3944
              pop_isearch
3950
3945
                (window, &isearch_string_index, &dir, &search_result);
3951
3946
              isearch_string[isearch_string_index] = '\0';
3952
 
              show_isearch_prompt (dir, isearch_string, search_result);
 
3947
              show_isearch_prompt (dir, (unsigned char *) isearch_string,
 
3948
                  search_result);
3953
3949
              goto after_search;
3954
3950
            }
3955
3951
        }
3967
3963
 
3968
3964
      if (!Meta_p (key) || key > 32)
3969
3965
        {
3970
 
          func = InfoFunction(window->keymap[key].function);
 
3966
          /* If this key is not a keymap, get its associated function,
 
3967
             if any.  If it is a keymap, then it's probably ESC from an
 
3968
             arrow key, and we handle that case below.  */
 
3969
          char type = window->keymap[key].type;
 
3970
          func = type == ISFUNC
 
3971
                 ? InfoFunction(window->keymap[key].function)
 
3972
                 : NULL;  /* function member is a Keymap if ISKMAP */
3971
3973
 
3972
 
          if (isprint (key) || func == (VFunction *)NULL)
 
3974
          if (isprint (key) || (type == ISFUNC && func == NULL))
3973
3975
            {
3974
3976
            insert_and_search:
3975
3977
 
3981
3983
              isearch_string[isearch_string_index] = '\0';
3982
3984
              goto search_now;
3983
3985
            }
3984
 
          else if (func == isearch_forward || func == isearch_backward)
 
3986
          else if (func == (VFunction *) isearch_forward
 
3987
              || func == (VFunction *) isearch_backward)
3985
3988
            {
3986
3989
              /* If this key invokes an incremental search, then this
3987
3990
                 means that we will either search again in the same
3988
3991
                 direction, search again in the reverse direction, or
3989
3992
                 insert the last search string that was accepted through
3990
3993
                 incremental searching. */
3991
 
              if ((func == isearch_forward && dir > 0) ||
3992
 
                  (func == isearch_backward && dir < 0))
 
3994
              if ((func == (VFunction *) isearch_forward && dir > 0) ||
 
3995
                  (func == (VFunction *) isearch_backward && dir < 0))
3993
3996
                {
3994
3997
                  /* If the user has typed no characters, then insert the
3995
3998
                     last successful search into the current search string. */
3998
4001
                      /* Of course, there must be something to insert. */
3999
4002
                      if (last_isearch_accepted)
4000
4003
                        {
4001
 
                          if (strlen (last_isearch_accepted) + 1 >=
4002
 
                              isearch_string_size)
 
4004
                          if (strlen ((char *) last_isearch_accepted) + 1
 
4005
                              >= (unsigned int) isearch_string_size)
4003
4006
                            isearch_string = (char *)
4004
4007
                              xrealloc (isearch_string,
4005
4008
                                        isearch_string_size += 10 +
4025
4028
                  dir = -dir;
4026
4029
                }
4027
4030
            }
4028
 
          else if (func == info_abort_key)
 
4031
          else if (func == (VFunction *) info_abort_key)
4029
4032
            {
4030
4033
              /* If C-g pressed, and the search is failing, pop the search
4031
4034
                 stack back to the last unfailed search. */
4036
4039
                    pop_isearch
4037
4040
                      (window, &isearch_string_index, &dir, &search_result);
4038
4041
                  isearch_string[isearch_string_index] = '\0';
4039
 
                  show_isearch_prompt (dir, isearch_string, search_result);
 
4042
                  show_isearch_prompt (dir, (unsigned char *) isearch_string,
 
4043
                      search_result);
4040
4044
                  continue;
4041
4045
                }
4042
4046
              else
4052
4056
             non-null.  Exit the search, remembering the search string.  If
4053
4057
             the key is not the same as the isearch_terminate_search_key,
4054
4058
             then push it into pending input. */
4055
 
          if (isearch_string_index && func != info_abort_key)
 
4059
          if (isearch_string_index && func != (VFunction *) info_abort_key)
4056
4060
            {
4057
4061
              maybe_free (last_isearch_accepted);
4058
4062
              last_isearch_accepted = xstrdup (isearch_string);
4071
4075
                  || info_any_buffered_input_p ()))
4072
4076
            info_set_pending_input (key);
4073
4077
 
4074
 
          if (func == info_abort_key)
 
4078
          if (func == (VFunction *) info_abort_key)
4075
4079
            {
4076
4080
              if (isearch_states_index)
4077
4081
                window_set_state (window, &orig_state);
4089
4093
 
4090
4094
      /* Search for the contents of isearch_string. */
4091
4095
    search_now:
4092
 
      show_isearch_prompt (dir, isearch_string, search_result);
 
4096
      show_isearch_prompt (dir, (unsigned char *) isearch_string, search_result);
4093
4097
 
4094
4098
      /* If the search string includes upper-case letters, make the
4095
4099
         search case-sensitive.  */
4131
4135
        terminal_ring_bell ();
4132
4136
 
4133
4137
    after_search:
4134
 
      show_isearch_prompt (dir, isearch_string, search_result);
 
4138
      show_isearch_prompt (dir, (unsigned char *) isearch_string, search_result);
4135
4139
 
4136
4140
      if (search_result == 0)
4137
4141
        {
4165
4169
   Garbage collecting a file buffer means to free the file buffers
4166
4170
   contents. */
4167
4171
static void
4168
 
info_gc_file_buffers ()
 
4172
info_gc_file_buffers (void)
4169
4173
{
4170
4174
  register int fb_index, iw_index, i;
4171
4175
  register FILE_BUFFER *fb;
4224
4228
 
4225
4229
/* Move to the next or previous cross reference in this node. */
4226
4230
static void
4227
 
info_move_to_xref (window, count, key, dir)
4228
 
     WINDOW *window;
4229
 
     int count;
4230
 
     unsigned char key;
4231
 
     int dir;
 
4231
info_move_to_xref (WINDOW *window, int count, unsigned char key, int dir)
4232
4232
{
4233
4233
  long firstmenu, firstxref;
4234
4234
  long nextmenu, nextxref;
4270
4270
 
4271
4271
  if (firstmenu == -1 && firstxref == -1)
4272
4272
    {
4273
 
      info_error (msg_no_xref_node);
 
4273
      info_error ((char *) msg_no_xref_node, NULL, NULL);
4274
4274
      return;
4275
4275
    }
4276
4276
 
4359
4359
                      _("Select reference or menu item appearing on this line"))
4360
4360
{
4361
4361
  char *line;
4362
 
  NODE *orig;
4363
4362
 
4364
 
  line = window->line_starts[window_line_of_point (window)];
4365
 
  orig = window->node;
 
4363
  if (window->line_starts)
 
4364
    line = window->line_starts[window_line_of_point (window)];
 
4365
  else
 
4366
    line = "";
4366
4367
 
4367
4368
  /* If this line contains a menu item, select that one. */
4368
4369
  if (strncmp ("* ", line, 2) == 0)
4385
4386
     do it. */
4386
4387
  if (!info_error_rings_bell_p)
4387
4388
    terminal_ring_bell ();
4388
 
  info_error (_("Quit"));
 
4389
  info_error ((char *) _("Quit"), NULL, NULL);
4389
4390
 
4390
4391
  info_initialize_numeric_arg ();
4391
4392
  info_clear_pending_input ();
4480
4481
{}
4481
4482
 
4482
4483
static void
4483
 
dispatch_error (keyseq)
4484
 
     char *keyseq;
 
4484
dispatch_error (char *keyseq)
4485
4485
{
4486
4486
  char *rep;
4487
4487
 
4488
4488
  rep = pretty_keyseq (keyseq);
4489
4489
 
4490
4490
  if (!echo_area_is_active)
4491
 
    info_error (_("Unknown command (%s)."), rep);
 
4491
    info_error ((char *) _("Unknown command (%s)."), rep, NULL);
4492
4492
  else
4493
4493
    {
4494
 
      char *temp = xmalloc (1 + strlen (rep) + strlen (_("\"\" is invalid")));
4495
 
      sprintf (temp, _("\"%s\" is invalid"), rep);
 
4494
      char *temp = xmalloc (1 + strlen (rep) + strlen (_("\"%s\" is invalid")));
 
4495
      sprintf (temp, _("`%s' is invalid"), rep);
4496
4496
      terminal_ring_bell ();
4497
4497
      inform_in_echo_area (temp);
4498
4498
      free (temp);
4507
4507
 
4508
4508
/* Initialize the length of the current key sequence. */
4509
4509
void
4510
 
initialize_keyseq ()
 
4510
initialize_keyseq (void)
4511
4511
{
4512
4512
  info_keyseq_index = 0;
4513
4513
  info_keyseq_displayed_p = 0;
4515
4515
 
4516
4516
/* Add CHARACTER to the current key sequence. */
4517
4517
void
4518
 
add_char_to_keyseq (character)
4519
 
     char character;
 
4518
add_char_to_keyseq (char character)
4520
4519
{
4521
4520
  if (info_keyseq_index + 2 >= info_keyseq_size)
4522
4521
    info_keyseq = (char *)xrealloc (info_keyseq, info_keyseq_size += 10);
4528
4527
/* Display the current value of info_keyseq.  If argument EXPECTING is
4529
4528
   non-zero, input is expected to be read after the key sequence is
4530
4529
   displayed, so add an additional prompting character to the sequence. */
4531
 
void
4532
 
display_info_keyseq (expecting_future_input)
4533
 
     int expecting_future_input;
 
4530
static void
 
4531
display_info_keyseq (int expecting_future_input)
4534
4532
{
4535
4533
  char *rep;
4536
4534
 
4542
4540
    inform_in_echo_area (rep);
4543
4541
  else
4544
4542
    {
4545
 
      window_message_in_echo_area (rep);
 
4543
      window_message_in_echo_area (rep, NULL, NULL);
4546
4544
      display_cursor_at_point (active_window);
4547
4545
    }
4548
4546
  info_keyseq_displayed_p = 1;
4550
4548
 
4551
4549
/* Called by interactive commands to read a keystroke. */
4552
4550
unsigned char
4553
 
info_get_another_input_char ()
 
4551
info_get_another_input_char (void)
4554
4552
{
4555
4553
  int ready = !info_keyseq_displayed_p; /* ready if new and pending key */
4556
4554
 
4587
4585
/* Do the command associated with KEY in MAP.  If the associated command is
4588
4586
   really a keymap, then read another key, and dispatch into that map. */
4589
4587
void
4590
 
info_dispatch_on_key (key, map)
4591
 
     unsigned char key;
4592
 
     Keymap map;
 
4588
info_dispatch_on_key (unsigned char key, Keymap map)
4593
4589
{
4594
4590
#if !defined(INFOKEY)
4595
4591
  if (Meta_p (key) && (!ISO_Latin_p || map[key].function != ea_insert))
4619
4615
        if (func != (VFunction *)NULL)
4620
4616
          {
4621
4617
            /* Special case info_do_lowercase_version (). */
4622
 
            if (func == info_do_lowercase_version)
 
4618
            if (func == (VFunction *) info_do_lowercase_version)
4623
4619
              {
4624
4620
#if defined(INFOKEY)
4625
4621
                unsigned char lowerkey;
4727
4723
 
4728
4724
/* Create a default argument. */
4729
4725
void
4730
 
info_initialize_numeric_arg ()
 
4726
info_initialize_numeric_arg (void)
4731
4727
{
4732
4728
  info_numeric_arg = info_numeric_arg_sign = 1;
4733
4729
  info_explicit_arg = 0;
4768
4764
        key = UnMeta (key);
4769
4765
#endif /* !defined(INFOKEY) */
4770
4766
 
4771
 
      if (keymap[key].type == ISFUNC &&
4772
 
          InfoFunction(keymap[key].function) == info_universal_argument)
 
4767
      if (keymap[key].type == ISFUNC
 
4768
          && InfoFunction(keymap[key].function)
 
4769
              == (VFunction *) info_universal_argument)
4773
4770
        {
4774
4771
          info_numeric_arg *= 4;
4775
4772
          key = 0;
4819
4816
 
4820
4817
/* How to make there be no pending input. */
4821
4818
static void
4822
 
info_clear_pending_input ()
 
4819
info_clear_pending_input (void)
4823
4820
{
4824
4821
  pending_input_character = 0;
4825
4822
}
4826
4823
 
4827
4824
/* How to set the pending input character. */
4828
4825
static void
4829
 
info_set_pending_input (key)
4830
 
     unsigned char key;
 
4826
info_set_pending_input (unsigned char key)
4831
4827
{
4832
4828
  pending_input_character = key;
4833
4829
}
4834
4830
 
4835
4831
/* How to see if there is any pending input. */
4836
4832
unsigned char
4837
 
info_input_pending_p ()
 
4833
info_input_pending_p (void)
4838
4834
{
4839
4835
  return (pending_input_character);
4840
4836
}
4847
4843
 
4848
4844
/* Add KEY to the buffer of characters to be read. */
4849
4845
static void
4850
 
info_push_typeahead (key)
4851
 
     unsigned char key;
 
4846
info_push_typeahead (unsigned char key)
4852
4847
{
4853
4848
  /* Flush all pending input in the case of C-g pressed. */
4854
4849
  if (key == Control ('g'))
4859
4854
  else
4860
4855
    {
4861
4856
      info_input_buffer[push_index++] = key;
4862
 
      if (push_index >= sizeof (info_input_buffer))
 
4857
      if ((unsigned int) push_index >= sizeof (info_input_buffer))
4863
4858
        push_index = 0;
4864
4859
    }
4865
4860
}
4866
4861
 
4867
4862
/* Return the amount of space available in INFO_INPUT_BUFFER for new chars. */
4868
4863
static int
4869
 
info_input_buffer_space_available ()
 
4864
info_input_buffer_space_available (void)
4870
4865
{
4871
4866
  if (pop_index > push_index)
4872
4867
    return (pop_index - push_index);
4878
4873
   Return the key in KEY.
4879
4874
   Result is non-zero if there was a key, or 0 if there wasn't. */
4880
4875
static int
4881
 
info_get_key_from_typeahead (key)
4882
 
     unsigned char *key;
 
4876
info_get_key_from_typeahead (unsigned char *key)
4883
4877
{
4884
4878
  if (push_index == pop_index)
4885
4879
    return (0);
4886
4880
 
4887
4881
  *key = info_input_buffer[pop_index++];
4888
4882
 
4889
 
  if (pop_index >= sizeof (info_input_buffer))
 
4883
  if ((unsigned int) pop_index >= sizeof (info_input_buffer))
4890
4884
    pop_index = 0;
4891
4885
 
4892
4886
  return (1);
4893
4887
}
4894
4888
 
4895
4889
int
4896
 
info_any_buffered_input_p ()
 
4890
info_any_buffered_input_p (void)
4897
4891
{
4898
4892
  info_gather_typeahead ();
4899
4893
  return (push_index != pop_index);
4902
4896
/* If characters are available to be read, then read them and stuff them into
4903
4897
   info_input_buffer.  Otherwise, do nothing. */
4904
4898
void
4905
 
info_gather_typeahead ()
 
4899
info_gather_typeahead (void)
4906
4900
{
4907
4901
  register int i = 0;
4908
4902
  int tty, space_avail;
4976
4970
 
4977
4971
/* How to read a single character. */
4978
4972
unsigned char
4979
 
info_get_input_char ()
 
4973
info_get_input_char (void)
4980
4974
{
4981
4975
  unsigned char keystroke;
4982
4976