mirror of
https://github.com/tcsenpai/UWINE.git
synced 2025-07-29 14:21:37 +00:00
382 lines
9.4 KiB
Bash
Executable File
382 lines
9.4 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# Copyright © 2019 Collabora Ltd.
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining
|
|
# a copy of this software and associated documentation files (the
|
|
# "Software"), to deal in the Software without restriction, including
|
|
# without limitation the rights to use, copy, modify, merge, publish,
|
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
# permit persons to whom the Software is furnished to do so, subject to
|
|
# the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included
|
|
# in all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
set -e
|
|
set -u
|
|
|
|
me="$0"
|
|
me="$(readlink -f "$0")"
|
|
here="${me%/*}"
|
|
me="${me##*/}"
|
|
|
|
opt_output_dir=.
|
|
opt_verbose=
|
|
|
|
# Look for try-setlocale helper executable next to this script
|
|
PATH="${here}:${PATH}"
|
|
|
|
LOCALE_ALIAS="/usr/share/locale/locale.alias"
|
|
|
|
if ! [ -f "$LOCALE_ALIAS" ]; then
|
|
LOCALE_ALIAS=
|
|
fi
|
|
|
|
# We currently only look for I18NDIR data in /usr/share/i18n, the
|
|
# glibc default path.
|
|
#
|
|
# Instead of just /usr/share/i18n/SUPPORTED, we also try to parse
|
|
# /etc/locale.gen because in some distributions, e.g. Arch Linux,
|
|
# /usr/share/i18n/SUPPORTED might not be present.
|
|
#
|
|
# If we discover that some distros use a different default, then we
|
|
# should enhance this script to iterate through a search path.
|
|
#
|
|
# Please keep this in sync with srt_system_info_get_locale_issues().
|
|
SUPPORTED="/etc/locale.gen /usr/share/i18n/SUPPORTED"
|
|
|
|
log () {
|
|
printf '%s\n' "$me: $*" >&2
|
|
}
|
|
|
|
verbose () {
|
|
if [ -n "$opt_verbose" ]; then
|
|
log "$@"
|
|
fi
|
|
}
|
|
|
|
# Return nonzero if the given locale cannot be generated normally.
|
|
can_generate () {
|
|
local locale="$1"
|
|
|
|
case "$locale" in
|
|
(C|C.UTF-8|C.utf8|POSIX|"")
|
|
return 1
|
|
;;
|
|
|
|
(*..*|*/*)
|
|
log "Avoiding potential path traversal in '$locale'"
|
|
return_ex_config=1
|
|
return 1
|
|
;;
|
|
|
|
(*)
|
|
return 0
|
|
;;
|
|
esac
|
|
}
|
|
|
|
generate_locale () {
|
|
local at_modifier=
|
|
local codeset=
|
|
local language=
|
|
local list=
|
|
local locale="$1"
|
|
local modifier=
|
|
local supported_codeset=
|
|
local territory=
|
|
local underscore_territory=
|
|
local without_codeset=
|
|
local status=
|
|
|
|
language="$locale"
|
|
|
|
case "$language" in
|
|
(*@*)
|
|
modifier="${language##*@}"
|
|
at_modifier="@${modifier}"
|
|
language="${language%@*}"
|
|
;;
|
|
esac
|
|
|
|
case "$language" in
|
|
(*.*)
|
|
codeset="${language##*.}"
|
|
language="${language%.*}"
|
|
;;
|
|
esac
|
|
|
|
case "$language" in
|
|
(*_*)
|
|
territory="${language##*_}"
|
|
underscore_territory="_${territory}"
|
|
language="${language%_*}"
|
|
;;
|
|
esac
|
|
|
|
# Speed up locale generation a bit by making e.g. en_GB.utf8 a
|
|
# symlink to en_GB.UTF-8
|
|
if [ "${codeset}" = 'utf8' ]; then
|
|
codeset="UTF-8"
|
|
locale="${language}${underscore_territory}.UTF-8${at_modifier}"
|
|
ln -fns "$locale" \
|
|
"${opt_output_dir}/${language}${underscore_territory}.utf8${at_modifier}"
|
|
|
|
if [ -d "$opt_output_dir/$locale" ]; then
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$codeset" ]; then
|
|
# We don't really need to parse $SUPPORTED to find out that
|
|
# en_US.UTF-8 is a UTF-8 locale. Do nothing. In particular,
|
|
# this works on distributions like Arch Linux that do not
|
|
# normally install $SUPPORTED.
|
|
:
|
|
else
|
|
for list in $SUPPORTED; do
|
|
if supported_codeset="$(
|
|
while read -r supported codeset; do
|
|
case "$supported" in
|
|
(\#*)
|
|
continue
|
|
;;
|
|
esac
|
|
|
|
if [ "$supported" = "$locale" ]; then
|
|
printf '%s' "$codeset"
|
|
fi
|
|
done < "$list"
|
|
)"; then
|
|
if [ -n "$supported_codeset" ]; then
|
|
break
|
|
fi
|
|
else
|
|
supported_codeset=
|
|
verbose "Unable to read $list"
|
|
fi
|
|
done
|
|
|
|
if [ -n "$supported_codeset" ]; then
|
|
codeset="$supported_codeset"
|
|
else
|
|
log "Unable to find $locale in $SUPPORTED"
|
|
log "Assuming UTF-8 and hoping that works..."
|
|
codeset="UTF-8"
|
|
fi
|
|
fi
|
|
|
|
without_codeset="${language}${underscore_territory}${at_modifier}"
|
|
|
|
if localedef \
|
|
${LOCALE_ALIAS+-A "${LOCALE_ALIAS}"} \
|
|
--no-archive \
|
|
-c \
|
|
-f "$codeset" \
|
|
-i "$without_codeset" \
|
|
"${opt_output_dir}/${locale}" \
|
|
; then
|
|
log "Generated locale $locale successfully"
|
|
else
|
|
status="$?"
|
|
|
|
if [ "$status" = 1 ]; then
|
|
log "Generated locale $locale, with warnings"
|
|
else
|
|
log "Unable to generate locale $locale: $status"
|
|
fi
|
|
fi
|
|
|
|
if ! LOCPATH="${opt_output_dir}" pressure-vessel-try-setlocale "$locale"; then
|
|
log "Warning: $locale was generated but does not appear to work!"
|
|
fi
|
|
}
|
|
|
|
usage () {
|
|
local code="$1"
|
|
shift
|
|
|
|
if [ "$code" -ne 0 ]; then
|
|
exec >&2
|
|
fi
|
|
|
|
echo "Usage: $me [OPTIONS] [LOCALE...]"
|
|
echo
|
|
echo "Generate the locales required by the locale environment"
|
|
echo "variables, and any extra locales from the command line,"
|
|
echo "in the current working directory."
|
|
echo
|
|
echo "Options:"
|
|
echo "--output-dir DIR, -o DIR"
|
|
echo " Create locales in the given directory [default: .]"
|
|
echo "--verbose Be more verbose"
|
|
echo
|
|
echo "Arguments:"
|
|
echo "LOCALE Zero or more locales in POSIX format,"
|
|
echo " such as en_US.UTF-8, be_BY@latin"
|
|
exit "$code"
|
|
}
|
|
|
|
getopt_temp="help"
|
|
getopt_temp="${getopt_temp},output-dir:,output-directory:"
|
|
getopt_temp="${getopt_temp},verbose"
|
|
|
|
getopt_temp="$(getopt -o 'o:' --long "$getopt_temp" -n "$me" -- "$@")"
|
|
eval "set -- $getopt_temp"
|
|
unset getopt_temp
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
(-o | --output-dir | --output-directory)
|
|
opt_output_dir="$2"
|
|
shift 2
|
|
;;
|
|
|
|
(--help)
|
|
usage 0
|
|
# not reached
|
|
;;
|
|
|
|
(--verbose)
|
|
opt_verbose=yes
|
|
shift
|
|
;;
|
|
|
|
(--)
|
|
shift
|
|
break
|
|
;;
|
|
|
|
(-*)
|
|
log "Unknown option: $1"
|
|
usage 64 # EX_USAGE from sysexits.h
|
|
# not reached
|
|
;;
|
|
|
|
(*)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
one_missing=
|
|
|
|
for var in \
|
|
LC_ADDRESS \
|
|
LC_CTYPE \
|
|
LC_COLLATE \
|
|
LC_IDENTIFICATION \
|
|
LC_MEASUREMENT \
|
|
LC_MESSAGES \
|
|
LC_MONETARY \
|
|
LC_NUMERIC \
|
|
LC_NAME \
|
|
LC_PAPER \
|
|
LC_TELEPHONE \
|
|
LC_TIME \
|
|
\
|
|
HOST_LC_ALL \
|
|
LANG \
|
|
LC_ALL \
|
|
; do
|
|
locale="$(eval "printf '%s' \${${var}-}")"
|
|
|
|
if [ -z "$locale" ] || ! can_generate "$locale"; then
|
|
continue
|
|
fi
|
|
|
|
if ! pressure-vessel-try-setlocale "$locale"; then
|
|
verbose "Missing locale $locale (found in \$$var)"
|
|
one_missing=yes
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -z "$one_missing" ]; then
|
|
for locale in en_US.UTF-8 "$@"; do
|
|
if ! can_generate "$locale" ; then
|
|
continue
|
|
fi
|
|
|
|
if ! pressure-vessel-try-setlocale "$locale"; then
|
|
verbose "Missing locale $locale"
|
|
one_missing=yes
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ -z "$one_missing" ]; then
|
|
verbose "No locales need to be generated"
|
|
exit 0
|
|
fi
|
|
|
|
# We have to generate all the locales we want, not just the ones that
|
|
# were missing, because they might have been in a locale archive,
|
|
# and setting LOCPATH disables use of the locale archive.
|
|
|
|
return_ex_cantcreat=
|
|
return_ex_config=
|
|
|
|
for var in \
|
|
LC_ADDRESS \
|
|
LC_CTYPE \
|
|
LC_COLLATE \
|
|
LC_IDENTIFICATION \
|
|
LC_MEASUREMENT \
|
|
LC_MESSAGES \
|
|
LC_MONETARY \
|
|
LC_NUMERIC \
|
|
LC_NAME \
|
|
LC_PAPER \
|
|
LC_TELEPHONE \
|
|
LC_TIME \
|
|
\
|
|
HOST_LC_ALL \
|
|
LANG \
|
|
LC_ALL \
|
|
; do
|
|
locale="$(eval "printf '%s' \${${var}-}")"
|
|
|
|
if [ -z "$locale" ] || ! can_generate "$locale" ; then
|
|
continue
|
|
fi
|
|
|
|
if ! [ -d "$opt_output_dir/$locale" ]; then
|
|
verbose "Generating locale $locale..."
|
|
generate_locale "$locale" || return_ex_cantcreat=yes
|
|
fi
|
|
done
|
|
|
|
for locale in en_US.UTF-8 "$@"; do
|
|
if ! can_generate "$locale" ; then
|
|
continue
|
|
fi
|
|
|
|
if ! [ -d "$opt_output_dir/$locale" ]; then
|
|
verbose "Generating locale $locale..."
|
|
generate_locale "$locale" || return_ex_cantcreat=yes
|
|
fi
|
|
done
|
|
|
|
if [ -n "$return_ex_config" ]; then
|
|
exit 78 # EX_CONFIG, "configuration error", from sysexits.h
|
|
elif [ -n "$return_ex_cantcreat" ]; then
|
|
exit 73 # EX_CANTCREATE, "can't create (user) output file"
|
|
else
|
|
exit 72 # EX_OSFILE, "OS file missing"
|
|
fi
|
|
|
|
# vim:set sw=4 sts=4 et:
|