aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014-2017, 2019-2021, 2023-2024 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2018 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2023 Janneke Nieuwenhuizen <jannek@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu system locale)
  #:use-module (guix gexp)
  #:use-module (guix store)
  #:use-module (guix modules)
  #:use-module (guix records)
  #:use-module (guix packages)
  #:use-module (guix utils)
  #:use-module (gnu packages base)
  #:use-module (gnu packages compression)
  #:use-module (srfi srfi-26)
  #:use-module (ice-9 match)
  #:export (locale-definition
            locale-definition?
            locale-definition-name
            locale-definition-source
            locale-definition-charset

            locale-name->definition
            locale-directory

            %default-locale-libcs
            %default-locale-definitions

            glibc-supported-locales))

;;; Commentary:
;;;
;;; Locale definitions, and compilation thereof.
;;;
;;; Code:

(define-record-type* <locale-definition> locale-definition
  make-locale-definition
  locale-definition?
  (name    locale-definition-name)                ;string--e.g., "fr_FR.utf8"
  (source  locale-definition-source)              ;string--e.g., "fr_FR"
  (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* (single-locale-directory locales
                                  #:key (libc glibc))
  "Return a directory containing all of LOCALES for LIBC compiled.

Because locale data formats are incompatible when switching from one libc to
another, locale data is put in a sub-directory named after the 'version' field
of LIBC."
  (define version
    (version-major+minor (package-version libc)))

  (define build
    (with-imported-modules (source-module-closure
                            '((gnu build locale)))
     #~(begin
         (use-modules (gnu build locale))

         (mkdir #$output)
         (mkdir (string-append #$output "/" #$version))

         ;; 'localedef' executes 'gzip' to access compressed locale sources.
         (setenv "PATH"
                 (string-append #+gzip "/bin:" #+libc "/bin"))

         (setvbuf (current-output-port) 'line)
         (setvbuf (current-error-port) 'line)
         (for-each (lambda (locale codeset name)
                     (build-locale locale
                                   #:codeset codeset
                                   #:name name
                                   #:directory
                                   (string-append #$output "/" #$version)))
                   '#$(map locale-definition-source locales)
                   '#$(map locale-definition-charset locales)
                   '#$(map locale-definition-name locales)))))

  (computed-file (string-append "locale-" version) build))

(define* (locale-directory locales
                           #:key (libcs %default-locale-libcs))
  "Return a locale directory containing all of LOCALES for each libc package
listed in LIBCS.

It is useful to list more than one libc when willing to support
already-installed packages built against a different libc since the locale
data format changes between libc versions."
  (match libcs
    ((libc)
     (single-locale-directory locales #:libc libc))
    ((libcs ..1)
     (let ((dirs (map (lambda (libc)
                        (single-locale-directory locales #:libc libc))
                      libcs)))
       (computed-file "locale-multiple-versions"
                      (with-imported-modules '((guix build union))
                        #~(begin
                            (use-modules (guix build union))
                            (union-build #$output (list #$@dirs))))
                      #:options '(#:local-build? #t
                                  #:substitutable? #f))))))

(define %default-locale-libcs
  ;; The libcs for which we build locales by default.
  (list glibc glibc-2.35))

(define %default-locale-definitions
  ;; Arbitrary set of locales that are built by default.  They come as a
  ;; "bonus" in addition to that specified in the 'locale' field of the
  ;; operating system, for the user's convenience, so they shouldn't take too
  ;; much space.
  (letrec-syntax ((utf8-locale (syntax-rules ()
                                 ((_ name*)
                                  (locale-definition
                                   ;; Note: We choose "utf8", which is the
                                   ;; "normalized codeset".
                                   (name (string-append name* ".utf8"))
                                   (source name*)
                                   (charset "UTF-8")))))
                  (utf8-locales (syntax-rules ()
                                  ((_ name ...)
                                   (list (utf8-locale name) ...)))))
    ;; The six UN official languages plus Portuguese, with at most two
    ;; variants per language.
    (utf8-locales "ar_DZ"
                  "en_GB"
                  "en_US"
                  "es_AR"
                  "es_ES"
                  "fr_FR"
                  "pt_BR"
                  "pt_PT"
                  "ru_RU"
                  "zh_CN")))


;;;
;;; Locales supported by glibc.
;;;

(define* (glibc-supported-locales #:optional (glibc glibc))
  "Return a file-like object that contains a list of locale name/encoding
pairs such as (\"oc_FR.UTF-8\" . \"UTF-8\").  Each pair corresponds to a
locale supported by GLIBC."
  (define build
    (with-imported-modules (source-module-closure
                            '((guix build gnu-build-system)
                              (gnu build locale)))
      #~(begin
          (use-modules (guix build gnu-build-system)
                       (gnu build locale)
                       (ice-9 pretty-print))

          (define unpack
            (assq-ref %standard-phases 'unpack))


          (setenv "PATH"
                  (string-append #+(file-append tar "/bin") ":"
                                 #+(file-append zstd "/bin") ":"
                                 #+(file-append gzip "/bin")))
          (unpack #:source #+(package-source glibc))

          (let ((locales (call-with-input-file "localedata/SUPPORTED"
                           read-supported-locales)))
            (call-with-output-file #$output
              (lambda (port)
                (pretty-print locales port)))))))

  (computed-file "glibc-supported-locales.scm" build))

;;; locale.scm ends here
Florian Pelz 2019-05-15services: Include ModemManager in %desktop-services....* gnu/services/desktop.scm (%desktop-services): Add modem-manager-service-type. Signed-off-by: Ludovic Courtès <ludo@gnu.org> Florian Pelz 2019-05-14services: Add 'network-manager-applet' to %DESKTOP-SERVICES....Fixes <https://bugs.gnu.org/35554>. Reported by Calle Kabo <calle@kabo.nu>. * gnu/services/desktop.scm (%desktop-services): Add 'network-manager-applet' service. Ludovic Courtès 2019-04-30services: colord: Make public and searchable....* gnu/services/desktop.scm (colord-service-type): Make public. [description]: New field. Ludovic Courtès 2019-04-30services: bluetooth: Make public and searchable....Until now 'guix system search bluetooth' would turn up nothing. * gnu/services/desktop.scm (bluetooth-service-type) (bluetooth-configuration): Make public. (bluetooth-service-type)[description]: New field. Ludovic Courtès 2019-04-26services: cups-pk-helper: Export....* gnu/services/desktop.scm (cups-pk-helper-service-type): Export. Ludovic Courtès 2019-04-05services: dbus: 'wrapped-dbus-service' accepts a list of variables....* gnu/services/dbus.scm (wrapped-dbus-service): Replace 'variable' and 'value' by 'variables', and adjust code accordingly. * gnu/services/desktop.scm (upower-dbus-service): (geoclue-dbus-service, elogind-dbus-service): Adjust accordingly. Ludovic Courtès 2019-04-05services: dbus: Add 'wrapped-dbus-service'....* gnu/services/desktop.scm (wrapped-dbus-service): Move to... * gnu/services/dbus.scm (wrapped-dbus-service): ... here. New procedure. Ludovic Courtès 2019-03-28services: desktop: Switch to GDM....* gnu/services/desktop.scm (%desktop-services): Replace SLIM-SERVICE-TYPE instance with an instance of GDM-SERVICE-TYPE. * doc/guix.texi (Keyboard Layout): Change example to mention GDM-SERVICE-TYPE. (X Window): Mention GDM. (Desktop Services): Adjust references to SLiM. Ludovic Courtès 2019-03-27services: Deprecate 'xfce-desktop-service'....* gnu/services/desktop.scm (xfce-desktop-service-type)[default-value] [description]: New fields. (xfce-desktop-service): Deprecate. * gnu/system/examples/desktop.tmpl: Use the (service …) form. * gnu/installer/services.scm (%desktop-environments): Add TODO comment. * doc/guix.texi (Desktop Services): Adjust accordingly, and fix spelling of "Xfce" throughout. Ludovic Courtès 2019-03-27services: Deprecate 'gnome-desktop-service'....* gnu/services/desktop.scm (gnome-desktop-service-type)[default-value]: New field. (gnome-desktop-service): Deprecate. * gnu/installer/services.scm (%desktop-environments): Use the (service …) form for GNOME. * gnu/system/examples/desktop.tmpl: Likewise. * doc/guix.texi (Desktop Services): Adjust accordingly. Ludovic Courtès 2019-03-18Correct name and email address for ng0....* .mailmap, Makefile.am, doc/guix.de.texi, doc/guix.fr.texi, doc/guix.texi, etc/completion/fish/guix.fish, gnu/packages/accessibility.scm, gnu/packages/admin.scm, gnu/packages/audio.scm, gnu/packages/autotools.scm, gnu/packages/cdrom.scm, gnu/packages/check.scm, gnu/packages/cinnamon.scm, gnu/packages/compression.scm, gnu/packages/crypto.scm, gnu/packages/databases.scm, gnu/packages/django.scm, gnu/packages/dns.scm, gnu/packages/elixir.scm, gnu/packages/emacs-xyz.scm, gnu/packages/emacs.scm, gnu/packages/enlightenment.scm, gnu/packages/erlang.scm, gnu/packages/fonts.scm, gnu/packages/fontutils.scm, gnu/packages/forth.scm, gnu/packages/fvwm.scm, gnu/packages/games.scm, gnu/packages/gl.scm, gnu/packages/gnome.scm, gnu/packages/gnunet.scm, gnu/packages/gnupg.scm, gnu/packages/gnuzilla.scm, gnu/packages/gtk.scm, gnu/packages/guile-wm.scm,gnu/packages/guile-xyz.scm, gnu/packages/haskell-check.scm, gnu/packages/haskell-crypto.scm, gnu/packages/haskell.scm, gnu/packages/image-viewers.scm, gnu/packages/image.scm, gnu/packages/irc.scm, gnu/packages/language.scm, gnu/packages/libcanberra.scm, gnu/packages/linux.scm, gnu/packages/lisp.scm, gnu/packages/lolcode.scm, gnu/packages/lxde.scm, gnu/packages/lxqt.scm, gnu/packages/mail.scm, gnu/packages/markup.scm, gnu/packages/mate.scm, gnu/packages/maths.scm, gnu/packages/mc.scm, gnu/packages/messaging.scm, gnu/packages/music.scm, gnu/packages/ncurses.scm, gnu/packages/networking.scm, gnu/packages/nickle.scm, gnu/packages/openbox.scm, gnu/packages/pdf.scm, gnu/packages/perl-check.scm, gnu/packages/perl.scm, gnu/packages/python-compression.scm, gnu/packages/python-crypto.scm, gnu/packages/python-web.scm, gnu/packages/python-xyz.scm, gnu/packages/python.scm, gnu/packages/qt.scm, gnu/packages/ruby.scm, gnu/packages/rust.scm, gnu/packages/scheme.scm, gnu/packages/serialization.scm, gnu/packages/shells.scm, gnu/packages/ssh.scm, gnu/packages/suckless.scm, gnu/packages/tbb.scm, gnu/packages/telephony.scm, gnu/packages/text-editors.scm, gnu/packages/textutils.scm, gnu/packages/time.scm, gnu/packages/tls.scm, gnu/packages/tor.scm, gnu/packages/version-control.scm, gnu/packages/video.scm, gnu/packages/vim.scm, gnu/packages/web.scm, gnu/packages/wm.scm, gnu/packages/xdisorg.scm, gnu/packages/xfce.scm, gnu/packages/xml.scm, gnu/packages/xorg.scm, gnu/services/certbot.scm, gnu/services/desktop.scm, gnu/services/version-control.scm, gnu/services/web.scm, guix/import/hackage.scm, guix/licenses.scm: Correct name and email address for ng0. Signed-off-by: Tobias Geerinckx-Rice <me@tobias.gr> ng0 2019-03-18gnu: Add inputattach service....Add a service that runs inputattach as a daemon to translate events from serial ports. * gnu/services/desktop.scm (<inputattach-configuration>): New record type. * gnu/services/desktop.scm (inputattach-service-type): New service type. * doc/guix.texi (Miscellaneous Services): Add inputattach Service subsubheading. Signed-off-by: Ludovic Courtès <ludo@gnu.org> Tim Gesthuizen 2019-03-11services: mate-desktop: Deprecate the 'mate-desktop-service' procedure....* gnu/services/desktop.scm (mate-desktop-service): Deprecate. * doc/guix.texi (Desktop Services): Document 'mate-desktop-service-type' and 'mate-desktop-configuration'. Fix spelling of "Enlightenment". Ludovic Courtès 2019-03-11services: mate-desktop: Add default value....* gnu/services/desktop.scm (mate-desktop-service-type)[default-value]: New field. Ludovic Courtès 2019-02-24services: desktop: Fix define for the upower-service procedure....* gnu/services/desktop.scm (upower-service): Fill in the replacement for upower-service. Christopher Baines 2019-02-16services: desktop: Deprecate the upower-service procedure....This has now been replaced by the upower-service-type and <upower-configuration> record. * gnu/services/desktop.scm (upower-service): Deprecate this procedure. Christopher Baines 2019-02-16services: Improve the upower-service-type....Add a description and default value. Switch the documentation to mention the service-type and the configuration record, rather than the upower-service procedure. * gnu/services/desktop.scm (upower-service-type)[description, default-value]: Define these fields. (%desktop-services): Change (upower-service) to (service upower-service-type). * doc/guix.texi (Desktop Services): Update the upower service documentation. Christopher Baines 2019-02-16services: Improve the upower-configuration record....Copy the defaults from the upower-service procedure to the <upower-configuration> record type. This will allow making it the default value for the upower-service-type, and deprecating the procedure. Export the field accessors so that the <upower-configuration> record type becomes more usable. * gnu/services/desktop.scm (<upower-configuration>): Export it. (upower-configuration-upower, upower-configuration-watts-up-pro?, upower-configuration-poll-batteries?, upower-configuration-ignore-lid?, upower-configuration-use-percentage-for-policy?, upower-configuration-percentage-low, upower-configuration-percentage-critical, upower-configuration-percentage-action, upower-configuration-time-low, upower-configuration-time-critical, upower-configuration-time-action, upower-configuration-critical-power-action): Add default and export. Christopher Baines 2019-02-13services: Add cups-pk-helper....This service integrates cups and PolicyKit. The gnome-control-center printing section uses this functionality. * gnu/sevices/desktop.scm (cups-pk-helper-service-type): New variable. (%desktop-services): Add the cups-pk-helper service. Christopher Baines