aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2019 Ludovic Courtès <ludo@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 build locale)
  #:use-module (guix build utils)
  #:use-module (srfi srfi-1)
  #:use-module (ice-9 rdelim)
  #:use-module (ice-9 match)
  #:use-module (ice-9 regex)
  #:export (build-locale
            normalize-codeset
            locale->name+codeset
            read-supported-locales))

(define locale-rx
  ;; Regexp matching a locale line in 'localedata/SUPPORTED'.
  (make-regexp
   "^[[:space:]]*([[:graph:]]+)/([[:graph:]]+)[[:space:]]*\\\\$"))

(define (read-supported-locales port)
  "Read the 'localedata/SUPPORTED' file from PORT.  That file is actually a
makefile snippet, with one locale per line, and a header that can be
discarded."
  (let loop ((locales '()))
    (define line
      (read-line port))

    (cond ((eof-object? line)
           (reverse locales))
          ((string-prefix? "#" (string-trim line)) ;comment
           (loop locales))
          ((string-contains line "=")            ;makefile variable assignment
           (loop locales))
          (else
           (match (regexp-exec locale-rx line)
             (#f
              (loop locales))
             (m
              (loop (alist-cons (match:substring m 1)
                                (match:substring m 2)
                                locales))))))))

(define (normalize-codeset codeset)
  "Compute the \"normalized\" variant of CODESET."
  ;; info "(libc) Using gettextized software", for the algorithm used to
  ;; compute the normalized codeset.
  (letrec-syntax ((-> (syntax-rules ()
                        ((_ proc value)
                         (proc value))
                        ((_ proc rest ...)
                         (proc (-> rest ...))))))
    (-> (lambda (str)
          (if (string-every char-set:digit str)
              (string-append "iso" str)
              str))
        string-downcase
        (lambda (str)
          (string-filter char-set:letter+digit str))
        codeset)))

(define* (build-locale locale
                       #:key
                       (localedef "localedef")
                       (directory ".")
                       (codeset "UTF-8")
                       (name (string-append locale "." codeset)))
  "Compute locale data for LOCALE and CODESET--e.g., \"en_US\" and
\"UTF-8\"--with LOCALEDEF, and store it in DIRECTORY under NAME."
  (format #t "building locale '~a'...~%" name)
  (invoke localedef "--no-archive" "--prefix" directory
          "-i" locale "-f" codeset
          (string-append directory "/" name)))

(define (locale->name+codeset locale)
  "Split a locale name such as \"aa_ER@saaho.UTF-8\" into two values: the
language/territory/modifier part, and the codeset."
  (match (string-rindex locale #\.)
    (#f  (values locale #f))
    (dot (values (string-take locale dot)
                 (string-drop locale (+ dot 1))))))
e> Eric Bavier <bavier@member.fsf.org> <ericbavier@gmail.com> Eric Dvorsak <eric@dvorsak.fr> <yenda1@gmail.com> George Clemmer <myglc2@gmail.com> Ivan Vilata i Balaguer <ivan@selidor.net> Jeff Mickey <j@codemac.net> <jm@igneous.io> John Darrington <jmd@gnu.org> <john@darrington.wattle.id.au> John J. Foerch <jjfoerch@earthlink.net> Joshua Grant <tadni@riseup.net> <gzg@riseup.net> Joshua Grant <tadni@riseup.net> <jgrant@parenthetical.io> Joshua Grant <tadni@riseup.net> <tadnimi@gmail.com> Joshua Grant <tadni@riseup.net> <youlysses@riseup.net> Kei Kebreau <kei@openmailbox.org> <kkebreau@posteo.net> Leo Famulari <leo@famulari.name> <lfamular@gmail.com> Ludovic Courtès <ludo@gnu.org> <ludovic.courtes@inria.fr> Marek Benc <dusxmt@gmx.com> <merkur32@gmail.com> Marius Bakke <mbakke@fastmail.com> <m.bakke@warwick.ac.uk> Mathieu Lirzin <mthl@gnu.org> <mthl@openmailbox.org> Mathieu Lirzin <mthl@gnu.org> <mathieu.lirzin@openmailbox.org> Mathieu Othacehe <m.othacehe@gmail.com> Nikita Karetnikov <nikita@karetnikov.org> <nikita.karetnikov@gmail.com> ng0 <ng0@infotropique.org> ng0 <ng0@infotropique.org> <ng0@no-reply.infotropique.org> ng0 <ng0@infotropique.org> <ng0@no-reply.pragmatique.xyz> ng0 <ng0@infotropique.org> <ng0@pragmatique.xyz> ng0 <ng0@infotropique.org> <contact.ng0@cryptolab.net> ng0 <ng0@infotropique.org> <ng0@we.make.ritual.n0.is> ng0 <ng0@infotropique.org> <ngillmann@runbox.com> ng0 <ng0@infotropique.org> <niasterisk@grrlz.net> ng0 <ng0@infotropique.org> <ng@niasterisk.space> ng0 <ng0@infotropique.org> <ng0@libertad.pw> Pjotr Prins <pjotr.guix@thebird.nl> <pjotr.public01@thebird.nl> Pjotr Prins <pjotr.guix@thebird.nl> <pjotr.public12@thebird.nl> Pjotr Prins <pjotr.guix@thebird.nl> <pjotr.public12@email> Raimon Grau <raimonster@gmail.com> <raimon@3scale.net> Raoul Jean Pierre Bonnal <ilpuccio.febo@gmail.com> Raymond Nicholson <rain1@openmailbox.org> Rene Saavedra <rennes@openmailbox.org> Ricardo Wurmus <rekado@elephly.net> Ricardo Wurmus <rekado@elephly.net> <ricardo.wurmus@mdc-berlin.de> Sou Bunnbu (宋文武) <iyzsong@gmail.com> Sou Bunnbu (宋文武) <iyzsong@gmail.com> <iyzsong@member.fsf.org> Stefan Reichör <stefan@xsteve.at> Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com> Theodoros Foradis <theodoros.for@openmailbox.org> <theodoros@foradis.org> Thomas Danckaert <thomas.danckaert@gmail.com> <post@thomasdanckaert.be> Tobias Geerinckx-Rice <me@tobias.gr> <tobias.geerinckx.rice@gmail.com> Tomáš Čech <sleep_walker@gnu.org> <sleep_walker@suse.cz> Vincent Legoll <vincent.legoll@gmail.com> <vincent.legoll@idgrilles.fr>