Raymond Toy pushed to branch issue-139-add-alias-local-external-format at cmucl / cmucl

Commits:

4 changed files:

Changes:

  • src/code/intl.lisp
    ... ... @@ -105,7 +105,7 @@
    105 105
     
    
    106 106
     (defun find-encoding (domain)
    
    107 107
       (when (null (domain-entry-encoding domain))
    
    108
    -    (setf (domain-entry-encoding domain) :iso-8859-1)
    
    108
    +    (setf (domain-entry-encoding domain) :iso8859-1)
    
    109 109
         ;; Domain lookup can call the compiler, so set the locale to "C"
    
    110 110
         ;; so things work.
    
    111 111
         (let* ((*locale* "C")
    

  • src/code/save.lisp
    ... ... @@ -145,53 +145,25 @@
    145 145
     (defun set-up-locale-external-format ()
    
    146 146
       "Add external format alias for :locale to the format specified by
    
    147 147
       the envvar LANG and friends if available."
    
    148
    -  ;; Find the envvar that will tell us what encoding to use.
    
    149
    -  ;;
    
    150
    -  ;; See https://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html
    
    151
    -  ;;
    
    152
    -  (let* ((lang (or (unix:unix-getenv "LC_ALL")
    
    153
    -                   (unix:unix-getenv "LC_MESSAGES")
    
    154
    -                   (unix:unix-getenv "LANG")))
    
    155
    -         (length (length lang)))
    
    156
    -    ;; If LANG isn't set, just set :locale to alias to the
    
    157
    -    ;; default-external-format.
    
    158
    -    (unless lang
    
    159
    -      (setf (gethash :locale stream::*external-format-aliases*) *default-external-format*)
    
    160
    -      (return-from set-up-locale-external-format (values)))
    
    161
    -    ;; Extract the external format from the envvar and set up the
    
    162
    -    ;; :locale alias.
    
    163
    -    (let ((new-alias
    
    164
    -	    (cond
    
    165
    -	      ((or (string-equal "C" lang :end2 (min 1 length))
    
    166
    -		   (string-equal "POSIX" lang :end2 (min 5 length)))
    
    167
    -	       ;; If the lang is "C" or "POSIX", ignoring anything after
    
    168
    -	       ;; that, default to :iso8859-1.
    
    169
    -	       :iso8859-1)
    
    170
    -	      ((string-equal "/" lang :end2 (min 1 length))
    
    171
    -	       ;; Also, we don't handle the case where the locale starts
    
    172
    -	       ;; with a slash which means a pathname to a file created by
    
    173
    -	       ;; the localedef utility.  So use our defaults for that case
    
    174
    -	       ;; as well.
    
    175
    -	       :iso8859-1)
    
    176
    -	      (t
    
    177
    -	       ;; Simple parsing of LANG.  We assume it looks like
    
    178
    -	       ;; "language[_territory][.codeset]".  We're only interested
    
    179
    -	       ;; in the codeset, if given.  Some LC_ vars also have an
    
    180
    -	       ;; optional @modifier after the codeset; we ignore that too.
    
    181
    -	       (let ((dot (position #\. lang))
    
    182
    -		     (at (or (position #\@ lang) nil)))
    
    183
    -		 (when dot
    
    184
    -		   (let* ((codeset (subseq lang (1+ dot) at))
    
    185
    -			  (format (intern codeset "KEYWORD")))
    
    186
    -		     (cond ((stream::find-external-format format nil)
    
    187
    -			    format)
    
    188
    -			   (t
    
    189
    -			    (warn "Unknown or unsupported external format: ~S"
    
    190
    -				  codeset)
    
    191
    -			    *default-external-format*)))))))))
    
    192
    -      (assert new-alias)
    
    193
    -      (setf (gethash :locale stream::*external-format-aliases*) new-alias))
    
    194
    -    (values)))
    
    148
    +  (let ((codeset (unix::unix-get-locale-codeset)))
    
    149
    +    (cond ((zerop (length codeset))
    
    150
    +	   ;; Codeset was the empty string, so just set :locale to
    
    151
    +	   ;; alias to the default external format.  
    
    152
    +	   (setf (gethash :locale stream::*external-format-aliases*)
    
    153
    +		 *default-external-format*))
    
    154
    +	  (t
    
    155
    +	   (let ((codeset-format (intern codeset "KEYWORD")))
    
    156
    +	     ;; If we know the format, we can set the alias.
    
    157
    +	     ;; Otherwise, print a warning and use :iso8859-1 as the
    
    158
    +	     ;; alias.
    
    159
    +	     (setf (gethash :locale stream::*external-format-aliases*)
    
    160
    +		   (if (stream::find-external-format codeset-format nil)
    
    161
    +		       codeset-format
    
    162
    +		       (progn
    
    163
    +			 (warn "Unsupported external format; using :iso8859-1 instead: ~S"
    
    164
    +			       codeset-format)
    
    165
    +			 :iso8859-1)))))))
    
    166
    +  (values))
    
    195 167
     
    
    196 168
      
    
    197 169
     (defun save-lisp (core-file-name &key
    
    ... ... @@ -301,6 +273,7 @@
    301 273
     	     (reinit)
    
    302 274
     	     (environment-init)
    
    303 275
     	     (dolist (f *after-save-initializations*) (funcall f))
    
    276
    +	     (stream::load-external-format-aliases)
    
    304 277
     	     (intl::setlocale)
    
    305 278
     	     (ext::process-command-strings process-command-line)
    
    306 279
     	     (setf *editor-lisp-p* nil)
    

  • src/code/unix.lisp
    ... ... @@ -2893,3 +2893,13 @@
    2893 2893
        of the child in the parent if it works, or NIL and an error number if it
    
    2894 2894
        doesn't work."
    
    2895 2895
       (int-syscall ("fork")))
    
    2896
    +
    
    2897
    +(defun unix-get-locale-codeset ()
    
    2898
    +  _N"Get the codeset from the locale"
    
    2899
    +  (with-alien ((codeset (array c-call:char 512)))
    
    2900
    +    (alien-funcall
    
    2901
    +	    (extern-alien "os_get_locale_codeset"
    
    2902
    +			  (function void (* char) int))
    
    2903
    +	    (cast codeset (* c-call:char))
    
    2904
    +	    512)
    
    2905
    +    (cast codeset c-string)))

  • src/lisp/os-common.c
    ... ... @@ -7,6 +7,8 @@
    7 7
     
    
    8 8
     #include <assert.h>
    
    9 9
     #include <errno.h>
    
    10
    +#include <langinfo.h>
    
    11
    +#include <locale.h>
    
    10 12
     #include <math.h>
    
    11 13
     #include <netdb.h>
    
    12 14
     #include <pwd.h>
    
    ... ... @@ -773,3 +775,15 @@ exit:
    773 775
         
    
    774 776
         return result;
    
    775 777
     }
    
    778
    +
    
    779
    +void
    
    780
    +os_get_locale_codeset(char* codeset, int len)
    
    781
    +{
    
    782
    +    char *code;
    
    783
    +    
    
    784
    +    setlocale(LC_ALL, "");
    
    785
    +
    
    786
    +    code = nl_langinfo(CODESET);
    
    787
    +
    
    788
    +    strncpy(codeset, code, len);
    
    789
    +}