[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[5255] Implement the --all (-a) option as per bug #38168.
From: |
Sergey Poznyakoff |
Subject: |
[5255] Implement the --all (-a) option as per bug #38168. |
Date: |
Mon, 15 Apr 2013 21:39:11 +0000 |
Revision: 5255
http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5255
Author: gray
Date: 2013-04-15 21:39:09 +0000 (Mon, 15 Apr 2013)
Log Message:
-----------
Implement the --all (-a) option as per bug #38168.
* info/infopath.c: New file.
* info/Makefile.am (ginfo_SOURCES): Add new file.
* info/tilde.c (tilde_expand_word): Argument is const char *.
All uses changed.
* info/info.c (all_matches_p): New variable.
(long_options, short_options): New option --all (-a).
(single_file, all_files): New functions.
(main): Handle new option.
* info/nodes.c (forget_info_file): Now extern.
* info/nodes.h (forget_info_file): New proto.
* info/indices.c (create_virtindex_file_buffer): Allow for
NULL as the filename.
(allfiles_create_node, info_all_files): New functions.
* info/dir.c (maybe_build_dir_node): Use infopath_first and
infopath_next to iterate over the INFOPATH.
* info/filesys.c: Remove infopath functions. See infopath.c
(info_file_in_path, info_file_find_next_in_path): New functions.
* info/indices.h (allfiles_create_node): New prototype.
* info/filesys.h (infopath): Remove extern.
(infopath): New prototype.
(zap_infopath): Rename to infopath_clear.
(info_add_path): Rename to infopath_add.
(infopath_init,infopath_first,infopath_next)
(info_file_find_next_in_path): New prototypes.
(INFOPATH_INIT): New constant.
* info/session.c (info_read_and_dispatch): Do not set
quit_info_immediately, it is done by info_quit.
(info_follow_menus): Take an additional argument.
(info_quit): Set quit_info_immediately.
* info/session.h (quit_info_immediately): Extern.
(info_follow_menus): Change signature.
* info/infomap.c: Bind `C-x f' in Emacs mode, and `:a' in Vi mode
to info_all_files.
* doc/info-stnd.texi: Document the --all option.
Ticket Links:
------------
http://savannah.gnu.org/bugs/?38168
Modified Paths:
--------------
trunk/ChangeLog
trunk/info/Makefile.am
trunk/info/dir.c
trunk/info/filesys.c
trunk/info/filesys.h
trunk/info/indices.c
trunk/info/indices.h
trunk/info/info.c
trunk/info/infodoc.c
trunk/info/infomap.c
trunk/info/nodes.c
trunk/info/nodes.h
trunk/info/session.c
trunk/info/session.h
trunk/info/tilde.c
trunk/info/tilde.h
Added Paths:
-----------
trunk/info/infopath.c
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/ChangeLog 2013-04-15 21:39:09 UTC (rev 5255)
@@ -1,3 +1,43 @@
+2013-04-16 Sergey Poznyakoff <address@hidden>
+
+ Implement the --all (-a) option as per bug #38168.
+
+ * info/infopath.c: New file.
+ * info/Makefile.am (ginfo_SOURCES): Add new file.
+ * info/tilde.c (tilde_expand_word): Argument is const char *.
+ All uses changed.
+ * info/info.c (all_matches_p): New variable.
+ (long_options, short_options): New option --all (-a).
+ (single_file, all_files): New functions.
+ (main): Handle new option.
+ * info/nodes.c (forget_info_file): Now extern.
+ * info/nodes.h (forget_info_file): New proto.
+ * info/indices.c (create_virtindex_file_buffer): Allow for
+ NULL as the filename.
+ (allfiles_create_node, info_all_files): New functions.
+ * info/dir.c (maybe_build_dir_node): Use infopath_first and
+ infopath_next to iterate over the INFOPATH.
+ * info/filesys.c: Remove infopath functions. See infopath.c
+ (info_file_in_path, info_file_find_next_in_path): New functions.
+ * info/indices.h (allfiles_create_node): New prototype.
+ * info/filesys.h (infopath): Remove extern.
+ (infopath): New prototype.
+ (zap_infopath): Rename to infopath_clear.
+ (info_add_path): Rename to infopath_add.
+ (infopath_init,infopath_first,infopath_next)
+ (info_file_find_next_in_path): New prototypes.
+ (INFOPATH_INIT): New constant.
+ * info/session.c (info_read_and_dispatch): Do not set
+ quit_info_immediately, it is done by info_quit.
+ (info_follow_menus): Take an additional argument.
+ (info_quit): Set quit_info_immediately.
+ * info/session.h (quit_info_immediately): Extern.
+ (info_follow_menus): Change signature.
+ * info/infomap.c: Bind `C-x f' in Emacs mode, and `:a' in Vi mode
+ to info_all_files.
+
+ * doc/info-stnd.texi: Document the --all option.
+
2013-04-13 Sergey Poznyakoff <address@hidden>
* info/infomap.c: Fix indentation and style.
Modified: trunk/info/Makefile.am
===================================================================
--- trunk/info/Makefile.am 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/Makefile.am 2013-04-15 21:39:09 UTC (rev 5255)
@@ -38,7 +38,7 @@
echo-area.c echo-area.h \
filesys.c filesys.h footnotes.c footnotes.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 \
+ infomap.c infomap.h infopath.c 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 \
tag.c tag.h termdep.h terminal.c terminal.h tilde.c tilde.h \
variables.c variables.h window.c window.h
Modified: trunk/info/dir.c
===================================================================
--- trunk/info/dir.c 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/dir.c 2013-04-15 21:39:09 UTC (rev 5255)
@@ -95,14 +95,15 @@
with the dir file just found. */
new_dir_file_p (&dir_buffer->finfo);
- path_index = update_tags = 0;
+ update_tags = 0;
/* Using each element of the path, check for one of the files in
DIRS_TO_ADD. Do not check for "localdir.info.Z" or anything else.
Only files explictly named are eligible. This is a design decision.
There can be an info file name "localdir.info" which contains
information on the setting up of "localdir" files. */
- while ((this_dir = extract_colon_unit (infopath, &path_index)))
+ for (this_dir = infopath_first (&path_index); this_dir;
+ this_dir = infopath_next (&path_index))
{
register int da_index;
char *from_file;
Modified: trunk/info/filesys.c
===================================================================
--- trunk/info/filesys.c 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/filesys.c 2013-04-15 21:39:09 UTC (rev 5255)
@@ -29,10 +29,8 @@
static char *info_file_in_path (char *filename, char *path);
static char *lookup_info_filename (char *filename);
static char *info_absolute_file (char *fname);
-static char *build_infopath_from_path (void);
static void remember_info_filename (char *filename, char *expansion);
-static void maybe_initialize_infopath (void);
typedef struct
{
@@ -75,13 +73,6 @@
{ NULL, NULL }
};
-/* The path on which we look for info files. You can initialize this
- from the environment variable INFOPATH if there is one, or you can
- call info_add_path () to add paths to the beginning or end of it.
- You can call zap_infopath () to make the path go away. */
-char *infopath = NULL;
-static int infopath_size = 0;
-
/* Expand the filename in PARTIAL to make a real name for this operating
system. This looks in INFO_PATHS in order to find the correct file.
If it can't find the file, it returns NULL. */
@@ -98,8 +89,6 @@
filesys_error_number = 0;
- maybe_initialize_infopath ();
-
if (partial && (initial_character = *partial))
{
char *expansion;
@@ -149,7 +138,7 @@
partial = local_temp_filename;
}
else
- temp = info_file_in_path (partial, infopath);
+ temp = info_file_in_path (partial, infopath ());
if (temp)
{
@@ -169,8 +158,8 @@
/* Scan the list of directories in PATH looking for FILENAME. If we find
one that is a regular file, return it as a new string. Otherwise, return
a NULL pointer. */
-static char *
-info_file_in_path (char *filename, char *path)
+char *
+info_file_find_next_in_path (char *filename, char *path, int *diridx)
{
struct stat finfo;
char *temp_dirname;
@@ -181,9 +170,7 @@
if (!*filename || STREQ (filename, ".") || STREQ (filename, ".."))
return NULL;
- dirname_index = 0;
-
- while ((temp_dirname = extract_colon_unit (path, &dirname_index)))
+ while ((temp_dirname = extract_colon_unit (path, diridx)))
{
register int i, pre_suffix_length;
char *temp;
@@ -268,6 +255,13 @@
return NULL;
}
+static char *
+info_file_in_path (char *filename, char *path)
+{
+ int i = 0;
+ return info_file_find_next_in_path (filename, path, &i);
+}
+
/* Assume FNAME is an absolute file name, and check whether it is
a regular file. If it is, return it as a new string; otherwise
return a NULL pointer. We do it by taking the file name apart
@@ -369,205 +363,21 @@
names_and_files[names_and_files_index] = NULL;
}
-static void
-maybe_initialize_infopath (void)
-{
- if (!infopath_size)
- {
- infopath = (char *)
- xmalloc (infopath_size = (1 + strlen (DEFAULT_INFOPATH)));
- debug(2, ("INFOPATH=%s", DEFAULT_INFOPATH));
- strcpy (infopath, DEFAULT_INFOPATH);
- }
-}
-
-/* For each path element PREFIX/DIR in PATH substitute either
- PREFIX/share/info or PREFIX/info if that directory exists.
- Avoid duplicates from, e.g., PREFIX/bin and PREFIX/sbin. */
-static char *
-build_infopath_from_path (void)
-{
- typedef struct path_el
- {
- struct path_el *next;
- char *path;
- unsigned int len;
- } PATH_EL, *PATH_PTR;
-
- PATH_EL path_head = { NULL, NULL, 1 };
- PATH_PTR path_prev, path_next;
- char *res, *path_from_env, *temp_dirname;
- int dirname_index = 0;
- struct stat finfo;
-
- path_from_env = getenv ("PATH");
-
- while ((temp_dirname = extract_colon_unit (path_from_env, &dirname_index)))
- {
- unsigned int i, dir = 0;
-
- /* Find end of DIRNAME/ (but ignore "/") */
- for (i = 0; temp_dirname[i]; i++)
- if (i && IS_SLASH (temp_dirname[i]))
- dir = i + 1;
-
- /* Discard path elements ending with "/", "/.", or "/.." */
- if (!temp_dirname[dir] || STREQ (temp_dirname + dir, ".") || STREQ
(temp_dirname + dir, "."))
- dir = 0;
-
- path_prev = &path_head;
- while (dir && (path_next = path_prev->next))
- {
- /* Ignore duplicate DIRNAME */
- if (dir == path_next->len && strncmp (temp_dirname, path_next->path,
dir) == 0)
- dir = 0;
-
- path_prev = path_next;
- }
-
- if (dir)
- {
- temp_dirname = xrealloc (temp_dirname, dir + strlen ("share/info")
+1);
-
- /* first try DIRNAME/share/info */
- strcpy (temp_dirname + dir, "share/info");
- if (stat (temp_dirname, &finfo) != 0 || !S_ISDIR (finfo.st_mode))
- {
- /* then try DIRNAME/info */
- strcpy (temp_dirname + dir, "info");
- if (stat (temp_dirname, &finfo) != 0 || !S_ISDIR (finfo.st_mode))
- dir = 0;
- }
- }
-
- if (dir)
- {
- path_next = xmalloc (sizeof (PATH_EL));
- path_next->next = NULL;
- path_next->path = temp_dirname;
- path_next->len = dir;
- path_prev->next = path_next;
- path_head.len += strlen (temp_dirname) + 1;
- }
- else
- free (temp_dirname);
- }
-
- /* Build the resulting sequence of paths */
- res = xmalloc (path_head.len);
- res[0] = '\0';
-
- for (path_prev = path_head.next; path_prev; path_prev = path_next)
- {
- strcat (res, path_prev->path);
- if ((path_next = path_prev->next))
- strcat (res, PATH_SEP);
-
- free (path_prev->path);
- free (path_prev);
- }
-
- return res;
-}
-
-/* Add PATH to the list of paths found in INFOPATH. 2nd argument says
- whether to put PATH at the front or end of INFOPATH.
- Replace one path element "PATH" in PATH by a sequence of
- path elements derived from the environment variable PATH. */
void
-info_add_path (char *path, int where)
+forget_file_names (void)
{
- int len;
- int found = 0;
- unsigned int i, j;
+ int i;
- /* Search for "PATH" in PATH */
- for (i = 0; path[i]; i++)
+ for (i = 0; i < names_and_files_index; i++)
{
- j = i + strlen ("PATH");
- if (strncmp (path + i, "PATH", strlen ("PATH")) == 0 &&
- (!path[j] || path[j] == PATH_SEP[0]))
- {
- found = 1;
- break;
- }
- else
- {
- /* Advance to next PATH_SEP. */
- while (path[i] && path[i] != PATH_SEP[0])
- i++;
-
- if (!path[i])
- break;
- }
+ free (names_and_files[i]->filename);
+ free (names_and_files[i]->expansion);
+ free (names_and_files[i]);
+ names_and_files[i] = NULL;
}
-
- if (found)
- {
- /* Build infopath from the environment variable PATH */
- char *temp = build_infopath_from_path ();
-
- if (i || path[j])
- {
- char *old_path = path;
-
- /* Splice it into OLD_PATH */
- path = xmalloc (1 + strlen (temp) + strlen (old_path) - strlen
("PATH"));
- if (i)
- strncpy (path, old_path, i);
- strcpy (path + i, temp);
- if (old_path[j])
- strcat (path, old_path + j);
-
- free (temp);
- }
- else
- path = temp;
- }
-
- if (!infopath)
- {
- infopath = xmalloc (infopath_size = 200 + strlen (path));
- infopath[0] = '\0';
- }
-
- len = strlen (path) + strlen (infopath);
-
- if (len + 2 >= infopath_size)
- infopath = xrealloc (infopath, (infopath_size += (2 * len) + 2));
-
- if (!*infopath)
- strcpy (infopath, path);
- else if (where == INFOPATH_APPEND)
- {
- strcat (infopath, PATH_SEP);
- strcat (infopath, path);
- }
- else if (where == INFOPATH_PREPEND)
- {
- char *temp = xstrdup (infopath);
- strcpy (infopath, path);
- strcat (infopath, PATH_SEP);
- strcat (infopath, temp);
- free (temp);
- }
- debug(2, ("INFOPATH=%s", infopath));
- if (found)
- free (path);
+ names_and_files_index = 0;
}
-
-/* Make INFOPATH have absolutely nothing in it. */
-void
-zap_infopath (void)
-{
- if (infopath)
- free (infopath);
-
- infopath = NULL;
- infopath_size = 0;
- debug(2, ("INFOPATH cleared"));
-}
-
+
/* Given a chunk of text and its length, convert all CRLF pairs at every
end-of-line into a single Newline character. Return the length of
produced text.
Modified: trunk/info/filesys.h
===================================================================
--- trunk/info/filesys.h 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/filesys.h 2013-04-15 21:39:09 UTC (rev 5255)
@@ -25,18 +25,27 @@
/* The path on which we look for info files. You can initialize this
from the environment variable INFOPATH if there is one, or you can
call info_add_path () to add paths to the beginning or end of it. */
-extern char *infopath;
+extern char *infopath ();
+
+/* Initialize INFOPATH */
+void infopath_init (void);
+
/* Make INFOPATH have absolutely nothing in it. */
-extern void zap_infopath (void);
+extern void infopath_clear (void);
/* Add PATH to the list of paths found in INFOPATH. 2nd argument says
whether to put PATH at the front or end of INFOPATH. */
-extern void info_add_path (char *path, int where);
+extern void infopath_add (char *path, int where);
-/* Defines that are passed along with the pathname to info_add_path (). */
+/* Iterate over INFOPATH */
+char *infopath_first (int *idx);
+char *infopath_next (int *idx);
+
+/* Defines that are passed along with the pathname to infopath_add (). */
#define INFOPATH_PREPEND 0
#define INFOPATH_APPEND 1
+#define INFOPATH_INIT 2
/* Expand the filename in PARTIAL to make a real name for this operating
system. This looks in INFO_PATHS in order to find the correct file.
@@ -76,6 +85,12 @@
/* Return true if FILENAME is `dir', with a possible compression suffix. */
extern int is_dir_name (char *filename);
+/* Scan the list of directories in PATH looking for FILENAME. If we find
+ one that is a regular file, return it as a new string. Otherwise, return
+ a NULL pointer. */
+extern char *info_file_find_next_in_path (char *filename, char *path,
+ int *diridx);
+
/* The default value of INFOPATH. */
#if !defined (DEFAULT_INFOPATH)
# define DEFAULT_INFOPATH
".:PATH:/usr/local/info:/usr/info:/usr/local/lib/info:/usr/lib/info:/usr/local/gnu/info:/usr/local/gnu/lib/info:/usr/gnu/info:/usr/gnu/lib/info:/opt/gnu/info:/usr/share/info:/usr/share/lib/info:/usr/local/share/info:/usr/local/share/lib/info:/usr/gnu/lib/emacs/info:/usr/local/gnu/lib/emacs/info:/usr/local/lib/emacs/info:/usr/local/emacs/info"
Modified: trunk/info/indices.c
===================================================================
--- trunk/info/indices.c 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/indices.c 2013-04-15 21:39:09 UTC (rev 5255)
@@ -810,8 +810,8 @@
FILE_BUFFER *file_buffer;
file_buffer = make_file_buffer ();
- file_buffer->filename = xstrdup (filename);
- file_buffer->fullpath = xstrdup (filename);
+ file_buffer->filename = filename ? xstrdup (filename) : NULL;
+ file_buffer->fullpath = filename ? xstrdup (filename) : NULL;
file_buffer->finfo.st_size = 0;
file_buffer->flags = (N_IsInternal | N_CannotGC);
@@ -960,3 +960,59 @@
if (!info_error_was_printed)
window_clear_echo_area ();
}
+
+static NODE *allfiles_node;
+
+NODE *
+allfiles_create_node (char *term, REFERENCE *fref)
+{
+ int i;
+ struct text_buffer text;
+ size_t off;
+ FILE_BUFFER *fb;
+ NODE *node;
+
+ text_buffer_init (&text);
+ text_buffer_printf (&text, _("File names matching `%s'"), term);
+ text_buffer_add_char (&text, 0);
+ off = text.off;
+
+ text_buffer_printf (&text,
+ "\n\n%c\n%s %s\n\n"
+ "Info File Index\n"
+ "***************\n\n"
+ "File names that match `%s':\n\n"
+ "* Menu:\n\n",
+ INFO_COOKIE,
+ INFO_NODE_LABEL, text.base, term);
+
+ memmove (text.base, text.base + off, text.off - off);
+ text.off -= off;
+
+ for (i = 0; fref[i].filename; i++)
+ {
+ text_buffer_printf (&text, "* %4i: (%s)", i+1, fref[i].filename);
+ if (fref[i].nodename)
+ text_buffer_printf (&text, "%s", fref[i].nodename);
+ text_buffer_printf (&text, ".\n");
+ }
+
+ fb = create_virtindex_file_buffer (NULL, text.base, text.off);
+ allfiles_node = create_virtindex_node (fb);
+
+ return allfiles_node;
+}
+
+DECLARE_INFO_COMMAND (info_all_files, _("Show all matching files"))
+{
+ if (!allfiles_node)
+ {
+ info_error (_("No file index"));
+ return;
+ }
+
+ info_set_node_of_window (1, window, allfiles_node);
+
+ if (!info_error_was_printed)
+ window_clear_echo_area ();
+}
Modified: trunk/info/indices.h
===================================================================
--- trunk/info/indices.h 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/indices.h 2013-04-15 21:39:09 UTC (rev 5255)
@@ -41,4 +41,6 @@
extern void do_info_index_search (WINDOW *window, int count, char
*search_string);
extern int index_entry_exists (WINDOW *window, char *string);
+NODE *allfiles_create_node (char *term, REFERENCE *fref);
+
#endif /* not INFO_INDICES_H */
Modified: trunk/info/info.c
===================================================================
--- trunk/info/info.c 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/info.c 2013-04-15 21:39:09 UTC (rev 5255)
@@ -80,6 +80,9 @@
/* Non-zero means don't remove ANSI escape sequences. */
int raw_escapes_p = 1;
+/* Print/visit all matching documents. */
+static int all_matches_p = 0;
+
/* Non-zero means print the absolute location of the file to be loaded. */
static int print_where_p = 0;
@@ -105,6 +108,7 @@
#define RESTORE_OPTION 3
#define IDXSRCH_OPTION 4
static struct option long_options[] = {
+ { "all", 0, 0, 'a' },
{ "apropos", 1, 0, 'k' },
{ "debug", 0, 0, 'x' },
{ "directory", 1, 0, 'd' },
@@ -136,9 +140,9 @@
/* String describing the shorthand versions of the long options found above. */
#if defined(__MSDOS__) || defined(__MINGW32__)
-static char *short_options = "k:d:n:f:ho:ORsv:wbx";
+static char *short_options = "ak:d:n:f:ho:ORsv:wbx";
#else
-static char *short_options = "k:d:n:f:ho:ORv:wsx";
+static char *short_options = "ak:d:n:f:ho:ORv:wsx";
#endif
/* When non-zero, the Info window system has been initialized. */
@@ -149,6 +153,314 @@
static void init_messages (void);
+static const char *
+node_file_name (NODE *node, int dirok)
+{
+ if (node->parent)
+ return node->parent;
+ else if (node->filename
+ && (dirok ||
+ !is_dir_name (filename_non_directory (node->filename))))
+ return node->filename;
+ return 0;
+}
+
+static int
+single_file (char *filename, int argc, char **argv)
+{
+ NODE *initial_node; /* First node loaded by Info. */
+ NODE *new_initial_node, *error_node;
+
+ /* Get the initial Info node. It is either "(dir)Top", or what the user
+ specifed with values in filename and user_nodenames. */
+ initial_node = info_get_node (filename,
+ user_nodenames ? user_nodenames[0] : 0,
+ PARSE_NODE_DFLT);
+
+ /* If we couldn't get the initial node, this user is in trouble. */
+ if (!initial_node)
+ {
+ if (info_recent_file_error)
+ info_error ("%s", info_recent_file_error);
+ else
+ info_error (msg_cant_find_node,
+ user_nodenames ? user_nodenames[0] : "Top");
+ return EXIT_FAILURE;
+ }
+
+ /* Special cases for when the user specifies multiple nodes. If we
+ are dumping to an output file, dump all of the nodes specified.
+ Otherwise, attempt to create enough windows to handle the nodes
+ that this user wants displayed. */
+ if (user_nodenames_index > 1)
+ {
+ free (initial_node);
+
+ if (print_where_p)
+ printf ("%s\n", filename ? filename : "unknown?!");
+ else if (user_output_filename)
+ dump_nodes_to_file
+ (filename, user_nodenames, user_output_filename, dump_subnodes);
+ else
+ begin_multiple_window_info_session (filename, user_nodenames);
+
+ return EXIT_SUCCESS;
+ }
+
+ /* If there are arguments remaining, they are the names of menu items
+ in sequential info files starting from the first one loaded. That
+ file name is either "dir", or the contents of filename if one
+ was specified. */
+ /* If they say info -O info, we want to show them the invocation node
+ for standalone info; there's nothing useful in info.texi. */
+ if (goto_invocation_p && *argv
+ && mbscasecmp (*argv, "info") == 0)
+ *argv = "info-stnd";
+
+ new_initial_node = info_follow_menus (initial_node, argv, &error_node, 0);
+
+ if (new_initial_node && new_initial_node != initial_node)
+ initial_node = new_initial_node;
+
+ if (print_where_p)
+ {
+ const char *name = node_file_name (initial_node, 0);
+ if (!name)
+ return EXIT_FAILURE;
+ printf ("%s\n", name);
+ return EXIT_SUCCESS;
+ }
+
+ /* If the user specified that this node should be output, then do that
+ now. Otherwise, start the Info session with this node. Or act
+ accordingly if the initial node was not found. */
+ if (user_output_filename && !goto_invocation_p)
+ {
+ if (error_node)
+ show_error_node (error_node);
+ else
+ dump_node_to_file (initial_node, user_output_filename,
+ dump_subnodes);
+ }
+ else
+ {
+ if (error_node)
+ {
+ initialize_info_session (initial_node, 1);
+ show_error_node (error_node);
+ info_session ();
+ }
+
+ /* If the user specified `--index-search=STRING' or
+ --show-options, start the info session in the node
+ corresponding to what they want. */
+ else if (index_search_p || goto_invocation_p)
+ {
+ int status = EXIT_SUCCESS;
+
+ initialize_info_session (initial_node, 0);
+
+ if (goto_invocation_p ||
+ index_entry_exists (windows, index_search_string))
+ {
+ terminal_prep_terminal ();
+ terminal_clear_screen ();
+ info_last_executed_command = NULL;
+
+ if (index_search_p)
+ do_info_index_search (windows, 0, index_search_string);
+ else
+ {
+ /* If they said "info --show-options foo bar baz",
+ the last of the arguments is the program whose
+ options they want to see. */
+ char **p = argv;
+ char *program;
+
+ if (*p)
+ {
+ while (p[1])
+ p++;
+ program = xstrdup (*p);
+ }
+ else if (filename)
+ /* If there's no command-line arguments to
+ supply the program name, use the Info file
+ name (sans extension and leading directories)
+ instead. */
+ program = program_name_from_file_name (filename);
+ else
+ program = xstrdup ("");
+
+ info_intuit_options_node (windows, initial_node, program);
+ free (program);
+ }
+
+ if (user_output_filename)
+ {
+ dump_node_to_file (windows->node, user_output_filename,
+ dump_subnodes);
+ }
+ else
+ info_read_and_dispatch ();
+
+ /* On program exit, leave the cursor at the bottom of the
+ window, and restore the terminal IO. */
+ terminal_goto_xy (0, screenheight - 1);
+ terminal_clear_to_eol ();
+ fflush (stdout);
+ terminal_unprep_terminal ();
+ }
+ else
+ {
+ fprintf (stderr, _("no index entries found for `%s'\n"),
+ index_search_string);
+ status = EXIT_FAILURE;
+ }
+
+ close_dribble_file ();
+ return status;
+ }
+ else
+ begin_info_session (initial_node);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+static char *
+dirname (const char *file)
+{
+ char *p;
+ size_t len;
+
+ p = strrchr (file, '/');
+ if (!p)
+ return NULL;
+ len = p - file;
+ p = xmalloc (len + 1);
+ memcpy (p, file, len);
+ p[len] = 0;
+ return p;
+}
+
+REFERENCE *
+info_find_matching_files (char *filename)
+{
+ size_t argc = 0;
+ size_t argn = 0;
+ REFERENCE *argv = NULL;
+ int i = 0;
+ char *p;
+
+ do
+ {
+ p = info_file_find_next_in_path (filename, infopath (), &i);
+ if (argc == argn)
+ {
+ if (argn == 0)
+ argn = 2;
+ argv = x2nrealloc (argv, &argn, sizeof (argv[0]));
+ }
+ memset (&argv[argc], 0, sizeof (argv[argc]));
+ argv[argc++].filename = p;
+ }
+ while (p);
+ return argv;
+}
+
+static int
+all_files (char *filename, int argc, char **argv)
+{
+ REFERENCE *fref;
+ char *fname;
+ int i, j;
+ int dirok;
+ size_t count;
+
+ if (user_filename)
+ {
+ fname = user_filename;
+ dirok = 0;
+ }
+ else
+ {
+ fname = "dir";
+ dirok = 1;
+ }
+
+ fref = info_find_matching_files (fname);
+
+ for (i = 0; fref[i].filename; )
+ {
+ NODE *node;
+
+ if (!user_filename)
+ {
+ char *p = dirname (fref[i].filename);
+ infopath_add (p, INFOPATH_INIT);
+ free (p);
+ }
+ node = info_get_node (fref[i].filename,
+ user_nodenames ? user_nodenames[0] : 0,
+ PARSE_NODE_DFLT);
+
+ if (node)
+ {
+ NODE *errnode;
+ NODE *subnode = info_follow_menus (node, argv, &errnode, 1);
+ if (errnode)
+ show_error_node (errnode);
+ if (!subnode)
+ {
+ forget_info_file (fref[i].filename);
+ node = NULL;
+ }
+ else
+ node = subnode;
+ }
+
+ if (node)
+ {
+ const char *name = node_file_name (node, dirok);
+ if (!name)
+ node = NULL;
+ else
+ {
+ free (fref[i].filename);
+ fref[i].filename = xstrdup (name);
+ }
+ }
+
+ if (!node)
+ {
+ free (fref[i].filename);
+ for (j = i; (fref[j] = fref[j + 1]).filename; j++);
+ }
+ else
+ {
+ if (print_where_p)
+ printf ("%s\n", fref[i].filename);
+ else if (user_output_filename)
+ dump_node_to_file (node, user_output_filename,
+ dump_subnodes);
+ else
+ fref[i].nodename = xstrdup (node->nodename);
+ ++i;
+ }
+ }
+
+ if (print_where_p || user_output_filename)
+ return EXIT_SUCCESS;
+
+ if (i <= 1)
+ return single_file (user_filename, argc, argv);
+
+ begin_info_session (allfiles_create_node (argc ? argv[0] : fname, fref));
+ return EXIT_SUCCESS;
+}
+
+
/* **************************************************************** */
/* */
/* Main Entry Point to the Info Program */
@@ -159,7 +471,6 @@
main (int argc, char *argv[])
{
int getopt_long_index; /* Index returned by getopt_long (). */
- NODE *initial_node; /* First node loaded by Info. */
#ifdef HAVE_SETLOCALE
/* Set locale via LC_ALL. */
@@ -173,7 +484,7 @@
#endif
init_messages ();
-
+ infopath_init ();
while (1)
{
int option_character;
@@ -195,9 +506,13 @@
case 0:
break;
+ case 'a':
+ all_matches_p = 1;
+ break;
+
/* User wants to add a directory. */
case 'd':
- info_add_path (optarg, INFOPATH_PREPEND);
+ infopath_add (optarg, INFOPATH_PREPEND);
break;
/* User is specifying a particular node. */
@@ -351,43 +666,6 @@
exit (EXIT_SUCCESS);
}
- /* If the user hasn't specified a path for Info files, default it.
- Lowest priority is our messy hardwired list in filesys.h.
- Then comes the user's INFODIR from the Makefile.
- Highest priority is the environment variable, if set. */
- if (!infopath)
- {
- char *path_from_env = getenv ("INFOPATH");
-
- if (path_from_env)
- {
- unsigned len = strlen (path_from_env);
- /* Trailing : on INFOPATH means insert the default path. */
- if (len && path_from_env[len - 1] == PATH_SEP[0])
- {
- path_from_env[len - 1] = 0;
- info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND);
- }
-#ifdef INFODIR /* from the Makefile */
- info_add_path (INFODIR, INFOPATH_PREPEND);
-#endif
- info_add_path (path_from_env, INFOPATH_PREPEND);
- }
- else
- {
- info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND);
-#ifdef INFODIR /* from the Makefile */
- info_add_path (INFODIR, INFOPATH_PREPEND);
-#endif
-#ifdef INFODIR2 /* from the Makefile, too */
-# ifdef INFODIR
- if (!STREQ (INFODIR, INFODIR2))
-# endif
- info_add_path (INFODIR2, INFOPATH_PREPEND);
-#endif
- }
- }
-
/* If the user specified a particular filename, add the path of that
file to the contents of INFOPATH. */
if (user_filename)
@@ -401,171 +679,13 @@
exit (EXIT_SUCCESS);
}
- /* Get the initial Info node. It is either "(dir)Top", or what the user
- specifed with values in user_filename and user_nodenames. */
- initial_node = info_get_node (user_filename,
- user_nodenames ? user_nodenames[0] : 0,
- PARSE_NODE_DFLT);
-
- /* If we couldn't get the initial node, this user is in trouble. */
- if (!initial_node)
- {
- if (info_recent_file_error)
- info_error ("%s", info_recent_file_error);
- else
- info_error (msg_cant_find_node,
- user_nodenames ? user_nodenames[0] : "Top");
- exit (EXIT_FAILURE);
- }
-
- /* Special cases for when the user specifies multiple nodes. If we
- are dumping to an output file, dump all of the nodes specified.
- Otherwise, attempt to create enough windows to handle the nodes
- that this user wants displayed. */
- if (user_nodenames_index > 1)
- {
- free (initial_node);
-
- if (print_where_p)
- printf ("%s\n", user_filename ? user_filename : "unknown?!");
- else if (user_output_filename)
- dump_nodes_to_file
- (user_filename, user_nodenames, user_output_filename, dump_subnodes);
- else
- begin_multiple_window_info_session (user_filename, user_nodenames);
-
- exit (EXIT_SUCCESS);
- }
-
- /* If there are arguments remaining, they are the names of menu items
- in sequential info files starting from the first one loaded. That
- file name is either "dir", or the contents of user_filename if one
- was specified. */
- {
- NODE *new_initial_node, *error_node;
-
- /* If they say info -O info, we want to show them the invocation node
- for standalone info; there's nothing useful in info.texi. */
- if (goto_invocation_p && argv[optind]
- && mbscasecmp (argv[optind], "info") == 0)
- argv[optind] = "info-stnd";
-
- new_initial_node = info_follow_menus (initial_node, argv + optind,
- &error_node);
-
- if (new_initial_node && new_initial_node != initial_node)
- initial_node = new_initial_node;
-
- if (print_where_p)
- {
- if (initial_node->parent)
- printf ("%s\n", initial_node->parent);
- else if (initial_node->filename
- && !is_dir_name (filename_non_directory (initial_node->filename)))
- printf ("%s\n", initial_node->filename);
- else
- exit (EXIT_FAILURE);
- exit (EXIT_SUCCESS);
- }
-
- /* If the user specified that this node should be output, then do that
- now. Otherwise, start the Info session with this node. Or act
- accordingly if the initial node was not found. */
- if (user_output_filename && !goto_invocation_p)
- {
- if (error_node)
- show_error_node (error_node);
- else
- dump_node_to_file (initial_node, user_output_filename,
- dump_subnodes);
- }
- else
- {
- if (error_node)
- {
- initialize_info_session (initial_node, 1);
- show_error_node (error_node);
- info_session ();
- }
-
- /* If the user specified `--index-search=STRING' or
- --show-options, start the info session in the node
- corresponding to what they want. */
- else if (index_search_p || goto_invocation_p)
- {
- int status = EXIT_SUCCESS;
-
- initialize_info_session (initial_node, 0);
-
- if (goto_invocation_p
- || index_entry_exists (windows, index_search_string))
- {
- terminal_prep_terminal ();
- terminal_clear_screen ();
- info_last_executed_command = NULL;
-
- if (index_search_p)
- do_info_index_search (windows, 0, index_search_string);
- else
- {
- /* If they said "info --show-options foo bar baz",
- the last of the arguments is the program whose
- options they want to see. */
- char **p = argv + optind;
- char *program;
-
- if (*p)
- {
- while (p[1])
- p++;
- program = xstrdup (*p);
- }
- else if (user_filename)
- /* If there's no command-line arguments to
- supply the program name, use the Info file
- name (sans extension and leading directories)
- instead. */
- program = program_name_from_file_name (user_filename);
- else
- program = xstrdup ("");
-
- info_intuit_options_node (windows, initial_node, program);
- free (program);
- }
-
- if (user_output_filename)
- {
- dump_node_to_file (windows->node, user_output_filename,
- dump_subnodes);
- }
- else
- info_read_and_dispatch ();
-
- /* On program exit, leave the cursor at the bottom of the
- window, and restore the terminal IO. */
- terminal_goto_xy (0, screenheight - 1);
- terminal_clear_to_eol ();
- fflush (stdout);
- terminal_unprep_terminal ();
- }
- else
- {
- fprintf (stderr, _("no index entries found for `%s'\n"),
- index_search_string);
- status = EXIT_FAILURE;
- }
-
- close_dribble_file ();
- exit (status);
- }
- else
- begin_info_session (initial_node);
- }
-
- exit (EXIT_SUCCESS);
- }
-
- return 0; /* Avoid bogus warnings. */
+ argc -= optind;
+ argv += optind;
+
+ if (all_matches_p)
+ return all_files (user_filename, argc, argv);
+
+ return single_file (user_filename, argc, argv);
}
void
@@ -584,7 +704,7 @@
temp += 2;
}
temp[-1] = 0;
- info_add_path (directory_name, INFOPATH_PREPEND);
+ infopath_add (directory_name, INFOPATH_PREPEND);
}
free (directory_name);
@@ -723,6 +843,7 @@
puts (_("\
Options:\n\
+ -a, --all visit all matching documents.\n\
-k, --apropos=STRING look up STRING in all indices of all manuals.\n\
-d, --directory=DIR add DIR to INFOPATH.\n\
--dribble=FILENAME remember user keystrokes in FILENAME.\n\
@@ -748,9 +869,11 @@
puts (_("\
--strict-node-location (for debugging) use Info file pointers as-is.\n\
--subnodes recursively output menu items.\n\
+ -v, --variable VAR=VALUE assign VALUE to the info variable VAR.\n\
--vi-keys use vi-like and less-like key bindings.\n\
--version display version information and exit.\n\
- -w, --where, --location print physical location of Info file."));
+ -w, --where, --location print physical location of Info file.\n\
+ -x, --debug increase debugging level.\n"));
puts (_("\n\
The first non-option argument, if present, is the menu entry to start from;\n\
Modified: trunk/info/infodoc.c
===================================================================
--- trunk/info/infodoc.c 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/infodoc.c 2013-04-15 21:39:09 UTC (rev 5255)
@@ -310,7 +310,7 @@
printf_to_message_buffer ("---------------------\n");
printf_to_message_buffer (_("The current search path is:\n"));
- printf_to_message_buffer ("%s\n", infopath);
+ 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);
Modified: trunk/info/infomap.c
===================================================================
--- trunk/info/infomap.c 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/infomap.c 2013-04-15 21:39:09 UTC (rev 5255)
@@ -297,7 +297,6 @@
CONTROL('f'), NUL, A_info_forward_char,
CONTROL('h'), NUL, A_info_get_help_window,
CONTROL('l'), NUL, A_info_redraw_display,
- CONTROL('n'), NUL, A_info_next_line,
CONTROL('p'), NUL, A_info_prev_line,
CONTROL('r'), NUL, A_isearch_backward,
CONTROL('s'), NUL, A_isearch_forward,
@@ -398,13 +397,14 @@
CONTROL('x'), '2', NUL, A_info_split_window,
CONTROL('x'), '^', NUL, A_info_grow_window,
CONTROL('x'), 'b', NUL, A_select_visited_node,
+ CONTROL('x'), 'f', NUL, A_info_all_files,
CONTROL('x'), 'k', NUL, A_info_kill_node,
CONTROL('x'), 'n', NUL, A_info_search_next,
CONTROL('x'), 'N', NUL, A_info_search_previous,
CONTROL('x'), 'o', NUL, A_info_next_window,
CONTROL('x'), 't', NUL, A_info_tile_windows,
CONTROL('x'), 'w', NUL, A_info_toggle_wrap,
-
+
/* Arrow key bindings for info keymaps. It seems that some
terminals do not match their termcap entries, so it's best to just
define everything with both of the usual prefixes. */
@@ -634,6 +634,7 @@
'l', NUL, A_info_history_node,
'm', NUL, A_info_menu_item,
'n', NUL, A_info_search_next,
+ ':', 'a', NUL, A_info_all_files,
'N', NUL, A_info_search_previous,
'O', NUL, A_info_goto_invocation_node,
'p', NUL, A_info_prev_node,
Added: trunk/info/infopath.c
===================================================================
--- trunk/info/infopath.c (rev 0)
+++ trunk/info/infopath.c 2013-04-15 21:39:09 UTC (rev 5255)
@@ -0,0 +1,335 @@
+/* infopath.c -- INFOPATH handling.
+
+ Copyright 1993, 1997, 1998, 2000, 2002, 2003, 2004, 2007, 2008, 2009, 2011,
+ 2012, 2013 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "info.h"
+#include "filesys.h"
+
+/* The path on which we look for info files. */
+static char *infopath_base = NULL;
+/* Allocated size of infopath_base. */
+static int infopath_size = 0;
+/* If 1, infopath_base has been modified and needs compaction */
+static int infopath_dirty = 0;
+
+/* Return a pointer to the next directory in STR (having length LEN).
+ *IDX points to the offset in STR where to start searching. Return
+ NULL if *IDX points at or after the trailing null character. Otherwise,
+ store the length of the returned directory segment into the memory
+ location pointed to by RETLEN. */
+static char *
+nextdir (char *str, int len, int *idx, int *retlen)
+{
+ int i;
+ char *ret;
+
+ if (!str || *idx >= len)
+ return NULL;
+
+ if (*idx > 0)
+ ++*idx;
+ ret = str + *idx;
+
+ for (i = *idx; str[i]; i++)
+ if (str[i] == PATH_SEP[0])
+ break;
+
+ *retlen = i - *idx;
+ *idx = i;
+ return ret;
+}
+
+/* Compact the INFOPATH value by removing repeated directory entries */
+void
+compact_infopath (void)
+{
+ int i, j, k, l;
+ int dl, pl;
+ char *dir, *p;
+ int chg = 0;
+
+ l = strlen (infopath_base);
+ for (i = 0; (dir = nextdir (infopath_base, l, &i, &dl)); )
+ {
+ for (j = k = i; (p = nextdir (infopath_base, l, &j, &pl)); k = j)
+ {
+ if (pl == dl && memcmp (dir, p, dl) == 0)
+ {
+ memmove (infopath_base + k, infopath_base + j, (l - j + 1));
+ l -= pl + 1;
+ chg = 1;
+ }
+ }
+ }
+ if (chg)
+ debug(2, ("INFOPATH compacted: %s", infopath_base));
+ infopath_dirty = 0;
+}
+
+void
+infopath_init ()
+{
+ /* Initialize INFOPATH.
+ The hardwired default settings (filesy.h) are the lowest priority.
+ Then comes the user's INFODIR from the Makefile.
+ Highest priority is the environment variable, if set. */
+ char *path_from_env = getenv ("INFOPATH");
+
+ if (path_from_env)
+ {
+ unsigned len = strlen (path_from_env);
+ /* Trailing : on INFOPATH means insert the default path. */
+ if (len && path_from_env[len - 1] == PATH_SEP[0])
+ {
+ path_from_env[len - 1] = 0;
+ infopath_add (DEFAULT_INFOPATH, INFOPATH_PREPEND);
+ }
+#ifdef INFODIR /* from the Makefile */
+ infopath_add (INFODIR, INFOPATH_PREPEND);
+#endif
+ infopath_add (path_from_env, INFOPATH_PREPEND);
+ }
+ else
+ {
+ infopath_add (DEFAULT_INFOPATH, INFOPATH_PREPEND);
+#ifdef INFODIR /* from the Makefile */
+ infopath_add (INFODIR, INFOPATH_PREPEND);
+#endif
+#ifdef INFODIR2 /* from the Makefile, too */
+# ifdef INFODIR
+ if (!STREQ (INFODIR, INFODIR2))
+# endif
+ infopath_add (INFODIR2, INFOPATH_PREPEND);
+#endif
+ }
+}
+
+char *
+infopath ()
+{
+ if (!infopath_base)
+ infopath_add (DEFAULT_INFOPATH, INFOPATH_INIT);
+ if (infopath_dirty)
+ compact_infopath ();
+ return infopath_base;
+}
+
+/* Make INFOPATH have absolutely nothing in it. */
+void
+infopath_clear (void)
+{
+ if (infopath_base)
+ {
+ infopath_base[0] = 0;
+ infopath_dirty = 0;
+ }
+ debug(2, ("INFOPATH cleared"));
+}
+
+/* For each path element PREFIX/DIR in PATH substitute either
+ PREFIX/share/info or PREFIX/info if that directory exists.
+ Avoid duplicates from, e.g., PREFIX/bin and PREFIX/sbin. */
+static char *
+build_infopath_from_path (void)
+{
+ typedef struct path_el
+ {
+ struct path_el *next;
+ char *path;
+ unsigned int len;
+ } PATH_EL, *PATH_PTR;
+
+ PATH_EL path_head = { NULL, NULL, 1 };
+ PATH_PTR path_prev, path_next;
+ char *res, *path_from_env, *temp_dirname;
+ int dirname_index = 0;
+ struct stat finfo;
+
+ path_from_env = getenv ("PATH");
+
+ while ((temp_dirname = extract_colon_unit (path_from_env, &dirname_index)))
+ {
+ unsigned int i, dir = 0;
+
+ /* Find end of DIRNAME/ (but ignore "/") */
+ for (i = 0; temp_dirname[i]; i++)
+ if (i && IS_SLASH (temp_dirname[i]))
+ dir = i + 1;
+
+ /* Discard path elements ending with "/", "/.", or "/.." */
+ if (!temp_dirname[dir] || STREQ (temp_dirname + dir, ".") || STREQ
(temp_dirname + dir, "."))
+ dir = 0;
+
+ path_prev = &path_head;
+ while (dir && (path_next = path_prev->next))
+ {
+ /* Ignore duplicate DIRNAME */
+ if (dir == path_next->len && strncmp (temp_dirname, path_next->path,
dir) == 0)
+ dir = 0;
+
+ path_prev = path_next;
+ }
+
+ if (dir)
+ {
+ temp_dirname = xrealloc (temp_dirname, dir + strlen ("share/info")
+1);
+
+ /* first try DIRNAME/share/info */
+ strcpy (temp_dirname + dir, "share/info");
+ if (stat (temp_dirname, &finfo) != 0 || !S_ISDIR (finfo.st_mode))
+ {
+ /* then try DIRNAME/info */
+ strcpy (temp_dirname + dir, "info");
+ if (stat (temp_dirname, &finfo) != 0 || !S_ISDIR (finfo.st_mode))
+ dir = 0;
+ }
+ }
+
+ if (dir)
+ {
+ path_next = xmalloc (sizeof (PATH_EL));
+ path_next->next = NULL;
+ path_next->path = temp_dirname;
+ path_next->len = dir;
+ path_prev->next = path_next;
+ path_head.len += strlen (temp_dirname) + 1;
+ }
+ else
+ free (temp_dirname);
+ }
+
+ /* Build the resulting sequence of paths */
+ res = xmalloc (path_head.len);
+ res[0] = '\0';
+
+ for (path_prev = path_head.next; path_prev; path_prev = path_next)
+ {
+ strcat (res, path_prev->path);
+ if ((path_next = path_prev->next))
+ strcat (res, PATH_SEP);
+
+ free (path_prev->path);
+ free (path_prev);
+ }
+
+ return res;
+}
+
+/* Add PATH to the list of paths found in INFOPATH. 2nd argument says
+ whether to put PATH at the front or end of INFOPATH.
+ Replace one path element "PATH" in PATH by a sequence of
+ path elements derived from the environment variable PATH. */
+void
+infopath_add (char *path, int where)
+{
+ int len;
+ int found = 0;
+ unsigned int i, j;
+
+ /* Search for "PATH" in PATH */
+ for (i = 0; path[i]; i++)
+ {
+ j = i + strlen ("PATH");
+ if (strncmp (path + i, "PATH", strlen ("PATH")) == 0 &&
+ (!path[j] || path[j] == PATH_SEP[0]))
+ {
+ found = 1;
+ break;
+ }
+ else
+ {
+ /* Advance to next PATH_SEP. */
+ while (path[i] && path[i] != PATH_SEP[0])
+ i++;
+
+ if (!path[i])
+ break;
+ }
+ }
+
+ if (found)
+ {
+ /* Build infopath from the environment variable PATH */
+ char *temp = build_infopath_from_path ();
+
+ if (i || path[j])
+ {
+ char *old_path = path;
+
+ /* Splice it into OLD_PATH */
+ path = xmalloc (1 + strlen (temp) +
+ strlen (old_path) - strlen ("PATH"));
+ if (i)
+ strncpy (path, old_path, i);
+ strcpy (path + i, temp);
+ if (old_path[j])
+ strcat (path, old_path + j);
+
+ free (temp);
+ }
+ else
+ path = temp;
+ }
+
+ if (where == INFOPATH_INIT)
+ infopath_clear ();
+
+ if (!infopath_base)
+ {
+ infopath_base = xmalloc (infopath_size = 200 + strlen (path));
+ infopath_base[0] = '\0';
+ }
+
+ len = strlen (path) + strlen (infopath_base);
+
+ if (len + 2 >= infopath_size)
+ infopath_base = xrealloc (infopath_base, (infopath_size += (2 * len) + 2));
+
+ if (!*infopath_base || !infopath_base[0])
+ strcpy (infopath_base, path);
+ else if (where == INFOPATH_APPEND)
+ {
+ strcat (infopath_base, PATH_SEP);
+ strcat (infopath_base, path);
+ }
+ else if (where == INFOPATH_PREPEND)
+ {
+ char *temp = xstrdup (infopath_base);
+ strcpy (infopath_base, path);
+ strcat (infopath_base, PATH_SEP);
+ strcat (infopath_base, temp);
+ free (temp);
+ }
+ infopath_dirty = 1;
+ debug(2, ("INFOPATH=%s", infopath_base));
+ if (found)
+ free (path);
+}
+
+char *
+infopath_next (int *idx)
+{
+ return extract_colon_unit (infopath_base, idx);
+}
+
+char *
+infopath_first (int *idx)
+{
+ *idx = 0;
+ return infopath_next (idx);
+}
Modified: trunk/info/nodes.c
===================================================================
--- trunk/info/nodes.c 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/nodes.c 2013-04-15 21:39:09 UTC (rev 5255)
@@ -30,7 +30,6 @@
# include "man.h"
#endif /* HANDLE_MAN_PAGES */
-static void forget_info_file (char *filename);
static void remember_info_file (FILE_BUFFER *file_buffer);
static void free_file_buffer_tags (FILE_BUFFER *file_buffer);
static void free_info_tag (TAG *tag);
@@ -1118,7 +1117,7 @@
}
/* Forget the contents, tags table, nodes list, and names of FILENAME. */
-static void
+void
forget_info_file (char *filename)
{
int i;
Modified: trunk/info/nodes.h
===================================================================
--- trunk/info/nodes.h 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/nodes.h 2013-04-15 21:39:09 UTC (rev 5255)
@@ -161,4 +161,6 @@
/* Create a new, empty file buffer. */
extern FILE_BUFFER *make_file_buffer (void);
+void forget_info_file (char *filename);
+
#endif /* not NODES_H */
Modified: trunk/info/session.c
===================================================================
--- trunk/info/session.c 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/session.c 2013-04-15 21:39:09 UTC (rev 5255)
@@ -188,10 +188,8 @@
info_read_and_dispatch (void)
{
unsigned char key;
- int done;
- done = 0;
- while (!done && !quit_info_immediately)
+ for (quit_info_immediately = 0; !quit_info_immediately; )
{
int lk = 0;
@@ -239,14 +237,9 @@
info_aborted_echo_area)
{
ea_last_executed_command = NULL;
- done = 1;
+ break;
}
-
- if (info_last_executed_command == (VFunction *) info_quit)
- quit_info_immediately = 1;
}
- else if (info_last_executed_command == (VFunction *) info_quit)
- done = 1;
}
}
@@ -2796,7 +2789,8 @@
will be NULL. */
NODE *
-info_follow_menus (NODE *initial_node, char **menus, NODE **err_node)
+info_follow_menus (NODE *initial_node, char **menus, NODE **err_node,
+ int strict)
{
NODE *node = NULL;
@@ -2826,7 +2820,7 @@
realize it. */
if (!menu)
{
- if (arg == first_arg)
+ if (arg == first_arg && !strict)
{
node = make_manpage_node (first_arg);
if (node)
@@ -2866,6 +2860,8 @@
node anyway. It is probably a misspelling. */
if (!entry)
{
+ if (strict)
+ return NULL;
if (arg == first_arg)
{
/* Maybe they typed "info foo" instead of "info -f foo". */
@@ -2999,7 +2995,7 @@
if (!dir_node)
info_error (msg_cant_find_node, "Top");
else
- node = info_follow_menus (dir_node, nodes, &err_node);
+ node = info_follow_menus (dir_node, nodes, &err_node, 0);
free (nodes);
if (err_node)
@@ -4944,10 +4940,12 @@
set_window_pagetop (window, new_pagetop);
}
}
-/* This command does nothing. It is the fact that a key is bound to it
- that has meaning. See the code at the top of info_session (). */
+
+/* Exit from info */
DECLARE_INFO_COMMAND (info_quit, _("Quit using Info"))
-{}
+{
+ quit_info_immediately = 1;
+}
/* **************************************************************** */
Modified: trunk/info/session.h
===================================================================
--- trunk/info/session.h 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/session.h 2013-04-15 21:39:09 UTC (rev 5255)
@@ -25,6 +25,8 @@
#include "info.h"
#include "dribble.h"
+extern int quit_info_immediately;
+
/* All commands that can be invoked from within info_session () receive
arguments in the same way. This simple define declares the header
of a function named NAME, with associated documentation DOC. The
@@ -197,7 +199,7 @@
extern void info_view_file (WINDOW *window, int count, unsigned char key);
extern void info_menu_sequence (WINDOW *window, int count, unsigned char key);
extern NODE *info_follow_menus (NODE *initial_node, char **menus,
- NODE **err_node);
+ NODE **err_node, int strict);
extern void info_man (WINDOW *window, int count, unsigned char key);
extern void list_visited_nodes (WINDOW *window, int count, unsigned char key);
extern void select_visited_node (WINDOW *window, int count, unsigned char key);
Modified: trunk/info/tilde.c
===================================================================
--- trunk/info/tilde.c 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/tilde.c 2013-04-15 21:39:09 UTC (rev 5255)
@@ -174,7 +174,7 @@
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
char *
-tilde_expand_word (char *filename)
+tilde_expand_word (const char *filename)
{
char *dirname = filename ? xstrdup (filename) : NULL;
Modified: trunk/info/tilde.h
===================================================================
--- trunk/info/tilde.h 2013-04-13 15:41:58 UTC (rev 5254)
+++ trunk/info/tilde.h 2013-04-15 21:39:09 UTC (rev 5255)
@@ -48,6 +48,6 @@
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
-extern char *tilde_expand_word (char *filename);
+extern char *tilde_expand_word (const char *filename);
#endif /* not TILDE_H */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [5255] Implement the --all (-a) option as per bug #38168.,
Sergey Poznyakoff <=