diff options
-rw-r--r-- | README | 1 | ||||
-rwxr-xr-x | locale-gen | 384 | ||||
-rw-r--r-- | locale-gen.8 | 69 | ||||
-rw-r--r-- | locale.gen | 36 | ||||
-rw-r--r-- | locale.gen.5 | 77 |
5 files changed, 567 insertions, 0 deletions
@@ -0,0 +1 @@ +A port/rewrite of Debian's locale-gen. See the man pages for more information. diff --git a/locale-gen b/locale-gen new file mode 100755 index 0000000..6653cad --- /dev/null +++ b/locale-gen @@ -0,0 +1,384 @@ +#!/bin/bash + +# +# Based upon Debian's locale-gen, fetched from glibc_2.3.6-7.diff.gz +# + +unset POSIXLY_CORRECT IFS +umask 0022 + +argv0=${0##*/} + +EPREFIX="@GENTOO_PORTAGE_EPREFIX@" +if [[ ${EPREFIX} == "@"GENTOO_PORTAGE_EPREFIX"@" ]] ; then + EPREFIX="" +fi + +FUNCTIONS_SH="/lib/gentoo/functions.sh" +source "${EPREFIX}"${FUNCTIONS_SH} || { + echo "${argv0}: Could not source ${FUNCTIONS_SH}!" 1>&2 + exit 1 +} + +show_usage() { + cat <<-EOF + Usage: ${HILITE}${argv0}${NORMAL} ${GOOD}[options]${NORMAL} -- ${GOOD}[localedef options]${NORMAL} + + Generate locales based upon the config file /etc/locale.gen. + + ${HILITE}Options:${NORMAL} + ${GOOD}-k, --keep${NORMAL} Don't nuke existing locales + ${GOOD}-d, --destdir <dir>${NORMAL} Use locale data in specified DESTDIR tree + ${GOOD}-c, --config <config>${NORMAL} Use specified config instead of default locale.gen + ${GOOD}-l, --list${NORMAL} List all the locales to be generated + ${GOOD}-a, --ask${NORMAL} Ask before generating each locale + ${GOOD}-A, --all${NORMAL} Pretend the locale list contains all locales + ${GOOD}-u, --update${NORMAL} Only generate locales that are missing + ${GOOD}-G, --generate <locale>${NORMAL} Generate specified locale (one shot; implies -k -u) + ${GOOD}-j, --jobs <num>${NORMAL} Number of locales to generate at a time (parallel) + ${GOOD}-q, --quiet${NORMAL} Only show errors + ${GOOD}-V, --version${NORMAL} Meaningless version information + ${GOOD}-h, --help${NORMAL} Show this help cruft + + ${HILITE}Localedef Options:${NORMAL} + By default, ${GOOD}${LOCALEDEF_OPTS}${NORMAL} is passed to localedef. + + For more info, see the ${HILITE}locale-gen${NORMAL}(1) and ${HILITE}locale.gen${NORMAL}(8) manpages. + EOF + [[ $# -eq 0 ]] && exit 0 + echo "" + eerror "Unknown option '$1'" + exit 1 +} +show_version() { + local b="(" a=")" + local cvsver="$Revision: 1.42 $b $Date: 2017/08/12 16:30:06 $a" + echo "locale-gen-${cvsver//: }" + exit 0 +} + + + +LOCALEDEF_OPTS="-c" +KEEP="" +DESTDIR="" +CONFIG="" +JUST_LIST="" +ASK="" +ALL="" +UPDATE="" +GENERATE="" +JOBS_MAX="" +QUIET=0 +SET_X="" +LOCALE_ARCHIVE=true +while [[ $# -gt 0 ]] ; do + case $1 in + -k|--keep|--keep-existing) KEEP=$1;; + -d|--destdir) shift; DESTDIR=$1; unset ROOT;; + -c|--config) shift; CONFIG=$1;; + -l|--list) JUST_LIST=$1;; + -a|--ask) ASK=$1;; + -A|--all) ALL=$1;; + -u|--update) UPDATE=$1;; + -G|--generate) shift; GENERATE=$1;; + -j|--jobs) shift; JOBS_MAX=$(( $1 ));; + -j*) : $(( JOBS_MAX = ${1#-j} ));; + -q|--quiet) : $(( ++QUIET ));; + -x|--debug) SET_X="true";; + -V|--version) show_version;; + -h|--help) show_usage;; + --) shift; LOCALEDEF_OPTS=$*; break;; + *) show_usage $1;; + esac + shift +done +if [[ -z ${JOBS_MAX} ]] ; then + JOBS_MAX=$(getconf _NPROCESSORS_ONLN 2>/dev/null) + : ${JOBS_MAX:=1} +fi +[[ ${JOBS_MAX} -lt 1 ]] && JOBS_MAX=1 +[[ -n ${SET_X} ]] && set -x +: ${KEEP:=${JUST_LIST}} +[[ -n ${GENERATE} ]] && UPDATE="true" && KEEP="true" + +: ${ROOT:=/} +ROOT="${ROOT%/}/" +if [[ -n ${DESTDIR} ]] && [[ ${ROOT} != "/" ]] ; then + eerror "DESTDIR and ROOT are mutually exclusive options" + exit 1 +fi +: ${EROOT:="${ROOT%/}${EPREFIX}/"} +if [[ ${EROOT} != "/" ]] ; then + einfo "Using locale.gen from ROOT ${EROOT}etc/" +fi +if [[ -n ${DESTDIR} ]] ; then + einfo "Building locales in DESTDIR '${DESTDIR}'" +else + DESTDIR=${EROOT} +fi + +# XXX: should fix this ... +if [[ ${ROOT} != "/" ]] ; then + eerror "Sorry, but ROOT support is incomplete at this time." + exit 0 +fi + +: ${CONFIG:=${EROOT}etc/locale.gen} +LOCALES=${DESTDIR}usr/share/i18n/locales +CHARMAPS=${DESTDIR}usr/share/i18n/charmaps +SUPPORTED=${DESTDIR}usr/share/i18n/SUPPORTED +ALIAS=${DESTDIR}usr/share/locale/locale.alias + +# +# Grab any user options in their config file +options=$(sed -n \ + -e '/^[[:space:]]*#%/s:^[[:space:]]*#%[[:space:]]*::p'\ + "${CONFIG}" 2>/dev/null +) +IFS=$'\n' +for option in ${options} ; do + case ${option} in + no-locale-archive) + LOCALE_ARCHIVE=false + ;; + *) + ewarn "Unrecognized option '${option}'" + ;; + esac +done +unset IFS + +[[ -n ${ALL} ]] && CONFIG=${SUPPORTED} + +# Extract the location of the locale dir on the fly as `localedef --help` has: +# locale path : /usr/lib64/locale:/usr/share/i18n +# For long paths, the line may get wrapped into two, in which case space (' ') is replaced +# by newline (\n). +LOCALEDIR=$(LC_ALL="C" "${DESTDIR}"usr/bin/localedef --help | sed -n -r '/locale path/{N;s|.*:[ \n](.*):/.*|\1|;p}') +LOCALEDIR="${DESTDIR}${LOCALEDIR#${EPREFIX}}" +if [[ $? -ne 0 ]] || [[ -z ${LOCALEDIR} ]] || [[ ${LOCALEDIR} != ${DESTDIR}/usr/lib*/locale ]] ; then + eerror "Unable to parse the output of your localedef utility." 1>&2 + eerror "File a bug about this issue and include the output of 'localedef --help'." 1>&2 + exit 1 +fi + +# Only generate locales the user specified before falling back to the config. +locales_to_generate=${GENERATE} + +if [[ -z ${locales_to_generate} ]] && [[ -e ${CONFIG} ]] ; then + locales_to_generate=$(sed \ + -e 's:#.*::' \ + -e '/^[[:space:]]*$/d' \ + "${CONFIG}" | sort) + # Sanity check to make sure people did not duplicate entries. #550884 + # The first column must be unique specifically. #235555 + dup_locales_to_generate=$( + echo "${locales_to_generate}" | \ + awk '{ if ($1 == last) { print lastline; print; } else { lastline = $0; last = $1; } }') + if [[ -n ${dup_locales_to_generate} ]] ; then + ewarn "These locales have been duplicated in your config:\n${dup_locales_to_generate}" + ewarn "Some might be filtered, but you must fix it." + locales_to_generate=$(echo "${locales_to_generate}" | uniq) + fi +fi + +if [[ -z ${locales_to_generate} ]] ; then + [[ ${QUIET} -eq 0 ]] && [[ -z ${JUST_LIST} ]] && \ + ewarn "No locales found" + exit 0 +fi + +mkdir -p "${LOCALEDIR}" +if [[ -z ${KEEP} && -z ${UPDATE} ]] ; then + # Remove all old locale dir and locale-archive before generating new + # locale data. Scrubbing via update is done elsewhere. + rm -rf "${LOCALEDIR}"/* || true +fi + +# Transform the name in locales.gen to the name used when storing +# the locale data in /usr/lib/locale/ ... this normalize algo is +# taken out of the glibc localedef source code ... +normalize() { + if [[ $1 == *.* ]] ; then + local ret=$(echo ${1##*.} | tr '[[:upper:]]' '[[:lower:]]') + echo ${1%%.*}.${ret//-} + else + echo $1 + fi +} + +# These funky sed's are based on the stuff in glibc's localedata/Makefile +# Basically we want to rewrite the display like so: +# <locale without a . or @>.<charmap>[@extra stuff after the @ in the locale] +# en_US ISO-8859-1 -> en_US.ISO-8859-1 +# en_US.UTF-8 UTF-8 -> en_US.UTF-8 +# de_DE@euro ISO-8859-15 -> de_DE.ISO-8859-15@euro +locales_disp=$(echo "${locales_to_generate}" | sed \ + -e ' /@/ s:[[:space:]]*\([^@[:space:]]*\)\([^[:space:]]*\)[[:space:]]\+\([^[:space:]]*\):\1.\3\2:' \ + -e '/^[^@]*$/s:[[:space:]]*\([^.[:space:]]*\)\([^[:space:]]*\)[[:space:]]\+\([^[:space:]]*\):\1.\3:') + +eval declare -a locales_disp=(${locales_disp}) +eval declare -a locales_to_generate=(${locales_to_generate}) +total=$(( ${#locales_to_generate[*]} / 2 )) + +[[ ${QUIET} -eq 0 ]] && [[ -z ${JUST_LIST} ]] && \ +einfo "Generating ${total} locales (this might take a while) with ${JOBS_MAX} jobs" + +if [[ -n ${UPDATE} ]] ; then + # normalize newlines into spaces + existing_locales=" $(echo $(locale -a 2>/dev/null)) " +fi + +generate_locale() { + local output="" + + if [[ -z ${ASK} ]] && [[ ${QUIET} -eq 0 ]] ; then + output=" (${cnt_fmt}/${total}) Generating ${disp}" + fi + + if [[ $(( JOB_IDX_E - JOB_IDX_S )) == ${JOBS_MAX} ]] ; then + wait ${JOB_PIDS[$(( JOB_IDX_S++ ))]} + JOB_RETS+=( $? ) + fi + ( + # Accumulate all the output in one go so the parallel + # jobs don't tromp on each other + x=$( + [[ -n ${output} ]] && ebegin "${output}" + "${DESTDIR}"usr/bin/localedef ${LOCALEDEF_OPTS} \ + --no-archive \ + -i "${input}" \ + -f "${charmap}" \ + -A "${ALIAS}" \ + --prefix "${DESTDIR%${EPREFIX}/}/" \ + "${locale}" 2>&1 + ret=$? + [[ -n ${output} ]] && eend ${ret} + exit ${ret} + ) + ret=$? + if [[ -n ${output} ]] ; then + echo "${x}" + elif [[ ${ret} -ne 0 ]] ; then + eerror "${disp}: ${x}" + fi + exit ${ret} + ) & + JOB_PIDS+=( $! ) + : $(( ++JOB_IDX_E )) + + if [[ ${ret} != 0 && ${locale} == */* ]] ; then + ewarn "Perhaps you meant to use a space instead of a / in your config file ?" + fi +} + +JOB_PIDS=() +JOB_RETS=() +JOB_IDX_S=0 +JOB_IDX_E=0 +cnt=0 +lidx=0 +while [[ -n ${locales_to_generate[${lidx}]} ]] ; do + : $(( ++cnt )) + locale=${locales_to_generate[$((lidx++))]} + charmap=${locales_to_generate[$((lidx++))]} + + # XXX: if we wanted to, we could check existence of + # ${LOCALES}/${locale} and ${CHARMAPS}/${charmap} + # this would fail for things like "en_US.UTF8", but + # in that case we could fall back to checking the + # SUPPORTED file ... then again, the localedef + # below will abort nicely for us ... + if [[ -z ${locale} || -z ${charmap} ]] ; then + eerror "Bad entry in locale.gen: '${locale} ${charmap}'; skipping" + continue + fi + + disp=${locales_disp[$(( cnt - 1 ))]} + + if [[ -n ${UPDATE} ]] ; then + normalized_locale=$(normalize ${locale}) + if [[ ${existing_locales} == *" ${normalized_locale} "* ]] ; then + existing_locales=${existing_locales/ ${normalized_locale} / } + if [[ ${QUIET} -eq 0 ]] ; then + cnt_fmt=$(printf "%${#total}i" ${cnt}) + einfo " (${cnt_fmt}/${total}) Skipping ${disp}" + fi + continue + fi + fi + + # If the locale is like 'en_US.UTF8', then we really want 'en_US' + if [[ -f ${LOCALES}/${locale} ]] ; then + input=${locale} + else + input=${locale%%.*} + fi + + if [[ -z ${JUST_LIST} ]] ; then + # Format the output for the question/status + cnt_fmt=$(printf "%${#total}i" ${cnt}) + if [[ -n ${ASK} ]] ; then + einfon " (${cnt_fmt}/${total}) Generate ${disp} ? (Y/n) " + read user_answer + [[ ${user_answer} == [nN]* ]] && continue + fi + generate_locale + else + echo "${disp}" + fi +done + +for (( i = JOB_IDX_S; i < JOB_IDX_E; ++i )) ; do + wait ${JOB_PIDS[i]} + JOB_RETS+=( $? ) +done +ret=$(( 0 ${JOB_RETS[@]/#/+} )) + +[[ ${QUIET} -eq 0 ]] && [[ -z ${JUST_LIST} ]] && \ +einfo "Generation complete" + +if ${LOCALE_ARCHIVE} ; then + ebegin "Adding locales to archive" + # The pattern ends with / on purpose: we don't care about files (like + # locale-archive) in the locale subdir, and we definitely don't want to + # delete them! + for LOC in "${LOCALEDIR}"/*/; do + LOC=${LOC%/} # Strip trailing /, since localedef doesn't like it + x=$( + "${DESTDIR}"usr/bin/localedef \ + --add-to-archive "${LOC}" \ + --replace \ + --prefix "${DESTDIR%${EPREFIX}/}/" + ret=$? + if [[ -n ${output} ]] ; then + echo "${x}" + elif [[ ${ret} -ne 0 ]] ; then + eerror "${disp}: ${x}" + fi + if [[ $ret -eq 0 ]]; then + rm -r "${LOC}" + fi + exit ${ret} + ) + done + eend $ret +fi + +# Remove locales that existed but were not requested +if [[ -n ${UPDATE} ]] ; then + # Ignore these pseudo locales + existing_locales=${existing_locales/ C / } + existing_locales=${existing_locales/ POSIX / } + if [[ -n ${existing_locales// } ]] ; then + if [[ -z ${KEEP} ]] ; then + [[ ${QUIET} -eq 0 ]] && einfo "Scrubbing old locales:"${existing_locales} + cd "${LOCALEDIR}" && rm -rf ${existing_locales} + else + [[ ${QUIET} -eq 0 ]] && einfo "Keeping old locales:"${existing_locales} + fi + fi +fi + +exit ${ret} diff --git a/locale-gen.8 b/locale-gen.8 new file mode 100644 index 0000000..a194be7 --- /dev/null +++ b/locale-gen.8 @@ -0,0 +1,69 @@ +.TH "locale-gen" "8" "Aug 2007" "Gentoo" +.SH "NAME" +locale\-gen \- generate locales on the fly +.SH "DESCRIPTION" +The locale\-gen utility is used to manage locales on your system. Often times +it merely generates a user configurable list of locales, but it can be used to +generate a few locales on the fly as needed. + +Normally all locales would be generated at build time, but this leads to waste +of disk and time as many users really just want a handful on their system. +.SH "OPTIONS" +.TP +\fB\-a\fR, \fB\-\-ask\fR +Ask before generating each locale +.TP +\fB\-A\fR, \fB\-\-all\fR +Generate all possible locales +.TP +\fB\-c\fR, \fB\-\-config\fR \fI<config>\fR +Use specified \fIconfig\fR file rather than default /etc/locale.gen +.TP +\fB\-d\fR, \fB\-\-destdir\fR \fI<dir>\fR +Look for locale definitions and store generated locale data in the specified +\fIdirectory\fR +.TP +\fB\-G\fR, \fB\-\-generate\fR \fI<locale>\fR +Only generate the specified \fIlocale\fR (implies \-\-keep \-\-update); +format of \fIlocale\fR matches a single line in the \fBlocale.gen\fR(5) +config file +.TP +\fB\-h\fR, \fB\-\-help\fR +Show the help output (imagine that) +.TP +\fB\-j\fR, \fB\-\-jobs\fR \fI<num>\fR +Generate the specified \fInumber\fR of locales in parallel +.TP +\fB\-k\fR, \fB\-\-keep\fR +Keep all existing locales even if they are not in the config file +.TP +\fB\-l\fR, \fB\-\-list\fR +List all the locales that we think should exist according to the config +.TP +\fB\-q\fR, \fB\-\-quiet\fR +Only spit out errors +.TP +\fB\-u\fR, \fB\-\-update\fR +Only generate locales that do not already exist (normally existing locales are regenerated) +.TP +\fB\-V\fR, \fB\-\-version\fR +Report the program version +.TP +\fB\-\-\fR +To pass custom options directly to the \fBlocaledef\fR utility, end the +\fBlocale\-gen\fR option list with \-\- and then everything after that will be +passed on through unmolested (the options \-c are passed by default) +.SH "AUTHORS" +.fi +Mike Frysinger <vapier@gentoo.org> +.nf +.SH "REPORTING BUGS" +Please report bugs via http://bugs.gentoo.org/ +.SH "FILES" +\fB/etc/locale.gen\fR \- locale list +.SH "SEE ALSO" +.BR locale (1), +.BR localedef (1), +.BR locale (5), +.BR locale.gen (5), +.BR locale (7) diff --git a/locale.gen b/locale.gen new file mode 100644 index 0000000..0786f17 --- /dev/null +++ b/locale.gen @@ -0,0 +1,36 @@ +# /etc/locale.gen: list all of the locales you want to have on your system. +# See the locale.gen(5) man page for more details. +# +# The format of each line: +# <locale name> <charset> +# +# Where <locale name> starts with a name as found in /usr/share/i18n/locales/. +# It must be unique in the file as it is used as the key to locale variables. +# For non-default encodings, the <charset> is typically appended. +# +# Where <charset> is a charset located in /usr/share/i18n/charmaps/ (sans any +# suffix like ".gz"). +# +# All blank lines and lines starting with # are ignored. +# +# For the default list of supported combinations, see the file: +# /usr/share/i18n/SUPPORTED +# +# Whenever glibc is emerged, the locales listed here will be automatically +# rebuilt for you. After updating this file, you can simply run `locale-gen` +# yourself instead of re-emerging glibc. + +#en_US ISO-8859-1 +#en_US.UTF-8 UTF-8 +#ja_JP.EUC-JP EUC-JP +#ja_JP.UTF-8 UTF-8 +#ja_JP EUC-JP +#en_HK ISO-8859-1 +#en_PH ISO-8859-1 +#de_DE ISO-8859-1 +#de_DE@euro ISO-8859-15 +#es_MX ISO-8859-1 +#fa_IR UTF-8 +#fr_FR ISO-8859-1 +#fr_FR@euro ISO-8859-15 +#it_IT ISO-8859-1 diff --git a/locale.gen.5 b/locale.gen.5 new file mode 100644 index 0000000..dbcc8c6 --- /dev/null +++ b/locale.gen.5 @@ -0,0 +1,77 @@ +.\" -*- nroff -*- +.\" Copyright (C) 2002, 2005 Free Software Foundation, Inc. +.\" +.\" This program 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 2, or (at your option) +.\" any later version. +.\" +.\" This program 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 this program; if not, write to the Free Software Foundation, +.\" Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +.TH locale.gen 5 "July 2005" "Debian GNU/Linux" +.SH "NAME" +locale.gen \- Configuration file for locale-gen +.SH "DESCRIPTION" +The file \fB/etc/locale.gen\fP lists the locales that are to be generated +by the \fBlocale-gen\fP command. + +Each line is of the form: + +<locale name> <charset> + +Where <locale name> starts with a name as found in +.BR /usr/share/i18n/locales/ . +It must be unique in the file as it is used as the key to locale variables +(e.g. when you do `export LANG="<locale name>"`). For default encodings, +the <charset> is typically omitted, else it is appended with a "." separator. + +Where <charset> is one of the character sets listed in +.B /usr/share/i18n/charmaps +(sans any suffix like ".gz"). It should use the same naming conventions too -- +all caps, and dashes/underscores included. e.g. Use "UTF-8", not "utf8". + +The +.B locale-gen +command will generate all the locales, placing them in +\fB/usr/lib/locale\fP. + +Comments start with the hash mark # and may only be on new lines. +.SH "OPTIONS" +Options start with #% (to preserve backwards compatibility). + +# This enables the "foo" option. +.br +#%foo +.TP +.B no-locale-archive +Disable generation of the locale archive file and instead generate multiple +files/directories for each locale. This slows down runtime greatly (by having +multiple files spread out in the filesystem instead of a single binary file), +but it does mean build time is much faster (as you can generate in parallel). + +You should not use this option. +.SH "EXAMPLES" +.nf +# Create a "en_US" locale using ISO-8859-1 encoding. +# When you set LANG=en_US or LANG=en_US.ISO-8859-1, this is used. +.B en_US ISO-8859-1 + +# Create a "en_US" locale using UTF-8 encoding. +# When you set LANG=en_US.UTF-8, this is used. +.B en_US.UTF-8 UTF-8 +.fi +.SH "SEE ALSO" +.BR locale (1), +.BR localedef (1), +.BR locale-gen (8) +.SH "AUTHORS" +.nf +Alastair McKinstry <mckinstry@computer.org> +Mike Frysinger <vapier@gentoo.org> +.fi |