#!/bin/sh
# locale-gen - compile the locales enabled in /etc/locale.gen into
# /usr/lib/locale/locale-archive (LE-OS).
#
#   locale-gen [--root DIR]
#
# /etc/locale.gen has one locale per line: NAME CHARSET, e.g. "en_US.UTF-8 UTF-8" or
# "de_DE@euro ISO-8859-15"; '#' starts a comment.  The archive is rebuilt from scratch,
# so a locale removed from the file disappears.  C.UTF-8 is built into glibc and needs
# no entry.  --root works on another system's tree (used by the glibc package's
# install script, which runs outside the target root).
set -eu

usage() { echo "usage: locale-gen [--root DIR]" >&2; }

root=
case ${1-} in
    "") ;;
    --root) [ $# -eq 2 ] || { usage; exit 2; }; root=${2%/} ;;
    -h|--help) usage; exit 0 ;;
    *) usage; exit 2 ;;
esac

conf=$root/etc/locale.gen
localedir=$root/usr/lib/locale
[ -f "$conf" ] || { echo "locale-gen: $conf not found" >&2; exit 1; }
command -v localedef >/dev/null || { echo "locale-gen: localedef not found" >&2; exit 1; }

# Locale sources and charmaps of the target tree, not of the running system.
I18NPATH=$root/usr/share/i18n
export I18NPATH

mkdir -p "$localedir"
rm -f "$localedir/locale-archive"

echo "Generating locales from $conf ..."
failed=0 count=0
# shellcheck disable=SC2034  # rest: anything after the charset is ignored
while read -r name charset rest; do
    case $name in ''|'#'*) continue ;; esac
    if [ -z "$charset" ]; then
        echo "  $name: no charset given, skipped" >&2
        failed=$((failed + 1)); continue
    fi
    # Source definition: the name without its .charset part, keeping an @modifier.
    input=${name%%.*}
    case $name in *.*@*) input=$input@${name#*@} ;; esac
    printf '  %s\n' "$name"
    rc=0
    if [ -n "$root" ]; then
        localedef --prefix="$root" -i "$input" -f "$charset" "$name" || rc=$?
    else
        localedef -i "$input" -f "$charset" "$name" || rc=$?
    fi
    # Exit status 1 means warnings only; the locale was still added.
    if [ "$rc" -gt 1 ]; then
        echo "  $name: localedef failed (exit $rc)" >&2
        failed=$((failed + 1))
    else
        count=$((count + 1))
    fi
done < "$conf"

if [ "$failed" -gt 0 ]; then echo "Generated $count locale(s), $failed failed."; else echo "Generated $count locale(s)."; fi
[ "$failed" -eq 0 ]
