Raymond Toy pushed to branch issue-140-stream-element-type-two-way-stream at cmucl / cmucl
Commits:
-
33c760fa
by Raymond Toy at 2022-11-03T04:47:09+00:00
-
317a33f8
by Raymond Toy at 2022-11-03T04:47:10+00:00
-
7bbb4843
by Raymond Toy at 2022-11-08T03:19:19+00:00
-
68f4ec70
by Raymond Toy at 2022-11-08T03:19:21+00:00
-
23f66902
by Raymond Toy at 2022-11-14T05:09:37+00:00
-
6764053d
by Raymond Toy at 2022-11-14T05:09:38+00:00
-
4cb049f3
by Raymond Toy at 2022-11-14T14:56:45-08:00
7 changed files:
- src/code/commandline.lisp
- src/code/intl.lisp
- src/code/save.lisp
- src/code/unix.lisp
- src/general-info/release-21e.md
- src/i18n/locale/cmucl-unix.pot
- src/lisp/os-common.c
Changes:
... | ... | @@ -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
|
... | ... | @@ -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)
|
... | ... | @@ -249,6 +249,10 @@ |
249 | 249 | (reinit)
|
250 | 250 | (environment-init)
|
251 | 251 | (dolist (f *after-save-initializations*) (funcall f))
|
252 | + ;; Set the runtime locale
|
|
253 | + (unless (zerop (unix::unix-setlocale))
|
|
254 | + (warn "os_setlocale failed"))
|
|
255 | + ;; Set the locale for lisp
|
|
252 | 256 | (intl::setlocale)
|
253 | 257 | (ext::process-command-strings process-command-line)
|
254 | 258 | (setf *editor-lisp-p* nil)
|
... | ... | @@ -2893,3 +2893,25 @@ |
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-setlocale ()
|
|
2898 | + _N"Call setlocale(3c) with fixed args. Returns 0 on success."
|
|
2899 | + (alien:alien-funcall
|
|
2900 | + (alien:extern-alien "os_setlocale"
|
|
2901 | + (function c-call:int))))
|
|
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))))) |
... | ... | @@ -61,8 +61,11 @@ public domain. |
61 | 61 | * ~~#136~~ `ensure-directories-exist` should return the given pathspec
|
62 | 62 | * #139 `*default-external-format*` defaults to `:utf-8`
|
63 | 63 | * ~~#140~~ External format of `two-way-stream`
|
64 | + * ~~#141~~ Disallow locales that are pathnames to a localedef file
|
|
64 | 65 | * ~~#142~~ `(random 0)` signals incorrect error
|
65 | - * ~~#147~~ `stream-line-column` method missing for `fundamental-character-output-stream`
|
|
66 | + * ~~#147~~ `stream-line-column` method missing for `fundamental-character-output-stream`
|
|
67 | + * ~~#149~~ Call setlocale(3C) on startup
|
|
68 | + * ~~#155~~ Wrap help strings neatly
|
|
66 | 69 | * Other changes:
|
67 | 70 | * Improvements to the PCL implementation of CLOS:
|
68 | 71 | * Changes to building procedure:
|
... | ... | @@ -1424,3 +1424,14 @@ msgid "" |
1424 | 1424 | " doesn't work."
|
1425 | 1425 | msgstr ""
|
1426 | 1426 | |
1427 | +#: src/code/unix.lisp
|
|
1428 | +msgid "Call setlocale(3c) with fixed args. Returns 0 on success."
|
|
1429 | +msgstr ""
|
|
1430 | + |
|
1431 | +#: src/code/unix.lisp
|
|
1432 | +msgid ""
|
|
1433 | +"Get LC_MESSAGES from the current locale. If we can't, return\n"
|
|
1434 | +" NIL. A call to UNIX-SETLOCALE must have been done previously before\n"
|
|
1435 | +" calling this so that the correct locale is returned."
|
|
1436 | +msgstr ""
|
|
1437 | + |
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 | |
8 | 8 | #include <assert.h>
|
9 | 9 | #include <errno.h>
|
10 | +#include <locale.h>
|
|
10 | 11 | #include <math.h>
|
11 | 12 | #include <netdb.h>
|
12 | 13 | #include <pwd.h>
|
... | ... | @@ -773,3 +774,25 @@ exit: |
773 | 774 |
|
774 | 775 | return result;
|
775 | 776 | }
|
777 | + |
|
778 | +int
|
|
779 | +os_setlocale(void)
|
|
780 | +{
|
|
781 | + char *result = setlocale(LC_ALL, "");
|
|
782 | + |
|
783 | + /* Return 0 if setlocale suceeded; otherwise -1. */
|
|
784 | + return result != NULL ? 0 : -1;
|
|
785 | +}
|
|
786 | + |
|
787 | +int
|
|
788 | +os_get_lc_messages(char *buf, int len)
|
|
789 | +{
|
|
790 | + char *locale = setlocale(LC_MESSAGES, NULL);
|
|
791 | + if (locale) {
|
|
792 | + strncpy(buf, locale, len - 1);
|
|
793 | + buf[len - 1] = '\0';
|
|
794 | + }
|
|
795 | + |
|
796 | + /* Return -1 if setlocale failed. */
|
|
797 | + return locale ? 0 : -1;
|
|
798 | +} |