From: Ben Pfaff <blp@gnu.org>
Date: Sun, 16 Apr 2006 23:35:19 +0000 (+0000)
Subject: * filename.c: (fn_tilde_expand) Rewrite for cleaner code.  Also, now
X-Git-Tag: sav-api~1988
X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1d0e2b0f070e3706238ae81f42bff6704ff0083;p=pspp

* filename.c: (fn_tilde_expand) Rewrite for cleaner code.  Also, now
it only tilde-expands file names, not paths.
(fn_search_path) Tilde-expand one directory at a time.
---

diff --git a/src/data/ChangeLog b/src/data/ChangeLog
index 009104b03b..4f9fd6ee7f 100644
--- a/src/data/ChangeLog
+++ b/src/data/ChangeLog
@@ -1,16 +1,26 @@
-Sun Apr 16 16:05:28 2006  Ben Pfaff  <blp@gnu.org>
+Sun Apr 16 16:33:58 2006  Ben Pfaff  <blp@gnu.org>
 
-	Continue reforming error message support.  In this phase, we get
-	rid of VM() and the other msg() support for "verbosity", replacing
-	it by a new function verbose_msg().
+	* filename.c: (fn_tilde_expand) Rewrite for cleaner code.  
+	Also, now it only tilde-expands file names, not paths.
+	(fn_search_path) Tilde-expand one directory at a time.
+
+Sun Apr 16 16:28:06 2006  Ben Pfaff  <blp@gnu.org>
 
-	* filename.c: (fn_search_path) Rewrite for cleaner code.  Also,
+	* filename.c: (fn_search_path) rewrite for cleaner code.  Also,
 	get rid of non-Unixlike version of the code, which has probably
 	never been tested.
 	(fn_prepend_dir) Removed (dead code).
 
 	* filename.h: (macro DIR_SEPARATOR_STRING) New.
 	(macro PATH_SEPARATOR_STRING) New.
+Sun Apr 16 16:05:28 2006  Ben Pfaff  <blp@gnu.org>
+
+	Continue reforming error message support.  In this phase, we get
+	rid of VM() and the other msg() support for "verbosity", replacing
+	it by a new function verbose_msg().
+
+	* filename.c: (fn_search_path) Use verbose_msg() instead of
+	msg(VM(), ...).  
 
 Sat Apr 15 19:53:19 2006  Ben Pfaff  <blp@gnu.org>
 
diff --git a/src/data/filename.c b/src/data/filename.c
index c015bda0ff..498963525d 100644
--- a/src/data/filename.c
+++ b/src/data/filename.c
@@ -160,53 +160,40 @@ fn_interp_vars (struct string *target,
 char *
 fn_tilde_expand (const char *input)
 {
-  const char *ip;
-  struct string output;
-
-  if (NULL == strchr (input, '~'))
-    return xstrdup (input);
-  ds_init (&output, strlen (input));
-
-  ip = input;
-
-  for (ip = input; *ip; )
-    if (*ip != '~' || (ip != input && ip[-1] != PATH_DELIMITER))
-      ds_putc (&output, *ip++);
-    else
-      {
-	static const char stop_set[3] = {DIR_SEPARATOR, PATH_DELIMITER, 0};
-	const char *cp;
-	
-	ip++;
-
-	cp = ip + strcspn (ip, stop_set);
-
-	if (cp > ip)
-	  {
-	    struct passwd *pwd;
-	    char username[9];
-
-	    strncpy (username, ip, cp - ip + 1);
-	    username[8] = 0;
-	    pwd = getpwnam (username);
-
-	    if (!pwd || !pwd->pw_dir)
-	      ds_putc (&output, *ip++);
-	    else
-	      ds_puts (&output, pwd->pw_dir);
-	  }
-	else
-	  {
-	    const char *home = fn_getenv ("HOME");
-	    if (!home)
-	      ds_putc (&output, *ip++);
-	    else
-	      ds_puts (&output, home);
-	  }
-
-	ip = cp;
-      }
-
+  struct string output = DS_INITIALIZER;
+  if (input[0] == '~')
+    {
+      const char *home = NULL;
+      const char *remainder = NULL;
+      if (input[1] == '/' || input[1] == '\0')
+        {
+          home = fn_getenv ("HOME");
+          remainder = input + 1; 
+        }
+      else
+        {
+          struct string user_name = DS_INITIALIZER;
+          struct passwd *pwd;
+
+          ds_assign_buffer (&user_name, input + 1, strcspn (input + 1, "/"));
+          pwd = getpwnam (ds_c_str (&user_name));
+          if (pwd != NULL && pwd->pw_dir[0] != '\0')
+            {
+              home = pwd->pw_dir;
+              remainder = input + 1 + ds_length (&user_name);
+            }
+          ds_destroy (&user_name);
+        }
+
+      if (home != NULL) 
+        {
+          ds_puts (&output, home);
+          if (*remainder != '\0')
+            ds_puts (&output, remainder);
+        }
+    }
+  if (ds_is_empty (&output))
+    ds_puts (&output, input);
   return ds_c_str (&output);
 }
 #else /* !unix */
@@ -232,24 +219,27 @@ fn_search_path (const char *base_name, const char *path_, const char *prefix)
   struct string path;
   struct string dir = DS_INITIALIZER;
   struct string file = DS_INITIALIZER;
-  char *tmp_str;
   size_t save_idx = 0;
 
   if (fn_absolute_p (base_name))
     return fn_tilde_expand (base_name);
 
-  /* Interpolate environment variables and do tilde-expansion. */
+  /* Interpolate environment variables. */
   ds_create (&path, path_);
   fn_interp_vars (&path, fn_getenv);
 
-  tmp_str = fn_tilde_expand (ds_c_str (&path));
-  ds_assign_c_str (&path, tmp_str);
-  free (tmp_str); 
-
   verbose_msg (2, _("searching for \"%s\" in path \"%s\""),
                base_name, ds_c_str (&path));
   while (ds_separate (&path, &dir, PATH_DELIMITER_STRING, &save_idx))
     {
+      /* Do tilde expansion. */
+      if (ds_first (&dir) == '~') 
+        {
+          char *tmp_str = fn_tilde_expand (ds_c_str (&dir));
+          ds_assign_c_str (&dir, tmp_str);
+          free (tmp_str); 
+        }
+
       /* Construct file name. */
       ds_clear (&file);
       if (prefix != NULL && !fn_absolute_p (ds_c_str (&dir)))