+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; UNIX processes inherit a list of name-to-string associations from their
+;; parents called their `environment'; these are commonly used to control
+;; program options. This package permits you to set environment variables
+;; to be passed to any sub-process run under Emacs.
+
+;; Note that the environment string `process-environment' is not
+;; decoded, but the args of `setenv' and `getenv' are normally
+;; multibyte text and get coding conversion.
+
+;;; Code:
+
+;; History list for environment variable names.
+(defvar read-envvar-name-history nil)
+
+(defun read-envvar-name (prompt &optional mustmatch)
+ "Read environment variable name, prompting with PROMPT.
+Optional second arg MUSTMATCH, if non-nil, means require existing envvar name.
+If it is also not t, RET does not exit if it does non-null completion."
+ (completing-read prompt
+ (mapcar (lambda (enventry)
+ (list (if enable-multibyte-characters
+ (decode-coding-string
+ (substring enventry 0
+ (string-match "=" enventry))
+ locale-coding-system t)
+ (substring enventry 0
+ (string-match "=" enventry)))))
+ process-environment)
+ nil mustmatch nil 'read-envvar-name-history))
+
+;; History list for VALUE argument to setenv.
+(defvar setenv-history nil)
+
+
+(defun substitute-env-vars (string)
+ "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
+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.
+
+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)
+ (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)))))
+ (t
+ (setq string (replace-match "$" t t string)
+ start (+ (match-beginning 0) 1)))))
+ string))
+
+;; Fixme: Should `process-environment' be recoded if LC_CTYPE &c is set?
+
+(defun setenv (variable &optional value substitute-env-vars)