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

Commits:

1 changed file:

Changes:

  • src/code/save.lisp
    ... ... @@ -147,23 +147,50 @@
    147 147
       codeset from LANG will be used to set *DEFAULT-EXTERNAL-FORMAT* and
    
    148 148
       sets the terminal and file name encoding to the specified codeset.
    
    149 149
       If Quiet is non-NIL, then messages will be suppressed."
    
    150
    -  (let ((lang (unix:unix-getenv "LANG")))
    
    150
    +  ;; Find the envvar that will tell us what encoding to use.
    
    151
    +  ;;
    
    152
    +  ;; See https://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html
    
    153
    +  ;;
    
    154
    +  (let* ((lang (or (unix:unix-getenv "LC_ALL")
    
    155
    +		   (unix:unix-getenv "LC_MESSAGES")
    
    156
    +		   (unix:unix-getenv "LANG")))
    
    157
    +	 (length (length lang)))
    
    158
    +    ;; If LANG isn't set, we don't need to do anything and just use
    
    159
    +    ;; the builtin defaults.
    
    151 160
         (when lang
    
    152
    -      ;; Simple parsing of LANG.
    
    153
    -      (let ((dot (position #\. lang))
    
    154
    -	    (at (or (position #\@ lang) nil)))
    
    155
    -	(when dot
    
    156
    -	  (let* ((codeset (subseq lang (1+ dot) at))
    
    157
    -		 (format (intern codeset "KEYWORD")))
    
    158
    -	    (cond ((stream::find-external-format format nil)
    
    159
    -		   (unless quiet
    
    160
    -		     (write-string "Default external format and filename encoding: ")
    
    161
    -		     (princ format)
    
    162
    -		     (terpri))
    
    163
    -		   (setf *default-external-format* format)
    
    164
    -		   (set-system-external-format format format))
    
    165
    -		  (t
    
    166
    -		   (warn "Unknown or unsupported external format: ~S" codeset)))))))))
    
    161
    +      (cond
    
    162
    +	((or (string-equal "C" lang :end2 (min 1 length))
    
    163
    +	     (string-equal "POSIX" lang :end2 (min 5 length)))
    
    164
    +	 ;; If the lang is "C" or "POSIX", ignoring anything after
    
    165
    +	 ;; that, we need to set the format accordingly.
    
    166
    +	 (setf *default-external-format* :iso8859-1)
    
    167
    +	 (set-system-external-format :iso8859-1 nil))
    
    168
    +	((string-equal "/" lang :end2 (min 1 length))
    
    169
    +	 ;; Also, we don't handle the case where the locale starts
    
    170
    +	 ;; with a slash which means a pathname to a file created by
    
    171
    +	 ;; the localdef utility.  So use our defaults for that case
    
    172
    +	 ;; as well.
    
    173
    +	 (setf *default-external-format* :iso8859-1)
    
    174
    +	 (set-system-external-format :iso8859-1 nil))
    
    175
    +	(t
    
    176
    +	 ;; Simple parsing of LANG.  We assume it looks like
    
    177
    +	 ;; "language[_territory][.codeset]".  We're only interested
    
    178
    +	 ;; in the codeset, if given.  Some LC_ vars also have an
    
    179
    +	 ;; optional @modifier after the codeset; we ignore that too.
    
    180
    +	 (let ((dot (position #\. lang))
    
    181
    +	       (at (or (position #\@ lang) nil)))
    
    182
    +	   (when dot
    
    183
    +	     (let* ((codeset (subseq lang (1+ dot) at))
    
    184
    +		    (format (intern codeset "KEYWORD")))
    
    185
    +	       (cond ((stream::find-external-format format nil)
    
    186
    +		      (unless quiet
    
    187
    +			(write-string "Default external format and filename encoding: ")
    
    188
    +			(princ format)
    
    189
    +			(terpri))
    
    190
    +		      (setf *default-external-format* format)
    
    191
    +		      (set-system-external-format format format))
    
    192
    +		     (t
    
    193
    +		      (warn "Unknown or unsupported external format: ~S" codeset)))))))))))
    
    167 194
     
    
    168 195
     (defun save-lisp (core-file-name &key
    
    169 196
     				 (purify t)