]> code.delx.au - gnu-emacs/blobdiff - lisp/env.el
Update copyright year to 2016
[gnu-emacs] / lisp / env.el
index 9e3aed95f8a4aa8699ab2e3b791077eba43677f6..6c39f825c3c775176a1ba7ca2310bfc16ccbcfd1 100644 (file)
@@ -1,8 +1,8 @@
-;;; env.el --- functions to manipulate environment variables
+;;; env.el --- functions to manipulate environment variables  -*- lexical-binding:t -*-
 
-;; Copyright (C) 1991, 1994, 2000-2013 Free Software Foundation, Inc.
+;; Copyright (C) 1991, 1994, 2000-2016 Free Software Foundation, Inc.
 
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: processes, unix
 ;; Package: emacs
 
@@ -57,8 +57,10 @@ If it is also not t, RET does not exit if it does non-null completion."
 ;; History list for VALUE argument to setenv.
 (defvar setenv-history nil)
 
+(defconst env--substitute-vars-regexp
+  "\\$\\(?:\\(?1:[[:alnum:]_]+\\)\\|{\\(?1:[^{}]+\\)}\\|\\$\\)")
 
-(defun substitute-env-vars (string)
+(defun substitute-env-vars (string &optional when-undefined)
   "Substitute environment variables referred to in STRING.
 `$FOO' where FOO is an environment variable name means to substitute
 the value of that variable.  The variable name should be terminated
@@ -66,27 +68,38 @@ with a character not a letter, digit or underscore; otherwise, enclose
 the entire variable name in braces.  For instance, in `ab$cd-x',
 `$cd' is treated as an environment variable.
 
+If WHEN-DEFINED is nil, references to undefined environment variables
+are replaced by the empty string; if it is a function, the function is called
+with the variable name as argument and should return the text with which
+to replace it or nil to leave it unchanged.
+If it is non-nil and not a function, references to undefined variables are
+left unchanged.
+
 Use `$$' to insert a single dollar sign."
   (let ((start 0))
-    (while (string-match
-           (eval-when-compile
-             (rx (or (and "$" (submatch (1+ (regexp "[[:alnum:]_]"))))
-                     (and "${" (submatch (minimal-match (0+ anything))) "}")
-                     "$$")))
-           string start)
+    (while (string-match env--substitute-vars-regexp string start)
       (cond ((match-beginning 1)
-            (let ((value (getenv (match-string 1 string))))
-              (setq string (replace-match (or value "") t t string)
-                    start (+ (match-beginning 0) (length value)))))
-           ((match-beginning 2)
-            (let ((value (getenv (match-string 2 string))))
-              (setq string (replace-match (or value "") t t string)
-                    start (+ (match-beginning 0) (length value)))))
+            (let* ((var (match-string 1 string))
+                    (value (getenv var)))
+               (if (and (null value)
+                        (if (functionp when-undefined)
+                            (null (setq value (funcall when-undefined var)))
+                          when-undefined))
+                   (setq start (match-end 0))
+                 (setq string (replace-match (or value "") t t string)
+                       start (+ (match-beginning 0) (length value))))))
            (t
             (setq string (replace-match "$" t t string)
                   start (+ (match-beginning 0) 1)))))
     string))
 
+(defun substitute-env-in-file-name (filename)
+  (substitute-env-vars filename
+                       ;; How 'bout we lookup other tables than the env?
+                       ;; E.g. we could accept bookmark names as well!
+                       (if (memq system-type '(windows-nt ms-dos))
+                           (lambda (var) (getenv (upcase var)))
+                         t)))
 
 (defun setenv-internal (env variable value keep-empty)
   "Set VARIABLE to VALUE in ENV, adding empty entries if KEEP-EMPTY.
@@ -185,7 +198,7 @@ VARIABLE should be a string.  Value is nil if VARIABLE is undefined in
 the environment.  Otherwise, value is a string.
 
 If optional parameter FRAME is non-nil, then it should be a
-frame.  This function will look up VARIABLE in its 'environment
+frame.  This function will look up VARIABLE in its `environment'
 parameter.
 
 Otherwise, this function searches `process-environment' for