# HG changeset patch # User Aidan Kehoe # Date 1197406222 -3600 # Node ID 5e526366d5332103a24a7af2fd0bb0c8a773e3b6 # Parent 94509abd0ef06178d898dd2af041c96eb3c5436e 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 * 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 * 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. diff -r 94509abd0ef0 -r 5e526366d533 src/ChangeLog --- 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 + + * 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 * search.c (simple_search): Fix underrun in reverse search. diff -r 94509abd0ef0 -r 5e526366d533 src/fileio.c --- 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 diff -r 94509abd0ef0 -r 5e526366d533 tests/ChangeLog --- 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 + + * 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 * reproduce-bugs.el (reproduce-bug): Add bug 10, crash in search. diff -r 94509abd0ef0 -r 5e526366d533 tests/automated/syntax-tests.el --- 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)))) +