#!/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##*/}
source /etc/init.d/functions.sh || {
echo "${argv0}: Could not source /etc/init.d/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
${NORMAL} Use locale data in specified DESTDIR tree
${GOOD}-c, --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}-u, --update${NORMAL} Only generate locales that are missing
${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
[[ -z $@ ]] && exit 0
echo ""
eerror "Unknown option '$1'"
exit 1
}
show_version() {
local cvsver="$Header: /var/cvsroot/gentoo/src/patchsets/glibc/extra/locale/locale-gen,v 1.8 2006/04/25 01:17:03 vapier Exp $"
cvsver=${cvsver##*locale-gen-}
echo "locale-gen-${cvsver%%,v *}"
exit 0
}
LOCALEDEF_OPTS="--no-archive -c"
KEEP=""
DESTDIR=""
CONFIG=""
JUST_LIST=""
ASK=""
UPDATE=""
QUIET=0
while [[ -n $1 ]] ; do
case $1 in
-k|--keep|--keep-existing) KEEP=$1;;
-d|--destdir) shift; DESTDIR=$1;;
-c|--config) shift; CONFIG=$1;;
-l|--list) JUST_LIST=$1;;
-a|--ask) ASK=$1;;
-u|--update) UPDATE=$1;;
-q|--quiet) ((++QUIET));;
-V|--version) show_version;;
-h|--help) show_usage;;
--) shift; LOCALEDEF_OPTS=$*; break;;
*) show_usage $1;;
esac
shift
done
KEEP=${KEEP:-${UPDATE:-${JUST_LIST}}}
ROOT=${ROOT:-/}
[[ ${ROOT} != */ ]] && ROOT="${ROOT}/"
if [[ -n ${DESTDIR} ]] && [[ ${ROOT} != "/" ]] ; then
eerror "DESTDIR and ROOT are mutually exclusive options"
exit 1
fi
if [[ ${ROOT} != "/" ]] ; then
einfo "Using locale.gen from ROOT ${ROOT}etc/"
fi
if [[ -n ${DESTDIR} ]] ; then
einfo "Building locales in DESTDIR ${DESTDIR}"
else
DESTDIR=${ROOT}
fi
# XXX: should fix this ...
if [[ ${DESTDIR} != "/" || ${ROOT} != "/" ]] ; then
eerror "Sorry, but DESTDIR/ROOT support is incomplete at this time."
exit 0
fi
LOCALEGEN=${CONFIG:-${ROOT}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
# Extract the location of the locale dir on the fly as `localedef --help` has:
# locale path : /usr/lib64/locale:/usr/share/i18n
LOCALEDIR=${DESTDIR}$(localedef --help | sed -n -e '/locale path/{s|.* : ||;s|:.*||;p}')
if [[ ${QUIET} -eq 0 ]] && [[ -z ${JUST_LIST} ]] && \
[[ -e ${ROOT}etc/locales.build ]]
then
ewarn "You should upgrade your /etc/locales.build to /etc/locale.gen"
ewarn "and then remove /etc/locales.build when you're done.\n"
fi
locales_to_generate=""
if [[ -e ${LOCALEGEN} ]] ; then
locales_to_generate=$(sed \
-e 's:#.*::' \
-e '/^[[:space:]]*$/d' \
"${LOCALEGEN}")
fi
if [[ -z ${locales_to_generate} ]] ; then
# Maybe they have /etc/locales.build setup still ...
if [[ ${LOCALEGEN} == */etc/locale.gen ]] ; then
LOCALEGEN=${LOCALEGEN/%locale.gen/locales.build}
locales_to_generate=$(sed \
-e 's:#.*::' \
-e '/^[[:space:]]*$/d' \
-e 's:/: :g' \
"${LOCALEGEN}")
if [[ -n ${locales_to_generate} ]] && \
[[ ${QUIET} -eq 0 ]] && [[ -z ${JUST_LIST} ]]
then
ewarn "Automatically importing locales from /etc/locales.build ..."
ewarn "You really should do this yourself ...\n"
fi
fi
if [[ -z ${locales_to_generate} ]] ; then
[[ ${QUIET} -eq 0 ]] && [[ -z ${JUST_LIST} ]] && \
ewarn "No locales found"
exit 0
fi
fi
mkdir -p "${LOCALEDIR}"
if [[ -z ${KEEP} ]] ; then
# Remove all old locale dir and locale-archive before generating new
# locale data.
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:
# .[@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:\([^\@ ]*\)\([^ ]*\) \(.*\):\1.\3\2:' \
-e '/[^\@]/s:\([^. ]*\)\([^ ]*\) \(.*\):\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)"
ret=0
cnt=0
if [[ -n ${UPDATE} ]] ; then
# normalize newlines into spaces
existing_locales=" $(echo $(locale -a)) "
fi
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} ]] && \
[[ ${existing_locales} == *" $(normalize ${locale}) "* ]]
then
[[ ${QUIET} -eq 0 ]] && einfo " (${cnt}/${total}) Skipping ${disp}"
continue
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
if [[ -n ${ASK} ]] ; then
einfon " (${cnt}/${total}) Generate ${disp} ? (Y/n) "
read user_answer
[[ ${user_answer} == [nN]* ]] && continue
elif [[ ${QUIET} -eq 0 ]] ; then
ebegin " (${cnt}/${total}) Generating ${disp}"
fi
localedef ${LOCALEDEF_OPTS} \
-i "${input}" \
-f "${charmap}" \
-A "${ALIAS}" \
"${locale}"
my_ret=$?
((ret+=my_ret))
[[ -z ${ASK} ]] && [[ ${QUIET} -eq 0 ]] && eend ${my_ret}
else
echo "${disp}"
fi
done
[[ ${QUIET} -eq 0 ]] && [[ -z ${JUST_LIST} ]] && \
einfo "Generation complete"
exit ${ret}