changeset 4324:5e526366d533

Don't error on unknown environment variables, #'substitute-in-file-name. SUPERSEDES 18270.47509.666061.606519@parhasard.net APPROVE COMMIT src/fileio.c addition: 2007-12-11 Aidan Kehoe <kehoea@parhasard.net> * fileio.c (Fsubstitute_in_file_name): On encountering non-existent environment variables or incorrect syntax for specifying environment variables (as is routine on Windows) don't error, instead pass the original strings through. tests/ChangeLog addition: 2007-12-11 Aidan Kehoe <kehoea@parhasard.net> * automated/syntax-tests.el: Check that substitute-in-file-name doesn't error when handed non-existing environment variables, passing through the specified string instead. Also check that existing environment variables are correctly substituted. Also check that double slashes in the middle of a path name are treated as re-starting the path.
author Aidan Kehoe <kehoea@parhasard.net>
date Tue, 11 Dec 2007 21:50:22 +0100
parents 94509abd0ef0
children 948c9b232595
files src/ChangeLog src/fileio.c tests/ChangeLog tests/automated/syntax-tests.el
diffstat 4 files changed, 105 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Tue Dec 11 21:41:54 2007 +0100
+++ b/src/ChangeLog	Tue Dec 11 21:50:22 2007 +0100
@@ -1,3 +1,10 @@
+2007-12-11  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fileio.c (Fsubstitute_in_file_name):
+	On encountering non-existent environment variables or incorrect
+	syntax for specifying environment variables (as is routine on
+	Windows) don't error, instead pass the original strings through.
+
 2007-12-05  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* search.c (simple_search): Fix underrun in reverse search.
--- a/src/fileio.c	Tue Dec 11 21:41:54 2007 +0100
+++ b/src/fileio.c	Tue Dec 11 21:50:22 2007 +0100
@@ -1518,10 +1518,10 @@
   /* This function can GC.  GC checked 2000-07-28 ben. */
   Ibyte *nm;
 
-  Ibyte *s, *p, *o, *x, *endp;
+  Ibyte *s, *p, *o, *x, *endp, *got;
   Ibyte *target = 0;
   int total = 0;
-  int substituted = 0;
+  int substituted = 0, seen_braces;
   Ibyte *xnm;
   Lisp_Object handler;
 
@@ -1576,7 +1576,10 @@
       {
 	p++;
 	if (p == endp)
-	  goto badsubst;
+	  {
+	    /* No substitution, no error. */
+	    break;
+	  }
 	else if (*p == '$')
 	  {
 	    /* "$$" means a single "$" */
@@ -1589,7 +1592,12 @@
 	  {
 	    o = ++p;
 	    while (p != endp && *p != '}') p++;
-	    if (*p != '}') goto missingclose;
+	    if (*p != '}')
+	      {
+		/* No substitution, no error. Keep looking. */
+		p = o;
+		continue;
+	      }
 	    s = p;
 	  }
 	else
@@ -1608,10 +1616,12 @@
 #endif /* WIN32_NATIVE */
 
 	/* Get variable value */
-	o = egetenv ((CIbyte *) target);
-	if (!o) goto badvar;
-	total += qxestrlen (o);
-	substituted = 1;
+	got = egetenv ((CIbyte *) target);
+	if (got)
+	  {
+	    total += qxestrlen (got);
+	    substituted = 1;
+	  }
       }
 
   if (!substituted)
@@ -1629,8 +1639,12 @@
     else
       {
 	p++;
+	seen_braces = 0;
 	if (p == endp)
-	  goto badsubst;
+	  {
+	    *x++ = '$';
+	    break;
+	  }
 	else if (*p == '$')
 	  {
 	    *x++ = *p++;
@@ -1638,9 +1652,16 @@
 	  }
 	else if (*p == '{')
 	  {
+	    seen_braces = 1;
 	    o = ++p;
 	    while (p != endp && *p != '}') p++;
-	    if (*p != '}') goto missingclose;
+	    if (*p != '}')
+	      {
+		/* Don't syntax error, don't substitute */
+		*x++ = '{';
+		p = o;
+		continue;
+	      }
 	    s = p++;
 	  }
 	else
@@ -1659,12 +1680,30 @@
 #endif /* WIN32_NATIVE */
 
 	/* Get variable value */
-	o = egetenv ((CIbyte *) target);
-	if (!o)
-	  goto badvar;
-
-	qxestrcpy (x, o);
-	x += qxestrlen (o);
+	got = egetenv ((CIbyte *) target);
+	if (got)
+	  {
+	    qxestrcpy (x, got);
+	    x += qxestrlen (got);
+	  }
+	else
+	  {
+	    *x++ = '$';
+	    if (seen_braces)
+	      {
+		*x++ = '{';
+                /* Preserve the original case. */
+		qxestrncpy (x, o, s - o);
+		x += s - o;
+		*x++ = '}';
+	      }
+	    else
+	      {
+                /* Preserve the original case. */
+		qxestrncpy (x, o, s - o);
+		x += s - o;
+	      }
+	  }
       }
 
   *x = 0;
@@ -1689,17 +1728,6 @@
 #endif
 
   return make_string (xnm, x - xnm);
-
- badsubst:
-  syntax_error ("Bad format environment-variable substitution", filename);
- missingclose:
-  syntax_error ("Missing \"}\" in environment-variable substitution",
-		filename);
- badvar:
-  syntax_error_2 ("Substituting nonexistent environment variable",
-		  filename, build_intstring (target));
-
-  RETURN_NOT_REACHED (Qnil);
 }
 
 /* A slightly faster and more convenient way to get
--- a/tests/ChangeLog	Tue Dec 11 21:41:54 2007 +0100
+++ b/tests/ChangeLog	Tue Dec 11 21:50:22 2007 +0100
@@ -1,3 +1,12 @@
+2007-12-11  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/syntax-tests.el:
+	Check that substitute-in-file-name doesn't error when handed
+	non-existing environment variables, passing through the specified
+	string instead. Also check that existing environment variables are
+	correctly substituted. Also check that double slashes in the
+	middle of a path name are treated as re-starting the path. 
+
 2007-12-10  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* reproduce-bugs.el (reproduce-bug): Add bug 10, crash in search.
--- a/tests/automated/syntax-tests.el	Tue Dec 11 21:41:54 2007 +0100
+++ b/tests/automated/syntax-tests.el	Tue Dec 11 21:50:22 2007 +0100
@@ -205,3 +205,37 @@
     ;; special-case check that point didn't move
     (Assert (= (point) 25))))
 
+(loop
+  with envvar-not-existing = (symbol-name (gensym "whatever"))
+  with envvar-existing = (symbol-name (gensym "whatever"))
+  with envvar-existing-val = (make-string #x10000 ?\xe1)
+  with examples = 
+  (list (list (format "%chome%cwhatever%c%chi-there%c$%s"
+                      directory-sep-char
+                      directory-sep-char
+                      directory-sep-char
+                      directory-sep-char
+                      directory-sep-char
+                      envvar-existing)
+              (format "%chi-there%c%s"
+                      directory-sep-char
+                      directory-sep-char
+                      envvar-existing-val))
+        (if (memq system-type '(windows-nt cygwin32))
+            '("//network-path/c$" "//network-path/c$")
+          '("/network-path/c$" "/network-path/c$"))
+        (list (format "/home/whoever/$%s" envvar-not-existing)
+              (format "/home/whoever/$%s" envvar-not-existing))
+        (list (format "/home/whoever/$%s" envvar-existing)
+              (format "/home/whoever/%s" envvar-existing-val))
+        (list (format "/home/whoever/${%s}" envvar-existing)
+              (format "/home/whoever/%s" envvar-existing-val))
+        (list (format "/home/whoever/${%s}" envvar-not-existing)
+              (format "/home/whoever/${%s}" envvar-not-existing)))
+  initially (progn (setenv envvar-not-existing nil t)
+                   (setenv envvar-existing envvar-existing-val))
+  for (pre post)
+  in examples
+  do 
+  (Assert (string= post (substitute-in-file-name pre))))
+