changeset 49968:80ed3e75ba10

(read-envvar-name): Decode names. (substitute-env-vars): Use eval-when-compile and char class. (setenv): Doc fix. Encode the data (after checking that's possible). (getenv): Encode the name and decode the result.
author Dave Love <fx@gnu.org>
date Mon, 24 Feb 2003 22:51:41 +0000
parents 4d32fa2a523d
children 1f508e24a50f
files lisp/env.el
diffstat 1 files changed, 43 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/env.el	Mon Feb 24 22:49:24 2003 +0000
+++ b/lisp/env.el	Mon Feb 24 22:51:41 2003 +0000
@@ -1,6 +1,6 @@
 ;;; env.el --- functions to manipulate environment variables
 
-;; Copyright (C) 1991, 1994, 2000, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 1991, 1994, 2000, 2001, 2003 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: processes, unix
@@ -29,6 +29,10 @@
 ;; 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.
@@ -39,10 +43,14 @@
 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 (function
-			    (lambda (enventry)
-			      (list (substring enventry 0
-					       (string-match "=" enventry)))))
+		   (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))
 
@@ -59,9 +67,10 @@
 dollar sign."
   (let ((start 0))
     (while (string-match
-	    (rx (or (and "$" (submatch (1+ (in "a-zA-Z0-9_"))))
-		    (and "${" (submatch (minimal-match (0+ anything))) "}")
-		    "$$"))
+	    (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))))
@@ -76,6 +85,7 @@
 		   start (+ (match-beginning 0) 1)))))
     string))
 
+;; Fixme: Should `process-environment' be recoded if LC_CTYPE &c is set?
 
 (defun setenv (variable &optional value unset substitute-env-vars)
   "Set the value of the environment variable named VARIABLE to VALUE.
@@ -92,7 +102,10 @@
 appears at the front of the history list when you type in the new value.
 Interactively, always replace environment variables in the new value.
 
-This function works by modifying `process-environment'."
+This function works by modifying `process-environment'.
+
+As a special case, setting variable `TZ' calls `set-time-zone-rule' as
+a side-effect."
   (interactive
    (if current-prefix-arg
        (list (read-envvar-name "Clear environment variable: " 'exact) nil t)
@@ -107,10 +120,22 @@
 				   value)
 	     nil
 	     t))))
-  (if unset
+  (if (and (multibyte-string-p variable) locale-coding-system)
+      (unless (memq (coding-system-base locale-coding-system)
+		    (find-coding-systems-string (concat variable value)))
+	(error "Can't encode `%s=%s' with `locale-coding-system'"
+	       variable (or value "")))
+    (unless (memq 'undecided (find-coding-systems-string variable))
+      (error "Can't encode `%s=%s' with unspecified `locale-coding-system'"
+	     variable (or value ""))))
+  (if unset 
       (setq value nil)
     (if substitute-env-vars
 	(setq value (substitute-env-vars value))))
+  (if (multibyte-string-p variable)
+      (setq variable (encode-coding-string variable locale-coding-system)))
+  (if (and value (multibyte-string-p value))
+      (setq value (encode-coding-string value locale-coding-system)))
   (if (string-match "=" variable)
       (error "Environment variable name `%s' contains `='" variable)
     (let ((pattern (concat "\\`" (regexp-quote (concat variable "="))))
@@ -123,7 +148,8 @@
 	(cond ((string-match pattern (car scan))
 	       (setq found t)
 	       (if (eq nil value)
-		   (setq process-environment (delq (car scan) process-environment))
+		   (setq process-environment (delq (car scan)
+						   process-environment))
 		 (setcar scan (concat variable "=" value)))
 	       (setq scan nil)))
 	(setq scan (cdr scan)))
@@ -142,7 +168,12 @@
 This function consults the variable `process-environment'
 for its value."
   (interactive (list (read-envvar-name "Get environment variable: " t)))
-  (let ((value (getenv-internal variable)))
+  (let ((value (getenv-internal (if (multibyte-string-p variable)
+				    (encode-coding-string
+				     variable locale-coding-system)
+				  variable))))
+    (if (and enable-multibyte-characters value)
+	(setq value (decode-coding-string value locale-coding-system)))
     (when (interactive-p)
       (message "%s" (if value value "Not set")))
     value))