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

Commits:

6 changed files:

Changes:

  • src/code/commandline.lisp
    ... ... @@ -339,16 +339,54 @@
    339 339
     (defun help-switch-demon (switch)
    
    340 340
       (declare (ignore switch))
    
    341 341
       (format t (intl:gettext "~&Usage: ~A <options>~2%") *command-line-utility-name*)
    
    342
    -  (dolist (s (sort *legal-cmd-line-switches* #'string<
    
    343
    -		   :key #'car))
    
    344
    -    (destructuring-bind (name doc arg)
    
    345
    -	s
    
    346
    -      (format t "    -~A ~@[~A~]~%" name (if arg (intl:gettext arg)))
    
    347
    -      ;; Poor man's formatting of the help string
    
    348
    -      (with-input-from-string (stream (intl:gettext doc))
    
    349
    -	(loop for line = (read-line stream nil nil)
    
    350
    -	   while line
    
    351
    -	   do (format t "~8T~A~%" line)))))
    
    342
    +  (flet
    
    343
    +      ((get-words (s)
    
    344
    +	 (declare (string s))
    
    345
    +	 ;; Return a list of all the words from S.  A word is defined
    
    346
    +	 ;; as any sequence of characters separated from others by
    
    347
    +	 ;; whitespace consisting of space, newline, tab, formfeed, or
    
    348
    +	 ;; carriage return.
    
    349
    +	 (let ((end (length s)))
    
    350
    +	   (loop for left = 0 then (+ right 1)
    
    351
    +		 for right = (or
    
    352
    +			      (position-if #'(lambda (c)
    
    353
    +					       (member c
    
    354
    +						       '(#\space #\newline #\tab #\ff #\cr)))
    
    355
    +					   s
    
    356
    +					   :start left)
    
    357
    +			      end)
    
    358
    +		 ;; Collect the word bounded by left and right in a list.
    
    359
    +		 unless (and (= right left))
    
    360
    +		   collect (subseq s left right) into subseqs
    
    361
    +		 ;; Keep going until we reach the end of the string.
    
    362
    +		 until (>= right end)
    
    363
    +		 finally (return subseqs)))))
    
    364
    +
    
    365
    +    (dolist (s (sort *legal-cmd-line-switches* #'string<
    
    366
    +		     :key #'car))
    
    367
    +      (destructuring-bind (name doc arg)
    
    368
    +	  s
    
    369
    +	(format t "    -~A ~@[~A~]~%" name (if arg (intl:gettext arg)))
    
    370
    +	;; Poor man's formatting of the help string
    
    371
    +	(let ((*print-right-margin* 80))
    
    372
    +	  ;; Extract all the words from the string and print them out
    
    373
    +	  ;; one by one with a space between each, wrapping the output
    
    374
    +	  ;; if needed.  Each line is indented by 8 spaces.
    
    375
    +	  ;;
    
    376
    +	  ;; "~@<       ~@;"
    
    377
    +	  ;;    per-line prefix of spaces and pass the whole arg list
    
    378
    +	  ;;    to this directive.
    
    379
    +	  ;;
    
    380
    +	  ;; "~{~A~^ ~}"
    
    381
    +	  ;;    loop over each word and print out the word followed by
    
    382
    +	  ;;    a space.
    
    383
    +	  ;;
    
    384
    +	  ;; "~:@>"
    
    385
    +	  ;;    No suffix, and insert conditional newline after each
    
    386
    +	  ;;    group of blanks if needed.
    
    387
    +	  (format t "~@<        ~@;~{~A~^ ~}~:@>"
    
    388
    +		  (get-words (intl:gettext doc))))
    
    389
    +	(terpri))))
    
    352 390
       (ext:quit))
    
    353 391
       
    
    354 392
     (defswitch "help" #'help-switch-demon
    

  • src/code/intl.lisp
    ... ... @@ -520,10 +520,7 @@
    520 520
     
    
    521 521
     (defun setlocale (&optional locale)
    
    522 522
       (setf *locale* (or locale
    
    523
    -		     (getenv "LANGUAGE")
    
    524
    -		     (getenv "LC_ALL")
    
    525
    -		     (getenv "LC_MESSAGES")
    
    526
    -		     (getenv "LANG")
    
    523
    +		     (unix::unix-get-lc-messages)
    
    527 524
     		     *locale*)))
    
    528 525
     
    
    529 526
     (defmacro textdomain (domain)
    

  • src/code/unix.lisp
    ... ... @@ -2900,6 +2900,22 @@
    2900 2900
        (alien:extern-alien "os_setlocale"
    
    2901 2901
     		       (function c-call:int))))
    
    2902 2902
     
    
    2903
    +(defun unix-get-lc-messages ()
    
    2904
    +  _N"Get LC_MESSAGES from the current locale.  If we can't, return
    
    2905
    +  NIL.  A call to UNIX-SETLOCALE must have been done previously before
    
    2906
    +  calling this so that the correct locale is returned."
    
    2907
    +  (with-alien ((buf (array c-call:char 256)))
    
    2908
    +    (let ((result
    
    2909
    +	    (alien-funcall
    
    2910
    +	     (extern-alien "os_get_lc_messages"
    
    2911
    +			   (function c-call:int
    
    2912
    +				     (* c-call:char)
    
    2913
    +				     c-call:int))
    
    2914
    +	     (cast buf (* c-call:char))
    
    2915
    +	     256)))
    
    2916
    +      (when (zerop result)
    
    2917
    +	(cast buf c-call:c-string)))))
    
    2918
    +
    
    2903 2919
     (defun unix-get-locale-codeset ()
    
    2904 2920
       _N"Get the codeset from the locale"
    
    2905 2921
       (with-alien ((codeset (array c-call:char 512)))
    

  • src/general-info/release-21e.md
    ... ... @@ -59,11 +59,12 @@ public domain.
    59 59
         * ~~#132~~ Ansi test `RENAME-FILE.1` no fails
    
    60 60
         * ~~#134~~ Handle the case of `(expt complex complex-rational)`
    
    61 61
         * ~~#136~~ `ensure-directories-exist` should return the given pathspec
    
    62
    -    * #139 `*default-external-format*` defaults to `:utf-8`
    
    63
    -    * #139 add alias for `:locale` external format
    
    62
    +    * #139 `*default-external-format*` defaults to `:utf-8`; add alias for `:locale` external format
    
    63
    +    * ~~#141~~ Disallow locales that are pathnames to a localedef file
    
    64 64
         * ~~#142~~ `(random 0)` signals incorrect error
    
    65 65
         * ~~#147~~ `stream-line-column` method missing for `fundamental-character-output-stream`
    
    66 66
         * ~~#149~~ Call setlocale(3C) on startup
    
    67
    +    * ~~#155~~ Wrap help strings neatly
    
    67 68
       * Other changes:
    
    68 69
       * Improvements to the PCL implementation of CLOS:
    
    69 70
       * Changes to building procedure:
    

  • src/lisp/os-common.c
    ... ... @@ -785,6 +785,19 @@ os_setlocale(void)
    785 785
         return result != NULL ? 0 : -1;
    
    786 786
     }
    
    787 787
     
    
    788
    +int
    
    789
    +os_get_lc_messages(char *buf, int len)
    
    790
    +{
    
    791
    +    char *locale = setlocale(LC_MESSAGES, NULL);
    
    792
    +    if (locale) {
    
    793
    +        strncpy(buf, locale, len - 1);
    
    794
    +        buf[len - 1] = '\0';
    
    795
    +    }
    
    796
    +
    
    797
    +    /* Return -1 if setlocale failed. */
    
    798
    +    return locale ? 0 : -1;
    
    799
    +}
    
    800
    +
    
    788 801
     void
    
    789 802
     os_get_locale_codeset(char* codeset, int len)
    
    790 803
     {
    
    ... ... @@ -794,4 +807,3 @@ os_get_locale_codeset(char* codeset, int len)
    794 807
     
    
    795 808
         strncpy(codeset, code, len);
    
    796 809
     }
    797
    -

  • tests/issues.lisp
    ... ... @@ -720,6 +720,30 @@
    720 720
           (assert-equal (map 'list #'char-name string)
    
    721 721
     		    (map 'list #'char-name (read-line s))))))
    
    722 722
     
    
    723
    +(define-test issue.139-default-external-format-write-file
    
    724
    +    (:tag :issues)
    
    725
    +  ;; Test that opening a file for writing uses the default :utf8.
    
    726
    +  ;; First write something out to the file.  Then read it back in
    
    727
    +  ;; using an explicit format of utf8 and verifying that we got the
    
    728
    +  ;; right contents.
    
    729
    +  (let ((string (concatenate 'string
    
    730
    +                             ;; This is "hello" in Korean
    
    731
    +                             '(#\Hangul_syllable_an
    
    732
    +                               #\Hangul_Syllable_Nyeong
    
    733
    +                               #\Hangul_Syllable_Ha
    
    734
    +                               #\Hangul_Syllable_Se
    
    735
    +                               #\Hangul_Syllable_Yo))))
    
    736
    +    (with-open-file (s (merge-pathnames "out-utf8.txt"
    
    737
    +                                        *test-path*)
    
    738
    +                       :direction :output
    
    739
    +                       :if-exists :supersede)
    
    740
    +      (write-line string s))
    
    741
    +    (with-open-file (s (merge-pathnames "out-utf8.txt"
    
    742
    +                                        *test-path*)
    
    743
    +                       :direction :input
    
    744
    +                       :external-format :utf-8)
    
    745
    +      (assert-equal (map 'list #'char-name string)
    
    746
    +                   (map 'list #'char-name (read-line s))))))
    
    723 747
     
    
    724 748
     (define-test issue.139-locale-external-format
    
    725 749
         (:tag :issues)