texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[5600] infopath: avoid duplicates and non-existent dirs


From: Gavin D. Smith
Subject: [5600] infopath: avoid duplicates and non-existent dirs
Date: Sun, 25 May 2014 15:45:45 +0000

Revision: 5600
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5600
Author:   gavin
Date:     2014-05-25 15:45:43 +0000 (Sun, 25 May 2014)
Log Message:
-----------
infopath: avoid duplicates and non-existent dirs

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/info/dir.c
    trunk/info/filesys.c
    trunk/info/filesys.h
    trunk/info/info.c
    trunk/info/info.h
    trunk/info/infodoc.c
    trunk/info/infopath.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2014-05-24 01:51:03 UTC (rev 5599)
+++ trunk/ChangeLog     2014-05-25 15:45:43 UTC (rev 5600)
@@ -1,3 +1,36 @@
+2014-05-25  Gavin Smith  <address@hidden>
+
+       * info/filesys.c (info_file_find_next_in_path): Use infopath_next
+       to iterate over INFOPATH.  Don't take a path argument.  Callers
+       updated.
+       (info_file_in_path): Don't take a path argument.  All callers updated.
+       
+       * info/filesys.c, info/infopath.c (extract_colon_unit): Function
+       definition moved.
+
+       * info/infopath.c (INFO_DIR): New typedef.
+       (infodirs, infodirs_index, infodirs_slots): New variables.
+       (infopath_add): Always add directory to end of search path, checking
+       if it doesn't exist or if it is a duplicate.  Check for inode == 0
+       for MS-Windows copied from dir.c:new_dir_file_p.  Argument 'where'
+       removed.  All callers updated.
+       (infopath_add_dir) New function.
+       (infopath_first, infopath_next): Return values not freed by caller.
+       Callers updated.
+       (infopath, infopath_string): Function renamed.  Return value to
+       be freed by caller.  Caller updated.
+       (build_infopath_from_path): Rely on duplicate detection in
+       infopath_add.  Add directories to search path instead of returning
+       a string containing their names.
+       (compact_infopath, infopath_clear,infopath_base, infopath_size)
+       (infopath_dirty, nextdir): Removed.
+       * info/infopath.h (INFOPATH_PREPEND, INFOPATH_APPEND, INFOPATH_INIT):
+       Removed.
+
+       * info/dir.c (dir_file_list_entry_type, new_dir_file_p): Removed.
+       (build_dir_node): Rely on duplicates being removed in INFOPATH to
+       avoid a duplicate dir file.
+
 2014-05-24  Gavin Smith  <address@hidden>
 
        * info/indices.c (apropos_in_all_indices): Fix code for avoiding

Modified: trunk/info/dir.c
===================================================================
--- trunk/info/dir.c    2014-05-24 01:51:03 UTC (rev 5599)
+++ trunk/info/dir.c    2014-05-25 15:45:43 UTC (rev 5600)
@@ -38,41 +38,6 @@
 
 FILE_BUFFER *dir_buffer = 0;
 
-/* Return zero if the file represented in the stat structure TEST has
-   already been seen, nonzero otherwise.  */
-
-typedef struct
-{
-  dev_t device;
-  ino_t inode;
-} dir_file_list_entry_type;
-
-static int
-new_dir_file_p (struct stat *test)
-{
-  static unsigned dir_file_list_len = 0;
-  static dir_file_list_entry_type *dir_file_list = NULL;
-  unsigned i;
-  
-  for (i = 0; i < dir_file_list_len; i++)
-    {
-      dir_file_list_entry_type entry;
-      entry = dir_file_list[i];
-      if (entry.device == test->st_dev && entry.inode == test->st_ino
-         /* On MS-Windows, `stat' returns zero as the inode, so we
-            effectively disable this optimization for that OS.  */
-         && entry.inode != 0)
-        return 0;
-    }
-  
-  dir_file_list_len++;
-  dir_file_list = xrealloc (dir_file_list, 
-                        dir_file_list_len * sizeof (dir_file_list_entry_type));
-  dir_file_list[dir_file_list_len - 1].device = test->st_dev;
-  dir_file_list[dir_file_list_len - 1].inode = test->st_ino;
-  return 1;
-}
-
 static void create_dir_buffer (void);
 static NODE *build_dir_node (void);
 
@@ -161,7 +126,6 @@
           tilde_expanded_dirname = tilde_expand_word (this_dir);
           if (tilde_expanded_dirname != this_dir)
             {
-              free (this_dir);
               this_dir = tilde_expanded_dirname;
             }
         }
@@ -182,8 +146,7 @@
 
           statable = (stat (fullpath, &finfo) == 0);
 
-          /* Only add this file if we have not seen it before.  */
-          if (statable && S_ISREG (finfo.st_mode) && new_dir_file_p (&finfo))
+          if (statable && S_ISREG (finfo.st_mode))
             {
               size_t filesize;
              int compressed;
@@ -198,7 +161,6 @@
 
           free (fullpath);
         }
-      free (this_dir);
     }
 
   {

Modified: trunk/info/filesys.c
===================================================================
--- trunk/info/filesys.c        2014-05-24 01:51:03 UTC (rev 5599)
+++ trunk/info/filesys.c        2014-05-25 15:45:43 UTC (rev 5600)
@@ -26,8 +26,7 @@
 #include "tag.h"
 
 /* Local to this file. */
-static char *info_file_in_path (char *filename, char *path,
-                                struct stat *finfo);
+static char *info_file_in_path (char *filename, struct stat *finfo);
 static char *info_add_extension (char *dirname, char *fname,
                                  struct stat *finfo);
 
@@ -129,7 +128,7 @@
     fullpath = info_add_extension (0, partial, finfo);
   /* If just a simple name element, look for it in the path. */
   else
-    fullpath = info_file_in_path (partial, infopath (), finfo);
+    fullpath = info_file_in_path (partial, finfo);
 
   if (!fullpath)
     filesys_error_number = ENOENT;
@@ -137,17 +136,15 @@
   return fullpath;
 }
 
-/* Scan the list of directories in PATH looking for FILENAME.  If we find
+/* Scan the directories in search path looking for FILENAME.  If we find
    one that is a regular file, return it as a new string.  Otherwise, return
    a NULL pointer.  Set *FINFO with information about file. */
 char *
-info_file_find_next_in_path (char *filename, char *path, int *diridx,
-                             struct stat *finfo)
+info_file_find_next_in_path (char *filename, int *path_index, struct stat 
*finfo)
 {
-  char *dirname;
   struct stat dummy;
 
-  /* Used for output of fstat in case the caller doesn't care about
+  /* Used for output of stat in case the caller doesn't care about
      its value. */
   if (!finfo)
     finfo = &dummy;
@@ -157,10 +154,14 @@
   if (!*filename || STREQ (filename, ".") || STREQ (filename, ".."))
     return NULL;
 
-  while ((dirname = extract_colon_unit (path, diridx)))
+  while (1)
     {
-      char *with_extension = 0;
+      char *dirname, *with_extension = 0;
 
+      dirname = infopath_next (path_index);
+      if (!dirname)
+        break;
+
       debug(1, (_("looking for file %s in %s"), filename, dirname));
 
       /* Expand a leading tilde if one is present. */
@@ -172,7 +173,6 @@
         }
 
       with_extension = info_add_extension (dirname, filename, finfo);
-      free (dirname);
 
       if (with_extension)
         return with_extension;
@@ -181,10 +181,10 @@
 }
 
 static char *
-info_file_in_path (char *filename, char *path, struct stat *finfo)
+info_file_in_path (char *filename, struct stat *finfo)
 {
   int i = 0;
-  return info_file_find_next_in_path (filename, path, &i, finfo);
+  return info_file_find_next_in_path (filename, &i, finfo);
 }
 
 /* Look for a file called FILENAME in a directory called DIRNAME, adding file
@@ -239,7 +239,7 @@
               char *newpath, *new_filename;
 
               newpath = xstrdup (try_filename);
-              new_filename = info_file_in_path (filename, newpath, finfo);
+              new_filename = info_add_extension (newpath, filename, finfo);
 
               free (newpath);
               if (new_filename)
@@ -276,37 +276,6 @@
   free (try_filename);
   return 0;
 }
-
-/* Given a string containing units of information separated by the
-   PATH_SEP character, return the next one after IDX, or NULL if there
-   are no more.  Advance IDX to the character after the colon. */
-
-char *
-extract_colon_unit (char *string, int *idx)
-{
-  unsigned int i = (unsigned int) *idx;
-  unsigned int start = i;
-
-  if (!string || i >= strlen (string))
-    return NULL;
-
-  if (!string[i]) /* end of string */
-    return NULL;
-
-  /* Advance to next PATH_SEP.  */
-  while (string[i] && string[i] != PATH_SEP[0])
-    i++;
-
-  {
-    char *value = xmalloc ((i - start) + 1);
-    strncpy (value, &string[start], (i - start));
-    value[i - start] = 0;
-
-    i++; /* move past PATH_SEP */
-    *idx = i;
-    return value;
-  }
-}
 
 /* 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

Modified: trunk/info/filesys.h
===================================================================
--- trunk/info/filesys.h        2014-05-24 01:51:03 UTC (rev 5599)
+++ trunk/info/filesys.h        2014-05-25 15:45:43 UTC (rev 5600)
@@ -22,28 +22,19 @@
 #ifndef INFO_FILESYS_H
 #define INFO_FILESYS_H
 
-/* 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. */
+/* Return a string describing the search path. */
+extern char *infopath_string ();
 
-extern char *infopath ();
-
 /* Initialize INFOPATH */
 void infopath_init (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 infopath_add (char *path, int where);
+/* Add PATH to the list of paths found in INFOPATH. */
+extern void infopath_add (char *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.
    If it can't find the file, it returns NULL. */
@@ -52,7 +43,7 @@
 /* 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,
+extern char *info_file_find_next_in_path (char *filename,
                                          int *diridx, struct stat *finfo);
 
 /* Read the contents of PATHNAME, returning a buffer with the contents of
@@ -69,11 +60,6 @@
 /* The number of the most recent file system error. */
 extern int filesys_error_number;
 
-/* Given a string containing units of information separated by colons,
-   return the next one pointed to by IDX, or NULL if there are no more.
-   Advance IDX to the character after the colon. */
-extern char *extract_colon_unit (char *string, int *idx);
-
 /* Return true if FILENAME is `dir', with a possible compression suffix.  */
 extern int is_dir_name (char *filename);
 

Modified: trunk/info/info.c
===================================================================
--- trunk/info/info.c   2014-05-24 01:51:03 UTC (rev 5599)
+++ trunk/info/info.c   2014-05-25 15:45:43 UTC (rev 5600)
@@ -458,7 +458,7 @@
     {
       char *p;
 
-      p = info_file_find_next_in_path (filename, infopath (), &i, 0);
+      p = info_file_find_next_in_path (filename, &i, 0);
       if (!p)
         break;
 
@@ -552,7 +552,7 @@
          
           /* User wants to add a directory. */
         case 'd':
-          infopath_add (optarg, INFOPATH_APPEND);
+          infopath_add (optarg);
           break;
 
           /* User is specifying a particular node. */
@@ -874,7 +874,7 @@
          temp += 2;
        }
       temp[-1] = 0;
-      infopath_add (directory_name, INFOPATH_PREPEND);
+      infopath_add (directory_name);
     }
 
   free (directory_name);

Modified: trunk/info/info.h
===================================================================
--- trunk/info/info.h   2014-05-24 01:51:03 UTC (rev 5599)
+++ trunk/info/info.h   2014-05-25 15:45:43 UTC (rev 5600)
@@ -58,7 +58,7 @@
 #endif /* !whitespace_or_newline */
 
 /* Add ELT to the list of elements found in ARRAY.  SLOTS is the number
-   of slots that have already been allocated.  INDEX is the index into the
+   of slots that have already been allocated.  IDX is the index into the
    array where ELT should be added.  MINSLOTS is the number of slots to
    start the array with in case it is empty. */
 #define add_pointer_to_array(elt, idx, array, slots, minslots) \
@@ -158,5 +158,12 @@
 extern char *read_function_name (const char *prompt, WINDOW *window);
 
 extern void show_error_node (char *error_msg);
+
+/* In infopath.c, but also used in man.c. */
 
+/* Given a string containing units of information separated by colons,
+   return the next one pointed to by IDX, or NULL if there are no more.
+   Advance IDX to the character after the colon. */
+char *extract_colon_unit (char *string, int *idx);
+
 #endif /* !INFO_H */

Modified: trunk/info/infodoc.c
===================================================================
--- trunk/info/infodoc.c        2014-05-24 01:51:03 UTC (rev 5599)
+++ trunk/info/infodoc.c        2014-05-25 15:45:43 UTC (rev 5600)
@@ -297,6 +297,7 @@
     {
       int printed_one_mx = 0;
       struct text_buffer msg;
+      char *infopath_str = infopath_string ();
 
       text_buffer_init (&msg);
 
@@ -325,8 +326,10 @@
 
       text_buffer_printf (&msg, "---------------------\n");
       text_buffer_printf (&msg, _("The current search path is:\n"));
-      text_buffer_printf (&msg, "%s\n", infopath ());
+      text_buffer_printf (&msg, "%s\n", infopath_str);
       text_buffer_printf (&msg, "---------------------\n\n");
+      free (infopath_str);
+
       text_buffer_printf (&msg, _("Commands available in Info windows:\n\n"));
       dump_map_to_text_buffer (&msg, "", info_keymap);
       text_buffer_printf (&msg, "---------------------\n\n");

Modified: trunk/info/infopath.c
===================================================================
--- trunk/info/infopath.c       2014-05-24 01:51:03 UTC (rev 5599)
+++ trunk/info/infopath.c       2014-05-25 15:45:43 UTC (rev 5600)
@@ -21,74 +21,22 @@
 #include "info.h"
 #include "filesys.h"
 
+typedef struct {
+  char *name;    /* Path to directory to be searched. */
+  dev_t device;  /* Storage device this directory is on. */
+  ino_t inode;   /* Inode number, used to detect duplicates. */
+} INFO_DIR;
+
+INFO_DIR **infodirs = 0;
+size_t infodirs_index = 0;
+size_t infodirs_slots = 0;
+
 /* Exclude default file search directories. */
 int infopath_no_defaults_p;
 
-/* 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;
+char *extract_colon_unit (char *string, int *idx);
 
-/* Make INFOPATH have absolutely nothing in it. */
-static void infopath_clear (void);
-
-/* 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.
@@ -99,22 +47,24 @@
 
   if (path_from_env)
     {
-      infopath_add (path_from_env, INFOPATH_APPEND);
+      infopath_add (path_from_env);
     }
 
   if (!infopath_no_defaults_p)
     {
 #ifdef INFODIR /* $infodir, set by configure script in Makefile */
-      infopath_add (INFODIR, INFOPATH_APPEND);
+      infopath_add (INFODIR);
 #ifdef INFODIR2 /* $datadir/info, which could be different. */
       if (!STREQ (INFODIR, INFODIR2))
-        infopath_add (INFODIR2, INFOPATH_APPEND);
+        infopath_add (INFODIR2);
 #endif /* INFODIR2 */
 #endif /* INFODIR */
     }
 
   if (!path_from_env)
-    infopath_add (DEFAULT_INFOPATH, INFOPATH_APPEND);
+    {
+      infopath_add (DEFAULT_INFOPATH);
+    }
   else
     { 
       /* Only insert default path if there is a trailing : on INFOPATH. */
@@ -123,48 +73,41 @@
       if (len && path_from_env[len - 1] == PATH_SEP[0])
        {
          path_from_env[len - 1] = 0;
-         infopath_add (DEFAULT_INFOPATH, INFOPATH_APPEND);
+         infopath_add (DEFAULT_INFOPATH);
        }
     }
 }
 
+/* Return value to be freed by caller. */
 char *
-infopath ()
+infopath_string ()
 {
-  if (!infopath_base)
-    infopath_add (DEFAULT_INFOPATH, INFOPATH_INIT);
-  if (infopath_dirty)
-    compact_infopath ();
-  return infopath_base;
-}
+  struct text_buffer path;
+  int dir_idx;
+  char *this_dir;
 
-/* Make INFOPATH have absolutely nothing in it. */
-static void
-infopath_clear (void)
-{
-  if (infopath_base)
+  this_dir = infopath_first (&dir_idx);
+  if (!this_dir)
+    return "";
+
+  text_buffer_init (&path);
+
+  while (1)
     {
-      infopath_base[0] = 0;
-      infopath_dirty = 0;
+      text_buffer_printf (&path, "%s", this_dir);
+      this_dir = infopath_next (&dir_idx);
+      if (!this_dir)
+        break;
+      text_buffer_add_char (&path, ':');
     }
-  debug(2, ("INFOPATH cleared"));
+  return text_buffer_base (&path); 
 }
 
 /* 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 *
+   PREFIX/share/info or PREFIX/info if that directory exists. */
+static void
 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;
@@ -184,16 +127,6 @@
       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);
@@ -210,130 +143,77 @@
         }
 
       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;
-        }
+        infopath_add (temp_dirname);
       else
         free (temp_dirname);
     }
+}
 
-  /* Build the resulting sequence of paths */
-  res = xmalloc (path_head.len);
-  res[0] = '\0';
+static void
+infopath_add_dir (char *path)
+{
+  struct stat dirinfo;
+  INFO_DIR *entry;
+  int i;
 
-  for (path_prev = path_head.next; path_prev; path_prev = path_next)
+  if (stat (path, &dirinfo) == -1)
     {
-      strcat (res, path_prev->path);
-      if ((path_next = path_prev->next))
-        strcat (res, PATH_SEP);
+      debug (2, ("inaccessible directory %s not added to INFOPATH", path));
+      return; /* Doesn't exist, or not accessible. */
+    }
 
-      free (path_prev->path);
-      free (path_prev);
+  for (i = 0; i < infodirs_index; i++)
+    {
+      if (   dirinfo.st_ino == infodirs[i]->inode
+          && dirinfo.st_dev == infodirs[i]->device
+          /* On MS-Windows, `stat' returns zero as the inode, so we
+             effectively disable this optimization for that OS.  */
+          && infodirs[i]->inode != 0)
+        {
+          debug (2, ("duplicate directory %s not added to INFOPATH", path));
+          return; /* We have it already. */
+        }
     }
 
-  return res;
+  debug (2, ("adding %s to INFOPATH", path));
+  entry = xmalloc (sizeof (INFO_DIR));
+  entry->name = path;
+  entry->inode = dirinfo.st_ino;
+  entry->device = dirinfo.st_dev;
+  add_pointer_to_array (entry, infodirs_index, infodirs, infodirs_slots, 8);
 }
 
-/* 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. */
+/* Add PATH to the list of paths found in INFOPATH.  PATH should be allocated
+   on the heap and not referenced by the caller after calling this function.
+   If PATH is "PATH", add a sequence of path elements derived from the
+   environment variable PATH. */
 void
-infopath_add (char *path, int where)
+infopath_add (char *path)
 {
-  int len;
-  int found = 0;
-  unsigned int i, j;
+  int idx = 0;
+  char *dirname;
 
-  /* Search for "PATH" in PATH */
-  for (i = 0; path[i]; i++)
+  while (dirname = extract_colon_unit (path, &idx))
     {
-      j = i + strlen ("PATH");
-      if (strncmp (path + i, "PATH", strlen ("PATH")) == 0 &&
-          (!path[j] || path[j] == PATH_SEP[0]))
+      if (!strcmp ("PATH", dirname))
         {
-          found = 1;
-          break;
+          free (dirname);
+          build_infopath_from_path ();
         }
       else
-        {
-          /* Advance to next PATH_SEP.  */
-          while (path[i] && path[i] != PATH_SEP[0])
-            i++;
-
-          if (!path[i])
-            break;
-        }
+        infopath_add_dir (dirname);
     }
-
-  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);
 }
 
+/* Used to iterate over INFOPATH.  Return value should not be freed
+   by caller. */
 char *
 infopath_next (int *idx)
 {
-  return extract_colon_unit (infopath_base, idx);
+  INFO_DIR *entry = infodirs[(*idx)++];
+  if (!entry)
+    return 0;
+  return entry->name;
 }
 
 char *
@@ -342,3 +222,33 @@
   *idx = 0;
   return infopath_next (idx);
 }
+
+/* Given a string containing units of information separated by the
+   PATH_SEP character, return the next one after IDX, or NULL if there
+   are no more.  Advance IDX to the character after the colon. */
+char *
+extract_colon_unit (char *string, int *idx)
+{
+  unsigned int i = (unsigned int) *idx;
+  unsigned int start = i;
+
+  if (!string || i >= strlen (string))
+    return NULL;
+
+  if (!string[i]) /* end of string */
+    return NULL;
+
+  /* Advance to next PATH_SEP.  */
+  while (string[i] && string[i] != PATH_SEP[0])
+    i++;
+
+  {
+    char *value = xmalloc ((i - start) + 1);
+    strncpy (value, &string[start], (i - start));
+    value[i - start] = 0;
+
+    i++; /* move past PATH_SEP */
+    *idx = i;
+    return value;
+  }
+}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]