[tex-k] An idea for texinfo
Peter Breitenlohner
peb at mppmu.mpg.de
Mon Jan 19 18:37:10 CET 2009
On Thu, 15 Jan 2009, Karl Berry wrote:
> I'd like to implement a feature in texinfo that allows to set an info_path
> constructed from PATH.
>
> Sounds good.
> path="PREFIX/DIR"
> => the first existing directory among
> PREFIX/share/info
> PREFIX/info
> and possibly also (inspired by man-db)
> PREFIX/DIR/share/info
> PREFIX/DIR/info
>
> I guess it doesn't hurt to check for more directories, but when would
> /PREFIX/DIR/{info,share...} be found?
The last two were inspired by the way man-db constructs a manpath, they are now
gone.
Attached are three patches:
(1) patch-02-infopath-from-path:
The implementation of this idea.
(2) patch-03-tell-the-truth:
A correction to the info-stnd manual.
(3) patch-04-infopath-from-path-doc:
Documentation for (1).
====================
At the moment all this only works for the standalone info reader.
To make INFOPATH=PATH in the environment usefull, would certainly require
to have the same mechanism as well in the (X)Emacs info reader.
Regards
Peter Breitenlohner <peb at mppmu.mpg.de>
-------------- next part --------------
diff -ur texinfo-4.12.orig/info/filesys.c texinfo-4.12/info/filesys.c
--- texinfo-4.12.orig/info/filesys.c 2008-04-19 19:03:13.000000000 +0200
+++ texinfo-4.12/info/filesys.c 2009-01-17 02:04:38.000000000 +0100
@@ -28,6 +28,7 @@
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);
@@ -365,12 +366,149 @@
}
}
+/* 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. */
+ 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)
{
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 (!infopath)
{
@@ -398,6 +536,9 @@
strcat (infopath, temp);
free (temp);
}
+
+ if (found)
+ free (path);
}
/* Make INFOPATH have absolutely nothing in it. */
-------------- next part --------------
diff -ur texinfo-4.12.orig/doc/info-stnd.texi texinfo-4.12/doc/info-stnd.texi
--- texinfo-4.12.orig/doc/info-stnd.texi 2008-03-05 09:45:38.000000000 +0100
+++ texinfo-4.12/doc/info-stnd.texi 2009-01-19 17:22:27.000000000 +0100
@@ -151,10 +151,11 @@
@itemx -d @var{directory-path}
Prepend @var{directory-path} to the list of directory paths searched
when Info needs to find a file. You may issue @code{--directory}
-multiple times; once for each directory which contains Info files. The
-list of directories searched by Info is constructed from the value of
-the environment variable @code{INFOPATH}; @code{--directory} causes the
-named @var{directory-path} to be prepended to that list. The value of
+multiple times; once for each directory which contains Info files,
+or with a list of such directories separated by a colon (or semicolon
+on MS-DOS/MS-Windows). In the absence of @code{--directory} options
+the list of directories searched by Info is constructed from the
+value of the environment variable @code{INFOPATH}. The value of
@code{INFOPATH} is a list of directories usually separated by a colon;
on MS-DOS/MS-Windows systems, the semicolon is used. If you do not
define @code{INFOPATH}, Info uses a default path defined when Info was
-------------- next part --------------
diff -ur texinfo-4.12.orig/doc/info-stnd.texi texinfo-4.12/doc/info-stnd.texi
--- texinfo-4.12.orig/doc/info-stnd.texi 2009-01-19 17:22:27.000000000 +0100
+++ texinfo-4.12/doc/info-stnd.texi 2009-01-19 17:34:49.000000000 +0100
@@ -164,6 +164,12 @@
the initial list of directories is constructed by appending the
build-time default to the value of @code{INFOPATH}.
+If the list of directories contains the element @code{PATH}, that
+element is replaced by a list of directories derived from the value of
+the environment variable @code{PATH}. Each path element of the form
+ at var{dir/base} is replaced by @var{dir}@code{/share/info} or
+ at var{dir}@code{/info}, provided that directory exists.
+
@cindex keystrokes, recording
@cindex remembering user keystrokes
@item --dribble=@var{dribble-file}
More information about the tex-k
mailing list