aboutsummaryrefslogtreecommitdiff
path: root/contrib/texinfo/info/infodoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/texinfo/info/infodoc.c')
-rw-r--r--contrib/texinfo/info/infodoc.c771
1 files changed, 0 insertions, 771 deletions
diff --git a/contrib/texinfo/info/infodoc.c b/contrib/texinfo/info/infodoc.c
deleted file mode 100644
index 35675095e70c..000000000000
--- a/contrib/texinfo/info/infodoc.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/* infodoc.c -- Functions which build documentation nodes. */
-
-/* This file is part of GNU Info, a program for reading online documentation
- stored in Info format.
-
- Copyright (C) 1993 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"
-
-/* Normally we do not define HELP_NODE_GETS_REGENERATED because the
- contents of the help node currently can never change once an info
- session has been started. You should consider defining this in
- the case that you place information about dynamic variables in the
- help text. When that happens, the contents of the help node will
- change dependent on the value of those variables, and the user will
- expect to see those changes. */
-/* #define HELP_NODE_GETS_REGENERATED 1 */
-
-/* **************************************************************** */
-/* */
-/* Info Help Windows */
-/* */
-/* **************************************************************** */
-
-/* The name of the node used in the help window. */
-static char *info_help_nodename = "*Info Help*";
-
-/* A node containing printed key bindings and their documentation. */
-static NODE *internal_info_help_node = (NODE *)NULL;
-
-/* A pointer to the contents of the help node. */
-static char *internal_info_help_node_contents = (char *)NULL;
-
-/* The static text which appears in the internal info help node. */
-static char *info_internal_help_text[] = {
- "Basic Commands in Info Windows",
- "******************************",
- "",
- " h Invoke the Info tutorial.",
- "",
- "Selecting other nodes:",
- "----------------------",
- " n Move to the \"next\" node of this node.",
- " p Move to the \"previous\" node of this node.",
- " u Move \"up\" from this node.",
- " m Pick menu item specified by name.",
- " Picking a menu item causes another node to be selected.",
- " f Follow a cross reference. Reads name of reference.",
- " l Move to the last node seen in this window.",
- " d Move to the `directory' node. Equivalent to `g(DIR)'.",
- "",
- "Moving within a node:",
- "---------------------",
- " SPC Scroll forward a page.",
- " DEL Scroll backward a page.",
- " b Go to the beginning of this node.",
- " e Go to the end of this node.",
- "",
- "\"Advanced\" commands:",
- "--------------------",
- " q Quit Info.",
- " 1 Pick first item in node's menu.",
- " 2-9 Pick second ... ninth item in node's menu.",
- " 0 Pick last item in node's menu.",
- " g Move to node specified by name.",
- " You may include a filename as well, as in (FILENAME)NODENAME.",
- " s Search through this Info file for a specified string,",
- " and select the node in which the next occurrence is found.",
- (char *)NULL
-};
-
-static char *where_is (), *where_is_internal ();
-
-void
-dump_map_to_message_buffer (prefix, map)
- char *prefix;
- Keymap map;
-{
- register int i;
-
- for (i = 0; i < 256; i++)
- {
- if (map[i].type == ISKMAP)
- {
- char *new_prefix, *keyname;
-
- keyname = pretty_keyname (i);
- new_prefix = (char *)
- xmalloc (3 + strlen (prefix) + strlen (keyname));
- sprintf (new_prefix, "%s%s%s ", prefix, *prefix ? " " : "", keyname);
-
- dump_map_to_message_buffer (new_prefix, (Keymap)map[i].function);
- free (new_prefix);
- }
- else if (map[i].function)
- {
- register int last;
- char *doc, *name;
-
- doc = function_documentation (map[i].function);
- name = function_name (map[i].function);
-
- if (!*doc)
- continue;
-
- /* Find out if there is a series of identical functions, as in
- ea_insert (). */
- for (last = i + 1; last < 256; last++)
- if ((map[last].type != ISFUNC) ||
- (map[last].function != map[i].function))
- break;
-
- if (last - 1 != i)
- {
- printf_to_message_buffer
- ("%s%s .. ", prefix, pretty_keyname (i));
- printf_to_message_buffer
- ("%s%s\t", prefix, pretty_keyname (last - 1));
- i = last - 1;
- }
- else
- printf_to_message_buffer ("%s%s\t", prefix, pretty_keyname (i));
-
-#if defined (NAMED_FUNCTIONS)
- /* Print the name of the function, and some padding before the
- documentation string is printed. */
- {
- int length_so_far;
- int desired_doc_start = 40; /* Must be multiple of 8. */
-
- printf_to_message_buffer ("(%s)", name);
- length_so_far = message_buffer_length_this_line ();
-
- if ((desired_doc_start + strlen (doc)) >= the_screen->width)
- printf_to_message_buffer ("\n ");
- else
- {
- while (length_so_far < desired_doc_start)
- {
- printf_to_message_buffer ("\t");
- length_so_far += character_width ('\t', length_so_far);
- }
- }
- }
-#endif /* NAMED_FUNCTIONS */
- printf_to_message_buffer ("%s\n", doc);
- }
- }
-}
-
-/* How to create internal_info_help_node. */
-static void
-create_internal_info_help_node ()
-{
- register int i;
- char *contents = (char *)NULL;
- NODE *node;
-
-#if !defined (HELP_NODE_GETS_REGENERATED)
- if (internal_info_help_node_contents)
- contents = internal_info_help_node_contents;
-#endif /* !HELP_NODE_GETS_REGENERATED */
-
- if (!contents)
- {
- int printed_one_mx = 0;
-
- initialize_message_buffer ();
-
- for (i = 0; info_internal_help_text[i]; i++)
- printf_to_message_buffer ("%s\n", info_internal_help_text[i]);
-
- printf_to_message_buffer ("---------------------\n\n");
- printf_to_message_buffer ("The current search path is:\n");
- printf_to_message_buffer (" \"%s\"\n", infopath);
- printf_to_message_buffer ("---------------------\n\n");
- printf_to_message_buffer ("Commands available in Info windows:\n\n");
- dump_map_to_message_buffer ("", info_keymap);
- printf_to_message_buffer ("---------------------\n\n");
- printf_to_message_buffer ("Commands available in the echo area:\n\n");
- dump_map_to_message_buffer ("", echo_area_keymap);
-
-#if defined (NAMED_FUNCTIONS)
- /* Get a list of the M-x commands which have no keystroke equivs. */
- for (i = 0; function_doc_array[i].func; i++)
- {
- VFunction *func = function_doc_array[i].func;
-
- if ((!where_is_internal (info_keymap, func)) &&
- (!where_is_internal (echo_area_keymap, func)))
- {
- if (!printed_one_mx)
- {
- printf_to_message_buffer ("---------------------\n\n");
- printf_to_message_buffer
- ("The following commands can only be invoked via M-x:\n\n");
- printed_one_mx = 1;
- }
-
- printf_to_message_buffer
- ("M-x %s\n %s\n",
- function_doc_array[i].func_name,
- replace_in_documentation (function_doc_array[i].doc));
- }
- }
-
- if (printed_one_mx)
- printf_to_message_buffer ("\n");
-#endif /* NAMED_FUNCTIONS */
-
- printf_to_message_buffer
- ("%s", replace_in_documentation
- ("--- Use `\\[history-node]' or `\\[kill-node]' to exit ---\n"));
- node = message_buffer_to_node ();
- internal_info_help_node_contents = node->contents;
- }
- else
- {
- /* We already had the right contents, so simply use them. */
- node = build_message_node ("", 0, 0);
- free (node->contents);
- node->contents = contents;
- node->nodelen = 1 + strlen (contents);
- }
-
- internal_info_help_node = node;
-
- /* Do not GC this node's contents. It never changes, and we never need
- to delete it once it is made. If you change some things (such as
- placing information about dynamic variables in the help text) then
- you will need to allow the contents to be gc'd, and you will have to
- arrange to always regenerate the help node. */
-#if defined (HELP_NODE_GETS_REGENERATED)
- add_gcable_pointer (internal_info_help_node->contents);
-#endif
-
- name_internal_node (internal_info_help_node, info_help_nodename);
-
- /* Even though this is an internal node, we don't want the window
- system to treat it specially. So we turn off the internalness
- of it here. */
- internal_info_help_node->flags &= ~N_IsInternal;
-}
-
-/* Return a window which is the window showing help in this Info. */
-static WINDOW *
-info_find_or_create_help_window ()
-{
- WINDOW *help_window, *eligible, *window;
-
- eligible = (WINDOW *)NULL;
- help_window = get_internal_info_window (info_help_nodename);
-
- /* If we couldn't find the help window, then make it. */
- if (!help_window)
- {
- int max = 0;
-
- for (window = windows; window; window = window->next)
- {
- if (window->height > max)
- {
- max = window->height;
- eligible = window;
- }
- }
-
- if (!eligible)
- return ((WINDOW *)NULL);
- }
-#if !defined (HELP_NODE_GETS_REGENERATED)
- else
- return (help_window);
-#endif /* !HELP_NODE_GETS_REGENERATED */
-
- /* Make sure that we have a node containing the help text. */
- create_internal_info_help_node ();
-
- /* Either use the existing window to display the help node, or create
- a new window if there was no existing help window. */
- if (!help_window)
- {
- /* Split the largest window into 2 windows, and show the help text
- in that window. */
- if (eligible->height > 30)
- {
- active_window = eligible;
- help_window = window_make_window (internal_info_help_node);
- }
- else
- {
- set_remembered_pagetop_and_point (active_window);
- window_set_node_of_window (active_window, internal_info_help_node);
- help_window = active_window;
- }
- }
- else
- {
- /* Case where help node always gets regenerated, and we have an
- existing window in which to place the node. */
- if (active_window != help_window)
- {
- set_remembered_pagetop_and_point (active_window);
- active_window = help_window;
- }
- window_set_node_of_window (active_window, internal_info_help_node);
- }
- remember_window_and_node (help_window, help_window->node);
- return (help_window);
-}
-
-/* Create or move to the help window. */
-DECLARE_INFO_COMMAND (info_get_help_window, "Display help message")
-{
- WINDOW *help_window;
-
- help_window = info_find_or_create_help_window ();
- if (help_window)
- {
- active_window = help_window;
- active_window->flags |= W_UpdateWindow;
- }
- else
- {
- info_error (CANT_MAKE_HELP);
- }
-}
-
-/* Show the Info help node. This means that the "info" file is installed
- where it can easily be found on your system. */
-DECLARE_INFO_COMMAND (info_get_info_help_node, "Visit Info node `(info)Help'")
-{
- NODE *node;
- char *nodename;
-
- /* If there is a window on the screen showing the node "(info)Help" or
- the node "(info)Help-Small-Screen", simply select that window. */
- {
- WINDOW *win;
-
- for (win = windows; win; win = win->next)
- {
- if (win->node && win->node->filename &&
- (strcasecmp
- (filename_non_directory (win->node->filename), "info") == 0) &&
- ((strcmp (win->node->nodename, "Help") == 0) ||
- (strcmp (win->node->nodename, "Help-Small-Screen") == 0)))
- {
- active_window = win;
- return;
- }
- }
- }
-
- /* If the current window is small, show the small screen help. */
- if (active_window->height < 24)
- nodename = "Help-Small-Screen";
- else
- nodename = "Help";
-
- /* Try to get the info file for Info. */
- node = info_get_node ("Info", nodename);
-
- if (!node)
- {
- if (info_recent_file_error)
- info_error (info_recent_file_error);
- else
- info_error (CANT_FILE_NODE, "Info", nodename);
- }
- else
- {
- /* If the current window is very large (greater than 45 lines),
- then split it and show the help node in another window.
- Otherwise, use the current window. */
-
- if (active_window->height > 45)
- active_window = window_make_window (node);
- else
- {
- set_remembered_pagetop_and_point (active_window);
- window_set_node_of_window (active_window, node);
- }
-
- remember_window_and_node (active_window, node);
- }
-}
-
-/* **************************************************************** */
-/* */
-/* Groveling Info Keymaps and Docs */
-/* */
-/* **************************************************************** */
-
-/* Return the documentation associated with the Info command FUNCTION. */
-char *
-function_documentation (function)
- VFunction *function;
-{
- register int i;
-
- for (i = 0; function_doc_array[i].func; i++)
- if (function == function_doc_array[i].func)
- break;
-
- return (replace_in_documentation (function_doc_array[i].doc));
-}
-
-#if defined (NAMED_FUNCTIONS)
-/* Return the user-visible name of the function associated with the
- Info command FUNCTION. */
-char *
-function_name (function)
-
- VFunction *function;
-{
- register int i;
-
- for (i = 0; function_doc_array[i].func; i++)
- if (function == function_doc_array[i].func)
- break;
-
- return (function_doc_array[i].func_name);
-}
-
-/* Return a pointer to the function named NAME. */
-VFunction *
-named_function (name)
- char *name;
-{
- register int i;
-
- for (i = 0; function_doc_array[i].func; i++)
- if (strcmp (function_doc_array[i].func_name, name) == 0)
- break;
-
- return (function_doc_array[i].func);
-}
-#endif /* NAMED_FUNCTIONS */
-
-/* Return the documentation associated with KEY in MAP. */
-char *
-key_documentation (key, map)
- char key;
- Keymap map;
-{
- VFunction *function = map[key].function;
-
- if (function)
- return (function_documentation (function));
- else
- return ((char *)NULL);
-}
-
-DECLARE_INFO_COMMAND (describe_key, "Print documentation for KEY")
-{
- char keyname[50];
- int keyname_index = 0;
- unsigned char keystroke;
- char *rep;
- Keymap map;
-
- keyname[0] = '\0';
- map = window->keymap;
-
- while (1)
- {
- message_in_echo_area ("Describe key: %s", keyname);
- keystroke = info_get_input_char ();
- unmessage_in_echo_area ();
-
- if (Meta_p (keystroke) && (!ISO_Latin_p || key < 160))
- {
- if (map[ESC].type != ISKMAP)
- {
- window_message_in_echo_area
- ("ESC %s is undefined.", pretty_keyname (UnMeta (keystroke)));
- return;
- }
-
- strcpy (keyname + keyname_index, "ESC ");
- keyname_index = strlen (keyname);
- keystroke = UnMeta (keystroke);
- map = (Keymap)map[ESC].function;
- }
-
- /* Add the printed representation of KEYSTROKE to our keyname. */
- rep = pretty_keyname (keystroke);
- strcpy (keyname + keyname_index, rep);
- keyname_index = strlen (keyname);
-
- if (map[keystroke].function == (VFunction *)NULL)
- {
- message_in_echo_area ("%s is undefined.", keyname);
- return;
- }
- else if (map[keystroke].type == ISKMAP)
- {
- map = (Keymap)map[keystroke].function;
- strcat (keyname, " ");
- keyname_index = strlen (keyname);
- continue;
- }
- else
- {
- char *message, *fundoc, *funname = "";
-
-#if defined (NAMED_FUNCTIONS)
- funname = function_name (map[keystroke].function);
-#endif /* NAMED_FUNCTIONS */
-
- fundoc = function_documentation (map[keystroke].function);
-
- message = (char *)xmalloc
- (10 + strlen (keyname) + strlen (fundoc) + strlen (funname));
-
-#if defined (NAMED_FUNCTIONS)
- sprintf (message, "%s (%s): %s.", keyname, funname, fundoc);
-#else
- sprintf (message, "%s is defined to %s.", keyname, fundoc);
-#endif /* !NAMED_FUNCTIONS */
-
- window_message_in_echo_area ("%s", message);
- free (message);
- break;
- }
- }
-}
-
-/* How to get the pretty printable name of a character. */
-static char rep_buffer[30];
-
-char *
-pretty_keyname (key)
- unsigned char key;
-{
- char *rep;
-
- if (Meta_p (key))
- {
- char temp[20];
-
- rep = pretty_keyname (UnMeta (key));
-
- sprintf (temp, "ESC %s", rep);
- strcpy (rep_buffer, temp);
- rep = rep_buffer;
- }
- else if (Control_p (key))
- {
- switch (key)
- {
- case '\n': rep = "LFD"; break;
- case '\t': rep = "TAB"; break;
- case '\r': rep = "RET"; break;
- case ESC: rep = "ESC"; break;
-
- default:
- sprintf (rep_buffer, "C-%c", UnControl (key));
- rep = rep_buffer;
- }
- }
- else
- {
- switch (key)
- {
- case ' ': rep = "SPC"; break;
- case DEL: rep = "DEL"; break;
- default:
- rep_buffer[0] = key;
- rep_buffer[1] = '\0';
- rep = rep_buffer;
- }
- }
- return (rep);
-}
-
-/* Replace the names of functions with the key that invokes them. */
-char *
-replace_in_documentation (string)
- char *string;
-{
- register int i, start, next;
- static char *result = (char *)NULL;
-
- maybe_free (result);
- result = (char *)xmalloc (1 + strlen (string));
-
- i = next = start = 0;
-
- /* Skip to the beginning of a replaceable function. */
- for (i = start; string[i]; i++)
- {
- /* Is this the start of a replaceable function name? */
- if (string[i] == '\\' && string[i + 1] == '[')
- {
- char *fun_name, *rep;
- VFunction *function;
-
- /* Copy in the old text. */
- strncpy (result + next, string + start, i - start);
- next += (i - start);
- start = i + 2;
-
- /* Move to the end of the function name. */
- for (i = start; string[i] && (string[i] != ']'); i++);
-
- fun_name = (char *)xmalloc (1 + i - start);
- strncpy (fun_name, string + start, i - start);
- fun_name[i - start] = '\0';
-
- /* Find a key which invokes this function in the info_keymap. */
- function = named_function (fun_name);
-
- /* If the internal documentation string fails, there is a
- serious problem with the associated command's documentation.
- We croak so that it can be fixed immediately. */
- if (!function)
- abort ();
-
- rep = where_is (info_keymap, function);
- strcpy (result + next, rep);
- next = strlen (result);
-
- start = i;
- if (string[i])
- start++;
- }
- }
- strcpy (result + next, string + start);
- return (result);
-}
-
-/* Return a string of characters which could be typed from the keymap
- MAP to invoke FUNCTION. */
-static char *where_is_rep = (char *)NULL;
-static int where_is_rep_index = 0;
-static int where_is_rep_size = 0;
-
-static char *
-where_is (map, function)
- Keymap map;
- VFunction *function;
-{
- char *rep;
-
- if (!where_is_rep_size)
- where_is_rep = (char *)xmalloc (where_is_rep_size = 100);
- where_is_rep_index = 0;
-
- rep = where_is_internal (map, function);
-
- /* If it couldn't be found, return "M-x Foo". */
- if (!rep)
- {
- char *name;
-
- name = function_name (function);
-
- if (name)
- sprintf (where_is_rep, "M-x %s", name);
-
- rep = where_is_rep;
- }
- return (rep);
-}
-
-/* Return the printed rep of FUNCTION as found in MAP, or NULL. */
-static char *
-where_is_internal (map, function)
- Keymap map;
- VFunction *function;
-{
- register int i;
-
- /* If the function is directly invokable in MAP, return the representation
- of that keystroke. */
- for (i = 0; i < 256; i++)
- if ((map[i].type == ISFUNC) && map[i].function == function)
- {
- sprintf (where_is_rep + where_is_rep_index, "%s", pretty_keyname (i));
- return (where_is_rep);
- }
-
- /* Okay, search subsequent maps for this function. */
- for (i = 0; i < 256; i++)
- {
- if (map[i].type == ISKMAP)
- {
- int saved_index = where_is_rep_index;
- char *rep;
-
- sprintf (where_is_rep + where_is_rep_index, "%s ",
- pretty_keyname (i));
-
- where_is_rep_index = strlen (where_is_rep);
- rep = where_is_internal ((Keymap)map[i].function, function);
-
- if (rep)
- return (where_is_rep);
-
- where_is_rep_index = saved_index;
- }
- }
-
- return ((char *)NULL);
-}
-
-extern char *read_function_name ();
-
-DECLARE_INFO_COMMAND (info_where_is,
- "Show what to type to execute a given command")
-{
- char *command_name;
-
- command_name = read_function_name ("Where is command: ", window);
-
- if (!command_name)
- {
- info_abort_key (active_window, count, key);
- return;
- }
-
- if (*command_name)
- {
- VFunction *function;
-
- function = named_function (command_name);
-
- if (function)
- {
- char *location;
-
- location = where_is (active_window->keymap, function);
-
- if (!location)
- {
- info_error ("`%s' is not on any keys", command_name);
- }
- else
- {
- if (strncmp (location, "M-x ", 4) == 0)
- window_message_in_echo_area
- ("%s can only be invoked via %s.", command_name, location);
- else
- window_message_in_echo_area
- ("%s can be invoked via %s.", command_name, location);
- }
- }
- else
- info_error ("There is no function named `%s'", command_name);
- }
-
- free (command_name);
-}