commit 1f09eec603b8233bd1eef11b152efb980cd8cc93 Author: openKylinBot Date: Sat May 14 01:46:27 2022 +0800 Import Upstream version 2.71 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cc8d637 --- /dev/null +++ b/Makefile @@ -0,0 +1,56 @@ +all: check-scripts debian/languagelist.data debian/short-tmp/shortlists debian/templates check-scripts check-data check-utf8 + +LIST = languagelist + +debian/languagelist.data: $(LIST) + LC_COLLATE=C ./mklanguagelist.data $(LIST) debian/languagelist.data + +debian/templates.base: debian/localechooser.templates-in debian/iso_3166.tab + ./mktemplates.continents debian/iso_3166.tab regionmap debian/templates.continents + cat debian/localechooser.templates-in debian/templates.continents >debian/templates.base-in + ./mktemplates.base debian/templates.base-in debian/templates.base + +debian/iso-codes: + ./get-iso-codes + +debian/iso_3166.tab: + isoquery -c | cut -f 1,4 | sort >debian/iso_3166.tab + [ -s debian/iso_3166.tab ] + +debian/templates: $(LIST) debian/templates.base debian/short-tmp/shortlists + ./mktemplates.shortlist + ./mktemplates.warnings $(LIST) debian/templates + +debian/short-tmp/shortlists: debian/iso_3166.tab debian/iso-codes + ./mkshort + +check-scripts: + @set -e ; \ + if [ -x /bin/ash ] ; then SH=ash ; else SH=dash; fi ; \ + for s in finish-install.d/05localechooser post-base-installer.d/05localechooser debian/postinst languagemap localechooser ; do \ + echo "Checking syntax of $$s" ; \ + $$SH -n $$s ; \ + done + +check-utf8: $(LIST) + iconv -f utf-8 -t unicode $(LIST) > /dev/null + +check-data: + # Check that the listed locale is supported, to make sure it will work. + @for locale in `grep -v "^#" $(LIST) | cut -d\; -f6 | grep _` ; do \ + if grep -q "^$$locale " /usr/share/i18n/SUPPORTED ; then \ + : ; \ + else \ + echo "warning: locale $$locale not listed in /usr/share/i18n/SUPPORTED" ; \ + fi ; \ + done + +.PHONY: demo +localechooser.templates: debian/templates + grep -v '#' $^ > $@ +demo: localechooser.templates localechooser + DEBIAN_FRONTEND=dialog DEBCONF_DEBUG=developer /usr/share/debconf/frontend ./localechooser + +clean: + $(RM) localechooser.templates debian/templates debian/templates.continents debian/templates.base-in debian/templates.base debian/templates.tmp debian/languagelist.data debian/iso_3166.tab + $(RM) -rf debian/short-tmp debian/iso-codes diff --git a/README b/README new file mode 100644 index 0000000..1572d40 --- /dev/null +++ b/README @@ -0,0 +1,328 @@ +debian-installer locale chooser +=============================== + +The purpose of localechooser is to ask the person doing the +installation about his preferred language and country of "residence". +This information can be used to choose which language and country or +region to use during installation and set this language and country as +the default language and country after the installation. + +This information will be used for building a value for the general system +locale. + +This task was formerly split in two packages, named languagechooser +and countrychooser. As both interacted heavily, it was finally decided +to merge them, mostly because changing the language implied prompting +for the country again. + +When merging the package, a new question about the final locale was added. + +The language will be chosen among a list of "supported" languages. The +choice of language presets some country and locale -related values. + +The country choice question refines the country choice inherited from +the language choice. It allows choosing any "country" in the +world. Depending on the language+country combination, this will be +used for setting a default locale or not (see below for details). + +Finally, a lower priority question is shown to users so that they can +choose a locale based on the two former choices when several different +locales for a single language/country combination are supported in +Debian. + +"Language" here means any language Debian has been significantly +translated into. This may be a simple ISO-639 code such as "en" or +"de" or a language "variant" code such as "pt_BR" (Brazilian +Portuguese) or zh_TW (for Traditional Chinese). The tradition of +representing language variants may here be confusing as zh_TW seems to +be "Chinese as spoken in Taiwan" while it is indeed "Traditional +Chinese". Debian has just here kept the most common way to represent +these language flavours. + +"Country" here is meant to represent the place the user or the machine +is located. This value will be used for several location-related +settings as well as locale-related settings. The list of countries is +taken from the ISO-3166 standards. The names used are the "common" +names of these countries, as defined in the iso-codes package. + +The way both packages collaborate is somewhat complicated and will be +described in details below. The general rationale is about building a +value for the system locale which may be as close as possible of the +"real" locale (language+country). As not all language+country +combinations are currently supported in Debian, approximations will +occur in some cases. + +The mechanism is the following: +1) propose a language choice +2) propose a "short" list of countries with all countries for which + this language has a supported locale +3) optionally propose the whole list of world countries, split into + separate questions for first continent/area and the country +4) (for medium priority installs) prompt for a locale if several locales + (with different modifiers or charsets) exist for that language/country + combination + +This package should behave as follows: + + +Language choice +--------------- + +Which languages are supported depends on the installation method and on +the cdebconf frontend that is being used. +Currently 5 levels are distinguished: +- dumb or serial terminal -->level 0 (only ASCII) +- no framebuffer -->level 1 (only Latin1) +- font load support -->level 2 (256-glyph langs) +- framebuffer and non-graphical interface-->level 3 (no combining langs) +- framebuffer and graphical interface -->level 4 (all langs) + +Depending on these values, we use different templates with a different +list of languages. These lists are created at package build-time from +the contents of the second field of languagelist entries. + +When the gtk frontend is used, it is assumed that all languages are supported. + +The steps during language selection are: + + 0. Ask the user to pick one of the available languages. + + 1. Change presentation language in debconf. + (value debconf/language; content=language ISO-639 code plus + optionally language variant, for instance pt_BR) + + 2. Set the following variables for later use: + -debian-installer/language + LIST of languages in order of + preference. This will be a succession of several xx_YY values + where xx is a ISO-639 code for language and YY is an ISO-3166 + code for country. The list is to be read from left to right + with the preferred combination at the left + This is meant to be used as the LANGUAGE variable later + -debian-installer/country: + This value may be pre-feeded with an ISO-3166 name for a country + This should be done when only one country has a valid locale + for the given language. For other languages, with several + possible countries ("possible" here is "supported by locales"), + the country must NOT be set by languagechooser + -debian-installer/locale + This should be a single entry such as fr_CA + Each language MUST provide one, which will be the default for this + language + + This entry may be modified by the country choice running after + the language choice + -debian-installer/fallbacklocale This should be similar to the + "locale" value. This value will *never* change. The country + choice section will set debian-installer/locale to it when the + chosen country builds an unsupported locale + + 3. pass the locale information on to the modules that needs it. + +The language code is passed into cdebconf. The locale, country code +and priority list of languages are passed to the installed system +via the cdebconf database. + +Country choice +-------------- + +1) If a country code was set by the language choice section + ("mono country" languages....that is, languages for which only one + country gives a valid locale) + +-always keep the valid locale inherited from languagechooser for + debian-installer/locale + +-present user, at medium priority only, with a screen listing all + world countries + This value will see the debian-installer/country value with the ISO-3166 + code of the country. This value will only be used as a default for + location related choices such as the timezone or the mirror + +2) If NO country code was set after the language choice + (language with at least two countries with a valid locale + for this language) + +-always prompt the user (high priority) with a *short* list of all + countries for which a valid locale exists for this language + THIS LIST IS BUILT AT BUILD TIME for countrychooser, not on the fly + at install time. It is built only for languages which have a debconf + translation for countrychooser + + This short list includes an "other" choice. + +2a) If the user picks up one of the countries in the short list + the debian-installer/locale value is CHANGED to language_COUNTRY + +2b) If the user picks up the "other" choice + the debian-installer/locale is set to the "fallback-locale" value + debian-installer/fallbacklocale + +Locale choice +------------- + +When both language (xx) and country (YY) are set, the locale is +defined as follows: + +-if the language was mono-country AND the locale set *in the language section* + is *different* from xx_YY because it was set differently in languagelist, this + locale is kept. This special case was historically meant to deal with + the Norwegian locales transition mechanism (requiring to keep no_NO as locale + even if the language code became nb) + +-if at least one xx_YY locale exists in Debian: + + -the fallback locale set in the language selection part (3rd field of + the languagelist file) is examined and any modifier or charset is + added to xx_YY, leading to xx_YY@modifier.charset: + + -if this locale exists it is kept to debian-installer/locale + -if this locale does not exists, xx_YY is set as debian-installer/locale + +-if no xx_YY locale exists in Debian, the fallback locale (3rd field of + languagelist) is set as debian-installer/locale + +If LANG (locale) and/or LANGUAGE (priority list of language codes) was +passed as arguments to the kernel from the boot prompt, these values +should be used instead of presenting the user with questions. + +Locale choice +------------- +This part only happens at medium and low priority, for instance in "expert" +installs. + +The xx_YY value is grepped in the list of all supported locales in +Debian. The remaining list is presented to the user with the above +determined default value. + +This part allows for a final refinement of the locale without filling +default installs with a rather technical question. + +There have been request for the possibility of editing the priority +list of language codes to use. This might be done, with debconf +priority 'low' to make sure the question will be invisible for most +users. I [pere 2003-02-28] do not think this is needed in the general +installation, and will keep it out of the first version. +On 2004-06-07, this hasn't been achieved yet. + +Information passed into other modules +------------------------------------- + + cdebconf + + - (List of?) language codes to use when choosing which translation + to use. Inserted into the 'debconf/language' debconf template. + + kbd-chooser + + - Selects default keyboard based on the locale selected. This information + is passed on to base-config and console-tools. + + At the moment this documentation is being rewritten, this is a + rather obscure mechanism which need more documentation. Adding a + way for localechooser to preseed kbd-chooser would be a great + enhancement. + + choose-mirror + + - The country set is used as a default choice + + tzsetup + + - Timezone restricted list of choices based on the selected country + + locales + - The selected additional locales will be generated on the installed system + +Interaction with the lowmem package +----------------------------------- + +The lowmem package is triggered when the available memory prevents +using translations, because they eat a lot of space on the ramdisk. + +For this to work, lowmem must set debian-installer/locale to en_US and set +its seen flag. + +With this, the installation will continue with English and USA as +values for language and country and the user will not be prompted for +language and country. + +Technical details +----------------- + +Language choice +--------------- + +The core of the package are the languagelist and languagelist.l10n files. +For a language to appear in the language chooser screen it must have entries in both these files. + + languagelist + ------------ +The format if the following: + +Language;supported_environments;langcode;countrycode;fallbacklocale;langlist;console-package + where: + + -Language =language name, in English + It is recommended to refer to ISO-639 + -Supported env. =code to define in which environments this language + can be supported by the installer + 0=OK in ASCII-only environments + 1=OK in Latin-1 only environment (Linux console + without framebuffer, some serial consoles) + 2=OK with font loading support + 3=OK with the framebuffer console but not + possible to display in the regular Linux console + 4=OK only with the graphical installer + -langcode =iso-639 TWO characters language code + + DO NOT GUESS IT. Please check in the iso-codes + and locales packages + + Three letter language code may, at the moment + this documentation is written, trigger hidden + problems. If a new language has no two-letter ISO + code, then this problem should be sorted out. + + If we're lucky, everything is OK and 3-letter codes + will work..:-) + + -countrycode =default value for country choice in countrychoose + MUST be a valid ISO-3166 alpha-2 code + + DO NOT GUESS IT. Please check in the iso-codes + package + + -fallbacklocale =fallback locale (MUST be valid, except for modifier + see below) + This locale will be used in case the user goes to + the "other" choice in countrychooser and chooses a + country with "unsupported" locale + + It is recommended to use here the country where + the language is most widely spoken + + Any modifier (@euro for instance) or charset mentioned + here will be ADDED to the final locale if such combination + is supported. + + Example: Assume English uses "en_US@euro". + If the user chooses + USA as country, the @euro will be dropped as + these is no en_US@euro locale. However, if + Ireland is chosen, the locale will be en_IE@euro + + -langlist =colon-separated list of possible fallback languages + It will usually be empty except for languages + where fallback to something else than English is wished + + Setting this field will enforce setting LANGUAGE in + /etc/environment or /etc/default/locale + + Never add random languages without talking deeply + with the i18n coordinators. + + -console-package =which console package to install (console-data or + console-setup) -- option is probably obsolete + for the console-data package special settings can be added + (mostly keyboard or terminal settings) diff --git a/finish-install.d/05localechooser b/finish-install.d/05localechooser new file mode 100755 index 0000000..a7a0140 --- /dev/null +++ b/finish-install.d/05localechooser @@ -0,0 +1,30 @@ +#! /bin/sh + +set -e + +. /usr/share/debconf/confmodule + +ARCH=`udpkg --print-architecture` + +db_get debian-installer/locale +LOCALE="$RET" + +# Set locale to C if it has not yet been set +# This can happen during e.g. s390 installs where localechooser is not run +[ -z "$LOCALE" ] && LOCALE="C.UTF-8" + +LANGUAGE=${LOCALE%%_*} + +# Install specific packages depending on selected language + +if [ "$LOCALE" != "C" ] && [ "$LOCALE" != "C.UTF-8" ]; then + # Other language specific packages + case "$LANGUAGE" in + ar|he|fa) + # RTL languages (Arabic, Hebrew, Farsi) + apt-install libfribidi0 || true + ;; + esac +fi + +exit 0 diff --git a/get-iso-codes b/get-iso-codes new file mode 100755 index 0000000..97e5390 --- /dev/null +++ b/get-iso-codes @@ -0,0 +1,23 @@ +#!/bin/sh + +# Get ISO codes from the iso-codes package and extract translations +set -e + +rm -rf debian/iso-codes >/dev/null 2>&1 +mkdir debian/iso-codes + +for i in $(find /usr/share/locale/ -name iso_3166.mo); do + language=$(echo $i | cut -f5 -d/) + # If a file exists in iso-codes.updates, then use it + # else extract translations from the iso-codes package + if [ ! -f iso-codes.updates/$language.po ]; then + msgunfmt $i >debian/iso-codes/${language}.po 2>/dev/null + else + cp iso-codes.updates/$language.po debian/iso-codes + fi +done + +# If no iso-codes translation is available for se, then use nb instead +if [ ! -f debian/iso-codes/se.po ] && [ -f debian/iso-codes/nb.po ]; then + cp debian/iso-codes/nb.po debian/iso-codes/se.po +fi diff --git a/languagelist b/languagelist new file mode 100644 index 0000000..e881403 --- /dev/null +++ b/languagelist @@ -0,0 +1,107 @@ +# +# This is the complete list of languages (locales) to choose from. +# langcode;language (en);language (orig);supported_environments;countrycode;fallbacklocale;langlist;console-setup +sq;Albanian;Shqip;2;AL;sq_AL.UTF-8;;console-setup +am;Amharic;አማርኛ;4;ET;am_ET;; +ar;Arabic;عربي;3;EG;ar_EG.UTF-8;;console-setup +ast;Asturian;Asturianu;2;ES;ast_ES.UTF-8;;console-setup +eu;Basque;Euskara;1;ES;eu_ES.UTF-8;;console-setup +be;Belarusian;Беларуская;2;BY;be_BY.UTF-8;;console-setup +bn;Bangla;বাংলা;4;BD;bn_BD;; +bs;Bosnian;Bosanski;2;BA;bs_BA.UTF-8;;console-setup +#X br;Breton;Brezhoneg;2;FR;br_FR.UTF-8;;console-setup +bg;Bulgarian;Български;2;BG;bg_BG.UTF-8;;console-setup +bo;Tibetan;བོད་ཡིག;4;IN;bo_IN;; +# For C locale, set language to 'en' to make sure questions are "translated" +# to English instead of showing codes. +C;C;No localization (ASCII);0;;C;en; +C.UTF-8;C.UTF-8;No localization (UTF-8);0;;C.UTF-8;en; +ca;Catalan;Català;1;ES;ca_ES.UTF-8;;console-setup +# Special case for Chinese as the two flavours share the same ISO 639 code +# Both will trigger countrychooser. Each will be the backup for the other +# one +zh_CN;Chinese (Simplified);中文(简体);3;CN;zh_CN.UTF-8;zh_CN:zh; +zh_TW;Chinese (Traditional);中文(繁體);3;TW;zh_TW.UTF-8;zh_TW:zh; +#X the;Chitwania Tharu;थारु;4;NP;the_NP;;console-setup +hr;Croatian;Hrvatski;2;HR;hr_HR.UTF-8;;console-setup +cs;Czech;Čeština;2;CZ;cs_CZ.UTF-8;;console-setup +da;Danish;Dansk;1;DK;da_DK.UTF-8;;console-setup +nl;Dutch;Nederlands;1;NL;nl_NL.UTF-8;;console-setup +dz;Dzongkha;རྫོང་ཁ།;4;BT;dz_BT;; +en;English;English;0;US;en_US.UTF-8;;console-setup +# The Esperanto locale is eo.UTF-8 +# so no country on purpose. The default country is Antarctica because... +# ...why not..:-) +eo;Esperanto;Esperanto;2;AQ;eo.UTF-8;;console-setup +et;Estonian;Eesti;2;EE;et_EE.UTF-8;;console-setup +fi;Finnish;Suomi;1;FI;fi_FI.UTF-8;;console-setup +fr;French;Français;1;FR;fr_FR.UTF-8;;console-setup +gl;Galician;Galego;1;ES;gl_ES.UTF-8;;console-setup +ka;Georgian;ქართული;4;GE;ka_GE.UTF-8;;console-setup +de;German;Deutsch;1;DE;de_DE.UTF-8;;console-setup +el;Greek;Ελληνικά;2;GR;el_GR.UTF-8;;console-setup +gu;Gujarati;ગુજરાતી;4;IN;gu_IN;; +he;Hebrew;עברית;3;IL;he_IL.UTF-8;;console-setup +hi;Hindi;हिन्दी ;4;IN;hi_IN;; +hu;Hungarian;Magyar;2;HU;hu_HU.UTF-8;;console-setup +is;Icelandic;Íslenska;1;IS;is_IS.UTF-8;;console-setup +id;Indonesian;Bahasa Indonesia;1;ID;id_ID.UTF-8;;console-setup +ga;Irish;Gaeilge;1;IE;ga_IE.UTF-8;;console-setup +it;Italian;Italiano;1;IT;it_IT.UTF-8;;console-setup +#X jam;Jamaican Creole English;Jamaican Creole English;1;JM;jam_JM;;console-setup +ja;Japanese;日本語;3;JP;ja_JP.UTF-8;; +#X ks;Kashmiri;कोशुर;4;IN;ks_IN;; +kk;Kazakh;Қазақ;2;KZ;kk_KZ.UTF-8;;console-setup +km;Khmer;ខ្មែរ;4;KH;km_KH;; +kn;Kannada;ಕನ್ನಡ;4;IN;kn_IN;; +ko;Korean;한국어;3;KR;ko_KR.UTF-8;; +ku;Kurdish;Kurdî;2;TR;ku_TR.UTF-8;;console-setup +#X ky;Kirghiz;Кыргызча;2;KG;ky_KG;;console-setup +lo;Lao;ລາວ;4;LA;lo_LA;;console-setup +lv;Latvian;Latviski;2;LV;lv_LV.UTF-8;;console-setup +lt;Lithuanian;Lietuviškai;2;LT;lt_LT.UTF-8;;console-setup +#X mg;Malagasy;Malagasy;1;MG;mg_MG.UTF-8;mg_MG:fr_FR:fr:en;console-setup +#X ms;Malay;Bahasa Malaysia;1;MY;ms_MY.UTF-8;;console-setup +ml;Malayalam;മലയാളം;4;IN;ml_IN;; +mr;Marathi;मराठी;4;IN;mr_IN;; +mk;Macedonian;Македонски;2;MK;mk_MK.UTF-8;;console-setup +my;Burmese; မြန်မာစာ;4;MM;my_MM;; +ne;Nepali;नेपाली ;4;NP;ne_NP;; +# The Sami translation is really incomplete. We however keep Sami on request +# of Skolelinux as a kind of reward to them..:-). They need to be able to +# choose Sami as an option so that the Sami locale is set as default +se_NO;Northern Sami;Sámegillii;1;NO;se_NO;se_NO:nb_NO:nb:no_NO:no:nn_NO:nn:da:sv:en;console-setup +nb_NO;Norwegian Bokmaal;Norsk bokmål;1;NO;nb_NO.UTF-8;nb_NO:nb:no_NO:no:nn_NO:nn:en;console-setup +nn_NO;Norwegian Nynorsk;Norsk nynorsk;1;NO;nn_NO.UTF-8;nn_NO:nn:no_NO:no:nb_NO:nb:en;console-setup +#X os;Ossetian;Ирон æвзаг;3;RU;os_RU;;console-setup +fa;Persian;فارسی;3;IR;fa_IR;;console-setup +pl;Polish;Polski;2;PL;pl_PL.UTF-8;;console-setup +pt;Portuguese;Português;1;PT;pt_PT.UTF-8;pt:pt_BR:en;console-setup +pt_BR;Portuguese (Brazil);Português do Brasil;1;BR;pt_BR.UTF-8;pt_BR:pt:en;console-setup +pa;Punjabi (Gurmukhi);ਪੰਜਾਬੀ;4;IN;pa_IN;; +ro;Romanian;Română;2;RO;ro_RO.UTF-8;;console-setup +ru;Russian;Русский;2;RU;ru_RU.UTF-8;;console-setup +#X sa;Sanskrit;संस्कृत;4;IN;sa_IN;; +#X sd;Sindhi;سنڌي;3;PK;sd_PK.UTF-8;;console-setup +si;Sinhala;සිංහල;4;LK;si_LK;; +sr;Serbian (Cyrillic);Српски;2;RS;sr_RS;;console-setup +#X sr@latin;Serbian (Latin);Srpski;2;RS;sr_RS@latin;;console-setup +szl;Silesian;Ślůnski;2;PL;szl_PL;; +sk;Slovak;Slovenčina;2;SK;sk_SK.UTF-8;;console-setup +sl;Slovenian;Slovenščina;2;SI;sl_SI.UTF-8;;console-setup +es;Spanish;Español;1;ES;es_ES.UTF-8;;console-setup +sv;Swedish;Svenska;1;SE;sv_SE.UTF-8;;console-setup +tl;Tagalog;Tagalog;1;PH;tl_PH.UTF-8;;console-setup +ta;Tamil;தமிழ்;4;IN;ta_IN;; +te;Telugu;తెలుగు;4;IN;te_IN;; +tg;Tajik;Тоҷикӣ;2;TJ;tg_TJ.UTF-8;;console-setup +th;Thai;ภาษาไทย;3;TH;th_TH.UTF-8;;console-setup +tr;Turkish;Türkçe;2;TR;tr_TR.UTF-8;;console-setup +ug;Uyghur;ئۇيغۇرچە;3;CN;ug_CN;; +uk;Ukrainian;Українська;2;UA;uk_UA.UTF-8;;console-setup +#X ur;Urdu;اردو;3;PK;ur_PK.UTF-8;;console-setup +#X ca@valencia;Valencian-Catalan;Valencià-Català;1;ES;ca_ES.UTF-8@valencia;;console-setup +vi;Vietnamese;Tiếng Việt;3;VN;vi_VN;;console-setup +cy;Welsh;Cymraeg;2;GB;cy_GB.UTF-8;;console-setup +#X wo;Wolof;Wolof;2;SN;wo_SN;wo:fr:en; +#X xh;Xhosa;Xhosa;2;ZA;xh_ZA.UTF-8;;console-setup diff --git a/languagemap b/languagemap new file mode 100644 index 0000000..9b48509 --- /dev/null +++ b/languagemap @@ -0,0 +1,46 @@ +#!/bin/sh +# +# Usage: +# LANGNAME= +# . languagemap +# +# The calling script should provide the log() function + +for list in /etc/languagelist /usr/share/localechooser/languagelist ./languagelist; do + if [ -f "$list" ]; then + languages="$list" + break + fi +done + +log "Language = '$LANGUAGE'" + +line=$(grep "^$LANGUAGE;" $languages || true) +log "line=$line" + +DEFAULT_COUNTRY="" +DEFAULT_LOCALE="" +LANGUAGELIST="" +CONSOLE="" + +if [ "$line" ] ; then + OLD_IFS="$IFS" + IFS=';' + set $line + IFS="$OLD_IFS" + + if [ "$3" ]; then DEFAULT_COUNTRY="$3"; fi + if [ "$4" ]; then DEFAULT_LOCALE="$4"; fi + if [ "$5" ]; then LANGUAGELIST="$5"; fi + if [ "$6" ]; then CONSOLE="$6"; fi + + if [ -z "$LANGUAGELIST" ] ; then + LANGUAGELIST="$LANGUAGE" + fi +else + log "error: Unable to locate info for language '$LANGUAGE'" + LANGUAGE=C.UTF-8 + DEFAULT_COUNTRY=US + DEFAULT_LOCALE=C.UTF-8 + LANGUAGELIST=en +fi diff --git a/localechooser b/localechooser new file mode 100644 index 0000000..f66a02f --- /dev/null +++ b/localechooser @@ -0,0 +1,946 @@ +#!/bin/sh +set -e + +. /usr/share/debconf/confmodule + +db_capb backup + +tpl_di_locale="debian-installer/locale" +tpl_di_language="debian-installer/language" +tpl_di_country="debian-installer/country" +tpl_di_consoledisplay="debian-installer/consoledisplay" +tpl_languagelist="localechooser/languagelist" +tpl_shortlist="localechooser/shortlist" +tpl_continentlist="localechooser/continentlist" +tpl_countrylist="localechooser/countrylist" +tpl_countrytxt="localechooser/text/country" +tpl_supportedlocales="localechooser/supported-locales" +tpl_preferredlocale="localechooser/preferred-locale" + +SUPPORTEDLOCALES=/usr/share/localechooser/SUPPORTED +if [ ! -f "$SUPPORTEDLOCALES" ]; then + SUPPORTEDLOCALES=/usr/share/i18n/SUPPORTED +fi +SHORTLISTS=/etc/shortlists +if [ ! -f "$SHORTLISTS" ]; then + SHORTLISTS=/usr/share/localechooser/shortlists +fi +LANGUAGELISTFILE=/usr/share/localechooser/languagelist +LANGUAGELISTDATA=/usr/share/localechooser/languagelist.data.gz + +ORIG_IFS="$IFS" +NL=" +" + +error() { + logger -t localechooser "error: $@" + exit 1 +} + +log() { + logger -t localechooser "info: $@" +} + + +locale2countrycode() { + if [ -n "$1" ]; then + if echo $1 | grep -q "_"; then + echo $1 | cut -f2 -d_ | cut -f1 -d@ | cut -f1 -d\. + else + echo + fi + else + error "Missing argument" + fi +} + +choices_add() { + echo "${1:+$1, }$2" +} + +# Determine the display level +language_display_level() { + local level + + #log "Frontend in use: $DEBIAN_FRONTEND" + case $DEBIAN_FRONTEND in + gtk) + level=4 ;; + *) + # We can not know what the ssh client supports, let it have + # everything. + if [ "$SSH_CLIENT" ]; then + level=4 + elif [ "$TERM_FRAMEBUFFER" ]; then + level=3 + else + # Keep only Latin1 languages if we don't have a framebuffer + if [ -x /usr/share/console-setup/font-switch ] + then + level=2 + else + level=1 + fi + fi + # The hurd text-mode console has decent charset support + if [ "$TERM" = "hurd" ]; then + level=3 + fi + # ASCII only if we are on serial console, dumb, or Mach terminal + # Both variables should already be set at init time + if [ "$TERM_TYPE" = "serial" ] || [ "$TERM" = "dumb" ] || [ "$TERM" = "mach-gnu-color" ] ; then + level=0 + fi + ;; + esac + + if [ "$OVERRIDE_SHOW_ALL_LANGUAGES" ]; then + level=4 + fi + #log "Language display level is $level" + echo $level +} + +# Build list of available languages for a display level +build_language_template() { + local level=$1 + local oldlevel=$(cat /var/lib/localechooser/langlevel \ + 2>/dev/null || true) + if [ "$level" = "$oldlevel" ]; then + return 0 + fi + + local IFS RET line name codes names_en names_both + rm -f /var/lib/localechooser/langlevel + + IFS="$NL" + for line in $(zcat $LANGUAGELISTDATA | grep -a "^[0-$level]:"); do + name="$(echo "$line" | cut -d: -f3)" + codes="$(choices_add "$codes" \ + "$(echo "$line" | cut -d: -f2)")" + names_en="$(choices_add "$names_en" \ + "$name")" + names_both="$(choices_add "$names_both" \ + "$name\${!TAB}-\${!TAB}$(echo "$line" | cut -d: -f4)")" + done + IFS="$ORIG_IFS" + + db_subst $tpl_languagelist CODES "$codes" + db_subst $tpl_languagelist NAMES_EN "$names_en" + db_subst $tpl_languagelist NAMES_BOTH "$names_both" + + echo $level >/var/lib/localechooser/langlevel +} + +get_preseed() { + local template="$1" + local RET value + + if db_get "$template" && [ "$RET" ]; then + value="$RET" + db_fget "$template" seen + log "$template preseeded to '$value' (seen: $RET)" + + echo "$value" + fi +} + +do_preseed() { + local RET ps_language ps_country ps_locale seenflag + + ps_language=$(get_preseed $tpl_di_language) + ps_country=$(get_preseed $tpl_di_country) + ps_locale=$(get_preseed $tpl_di_locale) + + # Only mark variables seen if locale is valid and was preseeded seen. + db_fget $tpl_di_locale seen + seenflag=$RET + db_fset $tpl_di_locale seen false || true + + # If language or country are preseeded the regular code will handle it, + # otherwise set default language and/or country based on locale + if [ "$ps_language" ] || [ "$ps_country" ]; then + if [ "$ps_language" ] && + ! has_choice $tpl_languagelist $ps_language; then + log "Preseeded language ignored: unknown language code" + fi + if [ "$ps_country" ]; then + country_preseeded=1 + fi + if [ "$ps_locale" ]; then + if grep -q "^$ps_locale " $SUPPORTEDLOCALES; then + db_fset $tpl_di_locale seen $seenflag || true + db_fset $tpl_supportedlocales seen $seenflag || true + locale_preseeded=1 + else + log "Preseeded locale ignored: unsupported locale" + fi + fi + return + elif [ -z "$ps_locale" ]; then + return # no preseeding + fi + + # Only populate debconf if this is a supported locale + # and if the language is supported in D-I + ps_language=${ps_locale%%.*} + if ! has_choice $tpl_languagelist "$ps_language"; then + ps_language=${ps_language%%_*} + if ! has_choice $tpl_languagelist "$ps_language"; then + log "Preseeded locale ignored: unsupported language" + return + fi + fi + + db_set $tpl_languagelist $ps_language + log "Set $tpl_languagelist = '$ps_language'" + db_fset $tpl_languagelist seen $seenflag || true + ps_country=$(locale2countrycode "$ps_locale") + if [ -n "$ps_country" ]; then + db_set $tpl_di_country "$ps_country" + log "Set $tpl_di_country = '$ps_country'" + db_fset $tpl_di_country seen $seenflag || true + country_preseeded=1 + + # Avoid (accidental) preseeding of legacy locales + if [ "$ps_locale" != "${ps_language}_$ps_country" ] && \ + grep -q "^$ps_locale " $SUPPORTEDLOCALES; then + db_set $tpl_di_locale $ps_locale + db_fset $tpl_di_locale seen $seenflag || true + db_fset $tpl_supportedlocales seen $seenflag || true + log "Set $tpl_di_locale = '$ps_locale'" + locale_preseeded=1 + fi + fi +} + +# Install specific packages depending on selected language +# Those we install here are those required immediately +# Otherwise we will install them in finish-install +install_lang_specific() { + if [ "$DEFAULT_LOCALE" != C ] && [ "$DEFAULT_LOCALE" != C.UTF-8 ]; then + case "$LANGUAGE" in + ar|el|fa|he|ja|ko|ku|tr|vi|wo|zh*) + # We need a complete font for later steps + anna-install bterm-unifont + ;; + esac + fi +} + +# Change language and switch font for graphical installer +set_debconf_language() { + local RET + + db_set "debconf/language" "$1" + + if type gtk-set-font >/dev/null 2>&1; then + gtk-set-font || true + fi +} + +# Determine which template to display to warn for incomplete translations +# and fill in the variable contents +warning_template() { + local RET status template tbase twarn tabort + status=$1 + tbase=localechooser/translation + + case $status in + 0) twarn=incomplete; tabort=abort ;; + 1) twarn=normal-ok; tabort=abort ;; + 2) twarn=partial; tabort=maybe-abort ;; + 3) twarn=mostly-ok ;; + 4) twarn=exceptions ;; + esac + if [ $status -le 2 ]; then + template=$tbase/warn-severe + db_metaget $tbase/text/$tabort description + db_subst $template TXT-ABORT "$RET" + else + template=$tbase/warn-light + fi + + # Languages that have fallbacks may have special templates + if [ "$twarn" != exceptions ] && \ + expr $LANGUAGELIST : ".*:" >/dev/null && \ + db_metaget $tbase/text/warn_$twarn/$LANGUAGE description; then + : + else + db_metaget $tbase/text/warn_$twarn description + fi + db_subst $template TXT-WARN "$RET" + + echo $template +} + +# Return the first language in the list that's listed in the +# language selection dialog +get_current_language() { + local OLDIFS="$IFS" + local IFS lang + + db_get $tpl_di_language + IFS=: + for lang in $RET; do + IFS="$OLDIFS" + if has_choice $tpl_languagelist $lang; then + echo $lang + break + fi + done +} + +# Test if a template has the requested value among its choices +has_choice() { + local RET template value + template="$1" + value="$2" + + [ "$value" ] || return 1 + + db_metaget $template Choices-C + echo " $RET," | grep -q " $value," +} + +# Get translation of current selection in select list +# Assumes untranslated values don't contain commas +choice_trans() { + local RET template value list list_trans + template=$1 + value=$2 + + # Use Choices-C to get the untranslated values + db_metaget $template Choices-C + list=$(echo $RET | sed 's/, */,/g') + db_metaget $template Choices + list_trans=$(echo $RET | sed 's/\\,/#%#/g; s/, */,/g') + + while :; do + if [ "${list%%,*}" = "$value" ]; then + echo "${list_trans%%,*}" | sed 's/#%#/\\,/g' + break + fi + list=${list#*,} + list_trans=${list_trans#*,} + done +} + +# Set defaults for continent based on country +set_default_continent() { + local IFS RET country continents c continent + country="$1" + + if [ -z "$country" ]; then + db_reset $tpl_continentlist + return + fi + + # Use Choices-C to get the untranslated values + db_metaget $tpl_continentlist Choices-C + continents=$(echo $RET | sed 's/, */,/g') + + IFS=, + for continent in $continents; do + IFS="$ORIG_IFS" + c=$(echo "$continent" | sed "s/ /_/g") + if has_choice $tpl_countrylist/$c "$country"; then + db_set $tpl_continentlist "$continent" + return 0 + fi + done + return 1 +} + +# Test if a locale includes a country part +is_complete_locale() { + echo "$1" | grep -q "_" +} + +# Find a supported locale which best fits the selected language and country. +# Refinement: use the modifier inherited from language selection (if the +# resulting locale is valid). +get_default_locale() { + local lang fallback entry + lang=${LANGUAGE%%_*} + + # Special handling of cases where the locale defined in the + # language list is NOT the combination of language_COUNTRY. + # Used for Norwegian Bokmal transition in order to keep no_NO as + # locale. May be used in the future for other special cases, so + # we'd better keep this. + fallback=$(echo "$DEFAULT_LOCALE" | sed -e 's/[.@].*$//') + if [ "$COUNTRYCODE" = "$DEFAULT_COUNTRY" ] && \ + [ "${lang}_$COUNTRYCODE" != "$fallback" ] && \ + is_complete_locale "$fallback"; then + # Explanation: we fall back to the locale inherited from the + # language step if the country selection did NOT result in + # a change in country but the resulting locale is different + # from the one we had in first step. + return + fi + + # Check if a valid locale exists for the selected language + country + for entry in ${lang}_$COUNTRYCODE$DEFAULT_LOCALE_POSTFIX \ + ${lang}_$COUNTRYCODE; do + if grep -q "^$entry " $SUPPORTEDLOCALES; then + echo "$entry" + break + fi + done +} + +build_preferredlocale_choices() { + local script="$(echo "$1" | cut -f2 -d@)" + local lang=${1%%_*} # strip country part + local default=$2 + local i ccode country locale + local sl_choices_c sl_choices choices_c choices + + db_metaget $tpl_shortlist choices-c + sl_choices_c="$(echo "$RET" | sed 's/, */,/g')" + db_metaget $tpl_shortlist choices + # Allow for escaped comma's in country names + sl_choices="$(echo "$RET" | sed 's/\\,/#%#/g; s/, */,/g')" + + i=1 + while :; do + ccode="$(echo "$sl_choices_c" | cut -d, -f $i)" + if [ -z "$ccode" ] || [ "$ccode" = other ]; then + break + fi + country="$(echo "$sl_choices" | cut -d, -f $i)" + i=$(($i + 1)) + + if grep -q "^${lang}_$ccode\.UTF-8 " $SUPPORTEDLOCALES; then + locale=${lang}_$ccode.UTF-8 + elif grep -q "^${lang}_$ccode " $SUPPORTEDLOCALES; then + locale=${lang}_$ccode + else + continue + fi + + choices_c="${choices_c:+$choices_c, }$locale" + choices="${choices:+$choices, }$country\${!TAB}-\${!TAB}$locale" + + if [ "$locale" = "$default" ]; then + db_set $tpl_preferredlocale $LOCALE + fi + done + choices="$(echo "$choices" | sed 's/#%#/\\,/g')" + db_subst $tpl_preferredlocale CHOICES-C "$choices_c" + db_subst $tpl_preferredlocale CHOICES "$choices" +} + +# Also allows to preseed with only comma as separator +validate_supportedlocales() { + local choices="$1" + local locale current new + local english= + + db_get $tpl_supportedlocales + current="$(echo "$RET" | sed 's/, */ /g')" + for locale in $current; do + if echo ", $choices, " | grep -q ", $locale, "; then + new="${new:+$new, }$locale" + fi + if [ "$locale" = C ] || [ "$locale" = C.UTF-8 ] || [ "$locale" = en_US.UTF-8 ]; then + english=1 + fi + done + # Always support English (unless preseeded otherwise), so that we + # get English language packs etc. + if [ "$english" ]; then + db_set $tpl_supportedlocales "$new" + else + db_set $tpl_supportedlocales "${new:+$new, }en_US.UTF-8" + fi +} + +# Extract a value from /etc/lsb-release +lsb_extract () { + [ -f /etc/lsb-release ] || return 0 + grep "^$1=" /etc/lsb-release | \ + sed 's/^[^=]*=//; s/^"//; s/"$//' || true +} + + +# debconf/language is an alias for debian-installer/language +db_register "$tpl_di_language" "debconf/language" + +# Only display the translated texts (ie the English "translation") when in +# UTF-8 mode. Note: seems the only case this triggers is serial console; +# probably not needed anymore: we already limit which languages we display. +if echo $LANG $LC_CTYPE | grep -q UTF-8; then + INITIAL_LANGUAGE=en +else + INITIAL_LANGUAGE="" +fi + +# Find the display level and set languages in the template +# Needs to be done before checking preseeding, so we can preseed the +# correct template. +build_language_template $(language_display_level) + +# Only check for preseeding the first time localechooser is run. +country_preseeded="" +locale_preseeded="" +if [ ! -f /var/lib/localechooser/preseeded ]; then + do_preseed + >/var/lib/localechooser/preseeded +fi + +db_fget $tpl_languagelist seen +if [ "$RET" = true ]; then + db_get $tpl_languagelist + PREVIOUS_LANGUAGE="$RET" +else + PREVIOUS_LANGUAGE="" +fi + + +# Main loop starts here +# Use a state machine to allow jumping back to previous questions. +# Main states are multiples of 10 to allow "preparation" states to be +# skipped when backing up. +STATE=10 +LASTSTATE=0 +while :; do + case $STATE in + 0) # Back up to menu + exit 10 + ;; + + 10) # Display language list + db_settitle localechooser/title/language + + if [ -x /usr/share/console-setup/font-switch ] + then + /usr/share/console-setup/font-switch "$INITIAL_LANGUAGE" + fi + + if [ -x /usr/lib/espeakup/espeakup.restart ] + then + /usr/lib/espeakup/espeakup.restart "$INITIAL_LANGUAGE" + fi + + sel_language=1 + # Disabled because of #470258: template is set to true too early + if false && \ + db_get debconf/translations-dropped && [ "$RET" = true ]; then + db_fget $tpl_di_language seen + if [ "$RET" != true ]; then + sel_language="" + db_input high localechooser/translation/no-select || true + fi + else + # Set initial language for correct display of list + set_debconf_language $INITIAL_LANGUAGE + + db_get $tpl_languagelist + if [ "$RET" != C ] && [ "$RET" != C.UTF-8 ]; then + current_language=$(get_current_language) + if [ "$current_language" ]; then + db_set $tpl_languagelist $current_language + db_fget $tpl_di_language seen + db_fset $tpl_languagelist seen $RET || true + fi + fi + + db_capb backup align + db_input critical $tpl_languagelist || [ $? -eq 30 ] + fi + ;; + + 11) # We have a language + db_get $tpl_languagelist + LANGUAGE="$RET" + + if [ -x /usr/share/console-setup/font-switch ] + then + /usr/share/console-setup/font-switch "$LANGUAGE" + fi + + if [ -x /usr/lib/espeakup/espeakup.restart ] + then + /usr/lib/espeakup/espeakup.restart "$LANGUAGE" + fi + + if [ "$LANGUAGE" = "$PREVIOUS_LANGUAGE" ]; then + # The user picked the same language as before. We + # don't need to reset the default country and + # locale, and doing so may be confusing. + STATE=12 + continue + fi + + # Determine defaults based on languagelist + . languagemap + db_set "$tpl_di_language" "$LANGUAGELIST" + log "Set $tpl_di_language = '$LANGUAGELIST'" + + if [ -n "$DEFAULT_COUNTRY" ]; then + log "Default country = '$DEFAULT_COUNTRY'" + fi + if [ -n "$DEFAULT_LOCALE" ]; then + log "Default locale = '$DEFAULT_LOCALE'" + fi + + db_set "$tpl_di_consoledisplay" "$CONSOLE" + log "Set $tpl_di_consoledisplay = '$CONSOLE'" + + X_INSTALLATION_MEDIUM="$(lsb_extract X_INSTALLATION_MEDIUM)" + if [ "$sel_language" ] && [ $LANGUAGE != en ] && \ + [ "$X_INSTALLATION_MEDIUM" = "floppy" ]; then + db_input high localechooser/translation/none-yet || true + fi + + # The language was changed, so a preseeded locale is no + # longer relevant. + locale_preseeded="" + ;; + + 12) # Warn if translation is incomplete + set_debconf_language "$LANGUAGELIST" + + # Display warning for incomplete translations; skip it for + # automated installs to prevent a loop if the default is false + twarning="" + if [ "$sel_language" ] && \ + db_get debconf/priority && [ "$RET" != critical ] && \ + tstatus=$(translation-check "$LANGUAGE"); then + twarning=$(warning_template $tstatus) + db_input high $twarning || [ $? -eq 30 ] + fi + ;; + + 13) # Continue or choose alternative language + if [ "$twarning" ]; then + if db_get $twarning && [ "$RET" = false ]; then + db_reset $twarning + STATE=10 + continue + fi + fi + + install_lang_specific + + # Display language selection on backup or rerun + db_fset $tpl_di_language seen false || true + STATE=19 + continue + ;; + + 19) # Prepare for country selection + FIRST_LANG="${LANGUAGELIST%%:*}" + + # We use /etc/shortlists to check if we should present a shortlist + # As we may unregister the question for shortlists, the value for the + # shortlist template is also saved with the language specific question + use_lang="" + if [ "$DEFAULT_LOCALE" != C ] && [ "$DEFAULT_LOCALE" != C.UTF-8 ]; then + if grep -q "^$FIRST_LANG" $SHORTLISTS; then + use_lang=$FIRST_LANG + elif grep -q "^$LANGUAGE" $SHORTLISTS; then + use_lang=$LANGUAGE + fi + fi + + db_metaget $tpl_countrytxt/1/country description + ctxt1=$RET + db_metaget $tpl_countrytxt/2 description + ctxt2=$RET + + shortlist_prio=critical + continent_prio=critical + country_prio=critical + ;; + + 20) # Display a country shortlist if there is one + db_settitle localechooser/title/location + + askedshort= + db_get $tpl_di_country + current_country="$RET" + + # Prompt with the short list for languages that are listed + # in /etc/shortlists; for others prompt with all continents + # and countries. + if [ "$use_lang" ]; then + shortlist_template="$tpl_shortlist/$use_lang" + db_unregister $tpl_shortlist || true + db_register $shortlist_template $tpl_shortlist + + db_fget $tpl_di_country seen + db_fset $tpl_shortlist seen $RET || true + db_subst $tpl_shortlist TXT1 "$ctxt1" + db_subst $tpl_shortlist TXT2 "$ctxt2" + db_metaget $tpl_countrytxt/3/shortlist description + db_subst $tpl_shortlist TXT3 "$RET" + + # Set default value + if [ $LASTSTATE -ne 21 ]; then + current_short="" + if [ "$current_country" ]; then + if has_choice $tpl_shortlist "$current_country"; then + current_short="$current_country" + else + current_short=other + fi + elif has_choice $tpl_shortlist "$DEFAULT_COUNTRY"; then + current_short="$DEFAULT_COUNTRY" + fi + db_set $tpl_shortlist "$current_short" + fi + + # If a preseeded value is not in the shortlist, skip + # to continent/country dialogs + if ! ([ "$country_preseeded" ] && \ + [ "$current_short" = other ]); then + db_input $shortlist_prio $tpl_shortlist || [ $? -eq 30 ] + askedshort=1 + fi + country_preseeded="" + else + # Initially show the continent dialog only at medium + # priority, but allow to back up from country selection + # to select countries on a different continent. + # But we need to ask for a country at critical priority + # if the fallback locale does not include a country + # (is not complete); example: Esperanto. + if is_complete_locale $DEFAULT_LOCALE; then + continent_prio=medium + country_prio=high + fi + + # Display continents after backing up from locale + # selection for countries without shortlist + if [ $LASTSTATE -gt 21 ]; then + STATE=21 + continue + fi + fi + ;; + + 21) # Check if a country was selected from the short list + # and if not, allow to select a continent + if [ "$askedshort" ]; then + db_get $tpl_shortlist + COUNTRYCODE="$RET" + if [ "$COUNTRYCODE" != "other" ]; then + STATE=24 + continue + fi + fi + + # Set default value + if [ $LASTSTATE -ne 22 ]; then + if [ "$current_country" ]; then + tcountry="$current_country" + else + tcountry="$DEFAULT_COUNTRY" + fi + if set_default_continent "$tcountry"; then + db_fget $tpl_di_country seen + db_fset $tpl_continentlist seen $RET || true + else + # Incorrect preseeding, show dialogs + log "Preseeded country ignored: unknown country code" + db_fset $tpl_di_country seen false || true + fi + else + # Backed up; reset continent template if no country + # was actually selected so it can get a new default + if [ -z "$current_country" ]; then + db_reset $country_template + fi + fi + + db_metaget $tpl_countrytxt/1/continent description + db_subst $tpl_continentlist TXT1 "$RET" + db_subst $tpl_continentlist TXT2 "$ctxt2" + db_metaget $tpl_countrytxt/3/continent description + db_subst $tpl_continentlist TXT3 "$RET" + db_input $continent_prio $tpl_continentlist || [ $? -eq 30 ] + ;; + + 22) # Select a country on the continent + # Always display continent dialog when backing up + continent_prio=$country_prio + + db_get $tpl_continentlist + continent=$RET + country_template="$tpl_countrylist/$(echo $continent | sed "s/ /_/g")" + db_fget $tpl_di_country seen + db_fset $country_template seen $RET || true + db_subst $country_template TXT1 "$ctxt1" + db_subst $country_template TXT2 "$ctxt2" + db_metaget $tpl_countrytxt/3/country description + db_subst $country_template TXT3 "$(printf "$RET" \ + "$(choice_trans $tpl_continentlist "$continent")")" + + if [ "$current_country" ] && \ + has_choice $country_template "$current_country"; then + db_set $country_template "$current_country" + elif db_get $country_template && [ -z "$RET" ] && \ + has_choice $country_template "$DEFAULT_COUNTRY"; then + db_set $country_template "$DEFAULT_COUNTRY" + fi + + db_input $country_prio $country_template || [ $? -eq 30 ] + ;; + + 23) # Get the selected country + db_get $country_template + COUNTRYCODE="$RET" + ;; + + 24) # We have a country + db_set "$tpl_di_country" "$COUNTRYCODE" + log "Set $tpl_di_country = '$COUNTRYCODE'" + + # Display country selection on backup or rerun + db_fset $tpl_di_country seen false || true + STATE=29 + continue + ;; + + 29) # Prepare for locale selection; determine default locale + # If present, keep track of charset or modifier we got previously + DEFAULT_LOCALE_POSTFIX=$(echo $DEFAULT_LOCALE | sed -e 's/^[^.@]*//') + + if [ "$locale_preseeded" ]; then + db_get "$tpl_di_locale" + LOCALE=$RET + log "Preseeded $tpl_di_locale = '$LOCALE'" + else + if [ "$DEFAULT_LOCALE" = C ] || [ "$DEFAULT_LOCALE" = C.UTF-8 ]; then + LOCALE=$DEFAULT_LOCALE + else + LOCALE="$(get_default_locale)" + + # Fall back to a supported locale + if [ -z "$LOCALE" ]; then + if grep -q "^$DEFAULT_LOCALE " $SUPPORTEDLOCALES; then + LOCALE="$DEFAULT_LOCALE" + else + LOCALE=$(echo $DEFAULT_LOCALE | \ + sed -e 's/[.@].*$//') + fi + log "Falling back to locale '$LOCALE'" + fi + fi + fi + ;; + + 30) # Select preferred locale if needed + db_settitle localechooser/title/locale + + askedpreflocale= + if [ -z "$locale_preseeded" ] && [ "$use_lang" ]; then + build_preferredlocale_choices $LANGUAGE $LOCALE + + if has_choice $tpl_shortlist $COUNTRYCODE; then + preflocale_prio=medium + tpl_txt=localechooser/text/preferred-locale/multi + else + preflocale_prio=high + tpl_txt=localechooser/text/preferred-locale/none + fi + db_metaget $tpl_txt description + db_subst $tpl_preferredlocale TXT "$RET" + + db_capb backup align + db_input $preflocale_prio $tpl_preferredlocale || [ $? -eq 30 ] + askedpreflocale=1 + fi + ;; + + 31) # Select additional locales + if [ "$askedpreflocale" ]; then + db_get $tpl_preferredlocale + LOCALE=$RET + fi + db_set "$tpl_di_locale" "$LOCALE" + log "Set $tpl_di_locale = '$LOCALE'" + + CHOICES= + # *.UTF-8@euro locales are deprecated; don't use them + for i in $(grep -v '^#' $SUPPORTEDLOCALES | grep -v '\.UTF-8@euro$' | cut -d' ' -f1 | grep -v "^$LOCALE$"); do + CHOICES="${CHOICES:+$CHOICES, }$i" + done + + # Validate current (preseeded) values + validate_supportedlocales "$CHOICES" + + db_subst $tpl_supportedlocales LOCALE "$LOCALE" + db_subst $tpl_supportedlocales LOCALELIST "$CHOICES" + db_input low $tpl_supportedlocales || [ $? -eq 30 ] + ;; + + 32) # Select system locale + # Display additional locale selection on backup or rerun + db_fset $tpl_supportedlocales seen false || true + + # Display only if additional locales were selected + db_get $tpl_supportedlocales + if [ "$RET" ]; then + db_subst $tpl_di_locale LOCALELIST "$LOCALE, $RET" + # TODO: when run again, preserve previous choice if in list + db_set $tpl_di_locale $LOCALE + db_input low $tpl_di_locale || [ $? -eq 30 ] + fi + ;; + + 33) # We have a locale + # Display system locale selection on backup or rerun + db_fset $tpl_di_locale seen false || true + + db_get $tpl_di_locale + log "System locale ($tpl_di_locale) = '$RET'" + + # The code below adds lang_COUNTRY at the beginning of the + # language list we got from language selection, unless it's + # already included or no locale exists for the combination. + if [ "$askedpreflocale" ]; then + extra_lang=$(echo "$LOCALE" | sed -e 's/[.@].*$//') + else + extra_lang=${LANGUAGE%%_*}_$COUNTRYCODE + fi + if [ "$LOCALE" != C ] && [ "$LOCALE" != C.UTF-8 ] && \ + [ "$LANGUAGE" ] && [ "$COUNTRYCODE" ] && \ + [ "$COUNTRYCODE" != "$DEFAULT_COUNTRY" ] && \ + ! echo ":$LANGUAGELIST:" | grep -q ":$extra_lang:" && \ + grep -q "^$extra_lang" $SUPPORTEDLOCALES; then + LANGUAGELIST=$extra_lang:$LANGUAGELIST + db_set "$tpl_di_language" "$LANGUAGELIST" + log "Set $tpl_di_language = '$LANGUAGELIST'" + set_debconf_language "$LANGUAGELIST" + fi + ;; + + 34) # All done + break + ;; + + *) + error "undefined STATE '$STATE'" + exit 1 + ;; + esac + + LASTSTATE=$STATE + if db_go; then + STATE=$(($STATE + 1)) + else + STATELEVEL=$(($STATE / 10 * 10)) # round down to multiple of 10 + if [ $STATE -eq $STATELEVEL ]; then + STATE=$(($STATE - 10)) + else + STATE=$(($STATE - 1)) + fi + fi + db_capb backup +done + +exit 0 diff --git a/mklanguagelist.data b/mklanguagelist.data new file mode 100755 index 0000000..4b4dcab --- /dev/null +++ b/mklanguagelist.data @@ -0,0 +1,71 @@ +#!/usr/bin/perl +# +# Authors: Petter Reinholdtsen (2003) +# Christian Perrier (2004) +# Frans Pop (2008) +# +# Extract language options for debian-installer + +use strict; +use warnings; + +my $list = shift; +my $outfile = shift; + +my $debug = 0; + +my %codes; +my %levels; +my %translations; + +sub get_language_names { + my $list = shift; + my @names; + print "Loading $list\n" if ($debug); + open(L, "< $list") || die "Unable to read $list"; + while () { + print if ($debug); + chomp; + next if m/^\#/; + my ($code, $name, $translation, $level, ) = split(/;/); + push(@names, $name); + + $codes{$name} = $code; + $levels{$name} = $level; + $translations{$name} = $translation; + } + close(L); + return @names; +} + +my @languagenames = get_language_names($list); + +sub order_trans { + return $a cmp $b; +} + +#Sorts languages, making sure that the C locale is listed first +sub sort_C_first { + my @full_list = @_; + my @C_locale = grep /^C/, @full_list; + my @languages = grep !/^C/, @full_list; + my @new_list = sort order_trans @languages; + unshift @new_list, @C_locale; + return @new_list; +} + +open(TOUT, "> $outfile") || die "Unable to write $outfile"; +for my $name (sort_C_first @languagenames) { + my $line; + if (exists $translations{$name}) { + $line = $levels{$name}. + ":". + $codes{$name}. + ":". + $name. + ":". + $translations{$name}; + print TOUT $line, "\n"; + } +} +close(TOUT) || warn; diff --git a/mkshort b/mkshort new file mode 100755 index 0000000..af1d7c9 --- /dev/null +++ b/mkshort @@ -0,0 +1,80 @@ +#! /bin/sh + +set -e + +ISO3166TAB=debian/iso_3166.tab +SUPPORTED=/usr/share/i18n/SUPPORTED +TAB=" " + +rm -rf debian/short-tmp +rm -rf debian/locales +mkdir debian/short-tmp +mkdir debian/locales + +echo "Building short lists of countries..." +for file in debian/po/*.po en.po; do + lang_variant=$(basename $file .po) + lang=$(echo "$lang_variant" | sed -e 's/_.*$//') + tabfile=debian/short-tmp/$lang_variant.tab + + # Create TAB file for this language + # Only if iso-codes have some translations + if [ -f debian/iso-codes/$lang_variant.po ]; then + msgconv debian/iso-codes/$lang_variant.po -t UTF-8 --stringtable-output | \ + tail -n +3 | \ + sed -e 's/" = "/\t/' -e 's/^"//' -e 's/";$//' | \ + awk '/^.+$/{print}' >$tabfile + fi + + outfile=debian/short-tmp/$lang_variant.short + lastlocale=C + : >$outfile + for locale in $( (grep -e "^${lang}_" $SUPPORTED 2>/dev/null || true) | \ + sed -e 's/[@. ].*//' | sort | uniq); do + if [ "$locale" = en_DK ] ; then + # Don't add Denmark to shortlist for English (per #276067) + continue + fi + + code=$(echo "$locale" | sed -e 's/.*_//') + line=$(grep -e "^$code" $ISO3166TAB || true) + lastlocale=$locale + if [ "$line" ]; then + OLD_IFS="$IFS" + IFS=' ' + set $line + IFS="$OLD_IFS" + if [ "$2" ]; then + if [ "$lang" != en ] ; then + translation=$( (grep "^$2$TAB" $tabfile 2>/dev/null || true) | sed -e 's/^.*\t//') + if [ "$translation" ]; then + printf '%s\t%s\t%s\n' "$1" "$translation" "$2" >>$outfile + else + printf '%s\t%s\t%s\n' "$1" "$2" "$2" >>$outfile + fi + else + printf '%s\t%s\t%s\n' "$1" "$2" "$2" >>$outfile + fi + fi + fi + done + + if [ $(wc -l <$outfile) -le 1 ]; then + rm -f $outfile + else + echo $lang_variant + localedef -c -f UTF-8 -i $lastlocale debian/locales/$lastlocale.UTF-8 + LOCPATH=`pwd` LC_ALL=debian/locales/$lastlocale.UTF-8 \ + sort -k 2.1 $outfile >$outfile.tmp && \ + mv $outfile.tmp $outfile + fi +done + +# Create a file listing the countries that have shortlists +SHORTLISTS=debian/short-tmp/shortlists +: >$SHORTLISTS + +for file in debian/short-tmp/*.short; do + lang=$(basename $file .short) + echo "$lang" >>$SHORTLISTS +done diff --git a/mktemplates.base b/mktemplates.base new file mode 100755 index 0000000..51366f7 --- /dev/null +++ b/mktemplates.base @@ -0,0 +1,57 @@ +#!/bin/sh + +set -e + +# Script for generating a debconf templates file from both files +# in debian/po/*.po and country names translations from the +# iso-codes package +# +# Translations location (relative to the build root directory) +ISO3166TRANSLATIONS=debian/iso-codes + +templates_in=$1 +templates_out=$2 + +# Create a temporary "pobuild" directory +rm -rf debian/pobuild >/dev/null 2>&1 +mkdir debian/pobuild + +# Create the appropriate POTFILES.in file there +cat >debian/pobuild/POTFILES.in <debian/pobuild/output <this will create pobuild/templates.pot +debconf-updatepo --podir debian/pobuild + +# process each existing file in debian/po +for pofile in debian/po/*.po ; do + pofilename=$(basename $pofile) + printf "$pofilename " + # If the country names are translated, we need to merge + # the translation with the templates translations + if [ -f $ISO3166TRANSLATIONS/$pofilename ]; then + # msgcat will properly handle different encodings + msgcat --use-first $ISO3166TRANSLATIONS/$pofilename \ + debian/po/$pofilename \ + > debian/pobuild/$pofilename 2>/dev/null + + msgmerge -U debian/pobuild/$pofilename \ + debian/pobuild/templates.pot + else + # just use what's translated + cp $pofile debian/pobuild/$pofilename + fi +done +echo + +# and now we generate the templates file from all this +po2debconf --podir debian/pobuild $templates_in >$templates_out diff --git a/mktemplates.continents b/mktemplates.continents new file mode 100755 index 0000000..4b18425 --- /dev/null +++ b/mktemplates.continents @@ -0,0 +1,122 @@ +#!/usr/bin/perl +# Builds templates with list of countries per continent (region) +# and a template to select the continent. +use strict; +use warnings; + +# Parameters. +my $iso3166tab=shift; +my $regionmap=shift; +my $outfile=shift; + +# These are the regions to use. The list should be sorted alphabetically. +# There is no call to gettext for Antarctica as that is included in ISO-3166. +my @known_regions = ( + gettext("Africa"), + "Antarctica", + gettext("Asia"), + gettext("Atlantic Ocean"), + gettext("Caribbean"), + gettext("Central America"), + gettext("Europe"), + gettext("Indian Ocean"), + gettext("North America"), + gettext("Oceania"), + gettext("South America"), + gettext("other"), +); + +my @regions; +my %is_region; +for (@known_regions) { $is_region{$_} = 1; } + +my %code2country; +my %country2code; +my %codes_listed; + +open (L, $iso3166tab) || die "$iso3166tab: $!"; +while () { + chomp; + my ($code, $country) = split(' ', $_, 2); + + # Escape commas + $country =~ s/,/\\,/g; + $code2country{$code}=$country; + $country2code{$country}=$code; + $codes_listed{$code}=0; +} + +my %regions; +open (R, $regionmap) || die "$regionmap: $!"; +while () { + chomp; + my ($code, $region) = split(' ', $_, 2); + if (exists $code2country{$code}) { + if ($is_region{$region}) { + push @{$regions{$region}}, $code2country{$code}; + $codes_listed{$code}++; + } else { + print STDERR "E: country code '$code': region '$region' is not defined\n"; + exit 1 + } + } elsif ($code ne 'unlisted') { + print STDERR "I: skipping country code '$code': in $regionmap but not in $iso3166tab\n"; + } +} +close R; + +# Add any unlisted countries to "other". +foreach my $code (keys %codes_listed) { + if ($codes_listed{$code} == 0) { + push @{$regions{"other"}}, $code2country{$code}; + print STDERR "W: unknown region for country $code: not listed in $regionmap\n"; + } +} + +open(TOUT, "> $outfile") || die "Unable to write $outfile"; +print TOUT "\n"; + +foreach my $region (@known_regions) { + if (exists $regions{$region}) { + push @regions, $region; + + my @countries; + my @codes; + foreach my $country (sort @{$regions{$region}}) { + push @countries, "$country"; + push @codes, "$country2code{$country}"; + } + + my $tregion = $region; + $tregion =~ s/ /_/g; + print TOUT "Template: localechooser/countrylist/$tregion\n"; + print TOUT "Type: select\n"; + print TOUT "Choices-C: ", join(", ", @codes), "\n"; + print TOUT "#flag:partial\n"; + print TOUT "__Choices: ", join(", ", @countries), "\n"; + print TOUT "Description: \${TXT1}\n"; + print TOUT " \${TXT2}\n"; + print TOUT " .\n"; + print TOUT " \${TXT3}\n"; + print TOUT "\n"; + } else { + print STDERR "I: skipping region $region: no associated countries in $regionmap\n"; + delete $regions{$region}; + } +} + +print TOUT "Template: localechooser/continentlist\n"; +print TOUT "Type: select\n"; +print TOUT "#flag:partial\n"; +print TOUT "__Choices: ", join(", ", @regions), "\n"; +print TOUT "Description: \${TXT1}\n"; +print TOUT " \${TXT2}\n"; +print TOUT " .\n"; +print TOUT " \${TXT3}\n"; + +close(TOUT) || warn; + +# Dummy. +sub gettext { + return shift; +} diff --git a/mktemplates.shortlist b/mktemplates.shortlist new file mode 100755 index 0000000..afbd760 --- /dev/null +++ b/mktemplates.shortlist @@ -0,0 +1,99 @@ +#!/bin/sh + +export LC_ALL=C # avoid sed hang + +SHORTLIST_DIR="./debian/short-tmp" +SHORTLIST_LANGS=$(cd $SHORTLIST_DIR; ls *.short | cut -d. -f1) + +TEMPLATE_BASE="./debian/templates.base" +TEMPLATE_TMP="./debian/templates.tmp" +TEMPLATE_NEW="./debian/templates" +TEMPLATE_NAME="localechooser/shortlist" + +NL=" +" + +print_trans () { + ITEM_TRANS=$(awk -v ITEM="$1-$LANG.UTF-8:" \ + -f template_get_item.awk $TEMPLATE_TMP) + if [ -n "$ITEM_TRANS" ] ; then + echo "$ITEM_TRANS" + else + # We use the original entry as default + REGEXP="s/$1:/$1-$LANG.UTF-8:/" + echo "$2" | sed "$REGEXP" + fi +} + +# First create empty new files +:>$TEMPLATE_NEW +:>$TEMPLATE_TMP + +# Extract the template for the shortlists to TEMPLATE_TMP +# Extract all other templates to TEMPLATE_NEW +awk -v TFILE1="$TEMPLATE_TMP" -v TFILE2="$TEMPLATE_NEW" \ + -v TEMPLATE="$TEMPLATE_NAME" -f template_extract.awk \ + $TEMPLATE_BASE +echo "" >>$TEMPLATE_NEW + +# Get the English versions of the template items +EN_CHOICES=$(awk -v ITEM="Choices:" -f template_get_item.awk $TEMPLATE_TMP) +EN_DESCR=$(awk -v ITEM="Description:" -f template_get_item.awk $TEMPLATE_TMP) + +# Add new templates for each language that needs a shortlist +for LANG in $SHORTLIST_LANGS; do + echo "$LANG" + + # Write the 'template header' to the file + echo "Template: $TEMPLATE_NAME/$LANG" >>$TEMPLATE_NEW + echo "Type: select" >>$TEMPLATE_NEW + + # Next we put the countrycodes in the untranslated shortlist + SHORTLIST= + for COUNTRYCODE in $(cat $SHORTLIST_DIR/$LANG.short | cut -f 1) ; do + SHORTLIST="$SHORTLIST$COUNTRYCODE, " + done + C_CHOICES=$(echo $EN_CHOICES | sed "s/Choices:/Choices-C:/") + REGEXP="s/\${SHORTLIST}, /$SHORTLIST/" + echo "$C_CHOICES" | sed "$REGEXP" >>$TEMPLATE_NEW + + # Next we build a shortlist containing the countrynames in English + SHORTLIST= + OLD_IFS="$IFS" + IFS="$NL" + COUNTRYLIST= + for COUNTRYNAME in $(cut -f 3 $SHORTLIST_DIR/$LANG.short); do + # Comma's in countrynames must be double-escaped here + # in order to end up escaped in the final list. + SL_NAME=$(echo "$COUNTRYNAME" | sed -e 's/,/\\\\,/') + SHORTLIST="$SHORTLIST$SL_NAME, " + done + IFS="$OLD_IFS" + REGEXP="s/\${SHORTLIST}, /$SHORTLIST/" >>$TEMPLATE_NEW + echo "$EN_CHOICES" | sed "$REGEXP" >>$TEMPLATE_NEW + + # Next we build the translated shortlist containing translated countrynames + if [ "$LANG" != en ]; then + SHORTLIST= + OLD_IFS="$IFS" + IFS="$NL" + COUNTRYLIST= + for COUNTRYNAME in $(cut -f 2 $SHORTLIST_DIR/$LANG.short) ; do + # Comma's in countrynames must be double-escaped here + # in order to end up escaped in the final list. + SL_NAME=$(echo "$COUNTRYNAME" | sed -e 's/,/\\\\,/') + SHORTLIST="$SHORTLIST$SL_NAME, " + done + IFS="$OLD_IFS" + TRANS_CHOICES=$(print_trans "Choices" "$EN_CHOICES") + REGEXP="s/\${SHORTLIST}, /$SHORTLIST/" >>$TEMPLATE_NEW + echo "$TRANS_CHOICES" | sed "$REGEXP" >>$TEMPLATE_NEW + fi + + # Finally we add the description and translated description + echo "$EN_DESCR" >>$TEMPLATE_NEW + if [ ! "$LANG" = en ]; then + print_trans "Description" "$EN_DESCR" >>$TEMPLATE_NEW + fi + echo "" >>$TEMPLATE_NEW +done diff --git a/mktemplates.warnings b/mktemplates.warnings new file mode 100755 index 0000000..57edc26 --- /dev/null +++ b/mktemplates.warnings @@ -0,0 +1,46 @@ +#!/usr/bin/perl +# +# Author: Frans Pop (2008) +# +# Append language-specific warnings about incomplete translations + +use strict; +use warnings; + +my $list = shift; +my $outfile = shift; + +print "Appending language-specific templates about incomplete translations...\n"; + +open(TOUT, ">> $outfile") || die "Unable to write $outfile"; +open(L, "< $list") || die "Unable to read $list"; +while () { + chomp; + next if m/^\#/; + my ($code, $name, $translation, $level, $country, $locale, $langlist, ) = split(/;/); + next if $langlist !~ /:/; + + my $have_template = 0; + if (! open(T, "< debian/localechooser.templates-$code")) { + print "Warning: missing localized warnings file for $code!\n"; + next + } + while () { + chomp; + next if m/^\#/; + if (! $have_template) { + if (m/^Template:/) { + $have_template = 1; + print TOUT "\n"; + print TOUT $_, "\n"; + } + } else { + print TOUT $_, "\n"; + } + } + if (! $have_template) { + print "Warning: no localized warnings for $code in file!\n"; + } +} +close(L); +close(TOUT) || warn; diff --git a/post-base-installer.d/05localechooser b/post-base-installer.d/05localechooser new file mode 100755 index 0000000..724d1f6 --- /dev/null +++ b/post-base-installer.d/05localechooser @@ -0,0 +1,159 @@ +#! /bin/sh + +set -e + +. /usr/share/debconf/confmodule + +# Avoid locale errors when using apt-install (logical consequence +# of the fact that locales is not yet installed). +export IT_LANG_OVERRIDE=C + + +db_get debian-installer/locale +LOCALE="$RET" + +# Set locale to C if it has not yet been set +# This can happen during e.g. s390 installs where localechooser is not run +[ "$LOCALE" ] || LOCALE="C.UTF-8" + +if [ "$LOCALE" != "C" ] && [ "$LOCALE" != "C.UTF-8" ]; then + db_get debian-installer/language + LANGLIST="$RET" +fi + +EXTRAS="" +if db_get localechooser/supported-locales; then + EXTRAS="$(echo "$RET" | sed 's/,//g')" +fi + +LANGUAGE="${LOCALE%%_*}" + +LOCALE_TRANSLATIONS="$LOCALE" + +case ${LOCALE%%_*} in + pt|zh) + # In the special cases of Portuguese and Chinese, selecting a + # different location may imply a different dialect of the language. + # In such cases, make LANG reflect the selected language (for + # messages, character types, and collation) and make the other + # locale categories reflect the selected language. + db_get localechooser/languagelist + ORIG_LANGUAGE="$RET" + db_get debian-installer/country + COUNTRY="$RET" + + if grep -q "^$ORIG_LANGUAGE;" /usr/share/localechooser/languagelist; then + SUPPORTEDLOCALES=/usr/share/localechooser/SUPPORTED + if [ ! -f "$SUPPORTEDLOCALES" ]; then + SUPPORTEDLOCALES=/usr/share/i18n/SUPPORTED + fi + + LOCALE_TRANSLATIONS="$(grep "^$ORIG_LANGUAGE;" /usr/share/localechooser/languagelist | cut -d';' -f4)" + newlocale="$(echo "$LOCALE" | sed "s/_[A-Z][A-Z]*/_$COUNTRY/")" + if grep -q "^${newlocale%%[.@]*}[.@ ]" $SUPPORTEDLOCALES && \ + [ "$newlocale" != "$LOCALE_TRANSLATIONS" ]; then + LOCALE="$newlocale" + LANGLIST="$(grep "^$ORIG_LANGUAGE;" /usr/share/localechooser/languagelist | cut -d';' -f5)" + fi + fi + ;; +esac + +# Enable translations +if [ "$LOCALE" != "C" ] && [ "$LOCALE" != "C.UTF-8" ] || [ "$EXTRAS" ]; then + apt-install locales || true +fi + +set_field () { + local file category value + file="$1" + category="$2" + value="$3" + + if grep -qs "^#* *$category=" "$file"; then + sed -i "s,^#* *$category=.*,$category=\"$value\"," "$file" + else + echo "$category=\"$value\"" >> "$file" + fi +} + +# Set global locale and language, and make sure the glibc locale is +# generated. +DESTFILE="/target/etc/default/locale" +if [ -e $DESTFILE ]; then + if grep -q '^LANG=' $DESTFILE; then + sed -i 's/^LANG=.*/LANG=\"'"$LOCALE_TRANSLATIONS"'\"/' $DESTFILE + elif grep -q '^# LANG=' $DESTFILE; then + sed -i 's/^# LANG=.*/LANG=\"'"$LOCALE_TRANSLATIONS"'\"/' $DESTFILE + else + echo "LANG=\"$LOCALE_TRANSLATIONS\"" >> $DESTFILE + fi + # We set LANGUAGE only if the languagelist is a list of + # languages with alternatives. Otherwise, setting it is useless + if echo "$LANGLIST" | grep -q ":"; then + if grep -q '^LANGUAGE=' $DESTFILE; then + sed -i 's/^LANGUAGE=.*/LANGUAGE=\"'"$LANGLIST"'\"/' $DESTFILE + elif grep -q '^# LANGUAGE=' $DESTFILE; then + sed -i 's/^# LANGUAGE=.*/LANGUAGE=\"'"$LANGLIST"'\"/' $DESTFILE + else + echo "LANGUAGE=\"$LANGLIST\"" >> $DESTFILE + fi + fi +fi +# Fallback in case the file wasn't provided by locales, or the format +# changed. +if [ ! -e "$DESTFILE" ] || ! grep -q '^LANG=' $DESTFILE; then + mkdir -p "${DESTFILE%/*}" + echo "LANG=\"$LOCALE_TRANSLATIONS\"" >> $DESTFILE + if echo "$LANGLIST" | grep -q ":"; then + echo "LANGUAGE=\"$LANGLIST\"" >> $DESTFILE + fi +fi +if [ "$LOCALE_TRANSLATIONS" != "$LOCALE" ]; then + for category in \ + LC_NUMERIC LC_TIME LC_MONETARY LC_PAPER LC_NAME LC_ADDRESS \ + LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION; do + set_field /target/etc/default/locale "$category" "$LOCALE" + done +fi + +# For languages that have no chance to be displayed at the Linux console +# let's set root's environment with a non localized environment +ROOTPROFILE="/target/root/.profile" +# We must map the language to its "level" from languagelist +LANGUAGECODE=`echo $LOCALE|cut -f1 -d_` +# For language with multiple entries such as pt/pt_BR or zh_CN/zh_TW +# we don't really care about the entry we will match as the level will always +# be the same +LEVEL=`cat /usr/share/localechooser/languagelist |\ + cut -f 2-3 -d\; | \ + grep "$LANGUAGECODE" | \ + head -n 1 | \ + cut -f1 -d\;` +if [ "$LEVEL" = "3" ] || [ "$LEVEL" = "4" ]; then + echo "# Installed by Debian Installer:" >>$ROOTPROFILE + echo "# no localization for root because $LOCALE" >>$ROOTPROFILE + echo "# cannot be properly displayed at the Linux console" >>$ROOTPROFILE + echo "LANG=C.UTF-8" >>$ROOTPROFILE + echo "LANGUAGE=C.UTF-8" >>$ROOTPROFILE +fi + +locale_gen () { + local loc + for loc; do + # Create a skeleton locale-langpack subdirectory so that + # /usr/share/language-tools/language-options knows that this + # locale is supposed to have a meaningful existence. + mkdir -p "/target/usr/share/locale-langpack/${loc%_*}" + done + log-output -t localechooser chroot /target /usr/sbin/locale-gen "$@" +} + +if [ "$LOCALE" != C ] && [ "$LOCALE" != "C.UTF-8" ]; then + locale_gen "$LOCALE" || true +fi +if [ "$EXTRAS" ]; then + locale_gen $EXTRAS || true +fi + +exit 0 diff --git a/regionmap b/regionmap new file mode 100644 index 0000000..caee9b6 --- /dev/null +++ b/regionmap @@ -0,0 +1,250 @@ +AO Africa +BF Africa +BI Africa +BJ Africa +BW Africa +CD Africa +CF Africa +CG Africa +CI Africa +CM Africa +CV Africa +DJ Africa +DZ Africa +EG Africa +EH Africa +ER Africa +ET Africa +GA Africa +GH Africa +GM Africa +GN Africa +GQ Africa +GW Africa +KE Africa +LR Africa +LS Africa +LY Africa +MA Africa +ML Africa +MR Africa +MW Africa +MZ Africa +NA Africa +NE Africa +NG Africa +RW Africa +SD Africa +SS Africa +SL Africa +SN Africa +SO Africa +ST Africa +SZ Africa +TD Africa +TG Africa +TN Africa +TZ Africa +UG Africa +ZA Africa +ZM Africa +ZW Africa +BZ Central America +CR Central America +GT Central America +HN Central America +NI Central America +PA Central America +SV Central America +CA North America +MX North America +PM North America +US North America +AR South America +BO South America +BR South America +CL South America +CO South America +EC South America +GF South America +GY South America +PE South America +PY South America +SR South America +UY South America +VE South America +AQ Antarctica +AE Asia +AF Asia +BD Asia +BH Asia +BN Asia +BT Asia +CN Asia +HK Asia +ID Asia +IL Asia +IN Asia +IQ Asia +IR Asia +JO Asia +JP Asia +KG Asia +KH Asia +KP Asia +KR Asia +KW Asia +KZ Asia +LA Asia +LB Asia +LK Asia +MM Asia +MN Asia +MO Asia +MY Asia +NP Asia +OM Asia +PH Asia +PK Asia +PS Asia +QA Asia +SA Asia +SG Asia +SY Asia +TH Asia +TJ Asia +TL Asia +TM Asia +TR Asia +TW Asia +UZ Asia +VN Asia +YE Asia +BV Atlantic Ocean +GS Atlantic Ocean +SH Atlantic Ocean +FK Atlantic Ocean +AG Caribbean +AI Caribbean +AN Caribbean +AW Caribbean +BB Caribbean +BL Caribbean +BM Caribbean +BQ Caribbean +BS Caribbean +CU Caribbean +DM Caribbean +DO Caribbean +GD Caribbean +GP Caribbean +HT Caribbean +JM Caribbean +KN Caribbean +KY Caribbean +LC Caribbean +MF Caribbean +MQ Caribbean +MS Caribbean +PR Caribbean +SX Caribbean +TC Caribbean +TT Caribbean +VC Caribbean +VG Caribbean +VI Caribbean +AD Europe +AL Europe +AM Europe +AT Europe +AX Europe +AZ Europe +BA Europe +BE Europe +BG Europe +BY Europe +CH Europe +CY Europe +CZ Europe +DE Europe +DK Europe +EE Europe +ES Europe +FI Europe +FO Europe +FR Europe +GB Europe +GE Europe +GG Europe +GI Europe +GL Europe +GR Europe +HR Europe +HU Europe +IE Europe +IM Europe +IS Europe +IT Europe +JE Europe +LI Europe +LT Europe +LU Europe +LV Europe +MC Europe +MD Europe +ME Europe +MK Europe +MT Europe +NL Europe +NO Europe +PL Europe +PT Europe +RO Europe +RS Europe +RU Europe +SE Europe +SI Europe +SJ Europe +SK Europe +SM Europe +UA Europe +VA Europe +CC Indian Ocean +CX Indian Ocean +TF Indian Ocean +HM Indian Ocean +IO Indian Ocean +KM Indian Ocean +MG Indian Ocean +MU Indian Ocean +MV Indian Ocean +RE Indian Ocean +SC Indian Ocean +YT Indian Ocean +AS Oceania +AU Oceania +CK Oceania +FJ Oceania +FM Oceania +GU Oceania +KI Oceania +MH Oceania +MP Oceania +NC Oceania +NF Oceania +NR Oceania +NU Oceania +NZ Oceania +PF Oceania +PG Oceania +PN Oceania +PW Oceania +SB Oceania +TK Oceania +TO Oceania +TV Oceania +UM Oceania +VU Oceania +WF Oceania +WS Oceania +unlisted Other diff --git a/sort-templates b/sort-templates new file mode 100755 index 0000000..302e341 --- /dev/null +++ b/sort-templates @@ -0,0 +1,70 @@ +#!/bin/sh + +[ -d debian/locales ] || mkdir debian/locales +[ -d debian/sort-tmp ] || mkdir debian/sort-tmp +cd debian/sort-tmp + +tplfile=../localechooser/DEBIAN/templates + +templates=$(grep -E "^Template: localechooser/(continent|country)list" $tplfile | \ + cut -d" " -f2-) + +# The first template will take longer because of locale generation +for template in $templates; do + echo "Sorting template '$template'..." + rm -f list.* sortedlist.* + + sed -n -e "\%^Template: $template$%,\%^Description:%p" $tplfile | + perl -p -e ' + chomp; + if (m/Choices-([^.]*)\.UTF-8:/) { + open (OUT, "> list.$1"); + s/Choices-([^.]*)\.UTF-8: //; + # split on commas, except for backslash-escaped ones + @t = split(/(?&2 + else + if [ ! -d ../locales/$unilang.UTF-8 ]; then + localedef -c -f UTF-8 -i $unilang ../locales/$unilang.UTF-8 + fi + LOCPATH=`pwd` LC_ALL=../locales/$unilang.UTF-8 \ + sort -k 2.1 $file | sed -e 's/ .*/, /' | tr -d '\n' | \ + sed -e "s/^/Indices-$lang.UTF-8: /" -e 's/, $//' \ + >sorted$file + if [ -s sorted$file ]; then + echo "" >>sorted$file + else + rm -f sorted$file + fi + fi + done + + # Now the template file must be patched: all sortedlist.* files have + # to be added to the current template. + if ls sorted* >/dev/null 2>&1; then + sed -e "\%$template$%{n;q;}" $tplfile >templates.tmp + cat sorted* >>templates.tmp + sed -e "\%$template$%!d;\%$template$%{:end;n;b end}" $tplfile | \ + sed '1,2d' >> templates.tmp + mv templates.tmp $tplfile + else + echo "I: nothing to be sorted" + fi +done + +cd ../.. +rm -r debian/locales debian/sort-tmp diff --git a/template_extract.awk b/template_extract.awk new file mode 100644 index 0000000..cffb98c --- /dev/null +++ b/template_extract.awk @@ -0,0 +1,33 @@ +# AWK-script to extract specific template from templates file + +# The script takes three parameters: +# - TEMPLATE: The template to be extracted from the templatefile +# - TFILE1: The extracted template will be written here +# - TFILE2: All other templates will be written here (can be /dev/null ;-) + +BEGIN { + FOUND = 0 + TEMPLATE = "Template: " TEMPLATE +} + +{ + line=$0 + + if (index(line, TEMPLATE) > 0) { + FOUND = 1 + print line >>TFILE1 + getline + line=$0 + } + + if (FOUND == 1) { + if (substr(line, 1, 9) == "Template:") { + FOUND = 0 + print line >>TFILE2 + } else { + print line >>TFILE1 + } + } else { + print line >>TFILE2 + } +} diff --git a/template_get_item.awk b/template_get_item.awk new file mode 100644 index 0000000..375b07b --- /dev/null +++ b/template_get_item.awk @@ -0,0 +1,24 @@ +# AWK-script to extract specific template from templates file + +BEGIN { + FOUND = 0 +} + +{ + line=$0 + + if (index(line, ITEM) > 0) { + FOUND = 1 + print line + getline + line=$0 + } + + if (FOUND == 1) { + if (match(line, /^[^\ ]*:/) > 0) { + FOUND = 0 + } else { + print line + } + } +} diff --git a/translation-check b/translation-check new file mode 100755 index 0000000..5a82650 --- /dev/null +++ b/translation-check @@ -0,0 +1,49 @@ +#! /bin/sh +set -e + +# Exits without error if translation is _not_ completely up-to-date; +# with errror if translation is up-to-date or on errors. + +if [ "$1" = en ] || [ "$1" = C ]; then + exit 9 # up-to-date by definition +fi + +sfile=/usr/share/localechooser/translation-status +[ -f $sfile ] || exit 1 + +tstatus=$(grep "^$1:" $sfile | sed "s/.*:[[:space:]]*//") +[ "$tstatus" ] || exit 1 + +tlevel=${tstatus% *} +tcompl=${tstatus#* } +expr "$tlevel" : "[1-5]" >/dev/null || exit 1 +expr "$tcompl" : "[FMPLU]" >/dev/null || exit 1 + +arch=$(archdetect) +case ${arch%/*} in + i386|amd64) + archlevel=3 ;; + arm*|mips*|powerpc|sparc) + archlevel=4 ;; + alpha|hppa|ia64|m68k|s390|s390x) + archlevel=5 ;; + *) + archlevel=5 ;; +esac + +if [ "$tcompl" = F ]; then + exit 9 # up-to-date +elif [ $archlevel = 3 ] && [ $tlevel -eq 2 ] && [ $tcompl != M ]; then + echo 0 # incomplete +elif [ $archlevel = 3 ] && [ $tlevel -eq 2 ]; then + echo 1 # incomplete, but normal installs mostly OK +elif [ $tlevel -lt $archlevel ] || + ([ $tlevel -eq $archlevel ] && [ $tcompl = U ]); then + echo 0 # incomplete +elif [ $tlevel -eq $archlevel ] && [ $tcompl != M ]; then + echo 2 # partial at wanted level +elif [ $tlevel -eq $archlevel ]; then + echo 3 # mostly complete +else + echo 4 # only exceptions untranslated +fi