[Git][cmucl/cmucl][issue-139-use-lang-to-set-external-format] Recognize LC_ALL and LC_MESSAGES for setting encodings

Raymond Toy (@rtoy) gitlab at common-lisp.net
Sat Oct 1 23:24:57 UTC 2022



Raymond Toy pushed to branch issue-139-use-lang-to-set-external-format at cmucl / cmucl


Commits:
48c9afad by Raymond Toy at 2022-10-01T16:24:35-07:00
Recognize LC_ALL and LC_MESSAGES for setting encodings

We look for LC_ALL and LC_MESSAGES (in that order) for encodings.  The
fallback is LANG.

We also recognize C and POSIX which mean ISO8859-1 encodings.

Finally, if LANG and friends starts with a "/" for a path, we ignore
the setting and just use the default encodings.

- - - - -


1 changed file:

- src/code/save.lisp


Changes:

=====================================
src/code/save.lisp
=====================================
@@ -147,23 +147,50 @@
   codeset from LANG will be used to set *DEFAULT-EXTERNAL-FORMAT* and
   sets the terminal and file name encoding to the specified codeset.
   If Quiet is non-NIL, then messages will be suppressed."
-  (let ((lang (unix:unix-getenv "LANG")))
+  ;; Find the envvar that will tell us what encoding to use.
+  ;;
+  ;; See https://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html
+  ;;
+  (let* ((lang (or (unix:unix-getenv "LC_ALL")
+		   (unix:unix-getenv "LC_MESSAGES")
+		   (unix:unix-getenv "LANG")))
+	 (length (length lang)))
+    ;; If LANG isn't set, we don't need to do anything and just use
+    ;; the builtin defaults.
     (when lang
-      ;; Simple parsing of LANG.
-      (let ((dot (position #\. lang))
-	    (at (or (position #\@ lang) nil)))
-	(when dot
-	  (let* ((codeset (subseq lang (1+ dot) at))
-		 (format (intern codeset "KEYWORD")))
-	    (cond ((stream::find-external-format format nil)
-		   (unless quiet
-		     (write-string "Default external format and filename encoding: ")
-		     (princ format)
-		     (terpri))
-		   (setf *default-external-format* format)
-		   (set-system-external-format format format))
-		  (t
-		   (warn "Unknown or unsupported external format: ~S" codeset)))))))))
+      (cond
+	((or (string-equal "C" lang :end2 (min 1 length))
+	     (string-equal "POSIX" lang :end2 (min 5 length)))
+	 ;; If the lang is "C" or "POSIX", ignoring anything after
+	 ;; that, we need to set the format accordingly.
+	 (setf *default-external-format* :iso8859-1)
+	 (set-system-external-format :iso8859-1 nil))
+	((string-equal "/" lang :end2 (min 1 length))
+	 ;; Also, we don't handle the case where the locale starts
+	 ;; with a slash which means a pathname to a file created by
+	 ;; the localdef utility.  So use our defaults for that case
+	 ;; as well.
+	 (setf *default-external-format* :iso8859-1)
+	 (set-system-external-format :iso8859-1 nil))
+	(t
+	 ;; Simple parsing of LANG.  We assume it looks like
+	 ;; "language[_territory][.codeset]".  We're only interested
+	 ;; in the codeset, if given.  Some LC_ vars also have an
+	 ;; optional @modifier after the codeset; we ignore that too.
+	 (let ((dot (position #\. lang))
+	       (at (or (position #\@ lang) nil)))
+	   (when dot
+	     (let* ((codeset (subseq lang (1+ dot) at))
+		    (format (intern codeset "KEYWORD")))
+	       (cond ((stream::find-external-format format nil)
+		      (unless quiet
+			(write-string "Default external format and filename encoding: ")
+			(princ format)
+			(terpri))
+		      (setf *default-external-format* format)
+		      (set-system-external-format format format))
+		     (t
+		      (warn "Unknown or unsupported external format: ~S" codeset)))))))))))
 
 (defun save-lisp (core-file-name &key
 				 (purify t)



View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/commit/48c9afadb56bc3d3da9c0bb9fd7490f5ee09feb6

-- 
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/commit/48c9afadb56bc3d3da9c0bb9fd7490f5ee09feb6
You're receiving this email because of your account on gitlab.common-lisp.net.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cmucl-cvs/attachments/20221001/7cefc6fb/attachment-0001.html>


More information about the cmucl-cvs mailing list