diff options
author | kstailey <kstailey@cvs.openbsd.org> | 1997-08-01 22:01:13 +0000 |
---|---|---|
committer | kstailey <kstailey@cvs.openbsd.org> | 1997-08-01 22:01:13 +0000 |
commit | fb4e1ba7a0121d1ec25d64c435bbe34d8af2c483 (patch) | |
tree | 56943425b2911615f1f19a77184fa1d158c23ab0 /gnu/usr.bin/texinfo/info | |
parent | 80b94d3721d130e60304019cc5c83ede42cd48a1 (diff) |
Import of FSF texinfo 3.11
Diffstat (limited to 'gnu/usr.bin/texinfo/info')
-rw-r--r-- | gnu/usr.bin/texinfo/info/Makefile.am | 44 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/README | 6 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/doc.c | 129 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/doc.h | 16 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/dribble.c | 2 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/echo-area.c | 1505 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/echo-area.h | 64 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/funs.h | 111 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/gc.c | 2 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/info-utils.c | 197 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/infomap.h | 10 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/nodes.c | 796 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/search.c | 180 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/session.h | 16 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/signals.c | 121 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/terminal.h | 16 | ||||
-rw-r--r-- | gnu/usr.bin/texinfo/info/tilde.h | 12 |
17 files changed, 2515 insertions, 712 deletions
diff --git a/gnu/usr.bin/texinfo/info/Makefile.am b/gnu/usr.bin/texinfo/info/Makefile.am new file mode 100644 index 00000000000..6ff91f8a51c --- /dev/null +++ b/gnu/usr.bin/texinfo/info/Makefile.am @@ -0,0 +1,44 @@ +## Makefile.am for texinfo/info. +## $Id: Makefile.am,v 1.1 1997/08/01 21:59:59 kstailey Exp $ +## Run automake in .. to produce Makefile.in from this. + +noinst_PROGRAMS = makedoc + +# Use `ginfo' for building to avoid confusion with the standard `info' +# target. The install rule removes the `g' before applying any +# user-specified name transformations. +bin_PROGRAMS = ginfo +transform = s/ginfo/info/; @program_transform_name@ + +localedir = $(datadir)/locale + +# -I. for funs.h. +INCLUDES = -I. -I$(top_srcdir)/lib -I../intl -DLOCALEDIR=\"$(localedir)\" +LDADD = ../lib/libtxi.a @TERMLIBS@ @INTLLIBS@ + +makedoc_SOURCES = makedoc.c +ginfo_SOURCES = dir.c display.c display.h doc.c doc.h dribble.c dribble.h \ + echo-area.c echo-area.h \ + filesys.c filesys.h footnotes.c footnotes.h funs.h gc.c gc.h \ + indices.c indices.h info-utils.c info-utils.h info.c info.h infodoc.c \ + infomap.c infomap.h m-x.c man.c man.h nodemenu.c nodes.c nodes.h \ + search.c search.h session.c session.h signals.c signals.h \ + termdep.h terminal.c terminal.h tilde.c tilde.h \ + variables.c variables.h window.c window.h + +EXTRA_DIST = README + +# The files `doc.c' and `funs.h' are created by ./makedoc run over the source +# files which contain DECLARE_INFO_COMMAND. `funs.h' is a header file +# listing the functions found. `doc.c' is a structure containing pointers +# to those functions along with completable names and documentation strings. +# +# I do not know how to get this right. +# BUILT_SOURCES = doc.c funs.h +# +#cmd_sources = $(srcdir)/session.c $(srcdir)/echo-area.c $(srcdir)/infodoc.c \ +# $(srcdir)/m-x.c $(srcdir)/indices.c $(srcdir)/nodemenu.c \ +# $(srcdir)/footnotes.c $(srcdir)/variables.c +# +#$(BUILTSOURCES): makedoc $(cmd_sources) +# ./makedoc $(cmd_sources) diff --git a/gnu/usr.bin/texinfo/info/README b/gnu/usr.bin/texinfo/info/README index d8f1ab624d8..90d3e2cd522 100644 --- a/gnu/usr.bin/texinfo/info/README +++ b/gnu/usr.bin/texinfo/info/README @@ -1,9 +1,3 @@ -The file NEWS contains information about what has changed since the last -release. - -The file ../INSTALL contains instructions on how to install Info. - - Info 2.0 is a complete rewrite of the original standalone Info I wrote in 1987, the first program I wrote for rms. That program was something like my second Unix program ever, and my die-hard machine language coding habits diff --git a/gnu/usr.bin/texinfo/info/doc.c b/gnu/usr.bin/texinfo/info/doc.c new file mode 100644 index 00000000000..3859b7fd66a --- /dev/null +++ b/gnu/usr.bin/texinfo/info/doc.c @@ -0,0 +1,129 @@ +/* doc.c -- Generated structure containing function names and doc strings. + + This file was automatically made from various source files with the + command "./makedoc". DO NOT EDIT THIS FILE, only "./makedoc.c". + Source files groveled to make this file include: + + ./session.c + ./echo-area.c + ./infodoc.c + ./m-x.c + ./indices.c + ./nodemenu.c + ./footnotes.c + ./variables.c + + An entry in the array FUNCTION_DOC_ARRAY is made for each command + found in the above files; each entry consists of a function pointer, + a string which is the user-visible name of the function, + and a string which documents its purpose. */ + +#include "doc.h" +#include "funs.h" + +FUNCTION_DOC function_doc_array[] = { + +/* Commands found in "./session.c". */ + { info_next_line, "next-line", N_("Move down to the next line") }, + { info_prev_line, "prev-line", N_("Move up to the previous line") }, + { info_end_of_line, "end-of-line", N_("Move to the end of the line") }, + { info_beginning_of_line, "beginning-of-line", N_("Move to the start of the line") }, + { info_forward_char, "forward-char", N_("Move forward a character") }, + { info_backward_char, "backward-char", N_("Move backward a character") }, + { info_forward_word, "forward-word", N_("Move forward a word") }, + { info_backward_word, "backward-word", N_("Move backward a word") }, + { info_global_next_node, "global-next-node", N_("Move forwards or down through node structure") }, + { info_global_prev_node, "global-prev-node", N_("Move backwards or up through node structure") }, + { info_scroll_forward, "scroll-forward", N_("Scroll forward in this window") }, + { info_scroll_backward, "scroll-backward", N_("Scroll backward in this window") }, + { info_beginning_of_node, "beginning-of-node", N_("Move to the start of this node") }, + { info_end_of_node, "end-of-node", N_("Move to the end of this node") }, + { info_next_window, "next-window", N_("Select the next window") }, + { info_prev_window, "prev-window", N_("Select the previous window") }, + { info_split_window, "split-window", N_("Split the current window") }, + { info_delete_window, "delete-window", N_("Delete the current window") }, + { info_keep_one_window, "keep-one-window", N_("Delete all other windows") }, + { info_scroll_other_window, "scroll-other-window", N_("Scroll the other window") }, + { info_grow_window, "grow-window", N_("Grow (or shrink) this window") }, + { info_tile_windows, "tile-windows", N_("Divide the available screen space among the visible windows") }, + { info_toggle_wrap, "toggle-wrap", N_("Toggle the state of line wrapping in the current window") }, + { info_next_node, "next-node", N_("Select the `Next' node") }, + { info_prev_node, "prev-node", N_("Select the `Prev' node") }, + { info_up_node, "up-node", N_("Select the `Up' node") }, + { info_last_node, "last-node", N_("Select the last node in this file") }, + { info_first_node, "first-node", N_("Select the first node in this file") }, + { info_history_node, "history-node", N_("Select the most recently selected node") }, + { info_last_menu_item, "last-menu-item", N_("Select the last item in this node's menu") }, + { info_menu_digit, "menu-digit", N_("Select this menu item") }, + { info_menu_item, "menu-item", N_("Read a menu item and select its node") }, + { info_xref_item, "xref-item", N_("Read a footnote or cross reference and select its node") }, + { info_find_menu, "find-menu", N_("Move to the start of this node's menu") }, + { info_visit_menu, "visit-menu", N_("Visit as many menu items at once as possible") }, + { info_goto_node, "goto-node", N_("Read a node name and select it") }, + { info_man, "man", N_("Read a manpage reference and select it") }, + { info_top_node, "top-node", N_("Select the node `Top' in this file") }, + { info_dir_node, "dir-node", N_("Select the node `(dir)'") }, + { info_kill_node, "kill-node", N_("Kill this node") }, + { info_view_file, "view-file", N_("Read the name of a file and select it") }, + { info_print_node, "print-node", N_("Pipe the contents of this node through INFO_PRINT_COMMAND") }, + { info_search, "search", N_("Read a string and search for it") }, + { isearch_forward, "isearch-forward", N_("Search interactively for a string as you type it") }, + { isearch_backward, "isearch-backward", N_("Search interactively for a string as you type it") }, + { info_move_to_prev_xref, "move-to-prev-xref", N_("Move to the previous cross reference") }, + { info_move_to_next_xref, "move-to-next-xref", N_("Move to the next cross reference") }, + { info_select_reference_this_line, "select-reference-this-line", N_("Select reference or menu item appearing on this line") }, + { info_abort_key, "abort-key", N_("Cancel current operation") }, + { info_move_to_window_line, "move-to-window-line", N_("Move to the cursor to a specific line of the window") }, + { info_redraw_display, "redraw-display", N_("Redraw the display") }, + { info_quit, "quit", N_("Quit using Info") }, + { info_do_lowercase_version, "do-lowercase-version", "" }, + { info_add_digit_to_numeric_arg, "add-digit-to-numeric-arg", N_("Add this digit to the current numeric argument") }, + { info_universal_argument, N_("universal-argument"), N_("Start (or multiply by 4) the current numeric argument") }, + { info_numeric_arg_digit_loop, "numeric-arg-digit-loop", N_("Internally used by \\[universal-argument]") }, +/* Commands found in "./echo-area.c". */ + { ea_forward, "echo-area-forward", N_("Move forward a character") }, + { ea_backward, "echo-area-backward", N_("Move backward a character") }, + { ea_beg_of_line, "echo-area-beg-of-line", N_("Move to the start of this line") }, + { ea_end_of_line, "echo-area-end-of-line", N_("Move to the end of this line") }, + { ea_forward_word, "echo-area-forward-word", N_("Move forward a word") }, + { ea_backward_word, "echo-area-backward-word", N_("Move backward a word") }, + { ea_delete, "echo-area-delete", N_("Delete the character under the cursor") }, + { ea_rubout, "echo-area-rubout", N_("Delete the character behind the cursor") }, + { ea_abort, "echo-area-abort", N_("Cancel or quit operation") }, + { ea_newline, "echo-area-newline", N_("Accept (or force completion of) this line") }, + { ea_quoted_insert, "echo-area-quoted-insert", N_("Insert next character verbatim") }, + { ea_insert, "echo-area-insert", N_("Insert this character") }, + { ea_tab_insert, "echo-area-tab-insert", N_("Insert a TAB character") }, + { ea_transpose_chars, "echo-area-transpose-chars", N_("Transpose characters at point") }, + { ea_yank, "echo-area-yank", N_("Yank back the contents of the last kill") }, + { ea_yank_pop, "echo-area-yank-pop", N_("Yank back a previous kill") }, + { ea_kill_line, "echo-area-kill-line", N_("Kill to the end of the line") }, + { ea_backward_kill_line, "echo-area-backward-kill-line", N_("Kill to the beginning of the line") }, + { ea_kill_word, "echo-area-kill-word", N_("Kill the word following the cursor") }, + { ea_backward_kill_word, "echo-area-backward-kill-word", N_("Kill the word preceding the cursor") }, + { ea_possible_completions, "echo-area-possible-completions", N_("List possible completions") }, + { ea_complete, "echo-area-complete", N_("Insert completion") }, + { ea_scroll_completions_window, "echo-area-scroll-completions-window", N_("Scroll the completions window") }, +/* Commands found in "./infodoc.c". */ + { info_get_help_window, "get-help-window", N_("Display help message") }, + { info_get_info_help_node, "get-info-help-node", N_("Visit Info node `(info)Help'") }, + { describe_key, "describe-key", N_("Print documentation for KEY") }, + { info_where_is, "where-is", N_("Show what to type to execute a given command") }, +/* Commands found in "./m-x.c". */ + { describe_command, "describe-command", N_("Read the name of an Info command and describe it") }, + { info_execute_command, "execute-command", N_("Read a command name in the echo area and execute it") }, + { set_screen_height, "set-screen-height", N_("Set the height of the displayed window") }, +/* Commands found in "./indices.c". */ + { info_index_search, "index-search", N_("Look up a string in the index for this file") }, + { info_next_index_match, "next-index-match", N_("Go to the next matching index item from the last `\\[index-search]' command") }, + { info_index_apropos, "index-apropos", N_("Grovel all known info file's indices for a string and build a menu") }, +/* Commands found in "./nodemenu.c". */ + { list_visited_nodes, "list-visited-nodes", N_("Make a window containing a menu of all of the currently visited nodes") }, + { select_visited_node, "select-visited-node", N_("Select a node which has been previously visited in a visible window") }, +/* Commands found in "./footnotes.c". */ + { info_show_footnotes, "show-footnotes", N_("Show the footnotes associated with this node in another window") }, +/* Commands found in "./variables.c". */ + { describe_variable, "describe-variable", N_("Explain the use of a variable") }, + { set_variable, "set-variable", N_("Set the value of an Info variable") }, + { (VFunction *)NULL, (char *)NULL, (char *)NULL } +}; diff --git a/gnu/usr.bin/texinfo/info/doc.h b/gnu/usr.bin/texinfo/info/doc.h index 8afc28f7446..423998e37c8 100644 --- a/gnu/usr.bin/texinfo/info/doc.h +++ b/gnu/usr.bin/texinfo/info/doc.h @@ -21,18 +21,10 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#if !defined (_DOC_H_) -#define _DOC_H_ +#if !defined (DOC_H) +#define DOC_H -#if !defined (NULL) -# define NULL 0x0 -#endif /* !NULL */ - -#if !defined (__FUNCTION_DEF) -# define __FUNCTION_DEF -typedef int Function (); -typedef void VFunction (); -#endif /* _FUNCTION_DEF */ +#include "info.h" /* for NAMED_FUNCTIONS, VFunction, etc. */ typedef struct { VFunction *func; @@ -55,4 +47,4 @@ extern void dump_map_to_message_buffer (); extern char *function_name (); extern VFunction *named_function (); #endif /* NAMED_FUNCTIONS */ -#endif /* !_DOC_H_ */ +#endif /* !DOC_H */ diff --git a/gnu/usr.bin/texinfo/info/dribble.c b/gnu/usr.bin/texinfo/info/dribble.c index 8e16cea4e45..d1d58486560 100644 --- a/gnu/usr.bin/texinfo/info/dribble.c +++ b/gnu/usr.bin/texinfo/info/dribble.c @@ -21,7 +21,7 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#include <stdio.h> +#include "info.h" #include "dribble.h" /* When non-zero, it is a stream to write all input characters to for the diff --git a/gnu/usr.bin/texinfo/info/echo-area.c b/gnu/usr.bin/texinfo/info/echo-area.c new file mode 100644 index 00000000000..f3e7a04f5af --- /dev/null +++ b/gnu/usr.bin/texinfo/info/echo-area.c @@ -0,0 +1,1505 @@ +/* echo-area.c -- How to read a line in the echo area. + $Id: echo-area.c,v 1.1 1997/08/01 22:00:07 kstailey Exp $ + + Copyright (C) 1993, 97 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Written by Brian Fox (bfox@ai.mit.edu). */ + +#include "info.h" + +#if defined (FD_SET) +# if defined (hpux) +# define fd_set_cast(x) (int *)(x) +# else +# define fd_set_cast(x) (fd_set *)(x) +# endif /* !hpux */ +#endif /* FD_SET */ + +/* Non-zero means that C-g was used to quit reading input. */ +int info_aborted_echo_area = 0; + +/* Non-zero means that the echo area is being used to read input. */ +int echo_area_is_active = 0; + +/* The address of the last command executed in the echo area. */ +VFunction *ea_last_executed_command = (VFunction *)NULL; + +/* Non-zero means that the last command executed while reading input + killed some text. */ +int echo_area_last_command_was_kill = 0; + +/* Variables which hold on to the current state of the input line. */ +static char input_line[1 + EA_MAX_INPUT]; +static char *input_line_prompt; +static int input_line_point; +static int input_line_beg; +static int input_line_end; +static NODE input_line_node = { + (char *)NULL, (char *)NULL, (char *)NULL, input_line, EA_MAX_INPUT, 0 +}; + +static void echo_area_initialize_node (); +static void push_echo_area (), pop_echo_area (); +static int echo_area_stack_contains_completions_p (); + +static void ea_kill_text (); + +/* Non-zero means we force the user to complete. */ +static int echo_area_must_complete_p = 0; +static int completions_window_p (); + +/* If non-null, this is a window which was specifically created to display + possible completions output. We remember it so we can delete it when + appropriate. */ +static WINDOW *echo_area_completions_window = (WINDOW *)NULL; + +/* Variables which keep track of the window which was active prior to + entering the echo area. */ +static WINDOW *calling_window = (WINDOW *)NULL; +static NODE *calling_window_node = (NODE *)NULL; +static long calling_window_point = 0; +static long calling_window_pagetop = 0; + +/* Remember the node and pertinent variables of the calling window. */ +static void +remember_calling_window (window) + WINDOW *window; +{ + /* Only do this if the calling window is not the completions window, or, + if it is the completions window and there is no other window. */ + if (!completions_window_p (window) || + ((window == windows) && !(window->next))) + { + calling_window = window; + calling_window_node = window->node; + calling_window_point = window->point; + calling_window_pagetop = window->pagetop; + } +} + +/* Restore the caller's window so that it shows the node that it was showing + on entry to info_read_xxx_echo_area (). */ +static void +restore_calling_window () +{ + register WINDOW *win, *compwin = (WINDOW *)NULL; + + /* If the calling window is still visible, and it is the window that + we used for completions output, then restore the calling window. */ + for (win = windows; win; win = win->next) + { + if (completions_window_p (win)) + compwin = win; + + if (win == calling_window && win == compwin) + { + window_set_node_of_window (calling_window, calling_window_node); + calling_window->point = calling_window_point; + calling_window->pagetop = calling_window_pagetop; + compwin = (WINDOW *)NULL; + break; + } + } + + /* Delete the completions window if it is still present, it isn't the + last window on the screen, and there aren't any prior echo area reads + pending which created a completions window. */ + if (compwin) + { + if ((compwin != windows || windows->next) && + !echo_area_stack_contains_completions_p ()) + { + WINDOW *next; + int pagetop, start, end, amount; + + next = compwin->next; + if (next) + { + start = next->first_row; + end = start + next->height; + amount = - (compwin->height + 1); + pagetop = next->pagetop; + } + + info_delete_window_internal (compwin); + + /* This is not necessary because info_delete_window_internal () + calls echo_area_inform_of_deleted_window (), which does the + right thing. */ +#if defined (UNNECESSARY) + echo_area_completions_window = (WINDOW *)NULL; +#endif /* UNNECESSARY */ + + if (next) + { + display_scroll_display (start, end, amount); + next->pagetop = pagetop; + display_update_display (windows); + } + } + } +} + +/* Set up a new input line with PROMPT. */ +static void +initialize_input_line (prompt) + char *prompt; +{ + input_line_prompt = prompt; + if (prompt) + strcpy (input_line, prompt); + else + input_line[0] = '\0'; + + input_line_beg = input_line_end = input_line_point = strlen (prompt); +} + +static char * +echo_area_after_read () +{ + char *return_value; + + if (info_aborted_echo_area) + { + info_aborted_echo_area = 0; + return_value = (char *)NULL; + } + else + { + if (input_line_beg == input_line_end) + return_value = xstrdup (""); + else + { + int line_len = input_line_end - input_line_beg; + return_value = (char *) xmalloc (1 + line_len); + strncpy (return_value, &input_line[input_line_beg], line_len); + return_value[line_len] = '\0'; + } + } + return (return_value); +} + +/* Read a line of text in the echo area. Return a malloc ()'ed string, + or NULL if the user aborted out of this read. WINDOW is the currently + active window, so that we can restore it when we need to. PROMPT, if + non-null, is a prompt to print before reading the line. */ +char * +info_read_in_echo_area (window, prompt) + WINDOW *window; + char *prompt; +{ + char *line; + + /* If the echo area is already active, remember the current state. */ + if (echo_area_is_active) + push_echo_area (); + + /* Initialize our local variables. */ + initialize_input_line (prompt); + + /* Initialize the echo area for the first (but maybe not the last) time. */ + echo_area_initialize_node (); + + /* Save away the original node of this window, and the window itself, + so echo area commands can temporarily use this window. */ + remember_calling_window (window); + + /* Let the rest of Info know that the echo area is active. */ + echo_area_is_active++; + active_window = the_echo_area; + + /* Read characters in the echo area. */ + info_read_and_dispatch (); + + echo_area_is_active--; + + /* Restore the original active window and show point in it. */ + active_window = calling_window; + restore_calling_window (); + display_cursor_at_point (active_window); + fflush (stdout); + + /* Get the value of the line. */ + line = echo_area_after_read (); + + /* If there is a previous loop waiting for us, restore it now. */ + if (echo_area_is_active) + pop_echo_area (); + + /* Return the results to the caller. */ + return (line); +} + +/* (re) Initialize the echo area node. */ +static void +echo_area_initialize_node () +{ + register int i; + + for (i = input_line_end; i < sizeof (input_line); i++) + input_line[i] = ' '; + + input_line[i - 1] = '\n'; + window_set_node_of_window (the_echo_area, &input_line_node); + input_line[input_line_end] = '\n'; +} + +/* Prepare to read characters in the echo area. This can initialize the + echo area node, but its primary purpose is to side effect the input + line buffer contents. */ +void +echo_area_prep_read () +{ + if (the_echo_area->node != &input_line_node) + echo_area_initialize_node (); + + the_echo_area->point = input_line_point; + input_line[input_line_end] = '\n'; + display_update_one_window (the_echo_area); + display_cursor_at_point (active_window); +} + + +/* **************************************************************** */ +/* */ +/* Echo Area Movement Commands */ +/* */ +/* **************************************************************** */ + +DECLARE_INFO_COMMAND (ea_forward, _("Move forward a character")) +{ + if (count < 0) + ea_backward (window, -count, key); + else + { + input_line_point += count; + if (input_line_point > input_line_end) + input_line_point = input_line_end; + } +} + +DECLARE_INFO_COMMAND (ea_backward, _("Move backward a character")) +{ + if (count < 0) + ea_forward (window, -count, key); + else + { + input_line_point -= count; + if (input_line_point < input_line_beg) + input_line_point = input_line_beg; + } +} + +DECLARE_INFO_COMMAND (ea_beg_of_line, _("Move to the start of this line")) +{ + input_line_point = input_line_beg; +} + +DECLARE_INFO_COMMAND (ea_end_of_line, _("Move to the end of this line")) +{ + input_line_point = input_line_end; +} + +#define alphabetic(c) (islower (c) || isupper (c) || isdigit (c)) + +/* Move forward a word in the input line. */ +DECLARE_INFO_COMMAND (ea_forward_word, _("Move forward a word")) +{ + int c; + + if (count < 0) + ea_backward_word (window, -count, key); + else + { + while (count--) + { + if (input_line_point == input_line_end) + return; + + /* If we are not in a word, move forward until we are in one. + Then, move forward until we hit a non-alphabetic character. */ + c = input_line[input_line_point]; + + if (!alphabetic (c)) + { + while (++input_line_point < input_line_end) + { + c = input_line[input_line_point]; + if (alphabetic (c)) + break; + } + } + + if (input_line_point == input_line_end) + return; + + while (++input_line_point < input_line_end) + { + c = input_line[input_line_point]; + if (!alphabetic (c)) + break; + } + } + } +} + +DECLARE_INFO_COMMAND (ea_backward_word, _("Move backward a word")) +{ + int c; + + if (count < 0) + ea_forward_word (window, -count, key); + else + { + while (count--) + { + if (input_line_point == input_line_beg) + return; + + /* Like ea_forward_word (), except that we look at the + characters just before point. */ + + c = input_line[input_line_point - 1]; + + if (!alphabetic (c)) + { + while ((--input_line_point) != input_line_beg) + { + c = input_line[input_line_point - 1]; + if (alphabetic (c)) + break; + } + } + + while (input_line_point != input_line_beg) + { + c = input_line[input_line_point - 1]; + if (!alphabetic (c)) + break; + else + --input_line_point; + } + } + } +} + +DECLARE_INFO_COMMAND (ea_delete, _("Delete the character under the cursor")) +{ + register int i; + + if (count < 0) + ea_rubout (window, -count, key); + else + { + if (input_line_point == input_line_end) + return; + + if (info_explicit_arg || count > 1) + { + int orig_point; + + orig_point = input_line_point; + ea_forward (window, count, key); + ea_kill_text (orig_point, input_line_point); + input_line_point = orig_point; + } + else + { + for (i = input_line_point; i < input_line_end; i++) + input_line[i] = input_line[i + 1]; + + input_line_end--; + } + } +} + +DECLARE_INFO_COMMAND (ea_rubout, _("Delete the character behind the cursor")) +{ + if (count < 0) + ea_delete (window, -count, key); + else + { + int start; + + if (input_line_point == input_line_beg) + return; + + start = input_line_point; + ea_backward (window, count, key); + + if (info_explicit_arg || count > 1) + ea_kill_text (start, input_line_point); + else + ea_delete (window, count, key); + } +} + +DECLARE_INFO_COMMAND (ea_abort, _("Cancel or quit operation")) +{ + /* If any text, just discard it, and restore the calling window's node. + If no text, quit. */ + if (input_line_end != input_line_beg) + { + terminal_ring_bell (); + input_line_end = input_line_point = input_line_beg; + if (calling_window->node != calling_window_node) + restore_calling_window (); + } + else + info_aborted_echo_area = 1; +} + +DECLARE_INFO_COMMAND (ea_newline, _("Accept (or force completion of) this line")) +{ + /* Stub does nothing. Simply here to see if it has been executed. */ +} + +DECLARE_INFO_COMMAND (ea_quoted_insert, _("Insert next character verbatim")) +{ + unsigned char character; + + character = info_get_another_input_char (); + ea_insert (window, count, character); +} + +DECLARE_INFO_COMMAND (ea_insert, _("Insert this character")) +{ + register int i; + + if ((input_line_end + 1) == EA_MAX_INPUT) + { + terminal_ring_bell (); + return; + } + + for (i = input_line_end + 1; i != input_line_point; i--) + input_line[i] = input_line[i - 1]; + + input_line[input_line_point] = key; + input_line_point++; + input_line_end++; +} + +DECLARE_INFO_COMMAND (ea_tab_insert, _("Insert a TAB character")) +{ + ea_insert (window, count, '\t'); +} + +/* Transpose the characters at point. If point is at the end of the line, + then transpose the characters before point. */ +DECLARE_INFO_COMMAND (ea_transpose_chars, _("Transpose characters at point")) +{ + /* Handle conditions that would make it impossible to transpose + characters. */ + if (!count || !input_line_point || (input_line_end - input_line_beg) < 2) + return; + + while (count) + { + int t; + if (input_line_point == input_line_end) + { + t = input_line[input_line_point - 1]; + + input_line[input_line_point - 1] = input_line[input_line_point - 2]; + input_line[input_line_point - 2] = t; + } + else + { + t = input_line[input_line_point]; + + input_line[input_line_point] = input_line[input_line_point - 1]; + input_line[input_line_point - 1] = t; + + if (count < 0 && input_line_point != input_line_beg) + input_line_point--; + else + input_line_point++; + } + + if (count < 0) + count++; + else + count--; + } +} + +/* **************************************************************** */ +/* */ +/* Echo Area Killing and Yanking */ +/* */ +/* **************************************************************** */ + +static char **kill_ring = (char **)NULL; +static int kill_ring_index = 0; /* Number of kills appearing in KILL_RING. */ +static int kill_ring_slots = 0; /* Number of slots allocated to KILL_RING. */ +static int kill_ring_loc = 0; /* Location of current yank pointer. */ + +/* The largest number of kills that we remember at one time. */ +static int max_retained_kills = 15; + +DECLARE_INFO_COMMAND (ea_yank, _("Yank back the contents of the last kill")) +{ + register int i; + register char *text; + + if (!kill_ring_index) + { + inform_in_echo_area (_("Kill ring is empty")); + return; + } + + text = kill_ring[kill_ring_loc]; + + for (i = 0; text[i]; i++) + ea_insert (window, 1, text[i]); +} + +/* If the last command was yank, or yank_pop, and the text just before + point is identical to the current kill item, then delete that text + from the line, rotate the index down, and yank back some other text. */ +DECLARE_INFO_COMMAND (ea_yank_pop, _("Yank back a previous kill")) +{ + register int len; + + if (((ea_last_executed_command != ea_yank) && + (ea_last_executed_command != ea_yank_pop)) || + (kill_ring_index == 0)) + return; + + len = strlen (kill_ring[kill_ring_loc]); + + /* Delete the last yanked item from the line. */ + { + register int i, counter; + + counter = input_line_end - input_line_point; + + for (i = input_line_point - len; counter; i++, counter--) + input_line[i] = input_line[i + len]; + + input_line_end -= len; + input_line_point -= len; + } + + /* Get a previous kill, and yank that. */ + kill_ring_loc--; + if (kill_ring_loc < 0) + kill_ring_loc = kill_ring_index - 1; + + ea_yank (window, count, key); +} + +/* Delete the text from point to end of line. */ +DECLARE_INFO_COMMAND (ea_kill_line, _("Kill to the end of the line")) +{ + if (count < 0) + { + ea_kill_text (input_line_point, input_line_beg); + input_line_point = input_line_beg; + } + else + ea_kill_text (input_line_point, input_line_end); +} + +/* Delete the text from point to beg of line. */ +DECLARE_INFO_COMMAND (ea_backward_kill_line, + _("Kill to the beginning of the line")) +{ + if (count < 0) + ea_kill_text (input_line_point, input_line_end); + else + { + ea_kill_text (input_line_point, input_line_beg); + input_line_point = input_line_beg; + } +} + +/* Delete from point to the end of the current word. */ +DECLARE_INFO_COMMAND (ea_kill_word, _("Kill the word following the cursor")) +{ + int orig_point = input_line_point; + + if (count < 0) + ea_backward_kill_word (window, -count, key); + else + { + ea_forward_word (window, count, key); + + if (input_line_point != orig_point) + ea_kill_text (orig_point, input_line_point); + + input_line_point = orig_point; + } +} + +/* Delete from point to the start of the current word. */ +DECLARE_INFO_COMMAND (ea_backward_kill_word, + _("Kill the word preceding the cursor")) +{ + int orig_point = input_line_point; + + if (count < 0) + ea_kill_word (window, -count, key); + else + { + ea_backward_word (window, count, key); + + if (input_line_point != orig_point) + ea_kill_text (orig_point, input_line_point); + } +} + +/* The way to kill something. This appends or prepends to the last + kill, if the last command was a kill command. If FROM is less + than TO, then the killed text is appended to the most recent kill, + otherwise it is prepended. If the last command was not a kill command, + then a new slot is made for this kill. */ +static void +ea_kill_text (from, to) + int from, to; +{ + register int i, counter, distance; + int killing_backwards, slot; + char *killed_text; + + killing_backwards = (from > to); + + /* If killing backwards, reverse the values of FROM and TO. */ + if (killing_backwards) + { + int temp = from; + from = to; + to = temp; + } + + /* Remember the text that we are about to delete. */ + distance = to - from; + killed_text = (char *)xmalloc (1 + distance); + strncpy (killed_text, &input_line[from], distance); + killed_text[distance] = '\0'; + + /* Actually delete the text from the line. */ + counter = input_line_end - to; + + for (i = from; counter; i++, counter--) + input_line[i] = input_line[i + distance]; + + input_line_end -= distance; + + /* If the last command was a kill, append or prepend the killed text to + the last command's killed text. */ + if (echo_area_last_command_was_kill) + { + char *old, *new; + + slot = kill_ring_loc; + old = kill_ring[slot]; + new = (char *)xmalloc (1 + strlen (old) + strlen (killed_text)); + + if (killing_backwards) + { + /* Prepend TEXT to current kill. */ + strcpy (new, killed_text); + strcat (new, old); + } + else + { + /* Append TEXT to current kill. */ + strcpy (new, old); + strcat (new, killed_text); + } + + free (old); + free (killed_text); + kill_ring[slot] = new; + } + else + { + /* Try to store the kill in a new slot, unless that would cause there + to be too many remembered kills. */ + slot = kill_ring_index; + + if (slot == max_retained_kills) + slot = 0; + + if (slot + 1 > kill_ring_slots) + kill_ring = (char **) xrealloc + (kill_ring, + (kill_ring_slots += max_retained_kills) * sizeof (char *)); + + if (slot != kill_ring_index) + free (kill_ring[slot]); + else + kill_ring_index++; + + kill_ring[slot] = killed_text; + + kill_ring_loc = slot; + } + + /* Notice that the last command was a kill. */ + echo_area_last_command_was_kill++; +} + +/* **************************************************************** */ +/* */ +/* Echo Area Completion */ +/* */ +/* **************************************************************** */ + +/* Pointer to an array of REFERENCE to complete over. */ +static REFERENCE **echo_area_completion_items = (REFERENCE **)NULL; + +/* Sorted array of REFERENCE * which is the possible completions found in + the variable echo_area_completion_items. If there is only one element, + it is the only possible completion. */ +static REFERENCE **completions_found = (REFERENCE **)NULL; +static int completions_found_index = 0; +static int completions_found_slots = 0; + +/* The lowest common denominator found while completing. */ +static REFERENCE *LCD_completion; + +/* Internal functions used by the user calls. */ +static void build_completions (), completions_must_be_rebuilt (); + +/* Variable which holds the output of completions. */ +static NODE *possible_completions_output_node = (NODE *)NULL; + +static char *compwin_name = "*Completions*"; + +/* Return non-zero if WINDOW is a window used for completions output. */ +static int +completions_window_p (window) + WINDOW *window; +{ + int result = 0; + + if (internal_info_node_p (window->node) && + (strcmp (window->node->nodename, compwin_name) == 0)) + result = 1; + + return (result); +} + +/* Workhorse for completion readers. If FORCE is non-zero, the user cannot + exit unless the line read completes, or is empty. */ +char * +info_read_completing_internal (window, prompt, completions, force) + WINDOW *window; + char *prompt; + REFERENCE **completions; + int force; +{ + char *line; + + /* If the echo area is already active, remember the current state. */ + if (echo_area_is_active) + push_echo_area (); + + echo_area_must_complete_p = force; + + /* Initialize our local variables. */ + initialize_input_line (prompt); + + /* Initialize the echo area for the first (but maybe not the last) time. */ + echo_area_initialize_node (); + + /* Save away the original node of this window, and the window itself, + so echo area commands can temporarily use this window. */ + remember_calling_window (window); + + /* Save away the list of items to complete over. */ + echo_area_completion_items = completions; + completions_must_be_rebuilt (); + + active_window = the_echo_area; + echo_area_is_active++; + + /* Read characters in the echo area. */ + while (1) + { + info_read_and_dispatch (); + + line = echo_area_after_read (); + + /* Force the completion to take place if the user hasn't accepted + a default or aborted, and if FORCE is active. */ + if (force && line && *line && completions) + { + register int i; + + build_completions (); + + /* If there is only one completion, then make the line be that + completion. */ + if (completions_found_index == 1) + { + free (line); + line = xstrdup (completions_found[0]->label); + break; + } + + /* If one of the completions matches exactly, then that is okay, so + return the current line. */ + for (i = 0; i < completions_found_index; i++) + if (strcasecmp (completions_found[i]->label, line) == 0) + { + free (line); + line = xstrdup (completions_found[i]->label); + break; + } + + /* If no match, go back and try again. */ + if (i == completions_found_index) + { + inform_in_echo_area (_("Not complete")); + continue; + } + } + break; + } + echo_area_is_active--; + + /* Restore the original active window and show point in it. */ + active_window = calling_window; + restore_calling_window (); + display_cursor_at_point (active_window); + fflush (stdout); + + echo_area_completion_items = (REFERENCE **)NULL; + completions_must_be_rebuilt (); + + /* If there is a previous loop waiting for us, restore it now. */ + if (echo_area_is_active) + pop_echo_area (); + + return (line); +} + +/* Read a line in the echo area with completion over COMPLETIONS. */ +char * +info_read_completing_in_echo_area (window, prompt, completions) + WINDOW *window; + char *prompt; + REFERENCE **completions; +{ + return (info_read_completing_internal (window, prompt, completions, 1)); +} + +/* Read a line in the echo area allowing completion over COMPLETIONS, but + not requiring it. */ +char * +info_read_maybe_completing (window, prompt, completions) + WINDOW *window; + char *prompt; + REFERENCE **completions; +{ + return (info_read_completing_internal (window, prompt, completions, 0)); +} + +DECLARE_INFO_COMMAND (ea_possible_completions, _("List possible completions")) +{ + if (!echo_area_completion_items) + { + ea_insert (window, count, key); + return; + } + + build_completions (); + + if (!completions_found_index) + { + terminal_ring_bell (); + inform_in_echo_area (_("No completions")); + } + else if ((completions_found_index == 1) && (key != '?')) + { + inform_in_echo_area (_("Sole completion")); + } + else + { + register int i, l; + int limit, count, max_label = 0; + + initialize_message_buffer (); + printf_to_message_buffer + (_("There %s %d "), completions_found_index == 1 ? _("is") : _("are"), + completions_found_index); + printf_to_message_buffer + (_("completion%s:\n"), completions_found_index == 1 ? "" : "s"); + + /* Find the maximum length of a label. */ + for (i = 0; i < completions_found_index; i++) + { + int len = strlen (completions_found[i]->label); + if (len > max_label) + max_label = len; + } + + max_label += 4; + + /* Find out how many columns we should print in. */ + limit = calling_window->width / max_label; + if (limit != 1 && (limit * max_label == calling_window->width)) + limit--; + + /* Avoid a possible floating exception. If max_label > width then + the limit will be 0 and a divide-by-zero fault will result. */ + if (limit == 0) + limit = 1; + + /* How many iterations of the printing loop? */ + count = (completions_found_index + (limit - 1)) / limit; + + /* Watch out for special case. If the number of completions is less + than LIMIT, then just do the inner printing loop. */ + if (completions_found_index < limit) + count = 1; + + /* Print the sorted items, up-and-down alphabetically. */ + for (i = 0; i < count; i++) + { + register int j; + + for (j = 0, l = i; j < limit; j++) + { + if (l >= completions_found_index) + break; + else + { + char *label; + int printed_length, k; + + label = completions_found[l]->label; + printed_length = strlen (label); + printf_to_message_buffer ("%s", label); + + if (j + 1 < limit) + { + for (k = 0; k < max_label - printed_length; k++) + printf_to_message_buffer (" "); + } + } + l += count; + } + printf_to_message_buffer ("\n"); + } + + /* Make a new node to hold onto possible completions. Don't destroy + dangling pointers. */ + { + NODE *temp; + + temp = message_buffer_to_node (); + add_gcable_pointer (temp->contents); + name_internal_node (temp, compwin_name); + possible_completions_output_node = temp; + } + + /* Find a suitable window for displaying the completions output. + First choice is an existing window showing completions output. + If there is only one window, and it is large, make another + (smaller) window, and use that one. Otherwise, use the caller's + window. */ + { + WINDOW *compwin; + + compwin = get_internal_info_window (compwin_name); + + if (!compwin) + { + /* If we can split the window to display most of the completion + items, then do so. */ + if (calling_window->height > (count * 2) + && calling_window->height / 2 >= WINDOW_MIN_SIZE) + { + int start, pagetop; +#ifdef SPLIT_BEFORE_ACTIVE + int end; +#endif + + active_window = calling_window; + + /* Perhaps we can scroll this window on redisplay. */ + start = calling_window->first_row; + pagetop = calling_window->pagetop; + + compwin = + window_make_window (possible_completions_output_node); + active_window = the_echo_area; + window_change_window_height + (compwin, -(compwin->height - (count + 2))); + + window_adjust_pagetop (calling_window); + remember_calling_window (calling_window); + +#if defined (SPLIT_BEFORE_ACTIVE) + /* If the pagetop hasn't changed, scrolling the calling + window is a reasonable thing to do. */ + if (pagetop == calling_window->pagetop) + { + end = start + calling_window->height; + display_scroll_display + (start, end, calling_window->prev->height + 1); + } +#else /* !SPLIT_BEFORE_ACTIVE */ + /* If the pagetop has changed, set the new pagetop here. */ + if (pagetop != calling_window->pagetop) + { + int newtop = calling_window->pagetop; + calling_window->pagetop = pagetop; + set_window_pagetop (calling_window, newtop); + } +#endif /* !SPLIT_BEFORE_ACTIVE */ + + echo_area_completions_window = compwin; + remember_window_and_node (compwin, compwin->node); + } + else + compwin = calling_window; + } + + if (compwin->node != possible_completions_output_node) + { + window_set_node_of_window + (compwin, possible_completions_output_node); + remember_window_and_node (compwin, compwin->node); + } + + display_update_display (windows); + } + } +} + +DECLARE_INFO_COMMAND (ea_complete, _("Insert completion")) +{ + if (!echo_area_completion_items) + { + ea_insert (window, count, key); + return; + } + + /* If KEY is SPC, and we are not forcing completion to take place, simply + insert the key. */ + if (!echo_area_must_complete_p && key == SPC) + { + ea_insert (window, count, key); + return; + } + + if (ea_last_executed_command == ea_complete) + { + /* If the keypress is a SPC character, and we have already tried + completing once, and there are several completions, then check + the batch of completions to see if any continue with a space. + If there are some, insert the space character and continue. */ + if (key == SPC && completions_found_index > 1) + { + register int i, offset; + + offset = input_line_end - input_line_beg; + + for (i = 0; i < completions_found_index; i++) + if (completions_found[i]->label[offset] == ' ') + break; + + if (completions_found[i]) + ea_insert (window, 1, ' '); + else + { + ea_possible_completions (window, count, key); + return; + } + } + else + { + ea_possible_completions (window, count, key); + return; + } + } + + input_line_point = input_line_end; + build_completions (); + + if (!completions_found_index) + terminal_ring_bell (); + else if (LCD_completion->label[0] == '\0') + ea_possible_completions (window, count, key); + else + { + register int i; + input_line_point = input_line_end = input_line_beg; + for (i = 0; LCD_completion->label[i]; i++) + ea_insert (window, 1, LCD_completion->label[i]); + } +} + +/* Utility REFERENCE used to store possible LCD. */ +static REFERENCE LCD_reference = { (char *)NULL, (char *)NULL, (char *)NULL }; + +static void remove_completion_duplicates (); + +/* Variables which remember the state of the most recent call + to build_completions (). */ +static char *last_completion_request = (char *)NULL; +static REFERENCE **last_completion_items = (REFERENCE **)NULL; + +/* How to tell the completion builder to reset internal state. */ +static void +completions_must_be_rebuilt () +{ + maybe_free (last_completion_request); + last_completion_request = (char *)NULL; + last_completion_items = (REFERENCE **)NULL; +} + +/* Build a list of possible completions from echo_area_completion_items, + and the contents of input_line. */ +static void +build_completions () +{ + register int i, len; + register REFERENCE *entry; + char *request; + int informed_of_lengthy_job = 0; + + /* If there are no items to complete over, exit immediately. */ + if (!echo_area_completion_items) + { + completions_found_index = 0; + LCD_completion = (REFERENCE *)NULL; + return; + } + + /* Check to see if this call to build completions is the same as the last + call to build completions. */ + len = input_line_end - input_line_beg; + request = (char *)xmalloc (1 + len); + strncpy (request, &input_line[input_line_beg], len); + request[len] = '\0'; + + if (last_completion_request && last_completion_items && + last_completion_items == echo_area_completion_items && + (strcmp (last_completion_request, request) == 0)) + { + free (request); + return; + } + + maybe_free (last_completion_request); + last_completion_request = request; + last_completion_items = echo_area_completion_items; + + /* Always start at the beginning of the list. */ + completions_found_index = 0; + LCD_completion = (REFERENCE *)NULL; + + for (i = 0; (entry = echo_area_completion_items[i]); i++) + { + if (strncasecmp (request, entry->label, len) == 0) + add_pointer_to_array (entry, completions_found_index, + completions_found, completions_found_slots, + 20, REFERENCE *); + + if (!informed_of_lengthy_job && completions_found_index > 100) + { + informed_of_lengthy_job = 1; + window_message_in_echo_area (_("Building completions...")); + } + } + + if (!completions_found_index) + return; + + /* Sort and prune duplicate entries from the completions array. */ + remove_completion_duplicates (); + + /* If there is only one completion, just return that. */ + if (completions_found_index == 1) + { + LCD_completion = completions_found[0]; + return; + } + + /* Find the least common denominator. */ + { + long shortest = 100000; + + for (i = 1; i < completions_found_index; i++) + { + register int j; + int c1, c2; + + for (j = 0; + (c1 = info_tolower (completions_found[i - 1]->label[j])) && + (c2 = info_tolower (completions_found[i]->label[j])); + j++) + if (c1 != c2) + break; + + if (shortest > j) + shortest = j; + } + + maybe_free (LCD_reference.label); + LCD_reference.label = (char *)xmalloc (1 + shortest); + strncpy (LCD_reference.label, completions_found[0]->label, shortest); + LCD_reference.label[shortest] = '\0'; + LCD_completion = &LCD_reference; + } + + if (informed_of_lengthy_job) + echo_area_initialize_node (); +} + +/* Function called by qsort. */ +static int +compare_references (entry1, entry2) + REFERENCE **entry1, **entry2; +{ + return (strcasecmp ((*entry1)->label, (*entry2)->label)); +} + +/* Prune duplicate entries from COMPLETIONS_FOUND. */ +static void +remove_completion_duplicates () +{ + register int i, j; + REFERENCE **temp; + int newlen; + + if (!completions_found_index) + return; + + /* Sort the items. */ + qsort (completions_found, completions_found_index, sizeof (REFERENCE *), + compare_references); + + for (i = 0, newlen = 1; i < completions_found_index - 1; i++) + { + if (strcmp (completions_found[i]->label, + completions_found[i + 1]->label) == 0) + completions_found[i] = (REFERENCE *)NULL; + else + newlen++; + } + + /* We have marked all the dead slots. It is faster to copy the live slots + twice than to prune the dead slots one by one. */ + temp = (REFERENCE **)xmalloc ((1 + newlen) * sizeof (REFERENCE *)); + for (i = 0, j = 0; i < completions_found_index; i++) + if (completions_found[i]) + temp[j++] = completions_found[i]; + + for (i = 0; i < newlen; i++) + completions_found[i] = temp[i]; + + completions_found[i] = (REFERENCE *)NULL; + completions_found_index = newlen; + free (temp); +} + +/* Scroll the "other" window. If there is a window showing completions, scroll + that one, otherwise scroll the window which was active on entering the read + function. */ +DECLARE_INFO_COMMAND (ea_scroll_completions_window, _("Scroll the completions window")) +{ + WINDOW *compwin; + int old_pagetop; + + compwin = get_internal_info_window (compwin_name); + + if (!compwin) + compwin = calling_window; + + old_pagetop = compwin->pagetop; + + /* Let info_scroll_forward () do the work, and print any messages that + need to be displayed. */ + info_scroll_forward (compwin, count, key); +} + +/* Function which gets called when an Info window is deleted while the + echo area is active. WINDOW is the window which has just been deleted. */ +void +echo_area_inform_of_deleted_window (window) + WINDOW *window; +{ + /* If this is the calling_window, forget what we remembered about it. */ + if (window == calling_window) + { + if (active_window != the_echo_area) + remember_calling_window (active_window); + else + remember_calling_window (windows); + } + + /* If this window was the echo_area_completions_window, then notice that + the window has been deleted. */ + if (window == echo_area_completions_window) + echo_area_completions_window = (WINDOW *)NULL; +} + +/* **************************************************************** */ +/* */ +/* Pushing and Popping the Echo Area */ +/* */ +/* **************************************************************** */ + +/* Push and Pop the echo area. */ +typedef struct { + char *line; + char *prompt; + REFERENCE **comp_items; + int point, beg, end; + int must_complete; + NODE node; + WINDOW *compwin; +} PUSHED_EA; + +static PUSHED_EA **pushed_echo_areas = (PUSHED_EA **)NULL; +static int pushed_echo_areas_index = 0; +static int pushed_echo_areas_slots = 0; + +/* Pushing the echo_area has a side effect of zeroing the completion_items. */ +static void +push_echo_area () +{ + PUSHED_EA *pushed; + + pushed = (PUSHED_EA *)xmalloc (sizeof (PUSHED_EA)); + pushed->line = xstrdup (input_line); + pushed->prompt = input_line_prompt; + pushed->point = input_line_point; + pushed->beg = input_line_beg; + pushed->end = input_line_end; + pushed->node = input_line_node; + pushed->comp_items = echo_area_completion_items; + pushed->must_complete = echo_area_must_complete_p; + pushed->compwin = echo_area_completions_window; + + add_pointer_to_array (pushed, pushed_echo_areas_index, pushed_echo_areas, + pushed_echo_areas_slots, 4, PUSHED_EA *); + + echo_area_completion_items = (REFERENCE **)NULL; +} + +static void +pop_echo_area () +{ + PUSHED_EA *popped; + + popped = pushed_echo_areas[--pushed_echo_areas_index]; + + strcpy (input_line, popped->line); + free (popped->line); + input_line_prompt = popped->prompt; + input_line_point = popped->point; + input_line_beg = popped->beg; + input_line_end = popped->end; + input_line_node = popped->node; + echo_area_completion_items = popped->comp_items; + echo_area_must_complete_p = popped->must_complete; + echo_area_completions_window = popped->compwin; + completions_must_be_rebuilt (); + + /* If the completion window no longer exists, forget about it. */ + if (echo_area_completions_window) + { + register WINDOW *win; + + for (win = windows; win; win = win->next) + if (echo_area_completions_window == win) + break; + + /* If the window wasn't found, then it has already been deleted. */ + if (!win) + echo_area_completions_window = (WINDOW *)NULL; + } + + free (popped); +} + +/* Returns non-zero if any of the prior stacked calls to read in the echo + area produced a completions window. */ +static int +echo_area_stack_contains_completions_p () +{ + register int i; + + for (i = 0; i < pushed_echo_areas_index; i++) + if (pushed_echo_areas[i]->compwin) + return (1); + + return (0); +} + +/* **************************************************************** */ +/* */ +/* Error Messages While Reading in Echo Area */ +/* */ +/* **************************************************************** */ + +#if defined (HAVE_SYS_TIME_H) +# include <sys/time.h> +# define HAVE_STRUCT_TIMEVAL +#endif /* HAVE_SYS_TIME_H */ + +static void +pause_or_input () +{ +#if defined (FD_SET) + struct timeval timer; + fd_set readfds; + int ready; + + FD_ZERO (&readfds); + FD_SET (fileno (stdin), &readfds); + timer.tv_sec = 2; + timer.tv_usec = 750; + ready = select (fileno (stdin) + 1, &readfds, (fd_set *) NULL, + (fd_set *) NULL, &timer); +#endif /* FD_SET */ +} + +/* Print MESSAGE right after the end of the current line, and wait + for input or 2.75 seconds, whichever comes first. Then flush the + informational message that was printed. */ +void +inform_in_echo_area (message) + char *message; +{ + register int i; + char *text; + + text = xstrdup (message); + for (i = 0; text[i] && text[i] != '\n'; i++); + text[i] = '\0'; + + echo_area_initialize_node (); + sprintf (&input_line[input_line_end], "%s[%s]\n", + echo_area_is_active ? " ": "", text); + free (text); + the_echo_area->point = input_line_point; + display_update_one_window (the_echo_area); + display_cursor_at_point (active_window); + fflush (stdout); + pause_or_input (); + echo_area_initialize_node (); +} diff --git a/gnu/usr.bin/texinfo/info/echo-area.h b/gnu/usr.bin/texinfo/info/echo-area.h new file mode 100644 index 00000000000..e794d596a4d --- /dev/null +++ b/gnu/usr.bin/texinfo/info/echo-area.h @@ -0,0 +1,64 @@ +/* echo-area.h -- Functions used in reading information from the echo area. + $Id: echo-area.h,v 1.1 1997/08/01 22:00:08 kstailey Exp $ + + This file is part of GNU Info, a program for reading online documentation + stored in Info format. + + Copyright (C) 1993, 97 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Written by Brian Fox (bfox@ai.mit.edu). */ + +#ifndef INFO_ECHO_AREA_H +#define INFO_ECHO_AREA_H + +#define EA_MAX_INPUT 256 + +extern int echo_area_is_active, info_aborted_echo_area; + +/* Non-zero means that the last command executed while reading input + killed some text. */ +extern int echo_area_last_command_was_kill; + +extern void inform_in_echo_area (), echo_area_inform_of_deleted_window (); +extern void echo_area_prep_read (); +extern VFunction *ea_last_executed_command; + +/* Read a line of text in the echo area. Return a malloc ()'ed string, + or NULL if the user aborted out of this read. WINDOW is the currently + active window, so that we can restore it when we need to. PROMPT, if + non-null, is a prompt to print before reading the line. */ +extern char *info_read_in_echo_area (); + +/* Read a line in the echo area with completion over COMPLETIONS. + Takes arguments of WINDOW, PROMPT, and COMPLETIONS, a REFERENCE **. */ +char *info_read_completing_in_echo_area (); + +/* Read a line in the echo area allowing completion over COMPLETIONS, but + not requiring it. Takes arguments of WINDOW, PROMPT, and COMPLETIONS, + a REFERENCE **. */ +extern char *info_read_maybe_completing (); + +extern void ea_insert (), ea_quoted_insert (); +extern void ea_beg_of_line (), ea_backward (), ea_delete (), ea_end_of_line (); +extern void ea_forward (), ea_abort (), ea_rubout (), ea_complete (); +extern void ea_newline (), ea_kill_line (), ea_transpose_chars (); +extern void ea_yank (), ea_tab_insert (), ea_possible_completions (); +extern void ea_backward_word (), ea_kill_word (), ea_forward_word (); +extern void ea_yank_pop (), ea_backward_kill_word (); +extern void ea_scroll_completions_window (); + +#endif /* not INFO_ECHO_AREA_H */ diff --git a/gnu/usr.bin/texinfo/info/funs.h b/gnu/usr.bin/texinfo/info/funs.h new file mode 100644 index 00000000000..45fcb6ae274 --- /dev/null +++ b/gnu/usr.bin/texinfo/info/funs.h @@ -0,0 +1,111 @@ +/* funs.h -- Generated declarations for Info commands. */ + +/* Functions declared in "./session.c". */ +extern void info_next_line (); +extern void info_prev_line (); +extern void info_end_of_line (); +extern void info_beginning_of_line (); +extern void info_forward_char (); +extern void info_backward_char (); +extern void info_forward_word (); +extern void info_backward_word (); +extern void info_global_next_node (); +extern void info_global_prev_node (); +extern void info_scroll_forward (); +extern void info_scroll_backward (); +extern void info_beginning_of_node (); +extern void info_end_of_node (); +extern void info_next_window (); +extern void info_prev_window (); +extern void info_split_window (); +extern void info_delete_window (); +extern void info_keep_one_window (); +extern void info_scroll_other_window (); +extern void info_grow_window (); +extern void info_tile_windows (); +extern void info_toggle_wrap (); +extern void info_next_node (); +extern void info_prev_node (); +extern void info_up_node (); +extern void info_last_node (); +extern void info_first_node (); +extern void info_history_node (); +extern void info_last_menu_item (); +extern void info_menu_digit (); +extern void info_menu_item (); +extern void info_xref_item (); +extern void info_find_menu (); +extern void info_visit_menu (); +extern void info_goto_node (); +extern void info_man (); +extern void info_top_node (); +extern void info_dir_node (); +extern void info_kill_node (); +extern void info_view_file (); +extern void info_print_node (); +extern void info_search (); +extern void isearch_forward (); +extern void isearch_backward (); +extern void info_move_to_prev_xref (); +extern void info_move_to_next_xref (); +extern void info_select_reference_this_line (); +extern void info_abort_key (); +extern void info_move_to_window_line (); +extern void info_redraw_display (); +extern void info_quit (); +extern void info_do_lowercase_version (); +extern void info_add_digit_to_numeric_arg (); +extern void info_universal_argument (); +extern void info_numeric_arg_digit_loop (); + +/* Functions declared in "./echo-area.c". */ +extern void ea_forward (); +extern void ea_backward (); +extern void ea_beg_of_line (); +extern void ea_end_of_line (); +extern void ea_forward_word (); +extern void ea_backward_word (); +extern void ea_delete (); +extern void ea_rubout (); +extern void ea_abort (); +extern void ea_newline (); +extern void ea_quoted_insert (); +extern void ea_insert (); +extern void ea_tab_insert (); +extern void ea_transpose_chars (); +extern void ea_yank (); +extern void ea_yank_pop (); +extern void ea_kill_line (); +extern void ea_backward_kill_line (); +extern void ea_kill_word (); +extern void ea_backward_kill_word (); +extern void ea_possible_completions (); +extern void ea_complete (); +extern void ea_scroll_completions_window (); + +/* Functions declared in "./infodoc.c". */ +extern void info_get_help_window (); +extern void info_get_info_help_node (); +extern void describe_key (); +extern void info_where_is (); + +/* Functions declared in "./m-x.c". */ +extern void describe_command (); +extern void info_execute_command (); +extern void set_screen_height (); + +/* Functions declared in "./indices.c". */ +extern void info_index_search (); +extern void info_next_index_match (); +extern void info_index_apropos (); + +/* Functions declared in "./nodemenu.c". */ +extern void list_visited_nodes (); +extern void select_visited_node (); + +/* Functions declared in "./footnotes.c". */ +extern void info_show_footnotes (); + +/* Functions declared in "./variables.c". */ +extern void describe_variable (); +extern void set_variable (); diff --git a/gnu/usr.bin/texinfo/info/gc.c b/gnu/usr.bin/texinfo/info/gc.c index 3b9b0907f51..1c868ba3284 100644 --- a/gnu/usr.bin/texinfo/info/gc.c +++ b/gnu/usr.bin/texinfo/info/gc.c @@ -56,7 +56,7 @@ gc_pointers () if (!info_windows || !gcable_pointers_index) return; - for (i = 0; iw = info_windows[i]; i++) + for (i = 0; (iw = info_windows[i]); i++) { for (j = 0; j < iw->nodes_index; j++) { diff --git a/gnu/usr.bin/texinfo/info/info-utils.c b/gnu/usr.bin/texinfo/info/info-utils.c index 6af3dd0e2ca..d9ab9a0634b 100644 --- a/gnu/usr.bin/texinfo/info/info-utils.c +++ b/gnu/usr.bin/texinfo/info/info-utils.c @@ -21,15 +21,8 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#include <stdio.h> /* For "NULL". Yechhh! */ -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> -#if defined (HAVE_STRING_H) -# include <string.h> -#endif /* HAVE_STRING_H */ +#include "info.h" #include "info-utils.h" - #if defined (HANDLE_MAN_PAGES) # include "man.h" #endif /* HANDLE_MAN_PAGES */ @@ -84,7 +77,7 @@ info_parse_node (string, newlines_okay) /* Find the closing paren. */ while (string[i] && string[i] != ')') - i++; + i++; /* Remember parsed filename. */ saven_filename (string, i); @@ -93,7 +86,7 @@ info_parse_node (string, newlines_okay) string += i; if (*string) - string++; + string++; } /* Parse out nodename. */ @@ -136,9 +129,9 @@ info_parse_label (label, node) } /* **************************************************************** */ -/* */ -/* Finding and Building Menus */ -/* */ +/* */ +/* Finding and Building Menus */ +/* */ /* **************************************************************** */ /* Return a NULL terminated array of REFERENCE * which represents the menu @@ -246,23 +239,23 @@ info_references_internal (label, binding) offset = string_in_line (":", refdef); /* When searching for menu items, if no colon, there is no - menu item on this line. */ + menu item on this line. */ if (offset == -1) - { - if (searching_for_menu_items) - continue; - else - { - int temp; - - temp = skip_line (refdef); - offset = string_in_line (":", refdef + temp); - if (offset == -1) - continue; /* Give up? */ - else - offset += temp; - } - } + { + if (searching_for_menu_items) + continue; + else + { + int temp; + + temp = skip_line (refdef); + offset = string_in_line (":", refdef + temp); + if (offset == -1) + continue; /* Give up? */ + else + offset += temp; + } + } entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->filename = (char *)NULL; @@ -277,32 +270,32 @@ info_references_internal (label, binding) entry->end = refdef - binding->buffer; /* If this reference entry continues with another ':' then the - nodename is the same as the label. */ + nodename is the same as the label. */ if (*refdef == ':') - { - entry->nodename = strdup (entry->label); - } + { + entry->nodename = xstrdup (entry->label); + } else - { - /* This entry continues with a specific nodename. Parse the - nodename from the specification. */ + { + /* This entry continues with a specific nodename. Parse the + nodename from the specification. */ - refdef += skip_whitespace_and_newlines (refdef); + refdef += skip_whitespace_and_newlines (refdef); - if (searching_for_menu_items) - info_parse_node (refdef, DONT_SKIP_NEWLINES); - else - info_parse_node (refdef, SKIP_NEWLINES); + if (searching_for_menu_items) + info_parse_node (refdef, DONT_SKIP_NEWLINES); + else + info_parse_node (refdef, SKIP_NEWLINES); - if (info_parsed_filename) - entry->filename = strdup (info_parsed_filename); + if (info_parsed_filename) + entry->filename = xstrdup (info_parsed_filename); - if (info_parsed_nodename) - entry->nodename = strdup (info_parsed_nodename); - } + if (info_parsed_nodename) + entry->nodename = xstrdup (info_parsed_nodename); + } add_pointer_to_array - (entry, refs_index, refs, refs_slots, 50, REFERENCE *); + (entry, refs_index, refs, refs_slots, 50, REFERENCE *); } return (refs); } @@ -320,7 +313,7 @@ info_get_labeled_reference (label, references) for (i = 0; references && (entry = references[i]); i++) { if (strcmp (label, entry->label) == 0) - return (entry); + return (entry); } return ((REFERENCE *)NULL); } @@ -375,13 +368,13 @@ info_free_references (references) if (references) { for (i = 0; references && (entry = references[i]); i++) - { - maybe_free (entry->label); - maybe_free (entry->filename); - maybe_free (entry->nodename); + { + maybe_free (entry->label); + maybe_free (entry->filename); + maybe_free (entry->nodename); - free (entry); - } + free (entry); + } free (references); } @@ -411,24 +404,24 @@ canonicalize_whitespace (string) for (i = 0, j = 0; string[i]; i++) { if (whitespace_or_newline (string[i])) - { - whitespace_found++; - whitespace_loc = i; - continue; - } + { + whitespace_found++; + whitespace_loc = i; + continue; + } else - { - if (whitespace_found && whitespace_loc) - { - whitespace_found = 0; - - /* Suppress whitespace at start of string. */ - if (j) - temp[j++] = ' '; - } - - temp[j++] = string[i]; - } + { + if (whitespace_found && whitespace_loc) + { + whitespace_found = 0; + + /* Suppress whitespace at start of string. */ + if (j) + temp[j++] = ' '; + } + + temp[j++] = string[i]; + } } /* Kill trailing whitespace. */ @@ -466,26 +459,26 @@ printed_representation (character, hpos) else if (iscntrl (character)) { switch (character) - { - case '\r': - case '\n': - the_rep[i++] = character; - break; - - case '\t': - { - int tw; - - tw = ((hpos + 8) & 0xf8) - hpos; - while (i < tw) - the_rep[i++] = ' '; - } - break; - - default: - the_rep[i++] = '^'; - the_rep[i++] = (character | 0x40); - } + { + case '\r': + case '\n': + the_rep[i++] = character; + break; + + case '\t': + { + int tw; + + tw = ((hpos + 8) & 0xf8) - hpos; + while (i < tw) + the_rep[i++] = ' '; + } + break; + + default: + the_rep[i++] = '^'; + the_rep[i++] = (character | 0x40); + } } else if (character > printable_limit) { @@ -502,9 +495,9 @@ printed_representation (character, hpos) /* **************************************************************** */ -/* */ -/* Functions Static To This File */ -/* */ +/* */ +/* Functions Static To This File */ +/* */ /* **************************************************************** */ /* Amount of space allocated to INFO_PARSED_FILENAME via xmalloc (). */ @@ -531,7 +524,7 @@ saven_filename (filename, len) int len; { saven_string (filename, len, - &info_parsed_filename, &parsed_filename_size); + &info_parsed_filename, &parsed_filename_size); } /* Remember NODENAME in PARSED_NODENAME. An empty NODENAME is translated @@ -550,7 +543,7 @@ saven_nodename (nodename, len) int len; { saven_string (nodename, len, - &info_parsed_nodename, &parsed_nodename_size); + &info_parsed_nodename, &parsed_nodename_size); } /* Remember STRING in STRING_P. STRING_P should currently have STRING_SIZE_P @@ -565,7 +558,7 @@ save_string (string, string_p, string_size_p) if (!string || !*string) { if (*string_p) - free (*string_p); + free (*string_p); *string_p = (char *)NULL; *string_size_p = 0; @@ -573,8 +566,8 @@ save_string (string, string_p, string_size_p) else { if (strlen (string) >= *string_size_p) - *string_p = (char *)xrealloc - (*string_p, (*string_size_p = 1 + strlen (string))); + *string_p = (char *)xrealloc + (*string_p, (*string_size_p = 1 + strlen (string))); strcpy (*string_p, string); } @@ -591,7 +584,7 @@ saven_string (string, len, string_p, string_size_p) if (!string) { if (*string_p) - free (*string_p); + free (*string_p); *string_p = (char *)NULL; *string_size_p = 0; @@ -599,7 +592,7 @@ saven_string (string, len, string_p, string_size_p) else { if (len >= *string_size_p) - *string_p = (char *)xrealloc (*string_p, (*string_size_p = 1 + len)); + *string_p = (char *)xrealloc (*string_p, (*string_size_p = 1 + len)); strncpy (*string_p, string, len); (*string_p)[len] = '\0'; @@ -665,7 +658,7 @@ get_internal_info_window (name) for (win = windows; win; win = win->next) if (internal_info_node_p (win->node) && - (strcmp (win->node->nodename, name) == 0)) + (strcmp (win->node->nodename, name) == 0)) break; return (win); diff --git a/gnu/usr.bin/texinfo/info/infomap.h b/gnu/usr.bin/texinfo/info/infomap.h index faf93884fd5..65968cbdff4 100644 --- a/gnu/usr.bin/texinfo/info/infomap.h +++ b/gnu/usr.bin/texinfo/info/infomap.h @@ -21,14 +21,14 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#if !defined (_INFOMAP_H_) -#define _INFOMAP_H_ +#ifndef INFOMAP_H +#define INFOMAP_H -#include "general.h" +#include "info.h" #define ESC '\033' #define DEL '\177' -#define TAB '\011' +#define TAB '\011' #define RET '\r' #define LFD '\n' #define SPC ' ' @@ -79,4 +79,4 @@ extern void keymap_discard_keymap (); /* Initialize the info keymaps. */ extern void initialize_info_keymaps (); -#endif /* !_INFOMAP_H_ */ +#endif /* not INFOMAP_H */ diff --git a/gnu/usr.bin/texinfo/info/nodes.c b/gnu/usr.bin/texinfo/info/nodes.c index 8995c78195f..f2737e7b354 100644 --- a/gnu/usr.bin/texinfo/info/nodes.c +++ b/gnu/usr.bin/texinfo/info/nodes.c @@ -21,17 +21,8 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#include <stdio.h> -#include <ctype.h> -#include <sys/types.h> -#if defined (HAVE_SYS_FILE_H) -#include <sys/file.h> -#endif /* HAVE_SYS_FILE_H */ -#include <sys/errno.h> -#include <sys/stat.h> -#if defined (HAVE_STRING_H) -#include <string.h> -#endif /* HAVE_STRING_H */ +#include "info.h" + #include "nodes.h" #include "search.h" #include "filesys.h" @@ -41,22 +32,10 @@ # include "man.h" #endif /* HANDLE_MAN_PAGES */ -#if !defined (O_RDONLY) -#if defined (HAVE_SYS_FCNTL_H) -#include <sys/fcntl.h> -#else /* !HAVE_SYS_FCNTL_H */ -#include <fcntl.h> -#endif /* !HAVE_SYS_FCNTL_H */ -#endif /* !O_RDONLY */ - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - /* **************************************************************** */ -/* */ -/* Functions Static to this File */ -/* */ +/* */ +/* Functions Static to this File */ +/* */ /* **************************************************************** */ static void forget_info_file (), remember_info_file (); @@ -81,9 +60,9 @@ static long get_node_length (); #define INFO_GET_TAGS 1 /* **************************************************************** */ -/* */ -/* Global Variables */ -/* */ +/* */ +/* Global Variables */ +/* */ /* **************************************************************** */ /* When non-zero, this is a string describing the recent file error. */ @@ -96,9 +75,9 @@ FILE_BUFFER **info_loaded_files = (FILE_BUFFER **)NULL; int info_loaded_files_slots = 0; /* **************************************************************** */ -/* */ -/* Public Functions for Node Manipulation */ -/* */ +/* */ +/* Public Functions for Node Manipulation */ +/* */ /* **************************************************************** */ /* Used to build "dir" menu from "localdir" files found in INFOPATH. */ @@ -142,8 +121,8 @@ info_get_node (filename, nodename) if (!file_buffer) { if (filesys_error_number) - info_recent_file_error = - filesys_error_string (filename, filesys_error_number); + info_recent_file_error = + filesys_error_string (filename, filesys_error_number); return ((NODE *)NULL); } @@ -154,9 +133,9 @@ info_get_node (filename, nodename) { node = info_get_node_of_file_buffer ("Top", file_buffer); if (!node) - node = info_get_node_of_file_buffer ("top", file_buffer); + node = info_get_node_of_file_buffer ("top", file_buffer); if (!node) - node = info_get_node_of_file_buffer ("TOP", file_buffer); + node = info_get_node_of_file_buffer ("TOP", file_buffer); } return (node); } @@ -193,7 +172,7 @@ info_get_node_of_file_buffer (nodename, file_buffer) node = (NODE *)xmalloc (sizeof (NODE)); node->filename = file_buffer->fullpath; node->parent = (char *)NULL; - node->nodename = strdup ("*"); + node->nodename = xstrdup ("*"); node->contents = file_buffer->contents; node->nodelen = file_buffer->filesize; node->flags = 0; @@ -203,7 +182,7 @@ info_get_node_of_file_buffer (nodename, file_buffer) the manpage node finding function instead. */ else if (file_buffer->flags & N_IsManPage) { - node = get_manpage_node (file_buffer, nodename); + node = get_manpage_node (file_buffer, nodename); } #endif /* HANDLE_MAN_PAGES */ /* If this is the "main" info file, it might contain a tags table. Search @@ -242,9 +221,9 @@ info_load_file (filename) /* **************************************************************** */ -/* */ -/* Private Functions Implementation */ -/* */ +/* */ +/* Private Functions Implementation */ +/* */ /* **************************************************************** */ /* The workhorse for info_find_file (). Non-zero 2nd argument says to @@ -263,58 +242,58 @@ info_find_file_internal (filename, get_tags) /* First try to find the file in our list of already loaded files. */ if (info_loaded_files) { - for (i = 0; file_buffer = info_loaded_files[i]; i++) - if ((strcmp (filename, file_buffer->filename) == 0) || - (strcmp (filename, file_buffer->fullpath) == 0) || - ((*filename != '/') && - strcmp (filename, - filename_non_directory (file_buffer->fullpath)) == 0)) - { - struct stat new_info, *old_info; - - /* This file is loaded. If the filename that we want is - specifically "dir", then simply return the file buffer. */ - if (strcasecmp (filename_non_directory (filename), "dir") == 0) - return (file_buffer); + for (i = 0; (file_buffer = info_loaded_files[i]); i++) + if ((strcmp (filename, file_buffer->filename) == 0) || + (strcmp (filename, file_buffer->fullpath) == 0) || + ((*filename != '/') && + strcmp (filename, + filename_non_directory (file_buffer->fullpath)) == 0)) + { + struct stat new_info, *old_info; + + /* This file is loaded. If the filename that we want is + specifically "dir", then simply return the file buffer. */ + if (strcasecmp (filename_non_directory (filename), "dir") == 0) + return (file_buffer); #if defined (HANDLE_MAN_PAGES) - /* Do the same for the magic MANPAGE file. */ - if (file_buffer->flags & N_IsManPage) - return (file_buffer); + /* Do the same for the magic MANPAGE file. */ + if (file_buffer->flags & N_IsManPage) + return (file_buffer); #endif /* HANDLE_MAN_PAGES */ - /* The file appears to be already loaded, and it is not "dir". - Check to see if it has changed since the last time it was - loaded. */ - if (stat (file_buffer->fullpath, &new_info) == -1) - { - filesys_error_number = errno; - return ((FILE_BUFFER *)NULL); - } - - old_info = &file_buffer->finfo; - - if ((new_info.st_size != old_info->st_size) || - (new_info.st_mtime != old_info->st_mtime)) - { - /* The file has changed. Forget that we ever had loaded it - in the first place. */ - forget_info_file (filename); - break; - } - else - { - /* The info file exists, and has not changed since the last - time it was loaded. If the caller requested a nodes list - for this file, and there isn't one here, build the nodes - for this file_buffer. In any case, return the file_buffer - object. */ - if (get_tags && !file_buffer->tags) - build_tags_and_nodes (file_buffer); - - return (file_buffer); - } - } + /* The file appears to be already loaded, and it is not "dir". + Check to see if it has changed since the last time it was + loaded. */ + if (stat (file_buffer->fullpath, &new_info) == -1) + { + filesys_error_number = errno; + return ((FILE_BUFFER *)NULL); + } + + old_info = &file_buffer->finfo; + + if ((new_info.st_size != old_info->st_size) || + (new_info.st_mtime != old_info->st_mtime)) + { + /* The file has changed. Forget that we ever had loaded it + in the first place. */ + forget_info_file (filename); + break; + } + else + { + /* The info file exists, and has not changed since the last + time it was loaded. If the caller requested a nodes list + for this file, and there isn't one here, build the nodes + for this file_buffer. In any case, return the file_buffer + object. */ + if (get_tags && !file_buffer->tags) + build_tags_and_nodes (file_buffer); + + return (file_buffer); + } + } } /* The file wasn't loaded. Try to load it now. */ @@ -364,21 +343,21 @@ info_load_file_internal (filename, get_tags) char *lowered_name; char *basename; - lowered_name = strdup (filename); + lowered_name = xstrdup (filename); basename = (char *) strrchr (lowered_name, '/'); if (basename) - basename++; + basename++; else - basename = lowered_name; + basename = lowered_name; while (*basename) - { - if (isupper (*basename)) - *basename = tolower (*basename); + { + if (isupper (*basename)) + *basename = tolower (*basename); - basename++; - } + basename++; + } fullpath = info_find_fullpath (lowered_name); free (lowered_name); @@ -402,8 +381,8 @@ info_load_file_internal (filename, get_tags) /* The file was found, and can be read. Allocate FILE_BUFFER and fill in the various members. */ file_buffer = make_file_buffer (); - file_buffer->filename = strdup (filename); - file_buffer->fullpath = strdup (fullpath); + file_buffer->filename = xstrdup (filename); + file_buffer->fullpath = xstrdup (fullpath); file_buffer->finfo = finfo; file_buffer->filesize = filesize; file_buffer->contents = contents; @@ -444,81 +423,81 @@ build_tags_and_nodes (file_buffer) if (position != -1) while (1) { - long tags_table_begin, tags_table_end; - - binding.end = position; - binding.start = binding.end - 5 - strlen (TAGS_TABLE_END_LABEL); - if (binding.start < 0) - binding.start = 0; - - position = find_node_separator (&binding); - - /* For this test, (and all others here) failure indicates a bogus - tags table. Grovel the file. */ - if (position == -1) - break; - - /* Remember the end of the tags table. */ - binding.start = position; - tags_table_end = binding.start; - binding.end = 0; - - /* Locate the start of the tags table. */ - position = search_backward (TAGS_TABLE_BEG_LABEL, &binding); - - if (position == -1) - break; - - binding.end = position; - binding.start = binding.end - 5 - strlen (TAGS_TABLE_BEG_LABEL); - position = find_node_separator (&binding); - - if (position == -1) - break; - - /* The file contains a valid tags table. Fill the FILE_BUFFER's - tags member. */ - file_buffer->flags |= N_HasTagsTable; - tags_table_begin = position; - - /* If this isn't an indirect tags table, just remember the nodes - described locally in this tags table. Note that binding.end - is pointing to just after the beginning label. */ - binding.start = binding.end; - binding.end = file_buffer->filesize; - - if (!looking_at (TAGS_TABLE_IS_INDIRECT_LABEL, &binding)) - { - binding.start = tags_table_begin; - binding.end = tags_table_end; - get_nodes_of_tags_table (file_buffer, &binding); - return; - } - else - { - /* This is an indirect tags table. Build TAGS member. */ - SEARCH_BINDING indirect; - - indirect.start = tags_table_begin; - indirect.end = 0; - indirect.buffer = binding.buffer; - indirect.flags = S_FoldCase; - - position = search_backward (INDIRECT_TAGS_TABLE_LABEL, &indirect); - - if (position == -1) - { - /* This file is malformed. Give up. */ - return; - } - - indirect.start = position; - indirect.end = tags_table_begin; - binding.start = tags_table_begin; - binding.end = tags_table_end; - get_tags_of_indirect_tags_table (file_buffer, &indirect, &binding); - return; - } + long tags_table_begin, tags_table_end; + + binding.end = position; + binding.start = binding.end - 5 - strlen (TAGS_TABLE_END_LABEL); + if (binding.start < 0) + binding.start = 0; + + position = find_node_separator (&binding); + + /* For this test, (and all others here) failure indicates a bogus + tags table. Grovel the file. */ + if (position == -1) + break; + + /* Remember the end of the tags table. */ + binding.start = position; + tags_table_end = binding.start; + binding.end = 0; + + /* Locate the start of the tags table. */ + position = search_backward (TAGS_TABLE_BEG_LABEL, &binding); + + if (position == -1) + break; + + binding.end = position; + binding.start = binding.end - 5 - strlen (TAGS_TABLE_BEG_LABEL); + position = find_node_separator (&binding); + + if (position == -1) + break; + + /* The file contains a valid tags table. Fill the FILE_BUFFER's + tags member. */ + file_buffer->flags |= N_HasTagsTable; + tags_table_begin = position; + + /* If this isn't an indirect tags table, just remember the nodes + described locally in this tags table. Note that binding.end + is pointing to just after the beginning label. */ + binding.start = binding.end; + binding.end = file_buffer->filesize; + + if (!looking_at (TAGS_TABLE_IS_INDIRECT_LABEL, &binding)) + { + binding.start = tags_table_begin; + binding.end = tags_table_end; + get_nodes_of_tags_table (file_buffer, &binding); + return; + } + else + { + /* This is an indirect tags table. Build TAGS member. */ + SEARCH_BINDING indirect; + + indirect.start = tags_table_begin; + indirect.end = 0; + indirect.buffer = binding.buffer; + indirect.flags = S_FoldCase; + + position = search_backward (INDIRECT_TAGS_TABLE_LABEL, &indirect); + + if (position == -1) + { + /* This file is malformed. Give up. */ + return; + } + + indirect.start = position; + indirect.end = tags_table_begin; + binding.start = tags_table_begin; + binding.end = tags_table_end; + get_tags_of_indirect_tags_table (file_buffer, &indirect, &binding); + return; + } } /* This file doesn't contain any kind of tags table. Grovel the @@ -561,37 +540,37 @@ get_nodes_of_info_file (file_buffer) /* If not there, this is not the start of a node. */ if (start == -1) - continue; + continue; /* Find the start of the nodename. */ start += skip_whitespace (nodeline + start); /* Find the end of the nodename. */ end = start + - skip_node_characters (nodeline + start, DONT_SKIP_NEWLINES); + skip_node_characters (nodeline + start, DONT_SKIP_NEWLINES); /* Okay, we have isolated the node name, and we know where the - node starts. Remember this information in a NODE structure. */ + node starts. Remember this information in a NODE structure. */ entry = (TAG *)xmalloc (sizeof (TAG)); entry->nodename = (char *)xmalloc (1 + (end - start)); strncpy (entry->nodename, nodeline + start, end - start); entry->nodename[end - start] = '\0'; entry->nodestart = nodestart; { - SEARCH_BINDING node_body; + SEARCH_BINDING node_body; - node_body.buffer = binding.buffer + binding.start; - node_body.start = 0; - node_body.end = binding.end - binding.start; - node_body.flags = S_FoldCase; - entry->nodelen = get_node_length (&node_body); + node_body.buffer = binding.buffer + binding.start; + node_body.start = 0; + node_body.end = binding.end - binding.start; + node_body.flags = S_FoldCase; + entry->nodelen = get_node_length (&node_body); } entry->filename = file_buffer->fullpath; /* Add this tag to the array of tag structures in this FILE_BUFFER. */ add_pointer_to_array (entry, tags_index, file_buffer->tags, - file_buffer->tags_slots, 100, TAG *); + file_buffer->tags_slots, 100, TAG *); } } @@ -608,7 +587,7 @@ get_node_length (binding) for (i = binding->start, body = binding->buffer; i < binding->end; i++) { if (body[i] == INFO_FF || body[i] == INFO_COOKIE) - break; + break; } return ((long) i - binding->start); } @@ -652,16 +631,16 @@ get_nodes_of_tags_table (file_buffer, buffer_binding) /* Skip past informative "(Indirect)" tags table line. */ if (!tags_index && looking_at (TAGS_TABLE_IS_INDIRECT_LABEL, search)) - continue; + continue; /* Find the label preceding the node name. */ offset = - string_in_line (INFO_NODE_LABEL, search->buffer + search->start); + string_in_line (INFO_NODE_LABEL, search->buffer + search->start); /* If not there, not a defining line, so we must be out of the - tags table. */ + tags table. */ if (offset == -1) - break; + break; /* Point to the beginning of the node definition. */ search->start += offset; @@ -670,11 +649,11 @@ get_nodes_of_tags_table (file_buffer, buffer_binding) /* Move past the node's name. */ for (offset = 0; - (nodedef[offset]) && (nodedef[offset] != INFO_TAGSEP); - offset++); + (nodedef[offset]) && (nodedef[offset] != INFO_TAGSEP); + offset++); if (nodedef[offset] != INFO_TAGSEP) - continue; + continue; entry = (TAG *)xmalloc (sizeof (TAG)); entry->nodename = (char *)xmalloc (1 + offset); @@ -687,13 +666,13 @@ get_nodes_of_tags_table (file_buffer, buffer_binding) entry->nodelen = -1; /* The filename of this node is currently known as the same as the - name of this file. */ + name of this file. */ entry->filename = file_buffer->fullpath; /* Add this node structure to the array of node structures in this - FILE_BUFFER. */ + FILE_BUFFER. */ add_pointer_to_array (entry, tags_index, file_buffer->tags, - file_buffer->tags_slots, 100, TAG *); + file_buffer->tags_slots, 100, TAG *); } free (search); } @@ -734,23 +713,23 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding) while (line < end) { - int colon; + int colon; - colon = string_in_line (":", line); + colon = string_in_line (":", line); - if (colon == -1) - break; + if (colon == -1) + break; - subfile = (SUBFILE *)xmalloc (sizeof (SUBFILE)); - subfile->filename = (char *)xmalloc (colon); - strncpy (subfile->filename, line, colon - 1); - subfile->filename[colon - 1] = '\0'; - subfile->first_byte = (long) atol (line + colon); + subfile = (SUBFILE *)xmalloc (sizeof (SUBFILE)); + subfile->filename = (char *)xmalloc (colon); + strncpy (subfile->filename, line, colon - 1); + subfile->filename[colon - 1] = '\0'; + subfile->first_byte = (long) atol (line + colon); - add_pointer_to_array - (subfile, subfiles_index, subfiles, subfiles_slots, 10, SUBFILE *); + add_pointer_to_array + (subfile, subfiles_index, subfiles, subfiles_slots, 10, SUBFILE *); - while (*line++ != '\n'); + while (*line++ != '\n'); } } @@ -768,10 +747,10 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding) SEARCH_BINDING binding; /* Find the length of the header of the file containing the indirect - tags table. This header appears at the start of every file. We - want the absolute position of each node within each subfile, so - we subtract the start of the containing subfile from the logical - position of the node, and then add the length of the header in. */ + tags table. This header appears at the start of every file. We + want the absolute position of each node within each subfile, so + we subtract the start of the containing subfile from the logical + position of the node, and then add the length of the header in. */ binding.buffer = file_buffer->contents; binding.start = 0; binding.end = file_buffer->filesize; @@ -779,81 +758,80 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding) header_length = find_node_separator (&binding); if (header_length == -1) - header_length = 0; + header_length = 0; /* Build the file buffer's list of subfiles. */ { - char *containing_dir, *temp; - int len_containing_dir; + char *containing_dir, *temp; + int len_containing_dir; - containing_dir = strdup (file_buffer->fullpath); - temp = (char *) strrchr (containing_dir, '/'); + containing_dir = xstrdup (file_buffer->fullpath); + temp = (char *) strrchr (containing_dir, '/'); - if (temp) - *temp = '\0'; + if (temp) + *temp = '\0'; - len_containing_dir = strlen (containing_dir); + len_containing_dir = strlen (containing_dir); - for (i = 0; subfiles[i]; i++); + for (i = 0; subfiles[i]; i++); - file_buffer->subfiles = (char **) xmalloc ((1 + i) * sizeof (char *)); + file_buffer->subfiles = (char **) xmalloc ((1 + i) * sizeof (char *)); - for (i = 0; subfiles[i]; i++) - { - char *fullpath; + for (i = 0; subfiles[i]; i++) + { + char *fullpath; - fullpath = (char *) xmalloc - (2 + strlen (subfiles[i]->filename) + len_containing_dir); + fullpath = (char *) xmalloc + (2 + strlen (subfiles[i]->filename) + len_containing_dir); - sprintf (fullpath, "%s/%s", - containing_dir, subfiles[i]->filename); + sprintf (fullpath, "%s/%s", + containing_dir, subfiles[i]->filename); - file_buffer->subfiles[i] = fullpath; - } - file_buffer->subfiles[i] = (char *)NULL; - free (containing_dir); + file_buffer->subfiles[i] = fullpath; + } + file_buffer->subfiles[i] = (char *)NULL; + free (containing_dir); } /* For each node in the file's tags table, remember the starting - position. */ - for (tags_index = 0; - entry = file_buffer->tags[tags_index]; - tags_index++) - { - for (i = 0; - subfiles[i] && entry->nodestart >= subfiles[i]->first_byte; - i++); - - /* If the Info file containing the indirect tags table is - malformed, then give up. */ - if (!i) - { - /* The Info file containing the indirect tags table is - malformed. Give up. */ - for (i = 0; subfiles[i]; i++) - { - free (subfiles[i]->filename); - free (subfiles[i]); - free (file_buffer->subfiles[i]); - } - file_buffer->subfiles = (char **)NULL; - free_file_buffer_tags (file_buffer); - return; - } - - /* SUBFILES[i] is the index of the first subfile whose logical - first byte is greater than the logical offset of this node's - starting position. This means that the subfile directly - preceding this one is the one containing the node. */ - - entry->filename = file_buffer->subfiles[i - 1]; - entry->nodestart -= subfiles[i -1]->first_byte; - entry->nodestart += header_length; - entry->nodelen = -1; - } + position. */ + for (tags_index = 0; (entry = file_buffer->tags[tags_index]); + tags_index++) + { + for (i = 0; + subfiles[i] && entry->nodestart >= subfiles[i]->first_byte; + i++); + + /* If the Info file containing the indirect tags table is + malformed, then give up. */ + if (!i) + { + /* The Info file containing the indirect tags table is + malformed. Give up. */ + for (i = 0; subfiles[i]; i++) + { + free (subfiles[i]->filename); + free (subfiles[i]); + free (file_buffer->subfiles[i]); + } + file_buffer->subfiles = (char **)NULL; + free_file_buffer_tags (file_buffer); + return; + } + + /* SUBFILES[i] is the index of the first subfile whose logical + first byte is greater than the logical offset of this node's + starting position. This means that the subfile directly + preceding this one is the one containing the node. */ + + entry->filename = file_buffer->subfiles[i - 1]; + entry->nodestart -= subfiles[i -1]->first_byte; + entry->nodestart += header_length; + entry->nodelen = -1; + } /* We have successfully built the tags table. Remember that it - was indirect. */ + was indirect. */ file_buffer->flags |= N_TagsIndirect; } @@ -878,105 +856,105 @@ info_node_of_file_buffer_tags (file_buffer, nodename) register int i; TAG *tag; - for (i = 0; tag = file_buffer->tags[i]; i++) + for (i = 0; (tag = file_buffer->tags[i]); i++) if (strcmp (nodename, tag->nodename) == 0) { - FILE_BUFFER *subfile; - - subfile = info_find_file_internal (tag->filename, INFO_NO_TAGS); - - if (!subfile) - return ((NODE *)NULL); - - if (!subfile->contents) - { - info_reload_file_buffer_contents (subfile); - - if (!subfile->contents) - return ((NODE *)NULL); - } - - /* If we were able to find this file and load it, then return - the node within it. */ - { - NODE *node; - - node = (NODE *)xmalloc (sizeof (NODE)); - node->filename = (subfile->fullpath); - node->nodename = tag->nodename; - node->contents = subfile->contents + tag->nodestart; - node->flags = 0; - node->parent = (char *)NULL; - - if (file_buffer->flags & N_HasTagsTable) - { - node->flags |= N_HasTagsTable; - - if (file_buffer->flags & N_TagsIndirect) - { - node->flags |= N_TagsIndirect; - node->parent = file_buffer->fullpath; - } - } - - if (subfile->flags & N_IsCompressed) - node->flags |= N_IsCompressed; - - /* If TAG->nodelen hasn't been calculated yet, then we aren't - in a position to trust the entry pointer. Adjust things so - that ENTRY->nodestart gets the exact address of the start of - the node separator which starts this node, and NODE->contents - gets the address of the line defining this node. If we cannot - do that, the node isn't really here. */ - if (tag->nodelen == -1) - { - int min, max; - char *node_sep; - SEARCH_BINDING node_body; - char *buff_end; - - min = max = DEFAULT_INFO_FUDGE; - - if (tag->nodestart < DEFAULT_INFO_FUDGE) - min = tag->nodestart; - - if (DEFAULT_INFO_FUDGE > - (subfile->filesize - tag->nodestart)) - max = subfile->filesize - tag->nodestart; - - /* NODE_SEP gets the address of the separator which defines - this node, or (char *)NULL if the node wasn't found. - NODE->contents is side-effected to point to right after - the separator. */ - node_sep = adjust_nodestart (node, min, max); - if (node_sep == (char *)NULL) - { - free (node); - return ((NODE *)NULL); - } - /* Readjust tag->nodestart. */ - tag->nodestart = node_sep - subfile->contents; - - /* Calculate the length of the current node. */ - buff_end = subfile->contents + subfile->filesize; - - node_body.buffer = node->contents; - node_body.start = 0; - node_body.end = buff_end - node_body.buffer; - node_body.flags = 0; - tag->nodelen = get_node_length (&node_body); - } - else - { - /* Since we know the length of this node, we have already - adjusted tag->nodestart to point to the exact start of - it. Simply skip the node separator. */ - node->contents += skip_node_separator (node->contents); - } - - node->nodelen = tag->nodelen; - return (node); - } + FILE_BUFFER *subfile; + + subfile = info_find_file_internal (tag->filename, INFO_NO_TAGS); + + if (!subfile) + return ((NODE *)NULL); + + if (!subfile->contents) + { + info_reload_file_buffer_contents (subfile); + + if (!subfile->contents) + return ((NODE *)NULL); + } + + /* If we were able to find this file and load it, then return + the node within it. */ + { + NODE *node; + + node = (NODE *)xmalloc (sizeof (NODE)); + node->filename = (subfile->fullpath); + node->nodename = tag->nodename; + node->contents = subfile->contents + tag->nodestart; + node->flags = 0; + node->parent = (char *)NULL; + + if (file_buffer->flags & N_HasTagsTable) + { + node->flags |= N_HasTagsTable; + + if (file_buffer->flags & N_TagsIndirect) + { + node->flags |= N_TagsIndirect; + node->parent = file_buffer->fullpath; + } + } + + if (subfile->flags & N_IsCompressed) + node->flags |= N_IsCompressed; + + /* If TAG->nodelen hasn't been calculated yet, then we aren't + in a position to trust the entry pointer. Adjust things so + that ENTRY->nodestart gets the exact address of the start of + the node separator which starts this node, and NODE->contents + gets the address of the line defining this node. If we cannot + do that, the node isn't really here. */ + if (tag->nodelen == -1) + { + int min, max; + char *node_sep; + SEARCH_BINDING node_body; + char *buff_end; + + min = max = DEFAULT_INFO_FUDGE; + + if (tag->nodestart < DEFAULT_INFO_FUDGE) + min = tag->nodestart; + + if (DEFAULT_INFO_FUDGE > + (subfile->filesize - tag->nodestart)) + max = subfile->filesize - tag->nodestart; + + /* NODE_SEP gets the address of the separator which defines + this node, or (char *)NULL if the node wasn't found. + NODE->contents is side-effected to point to right after + the separator. */ + node_sep = adjust_nodestart (node, min, max); + if (node_sep == (char *)NULL) + { + free (node); + return ((NODE *)NULL); + } + /* Readjust tag->nodestart. */ + tag->nodestart = node_sep - subfile->contents; + + /* Calculate the length of the current node. */ + buff_end = subfile->contents + subfile->filesize; + + node_body.buffer = node->contents; + node_body.start = 0; + node_body.end = buff_end - node_body.buffer; + node_body.flags = 0; + tag->nodelen = get_node_length (&node_body); + } + else + { + /* Since we know the length of this node, we have already + adjusted tag->nodestart to point to the exact start of + it. Simply skip the node separator. */ + node->contents += skip_node_separator (node->contents); + } + + node->nodelen = tag->nodelen; + return (node); + } } /* There was a tag table for this file, and the node wasn't found. @@ -985,9 +963,9 @@ info_node_of_file_buffer_tags (file_buffer, nodename) } /* **************************************************************** */ -/* */ -/* Managing file_buffers, nodes, and tags. */ -/* */ +/* */ +/* Managing file_buffers, nodes, and tags. */ +/* */ /* **************************************************************** */ /* Create a new, empty file buffer. */ @@ -1018,7 +996,7 @@ remember_info_file (file_buffer) ; add_pointer_to_array (file_buffer, i, info_loaded_files, - info_loaded_files_slots, 10, FILE_BUFFER *); + info_loaded_files_slots, 10, FILE_BUFFER *); } /* Forget the contents, tags table, nodes list, and names of FILENAME. */ @@ -1032,25 +1010,25 @@ forget_info_file (filename) if (!info_loaded_files) return; - for (i = 0; file_buffer = info_loaded_files[i]; i++) + for (i = 0; (file_buffer = info_loaded_files[i]); i++) if ((strcmp (filename, file_buffer->filename) == 0) || - (strcmp (filename, file_buffer->fullpath) == 0)) + (strcmp (filename, file_buffer->fullpath) == 0)) { - free (file_buffer->filename); - free (file_buffer->fullpath); + free (file_buffer->filename); + free (file_buffer->fullpath); - if (file_buffer->contents) - free (file_buffer->contents); - - /* Note that free_file_buffer_tags () also kills the subfiles - list, since the subfiles list is only of use in conjunction - with tags. */ - free_file_buffer_tags (file_buffer); + if (file_buffer->contents) + free (file_buffer->contents); + + /* Note that free_file_buffer_tags () also kills the subfiles + list, since the subfiles list is only of use in conjunction + with tags. */ + free_file_buffer_tags (file_buffer); - while (info_loaded_files[i] = info_loaded_files[++i]) - ; + while ((info_loaded_files[i] = info_loaded_files[++i])) + ; - break; + break; } } @@ -1065,8 +1043,8 @@ free_file_buffer_tags (file_buffer) { register TAG *tag; - for (i = 0; tag = file_buffer->tags[i]; i++) - free_info_tag (tag); + for (i = 0; (tag = file_buffer->tags[i]); i++) + free_info_tag (tag); free (file_buffer->tags); file_buffer->tags = (TAG **)NULL; @@ -1076,7 +1054,7 @@ free_file_buffer_tags (file_buffer) if (file_buffer->subfiles) { for (i = 0; file_buffer->subfiles[i]; i++) - free (file_buffer->subfiles[i]); + free (file_buffer->subfiles[i]); free (file_buffer->subfiles); file_buffer->subfiles = (char **)NULL; @@ -1160,29 +1138,29 @@ adjust_nodestart (node, min, max) sep_len = skip_node_separator (node->contents); /* If we managed to skip a node separator, then check for this node - being the right one. */ + being the right one. */ if (sep_len != 0) - { - char *nodedef, *nodestart; - int offset; - - nodestart = node_body.buffer + position + sep_len; - nodedef = nodestart; - offset = string_in_line (INFO_NODE_LABEL, nodedef); - - if (offset != -1) - { - nodedef += offset; - nodedef += skip_whitespace (nodedef); - offset = skip_node_characters (nodedef, DONT_SKIP_NEWLINES); - if ((offset == strlen (node->nodename)) && - (strncmp (node->nodename, nodedef, offset) == 0)) - { - node->contents = nodestart; - return (node_body.buffer + position); - } - } - } + { + char *nodedef, *nodestart; + int offset; + + nodestart = node_body.buffer + position + sep_len; + nodedef = nodestart; + offset = string_in_line (INFO_NODE_LABEL, nodedef); + + if (offset != -1) + { + nodedef += offset; + nodedef += skip_whitespace (nodedef); + offset = skip_node_characters (nodedef, DONT_SKIP_NEWLINES); + if ((offset == strlen (node->nodename)) && + (strncmp (node->nodename, nodedef, offset) == 0)) + { + node->contents = nodestart; + return (node_body.buffer + position); + } + } + } } /* Oh well, I guess we have to try to find it in a larger area. */ diff --git a/gnu/usr.bin/texinfo/info/search.c b/gnu/usr.bin/texinfo/info/search.c index c5fd47794b0..0e8e619256a 100644 --- a/gnu/usr.bin/texinfo/info/search.c +++ b/gnu/usr.bin/texinfo/info/search.c @@ -3,7 +3,7 @@ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. - Copyright (C) 1993 Free Software Foundation, Inc. + Copyright (C) 1993, 97 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,17 +21,11 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> -#include "general.h" +#include "info.h" + #include "search.h" #include "nodes.h" -#if !defined (NULL) -# define NULL 0x0 -#endif /* !NULL */ - /* The search functions take two arguments: 1) a string to search for, and @@ -73,9 +67,9 @@ copy_binding (binding) /* **************************************************************** */ -/* */ -/* The Actual Searching Functions */ -/* */ +/* */ +/* The Actual Searching Functions */ +/* */ /* **************************************************************** */ /* Search forwards or backwards for the text delimited by BINDING. @@ -115,15 +109,15 @@ search_forward (string, binding) if (binding->flags & S_FoldCase) { - alternate = strdup (string); + alternate = xstrdup (string); for (i = 0; i < len; i++) - { - if (islower (alternate[i])) - alternate[i] = toupper (alternate[i]); - else if (isupper (alternate[i])) - alternate[i] = tolower (alternate[i]); - } + { + if (islower (alternate[i])) + alternate[i] = toupper (alternate[i]); + else if (isupper (alternate[i])) + alternate[i] = tolower (alternate[i]); + } } buff = binding->buffer + binding->start; @@ -132,21 +126,21 @@ search_forward (string, binding) while (buff < (end - len)) { for (i = 0; i < len; i++) - { - c = buff[i]; + { + c = buff[i]; - if ((c != string[i]) && (!alternate || c != alternate[i])) - break; - } + if ((c != string[i]) && (!alternate || c != alternate[i])) + break; + } if (!string[i]) - { - if (alternate) - free (alternate); - if (binding->flags & S_SkipDest) - buff += len; - return ((long) (buff - binding->buffer)); - } + { + if (alternate) + free (alternate); + if (binding->flags & S_SkipDest) + buff += len; + return ((long) (buff - binding->buffer)); + } buff++; } @@ -184,15 +178,15 @@ search_backward (input_string, binding) if (binding->flags & S_FoldCase) { - alternate = strdup (string); + alternate = xstrdup (string); for (i = 0; i < len; i++) - { - if (islower (alternate[i])) - alternate[i] = toupper (alternate[i]); - else if (isupper (alternate[i])) - alternate[i] = tolower (alternate[i]); - } + { + if (islower (alternate[i])) + alternate[i] = toupper (alternate[i]); + else if (isupper (alternate[i])) + alternate[i] = tolower (alternate[i]); + } } buff = binding->buffer + binding->start - 1; @@ -201,23 +195,23 @@ search_backward (input_string, binding) while (buff > (end + len)) { for (i = 0; i < len; i++) - { - c = *(buff - i); + { + c = *(buff - i); - if (c != string[i] && (alternate && c != alternate[i])) - break; - } + if (c != string[i] && (alternate && c != alternate[i])) + break; + } if (!string[i]) - { - free (string); - if (alternate) - free (alternate); + { + free (string); + if (alternate) + free (alternate); - if (binding->flags & S_SkipDest) - buff -= len; - return ((long) (1 + (buff - binding->buffer))); - } + if (binding->flags & S_SkipDest) + buff -= len; + return ((long) (1 + (buff - binding->buffer))); + } buff--; } @@ -268,9 +262,9 @@ looking_at (string, binding) } /* **************************************************************** */ -/* */ -/* Small String Searches */ -/* */ +/* */ +/* Small String Searches */ +/* */ /* **************************************************************** */ /* Function names that start with "skip" are passed a string, and return @@ -346,37 +340,43 @@ skip_node_characters (string, newlines_okay) for (; string && (c = string[i]); i++) { if (paren) - { - if (c == '(') - paren++; - else if (c == ')') - paren--; - - continue; - } + { + if (c == '(') + paren++; + else if (c == ')') + paren--; + + continue; + } /* If the character following the close paren is a space or period, - then this node name has no more characters associated with it. */ + then this node name has no more characters associated with it. */ if (c == '\t' || - c == ',' || - c == INFO_TAGSEP || - ((!newlines_okay) && (c == '\n')) || - ((paren_seen && string[i - 1] == ')') && - (c == ' ' || c == '.')) || - (c == '.' && - ((!string[i + 1]) || - (whitespace_or_newline (string[i + 1])) || - (string[i + 1] == ')')))) - break; + c == ',' || + c == INFO_TAGSEP || + ((!newlines_okay) && (c == '\n')) || + ((paren_seen && string[i - 1] == ')') && + (c == ' ' || c == '.')) || + (c == '.' && + ( +#if 0 +/* This test causes a node name ending in a period, like `This.', not to + be found. The trailing . is stripped. This occurs in the jargon + file (`I see no X here.' is a node name). */ + (!string[i + 1]) || +#endif + (whitespace_or_newline (string[i + 1])) || + (string[i + 1] == ')')))) + break; } return (i); } /* **************************************************************** */ -/* */ -/* Searching FILE_BUFFER's */ -/* */ +/* */ +/* Searching FILE_BUFFER's */ +/* */ /* **************************************************************** */ /* Return the absolute position of the first occurence of a node separator in @@ -397,11 +397,11 @@ find_node_separator (binding) table (if present) and the indirect tags table (if present). */ for (i = binding->start; i < binding->end - 1; i++) if (((body[i] == INFO_FF && body[i + 1] == INFO_COOKIE) && - (body[i + 2] == '\n' || - (body[i + 2] == INFO_FF && body[i + 3] == '\n'))) || - ((body[i] == INFO_COOKIE) && - (body[i + 1] == '\n' || - (body[i + 1] == INFO_FF && body[i + 2] == '\n')))) + (body[i + 2] == '\n' || + (body[i + 2] == INFO_FF && body[i + 3] == '\n'))) || + ((body[i] == INFO_COOKIE) && + (body[i + 1] == '\n' || + (body[i + 1] == INFO_FF && body[i + 2] == '\n')))) return (i); return (-1); } @@ -467,7 +467,7 @@ find_tags_table (binding) search.start += skip_node_separator (search.buffer + search.start); if (looking_at (TAGS_TABLE_BEG_LABEL, &search)) - return (position); + return (position); } return (-1); } @@ -482,8 +482,8 @@ find_node_in_binding (nodename, binding) char *nodename; SEARCH_BINDING *binding; { - register long position; - register int offset, namelen; + long position; + int offset, namelen; SEARCH_BINDING search; namelen = strlen (nodename); @@ -501,19 +501,19 @@ find_node_in_binding (nodename, binding) offset = string_in_line (INFO_NODE_LABEL, search.buffer + search.start); if (offset == -1) - continue; + continue; search.start += offset; search.start += skip_whitespace (search.buffer + search.start); offset = skip_node_characters - (search.buffer + search.start, DONT_SKIP_NEWLINES); + (search.buffer + search.start, DONT_SKIP_NEWLINES); /* Notice that this is an exact match. You cannot grovel through - the buffer with this function looking for random nodes. */ + the buffer with this function looking for random nodes. */ if ((offset == namelen) && - (search.buffer[search.start] == nodename[0]) && - (strncmp (search.buffer + search.start, nodename, offset) == 0)) - return (position); + (search.buffer[search.start] == nodename[0]) && + (strncmp (search.buffer + search.start, nodename, offset) == 0)) + return (position); } return (-1); } diff --git a/gnu/usr.bin/texinfo/info/session.h b/gnu/usr.bin/texinfo/info/session.h index 98b8ccf695f..f1e5b23be8a 100644 --- a/gnu/usr.bin/texinfo/info/session.h +++ b/gnu/usr.bin/texinfo/info/session.h @@ -21,10 +21,10 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#if !defined (_SESSION_H_) -#define _SESSION_H_ +#if !defined (SESSION_H) +#define SESSION_H -#include "general.h" +#include "info.h" #include "dribble.h" /* All commands that can be invoked from within info_session () receive @@ -55,11 +55,11 @@ extern int info_scroll_behaviour; extern char *info_scroll_choices[]; /* Values for info_scroll_behaviour. */ -#define IS_Continuous 0 /* Try to get first menu item, or failing that, the - "Next:" pointer, or failing that, the "Up:" and - "Next:" of the up. */ +#define IS_Continuous 0 /* Try to get first menu item, or failing that, the + "Next:" pointer, or failing that, the "Up:" and + "Next:" of the up. */ #define IS_NextOnly 1 /* Try to get "Next:" menu item. */ -#define IS_PageOnly 2 /* Simply give up at the bottom of a node. */ +#define IS_PageOnly 2 /* Simply give up at the bottom of a node. */ /* Utility functions found in session.c */ extern void info_dispatch_on_key (); @@ -143,4 +143,4 @@ extern void info_print_node (); /* Miscellaneous commands. */ extern void info_abort_key (), info_quit (), info_do_lowercase_version (); -#endif /* _SESSION_H_ */ +#endif /* SESSION_H */ diff --git a/gnu/usr.bin/texinfo/info/signals.c b/gnu/usr.bin/texinfo/info/signals.c index a60777fe597..b93a585f567 100644 --- a/gnu/usr.bin/texinfo/info/signals.c +++ b/gnu/usr.bin/texinfo/info/signals.c @@ -25,9 +25,9 @@ #include "signals.h" /* **************************************************************** */ -/* */ -/* Pretending That We Have POSIX Signals */ -/* */ +/* */ +/* Pretending That We Have POSIX Signals */ +/* */ /* **************************************************************** */ #if !defined (HAVE_SIGPROCMASK) && defined (HAVE_SIGSETMASK) @@ -57,33 +57,32 @@ sigprocmask (operation, newset, oldset) #endif /* !HAVE_SIGPROCMASK && HAVE_SIGSETMASK */ /* **************************************************************** */ -/* */ -/* Signal Handling for Info */ -/* */ +/* */ +/* Signal Handling for Info */ +/* */ /* **************************************************************** */ -typedef void SigHandlerType; -typedef SigHandlerType SigHandler (); +typedef RETSIGTYPE signal_handler (); -static SigHandlerType info_signal_handler (); -static SigHandler *old_TSTP, *old_TTOU, *old_TTIN; -static SigHandler *old_WINCH, *old_INT; +static RETSIGTYPE info_signal_handler (); +static signal_handler *old_TSTP, *old_TTOU, *old_TTIN; +static signal_handler *old_WINCH, *old_INT; void initialize_info_signal_handler () { #if defined (SIGTSTP) - old_TSTP = (SigHandler *) signal (SIGTSTP, info_signal_handler); - old_TTOU = (SigHandler *) signal (SIGTTOU, info_signal_handler); - old_TTIN = (SigHandler *) signal (SIGTTIN, info_signal_handler); + old_TSTP = (signal_handler *) signal (SIGTSTP, info_signal_handler); + old_TTOU = (signal_handler *) signal (SIGTTOU, info_signal_handler); + old_TTIN = (signal_handler *) signal (SIGTTIN, info_signal_handler); #endif /* SIGTSTP */ #if defined (SIGWINCH) - old_WINCH = (SigHandler *) signal (SIGWINCH, info_signal_handler); + old_WINCH = (signal_handler *) signal (SIGWINCH, info_signal_handler); #endif #if defined (SIGINT) - old_INT = (SigHandler *) signal (SIGINT, info_signal_handler); + old_INT = (signal_handler *) signal (SIGINT, info_signal_handler); #endif } @@ -98,11 +97,11 @@ redisplay_after_signal () fflush (stdout); } -static SigHandlerType +static RETSIGTYPE info_signal_handler (sig) int sig; { - SigHandler **old_signal_handler; + signal_handler **old_signal_handler; switch (sig) { @@ -116,56 +115,56 @@ info_signal_handler (sig) #endif { #if defined (SIGTSTP) - if (sig == SIGTSTP) - old_signal_handler = &old_TSTP; - if (sig == SIGTTOU) - old_signal_handler = &old_TTOU; - if (sig == SIGTTIN) - old_signal_handler = &old_TTIN; + if (sig == SIGTSTP) + old_signal_handler = &old_TSTP; + if (sig == SIGTTOU) + old_signal_handler = &old_TTOU; + if (sig == SIGTTIN) + old_signal_handler = &old_TTIN; #endif /* SIGTSTP */ - if (sig == SIGINT) - old_signal_handler = &old_INT; - - /* For stop signals, restore the terminal IO, leave the cursor - at the bottom of the window, and stop us. */ - terminal_goto_xy (0, screenheight - 1); - terminal_clear_to_eol (); - fflush (stdout); - terminal_unprep_terminal (); - signal (sig, *old_signal_handler); - UNBLOCK_SIGNAL (sig); - kill (getpid (), sig); - - /* The program is returning now. Restore our signal handler, - turn on terminal handling, redraw the screen, and place the - cursor where it belongs. */ - terminal_prep_terminal (); - *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler); - redisplay_after_signal (); - fflush (stdout); + if (sig == SIGINT) + old_signal_handler = &old_INT; + + /* For stop signals, restore the terminal IO, leave the cursor + at the bottom of the window, and stop us. */ + terminal_goto_xy (0, screenheight - 1); + terminal_clear_to_eol (); + fflush (stdout); + terminal_unprep_terminal (); + signal (sig, *old_signal_handler); + UNBLOCK_SIGNAL (sig); + kill (getpid (), sig); + + /* The program is returning now. Restore our signal handler, + turn on terminal handling, redraw the screen, and place the + cursor where it belongs. */ + terminal_prep_terminal (); + *old_signal_handler = (signal_handler *) signal (sig, info_signal_handler); + redisplay_after_signal (); + fflush (stdout); } break; #if defined (SIGWINCH) case SIGWINCH: { - /* Turn off terminal IO, tell our parent that the window has changed, - then reinitialize the terminal and rebuild our windows. */ - old_signal_handler = &old_WINCH; - terminal_goto_xy (0, 0); - fflush (stdout); - terminal_unprep_terminal (); - signal (sig, *old_signal_handler); - UNBLOCK_SIGNAL (sig); - kill (getpid (), sig); - - /* After our old signal handler returns... */ - terminal_get_screen_size (); - terminal_prep_terminal (); - display_initialize_display (screenwidth, screenheight); - window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL); - *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler); - redisplay_after_signal (); + /* Turn off terminal IO, tell our parent that the window has changed, + then reinitialize the terminal and rebuild our windows. */ + old_signal_handler = &old_WINCH; + terminal_goto_xy (0, 0); + fflush (stdout); + terminal_unprep_terminal (); + signal (sig, *old_signal_handler); + UNBLOCK_SIGNAL (sig); + kill (getpid (), sig); + + /* After our old signal handler returns... */ + terminal_get_screen_size (); + terminal_prep_terminal (); + display_initialize_display (screenwidth, screenheight); + window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL); + *old_signal_handler = (signal_handler *) signal (sig, info_signal_handler); + redisplay_after_signal (); } break; #endif /* SIGWINCH */ diff --git a/gnu/usr.bin/texinfo/info/terminal.h b/gnu/usr.bin/texinfo/info/terminal.h index 7cb115835c6..2e27268ea7f 100644 --- a/gnu/usr.bin/texinfo/info/terminal.h +++ b/gnu/usr.bin/texinfo/info/terminal.h @@ -3,7 +3,7 @@ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. - Copyright (C) 1993, 96 Free Software Foundation, Inc. + Copyright (C) 1993, 96, 97 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,15 +21,10 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -#if !defined (_TERMINAL_H_) -#define _TERMINAL_H_ +#if !defined (TERMINAL_H) +#define TERMINAL_H -/* We use the following data type to talk about pointers to functions. */ -#if !defined (__FUNCTION_DEF) -# define __FUNCTION_DEF -typedef int Function (); -typedef void VFunction (); -#endif /* _FUNCTION_DEF */ +#include "info.h" /* For almost every function externally visible from terminal.c, there is a corresponding "hook" function which can be bound in order to replace @@ -125,5 +120,6 @@ extern VFunction *terminal_ring_bell_hook; /* The key sequences output by the arrow keys, if this terminal has any. */ extern char *term_ku, *term_kd, *term_kr, *term_kl; +extern char *term_kP, *term_kN; -#endif /* !_TERMINAL_H_ */ +#endif /* !TERMINAL_H */ diff --git a/gnu/usr.bin/texinfo/info/tilde.h b/gnu/usr.bin/texinfo/info/tilde.h index d66aee95015..83f534b2bac 100644 --- a/gnu/usr.bin/texinfo/info/tilde.h +++ b/gnu/usr.bin/texinfo/info/tilde.h @@ -25,13 +25,10 @@ Written by Brian Fox (bfox@ai.mit.edu). */ -/* Function pointers can be declared as (Function *)foo. */ -#if !defined (__FUNCTION_DEF) -# define __FUNCTION_DEF -typedef int Function (); -typedef void VFunction (); -typedef char *CFunction (); -#endif /* _FUNCTION_DEF */ +#ifndef TILDE_H +#define TILDE_H + +#include "info.h" /* If non-null, this contains the address of a function to call if the standard meaning for expanding a tilde fails. The function is called @@ -56,3 +53,4 @@ extern char *tilde_expand (); tilde. If there is no expansion, call tilde_expansion_failure_hook. */ extern char *tilde_expand_word (); +#endif /* not TILDE_H */ |