system: Selected locale is automatically built.

Fixes <http://bugs.gnu.org/22572>.
Reported by Mark H Weaver <mhw@netris.org>.

* gnu/system/locale.scm (%not-dot): New variable.
(denormalize-codeset, locale-name->definition): New procedures.
* gnu/system.scm (locale-name->definition*): New procedure.
(operating-system-locale-directory): Instead of raising an error, add
the missing locale.
* doc/guix.texi (Locales): Adjust accordingly.
This commit is contained in:
Ludovic Courtès 2016-02-10 11:01:54 +01:00
parent 32e1611206
commit f5582b2c1d
3 changed files with 61 additions and 18 deletions

View file

@ -6452,17 +6452,17 @@ Usually, you will want to specify the default locale for the machine
using the @code{locale} field of the @code{operating-system} declaration
(@pxref{operating-system Reference, @code{locale}}).
That locale must be among the @dfn{locale definitions} that are known to
the system---and these are specified in the @code{locale-definitions}
slot of @code{operating-system}. The default value includes locale
definitions for some widely used locales, but not for all the available
locales, in order to save space.
The selected locale is automatically added to the @dfn{locale
definitions} known to the system if needed, with its codeset inferred
from its name---e.g., @code{bo_CN.utf8} will be assumed to use the
@code{UTF-8} codeset. Additional locale definitions can be specified in
the @code{locale-definitions} slot of @code{operating-system}---this is
useful, for instance, if the codeset could not be inferred from the
locale name. The default set of locale definitions includes some widely
used locales, but not all the available locales, in order to save space.
If the locale specified in the @code{locale} field is not among the
definitions listed in @code{locale-definitions}, @command{guix system}
raises an error. In that case, you should add the locale definition to
the @code{locale-definitions} field. For instance, to add the North
Frisian locale for Germany, the value of that field may be:
For instance, to add the North Frisian locale for Germany, the value of
that field may be:
@example
(cons (locale-definition

View file

@ -669,18 +669,31 @@ (define make-initrd
#:mapped-devices mapped-devices)))
(return #~(string-append #$initrd "/initrd"))))
(define (locale-name->definition* name)
"Variant of 'locale-name->definition' that raises an error upon failure."
(match (locale-name->definition name)
(#f
(raise (condition
(&message
(message (format #f (_ "~a: invalid locale name") name))))))
(def def)))
(define (operating-system-locale-directory os)
"Return the directory containing the locales compiled for the definitions
listed in OS. The C library expects to find it under
/run/current-system/locale."
;; While we're at it, check whether the locale of OS is defined.
(unless (member (operating-system-locale os)
(map locale-definition-name
(operating-system-locale-definitions os)))
(raise (condition
(&message (message "system locale lacks a definition")))))
(define name
(operating-system-locale os))
(locale-directory (operating-system-locale-definitions os)
(define definitions
;; While we're at it, check whether NAME is defined and add it if needed.
(if (member name (map locale-definition-name
(operating-system-locale-definitions os)))
(operating-system-locale-definitions os)
(cons (locale-name->definition* name)
(operating-system-locale-definitions os))))
(locale-directory definitions
#:libcs (operating-system-locale-libcs os)))
(define (kernel->grub-label kernel)

View file

@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014, 2015 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@ -33,6 +33,7 @@ (define-module (gnu system locale)
locale-definition-source
locale-definition-charset
locale-name->definition
locale-directory
%default-locale-libcs
@ -52,6 +53,35 @@ (define-record-type* <locale-definition> locale-definition
(charset locale-definition-charset ;string--e.g., "UTF-8"
(default "UTF-8")))
(define %not-dot
(char-set-complement (char-set #\.)))
(define (denormalize-codeset codeset)
"Attempt to guess the \"real\" name of CODESET, a normalized codeset as
defined in (info \"(libc) Using gettextized software\")."
(cond ((string=? codeset "utf8")
"UTF-8")
((string-prefix? "iso8859" codeset)
(string-append "ISO-8859-" (string-drop codeset 7)))
((string=? codeset "eucjp")
"EUC-JP")
(else ;cross fingers, hope for the best
codeset)))
(define (locale-name->definition name)
"Return a <locale-definition> corresponding to NAME, guessing the charset,
or #f on failure."
(match (string-tokenize name %not-dot)
((source charset)
;; XXX: NAME is supposed to use the "normalized codeset", such as "utf8",
;; whereas the actual name used is different. Add a special case to make
;; the right guess for UTF-8.
(locale-definition (name name)
(source source)
(charset (denormalize-codeset charset))))
(_
#f)))
(define* (localedef-command locale
#:key (libc (canonical-package glibc)))
"Return a gexp that runs 'localedef' from LIBC to build LOCALE."