summaryrefslogtreecommitdiff
path: root/texinfo/info/indices.c
diff options
context:
space:
mode:
Diffstat (limited to 'texinfo/info/indices.c')
-rw-r--r--texinfo/info/indices.c727
1 files changed, 0 insertions, 727 deletions
diff --git a/texinfo/info/indices.c b/texinfo/info/indices.c
deleted file mode 100644
index 03e4b35a75a..00000000000
--- a/texinfo/info/indices.c
+++ /dev/null
@@ -1,727 +0,0 @@
-/* indices.c -- Commands for dealing with an Info file Index.
- $Id: indices.c,v 1.1.1.2 1998/03/22 20:42:33 law 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"
-#include "indices.h"
-
-/* User-visible variable controls the output of info-index-next. */
-int show_index_match = 1;
-
-/* In the Info sense, an index is a menu. This variable holds the last
- parsed index. */
-static REFERENCE **index_index = (REFERENCE **)NULL;
-
-/* The offset of the most recently selected index element. */
-static int index_offset = 0;
-
-/* Variable which holds the last string searched for. */
-static char *index_search = (char *)NULL;
-
-/* A couple of "globals" describing where the initial index was found. */
-static char *initial_index_filename = (char *)NULL;
-static char *initial_index_nodename = (char *)NULL;
-
-/* A structure associating index names with index offset ranges. */
-typedef struct {
- char *name; /* The nodename of this index. */
- int first; /* The index in our list of the first entry. */
- int last; /* The index in our list of the last entry. */
-} INDEX_NAME_ASSOC;
-
-/* An array associating index nodenames with index offset ranges. */
-static INDEX_NAME_ASSOC **index_nodenames = (INDEX_NAME_ASSOC **)NULL;
-static int index_nodenames_index = 0;
-static int index_nodenames_slots = 0;
-
-/* Add the name of NODE, and the range of the associated index elements
- (passed in ARRAY) to index_nodenames. */
-static void
-add_index_to_index_nodenames (array, node)
- REFERENCE **array;
- NODE *node;
-{
- register int i, last;
- INDEX_NAME_ASSOC *assoc;
-
- for (last = 0; array[last]; last++);
- assoc = (INDEX_NAME_ASSOC *)xmalloc (sizeof (INDEX_NAME_ASSOC));
- assoc->name = xstrdup (node->nodename);
-
- if (!index_nodenames_index)
- {
- assoc->first = 0;
- assoc->last = last;
- }
- else
- {
- for (i = 0; index_nodenames[i + 1]; i++);
- assoc->first = 1 + index_nodenames[i]->last;
- assoc->last = assoc->first + last;
- }
- add_pointer_to_array
- (assoc, index_nodenames_index, index_nodenames, index_nodenames_slots,
- 10, INDEX_NAME_ASSOC *);
-}
-
-/* Find and return the indices of WINDOW's file. The indices are defined
- as the first node in the file containing the word "Index" and any
- immediately following nodes whose names also contain "Index". All such
- indices are concatenated and the result returned. If WINDOW's info file
- doesn't have any indices, a NULL pointer is returned. */
-REFERENCE **
-info_indices_of_window (window)
- WINDOW *window;
-{
- FILE_BUFFER *fb;
-
- fb = file_buffer_of_window (window);
-
- return (info_indices_of_file_buffer (fb));
-}
-
-REFERENCE **
-info_indices_of_file_buffer (file_buffer)
- FILE_BUFFER *file_buffer;
-{
- register int i;
- REFERENCE **result = (REFERENCE **)NULL;
-
- /* No file buffer, no indices. */
- if (!file_buffer)
- return ((REFERENCE **)NULL);
-
- /* Reset globals describing where the index was found. */
- maybe_free (initial_index_filename);
- maybe_free (initial_index_nodename);
- initial_index_filename = (char *)NULL;
- initial_index_nodename = (char *)NULL;
-
- if (index_nodenames)
- {
- for (i = 0; index_nodenames[i]; i++)
- {
- free (index_nodenames[i]->name);
- free (index_nodenames[i]);
- }
-
- index_nodenames_index = 0;
- index_nodenames[0] = (INDEX_NAME_ASSOC *)NULL;
- }
-
- /* Grovel the names of the nodes found in this file. */
- if (file_buffer->tags)
- {
- TAG *tag;
-
- for (i = 0; (tag = file_buffer->tags[i]); i++)
- {
- if (string_in_line ("Index", tag->nodename) != -1)
- {
- NODE *node;
- REFERENCE **menu;
-
- /* Found one. Get its menu. */
- node = info_get_node (tag->filename, tag->nodename);
- if (!node)
- continue;
-
- /* Remember the filename and nodename of this index. */
- initial_index_filename = xstrdup (file_buffer->filename);
- initial_index_nodename = xstrdup (tag->nodename);
-
- menu = info_menu_of_node (node);
-
- /* If we have a menu, add this index's nodename and range
- to our list of index_nodenames. */
- if (menu)
- {
- add_index_to_index_nodenames (menu, node);
-
- /* Concatenate the references found so far. */
- result = info_concatenate_references (result, menu);
- }
- free (node);
- }
- }
- }
-
- /* If there is a result, clean it up so that every entry has a filename. */
- for (i = 0; result && result[i]; i++)
- if (!result[i]->filename)
- result[i]->filename = xstrdup (file_buffer->filename);
-
- return (result);
-}
-
-DECLARE_INFO_COMMAND (info_index_search,
- _("Look up a string in the index for this file"))
-{
- do_info_index_search (window, count, 0);
-}
-
-/* Look up SEARCH_STRING in the index for this file. If SEARCH_STRING
- is NULL, prompt user for input. */
-void
-do_info_index_search (window, count, search_string)
- WINDOW *window;
- int count;
- char *search_string;
-{
- FILE_BUFFER *fb;
- char *line;
-
- /* Reset the index offset, since this is not the info-index-next command. */
- index_offset = 0;
-
- /* The user is selecting a new search string, so flush the old one. */
- maybe_free (index_search);
- index_search = (char *)NULL;
-
- /* If this window's file is not the same as the one that we last built an
- index for, build and remember an index now. */
- fb = file_buffer_of_window (window);
- if (!initial_index_filename ||
- (strcmp (initial_index_filename, fb->filename) != 0))
- {
- info_free_references (index_index);
- window_message_in_echo_area (_("Finding index entries..."));
- index_index = info_indices_of_file_buffer (fb);
- }
-
- /* If there is no index, quit now. */
- if (!index_index)
- {
- info_error (_("No indices found."));
- return;
- }
-
- /* Okay, there is an index. Look for SEARCH_STRING, or, if it is
- empty, prompt for one. */
- if (search_string && *search_string)
- line = xstrdup (search_string);
- else
- {
- line = info_read_maybe_completing (window, _("Index entry: "),
- index_index);
- window = active_window;
-
- /* User aborted? */
- if (!line)
- {
- info_abort_key (active_window, 1, 0);
- return;
- }
-
- /* Empty line means move to the Index node. */
- if (!*line)
- {
- free (line);
-
- if (initial_index_filename && initial_index_nodename)
- {
- NODE *node;
-
- node = info_get_node (initial_index_filename,
- initial_index_nodename);
- set_remembered_pagetop_and_point (window);
- window_set_node_of_window (window, node);
- remember_window_and_node (window, node);
- window_clear_echo_area ();
- return;
- }
- }
- }
-
- /* The user typed either a completed index label, or a partial string.
- Find an exact match, or, failing that, the first index entry containing
- the partial string. So, we just call info_next_index_match () with minor
- manipulation of INDEX_OFFSET. */
- {
- int old_offset;
-
- /* Start the search right after/before this index. */
- if (count < 0)
- {
- register int i;
- for (i = 0; index_index[i]; i++);
- index_offset = i;
- }
- else
- index_offset = -1;
-
- old_offset = index_offset;
-
- /* The "last" string searched for is this one. */
- index_search = line;
-
- /* Find it, or error. */
- info_next_index_match (window, count, 0);
-
- /* If the search failed, return the index offset to where it belongs. */
- if (index_offset == old_offset)
- index_offset = 0;
- }
-}
-
-int
-index_entry_exists (window, string)
- WINDOW *window;
- char *string;
-{
- register int i;
- FILE_BUFFER *fb;
-
- /* If there is no previous search string, the user hasn't built an index
- yet. */
- if (!string)
- return 0;
-
- fb = file_buffer_of_window (window);
- if (!initial_index_filename
- || (strcmp (initial_index_filename, fb->filename) != 0))
- {
- info_free_references (index_index);
- index_index = info_indices_of_file_buffer (fb);
- }
-
- /* If there is no index, that is an error. */
- if (!index_index)
- return 0;
-
- for (i = 0; (i > -1) && (index_index[i]); i++)
- if (strcmp (string, index_index[i]->label) == 0)
- break;
-
- /* If that failed, look for the next substring match. */
- if ((i < 0) || (!index_index[i]))
- {
- for (i = 0; (i > -1) && (index_index[i]); i++)
- if (string_in_line (string, index_index[i]->label) != -1)
- break;
-
- if ((i > -1) && (index_index[i]))
- string_in_line (string, index_index[i]->label);
- }
-
- /* If that failed, return 0. */
- if ((i < 0) || (!index_index[i]))
- return 0;
-
- return 1;
-}
-
-DECLARE_INFO_COMMAND (info_next_index_match,
- _("Go to the next matching index item from the last `\\[index-search]' command"))
-{
- register int i;
- int partial, dir;
- NODE *node;
-
- /* If there is no previous search string, the user hasn't built an index
- yet. */
- if (!index_search)
- {
- info_error (_("No previous index search string."));
- return;
- }
-
- /* If there is no index, that is an error. */
- if (!index_index)
- {
- info_error (_("No index entries."));
- return;
- }
-
- /* The direction of this search is controlled by the value of the
- numeric argument. */
- if (count < 0)
- dir = -1;
- else
- dir = 1;
-
- /* Search for the next occurence of index_search. First try to find
- an exact match. */
- partial = 0;
-
- for (i = index_offset + dir; (i > -1) && (index_index[i]); i += dir)
- if (strcmp (index_search, index_index[i]->label) == 0)
- break;
-
- /* If that failed, look for the next substring match. */
- if ((i < 0) || (!index_index[i]))
- {
- for (i = index_offset + dir; (i > -1) && (index_index[i]); i += dir)
- if (string_in_line (index_search, index_index[i]->label) != -1)
- break;
-
- if ((i > -1) && (index_index[i]))
- partial = string_in_line (index_search, index_index[i]->label);
- }
-
- /* If that failed, print an error. */
- if ((i < 0) || (!index_index[i]))
- {
- info_error (_("No %sindex entries containing \"%s\"."),
- index_offset > 0 ? _("more ") : "", index_search);
- return;
- }
-
- /* Okay, we found the next one. Move the offset to the current entry. */
- index_offset = i;
-
- /* Report to the user on what we have found. */
- {
- register int j;
- char *name = _("CAN'T SEE THIS");
- char *match;
-
- for (j = 0; index_nodenames[j]; j++)
- {
- if ((i >= index_nodenames[j]->first) &&
- (i <= index_nodenames[j]->last))
- {
- name = index_nodenames[j]->name;
- break;
- }
- }
-
- /* If we had a partial match, indicate to the user which part of the
- string matched. */
- match = xstrdup (index_index[i]->label);
-
- if (partial && show_index_match)
- {
- int j, ls, start, upper;
-
- ls = strlen (index_search);
- start = partial - ls;
- upper = isupper (match[start]) ? 1 : 0;
-
- for (j = 0; j < ls; j++)
- if (upper)
- match[j + start] = info_tolower (match[j + start]);
- else
- match[j + start] = info_toupper (match[j + start]);
- }
-
- {
- char *format;
-
- format = replace_in_documentation
- (_("Found \"%s\" in %s. (`\\[next-index-match]' tries to find next.)"));
-
- window_message_in_echo_area (format, match, name);
- }
-
- free (match);
- }
-
- /* Select the node corresponding to this index entry. */
- node = info_get_node (index_index[i]->filename, index_index[i]->nodename);
-
- if (!node)
- {
- info_error (CANT_FILE_NODE,
- index_index[i]->filename, index_index[i]->nodename);
- return;
- }
-
- set_remembered_pagetop_and_point (window);
- window_set_node_of_window (window, node);
- remember_window_and_node (window, node);
-
-
- /* Try to find an occurence of LABEL in this node. */
- {
- long start, loc;
-
- start = window->line_starts[1] - window->node->contents;
- loc = info_target_search_node (node, index_index[i]->label, start);
-
- if (loc != -1)
- {
- window->point = loc;
- window_adjust_pagetop (window);
- }
- }
-}
-
-/* **************************************************************** */
-/* */
-/* Info APROPOS: Search every known index. */
-/* */
-/* **************************************************************** */
-
-/* For every menu item in DIR, search the indices of that file for
- SEARCH_STRING. */
-REFERENCE **
-apropos_in_all_indices (search_string, inform)
- char *search_string;
- int inform;
-{
- register int i, dir_index;
- REFERENCE **all_indices = (REFERENCE **)NULL;
- REFERENCE **dir_menu = (REFERENCE **)NULL;
- NODE *dir_node;
-
- dir_node = info_get_node ("dir", "Top");
- if (dir_node)
- dir_menu = info_menu_of_node (dir_node);
-
- if (!dir_menu)
- return NULL;
-
- /* For every menu item in DIR, get the associated node's file buffer and
- read the indices of that file buffer. Gather all of the indices into
- one large one. */
- for (dir_index = 0; dir_menu[dir_index]; dir_index++)
- {
- REFERENCE **this_index, *this_item;
- NODE *this_node;
- FILE_BUFFER *this_fb;
-
- this_item = dir_menu[dir_index];
-
- if (!this_item->filename)
- {
- if (dir_node->parent)
- this_item->filename = xstrdup (dir_node->parent);
- else
- this_item->filename = xstrdup (dir_node->filename);
- }
-
- /* Find this node. If we cannot find it, try using the label of the
- entry as a file (i.e., "(LABEL)Top"). */
- this_node = info_get_node (this_item->filename, this_item->nodename);
-
- if (!this_node && this_item->nodename &&
- (strcmp (this_item->label, this_item->nodename) == 0))
- this_node = info_get_node (this_item->label, "Top");
-
- if (!this_node)
- continue;
-
- /* Get the file buffer associated with this node. */
- {
- char *files_name;
-
- files_name = this_node->parent;
- if (!files_name)
- files_name = this_node->filename;
-
- this_fb = info_find_file (files_name);
-
- if (this_fb && inform)
- message_in_echo_area (_("Scanning indices of \"%s\"..."), files_name);
-
- this_index = info_indices_of_file_buffer (this_fb);
- free (this_node);
-
- if (this_fb && inform)
- unmessage_in_echo_area ();
- }
-
- if (this_index)
- {
- /* Remember the filename which contains this set of references. */
- for (i = 0; this_index && this_index[i]; i++)
- if (!this_index[i]->filename)
- this_index[i]->filename = xstrdup (this_fb->filename);
-
- /* Concatenate with the other indices. */
- all_indices = info_concatenate_references (all_indices, this_index);
- }
- }
-
- info_free_references (dir_menu);
-
- /* Build a list of the references which contain SEARCH_STRING. */
- if (all_indices)
- {
- REFERENCE *entry, **apropos_list = (REFERENCE **)NULL;
- int apropos_list_index = 0;
- int apropos_list_slots = 0;
-
- for (i = 0; (entry = all_indices[i]); i++)
- {
- if (string_in_line (search_string, entry->label) != -1)
- {
- add_pointer_to_array
- (entry, apropos_list_index, apropos_list, apropos_list_slots,
- 100, REFERENCE *);
- }
- else
- {
- maybe_free (entry->label);
- maybe_free (entry->filename);
- maybe_free (entry->nodename);
- free (entry);
- }
- }
-
- free (all_indices);
- all_indices = apropos_list;
- }
- return (all_indices);
-}
-
-#define APROPOS_NONE \
- _("No available info files reference \"%s\" in their indices.")
-
-void
-info_apropos (string)
- char *string;
-{
- REFERENCE **apropos_list;
-
- apropos_list = apropos_in_all_indices (string, 0);
-
- if (!apropos_list)
- {
- info_error (APROPOS_NONE, string);
- }
- else
- {
- register int i;
- REFERENCE *entry;
-
- for (i = 0; (entry = apropos_list[i]); i++)
- fprintf (stderr, "\"(%s)%s\" -- %s\n",
- entry->filename, entry->nodename, entry->label);
- }
- info_free_references (apropos_list);
-}
-
-static char *apropos_list_nodename = "*Apropos*";
-
-DECLARE_INFO_COMMAND (info_index_apropos,
- _("Grovel all known info file's indices for a string and build a menu"))
-{
- char *line;
-
- line = info_read_in_echo_area (window, _("Index apropos: "));
-
- window = active_window;
-
- /* User aborted? */
- if (!line)
- {
- info_abort_key (window, 1, 1);
- return;
- }
-
- /* User typed something? */
- if (*line)
- {
- REFERENCE **apropos_list;
- NODE *apropos_node;
-
- apropos_list = apropos_in_all_indices (line, 1);
-
- if (!apropos_list)
- {
- info_error (APROPOS_NONE, line);
- }
- else
- {
- register int i;
- char *line_buffer;
-
- initialize_message_buffer ();
- printf_to_message_buffer
- (_("\n* Menu: Nodes whoses indices contain \"%s\":\n"), line);
- line_buffer = (char *)xmalloc (500);
-
- for (i = 0; apropos_list[i]; i++)
- {
- int len;
- sprintf (line_buffer, "* (%s)%s::",
- apropos_list[i]->filename, apropos_list[i]->nodename);
- len = pad_to (36, line_buffer);
- sprintf (line_buffer + len, "%s", apropos_list[i]->label);
- printf_to_message_buffer ("%s\n", line_buffer);
- }
- free (line_buffer);
- }
-
- apropos_node = message_buffer_to_node ();
- add_gcable_pointer (apropos_node->contents);
- name_internal_node (apropos_node, apropos_list_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. */
- apropos_node->flags &= ~N_IsInternal;
-
- /* Find/Create a window to contain this node. */
- {
- WINDOW *new;
- NODE *node;
-
- set_remembered_pagetop_and_point (window);
-
- /* If a window is visible and showing an apropos list already,
- re-use it. */
- for (new = windows; new; new = new->next)
- {
- node = new->node;
-
- if (internal_info_node_p (node) &&
- (strcmp (node->nodename, apropos_list_nodename) == 0))
- break;
- }
-
- /* If we couldn't find an existing window, try to use the next window
- in the chain. */
- if (!new && window->next)
- new = window->next;
-
- /* If we still don't have a window, make a new one to contain
- the list. */
- if (!new)
- {
- WINDOW *old_active;
-
- old_active = active_window;
- active_window = window;
- new = window_make_window ((NODE *)NULL);
- active_window = old_active;
- }
-
- /* If we couldn't make a new window, use this one. */
- if (!new)
- new = window;
-
- /* Lines do not wrap in this window. */
- new->flags |= W_NoWrap;
-
- window_set_node_of_window (new, apropos_node);
- remember_window_and_node (new, apropos_node);
- active_window = new;
- }
- info_free_references (apropos_list);
- }
- free (line);
-
- if (!info_error_was_printed)
- window_clear_echo_area ();
-}
-