+++ /dev/null
-/*
- findlocale-0.46.tar.gz from http://icculus.org/~aspirin/findlocale/
-
-Copyright (C) 2004 Adam D. Moss (the "Author"). All Rights Reserved.
-
-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 fur-
-nished 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, FIT-
-NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
-NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the Author of the
-Software shall not be used in advertising or otherwise to promote the sale,
-use or other dealings in this Software without prior written authorization
-from the Author.
-
-*/
-#include <config.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#ifdef WIN32
-#include <windows.h>
-#include <winnt.h>
-#endif
-
-#ifdef MACOSX
-#include <CoreFoundation/CoreFoundation.h>
-#endif
-
-#include "findlocale.hpp"
-
-static int
-is_lcchar(const int c) {
- return isalnum(c);
-}
-
-static void
-lang_country_variant_from_envstring(const char *str,
- char **lang,
- char **country,
- char **variant) {
- int end = 0;
- int start;
-
- /* get lang, if any */
- start = end;
- while (is_lcchar(str[end])) {
- ++end;
- }
- if (start != end) {
- int i;
- int len = end - start;
- char *s = (char*) malloc(len + 1);
- for (i=0; i<len; ++i) {
- s[i] = tolower(str[start + i]);
- }
- s[i] = '\0';
- *lang = s;
- } else {
- *lang = NULL;
- }
-
- if (str[end] && str[end]!=':') { /* not at end of str */
- ++end;
- }
-
- /* get country, if any */
- start = end;
- while (is_lcchar(str[end])) {
- ++end;
- }
- if (start != end) {
- int i;
- int len = end - start;
- char *s = (char*) malloc(len + 1);
- for (i=0; i<len; ++i) {
- s[i] = toupper(str[start + i]);
- }
- s[i] = '\0';
- *country = s;
- } else {
- *country = NULL;
- }
-
- if (str[end] && str[end]!=':') { /* not at end of str */
- ++end;
- }
-
- /* get variant, if any */
- start = end;
- while (str[end] && str[end]!=':') {
- ++end;
- }
- if (start != end) {
- int i;
- int len = end - start;
- char *s = (char*) malloc(len + 1);
- for (i=0; i<len; ++i) {
- s[i] = str[start + i];
- }
- s[i] = '\0';
- *variant = s;
- } else {
- *variant = NULL;
- }
-}
-
-
-static int
-accumulate_locstring(const char *str, FL_Locale *l) {
- char *lang = NULL;
- char *country = NULL;
- char *variant = NULL;
- if (str) {
- lang_country_variant_from_envstring(str, &lang, &country, &variant);
- if (lang) {
- l->lang = lang;
- l->country = country;
- l->variant = variant;
- return 1;
- }
- }
- free(lang); free(country); free(variant);
- return 0;
-}
-
-
-#ifndef WIN32
-static int
-accumulate_env(const char *name, FL_Locale *l) {
- char *env;
- char *lang = NULL;
- char *country = NULL;
- char *variant = NULL;
- env = getenv(name);
- if (env) {
- return accumulate_locstring(env, l);
- }
- free(lang); free(country); free(variant);
- return 0;
-}
-#endif
-
-static void
-canonize_fl(FL_Locale *l) {
- /* this function fixes some common locale-specifying mistakes */
- /* en_UK -> en_GB */
- if (l->lang && 0 == strcmp(l->lang, "en")) {
- if (l->country && 0 == strcmp(l->country, "UK")) {
- free((void*)l->country);
- l->country = strdup("GB");
- }
- }
- /* ja_JA -> ja_JP */
- if (l->lang && 0 == strcmp(l->lang, "ja")) {
- if (l->country && 0 == strcmp(l->country, "JA")) {
- free((void*)l->country);
- l->country = strdup("JP");
- }
- }
-}
-
-
-#ifdef WIN32
-#include <stdio.h>
-#define ML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##pn##_##sn)
-#define MLN(pn) MAKELANGID(LANG_##pn, SUBLANG_DEFAULT)
-#define RML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##sn)
-typedef struct {
- LANGID id;
- const char* code;
-} IDToCode;
-static const IDToCode both_to_code[] = {
- {ML(ENGLISH,US), "en_US.ISO_8859-1"},
- {ML(ENGLISH,CAN), "en_CA"}, /* english / canadian */
- {ML(ENGLISH,UK), "en_GB"},
- {ML(ENGLISH,EIRE), "en_IE"},
- {ML(ENGLISH,AUS), "en_AU"},
- {MLN(GERMAN), "de_DE"},
- {MLN(SPANISH), "es_ES"},
- {ML(SPANISH,MEXICAN), "es_MX"},
- {MLN(FRENCH), "fr_FR"},
- {ML(FRENCH,CANADIAN), "fr_CA"},
- {ML(FRENCH,BELGIAN), "fr_BE"}, /* ? */
- {ML(DUTCH,BELGIAN), "nl_BE"}, /* ? */
- {ML(PORTUGUESE,BRAZILIAN), "pt_BR"},
- {MLN(PORTUGUESE), "pt_PT"},
- {MLN(SWEDISH), "sv_SE"},
- {ML(CHINESE,HONGKONG), "zh_HK"},
- /* these are machine-generated and not yet verified */
- {RML(AFRIKAANS,DEFAULT), "af_ZA"},
- {RML(ALBANIAN,DEFAULT), "sq_AL"},
- {RML(ARABIC,ARABIC_ALGERIA), "ar_DZ"},
- {RML(ARABIC,ARABIC_BAHRAIN), "ar_BH"},
- {RML(ARABIC,ARABIC_EGYPT), "ar_EG"},
- {RML(ARABIC,ARABIC_IRAQ), "ar_IQ"},
- {RML(ARABIC,ARABIC_JORDAN), "ar_JO"},
- {RML(ARABIC,ARABIC_KUWAIT), "ar_KW"},
- {RML(ARABIC,ARABIC_LEBANON), "ar_LB"},
- {RML(ARABIC,ARABIC_LIBYA), "ar_LY"},
- {RML(ARABIC,ARABIC_MOROCCO), "ar_MA"},
- {RML(ARABIC,ARABIC_OMAN), "ar_OM"},
- {RML(ARABIC,ARABIC_QATAR), "ar_QA"},
- {RML(ARABIC,ARABIC_SAUDI_ARABIA), "ar_SA"},
- {RML(ARABIC,ARABIC_SYRIA), "ar_SY"},
- {RML(ARABIC,ARABIC_TUNISIA), "ar_TN"},
- {RML(ARABIC,ARABIC_UAE), "ar_AE"},
- {RML(ARABIC,ARABIC_YEMEN), "ar_YE"},
- {RML(ARMENIAN,DEFAULT), "hy_AM"},
- {RML(AZERI,AZERI_CYRILLIC), "az_AZ"},
- {RML(AZERI,AZERI_LATIN), "az_AZ"},
- {RML(BASQUE,DEFAULT), "eu_ES"},
- {RML(BELARUSIAN,DEFAULT), "be_BY"},
-/*{RML(BRETON,DEFAULT), "br_FR"},*/
- {RML(BULGARIAN,DEFAULT), "bg_BG"},
- {RML(CATALAN,DEFAULT), "ca_ES"},
- {RML(CHINESE,CHINESE_HONGKONG), "zh_HK"},
- {RML(CHINESE,CHINESE_MACAU), "zh_MO"},
- {RML(CHINESE,CHINESE_SIMPLIFIED), "zh_CN"},
- {RML(CHINESE,CHINESE_SINGAPORE), "zh_SG"},
- {RML(CHINESE,CHINESE_TRADITIONAL), "zh_TW"},
-/*{RML(CORNISH,DEFAULT), "kw_GB"},*/
- {RML(CZECH,DEFAULT), "cs_CZ"},
- {RML(DANISH,DEFAULT), "da_DK"},
- {RML(DUTCH,DUTCH), "nl_NL"},
- {RML(DUTCH,DUTCH_BELGIAN), "nl_BE"},
-/*{RML(DUTCH,DUTCH_SURINAM), "nl_SR"},*/
- {RML(ENGLISH,ENGLISH_AUS), "en_AU"},
- {RML(ENGLISH,ENGLISH_BELIZE), "en_BZ"},
- {RML(ENGLISH,ENGLISH_CAN), "en_CA"},
- {RML(ENGLISH,ENGLISH_CARIBBEAN), "en_CB"},
- {RML(ENGLISH,ENGLISH_EIRE), "en_IE"},
- {RML(ENGLISH,ENGLISH_JAMAICA), "en_JM"},
- {RML(ENGLISH,ENGLISH_NZ), "en_NZ"},
- {RML(ENGLISH,ENGLISH_PHILIPPINES), "en_PH"},
- {RML(ENGLISH,ENGLISH_SOUTH_AFRICA), "en_ZA"},
- {RML(ENGLISH,ENGLISH_TRINIDAD), "en_TT"},
- {RML(ENGLISH,ENGLISH_UK), "en_GB"},
- {RML(ENGLISH,ENGLISH_US), "en_US"},
- {RML(ENGLISH,ENGLISH_ZIMBABWE), "en_ZW"},
-/*{RML(ESPERANTO,DEFAULT), "eo_"},*/
- {RML(ESTONIAN,DEFAULT), "et_EE"},
- {RML(FAEROESE,DEFAULT), "fo_FO"},
- {RML(FARSI,DEFAULT), "fa_IR"},
- {RML(FINNISH,DEFAULT), "fi_FI"},
- {RML(FRENCH,FRENCH), "fr_FR"},
- {RML(FRENCH,FRENCH_BELGIAN), "fr_BE"},
- {RML(FRENCH,FRENCH_CANADIAN), "fr_CA"},
- {RML(FRENCH,FRENCH_LUXEMBOURG), "fr_LU"},
- {RML(FRENCH,FRENCH_MONACO), "fr_MC"},
- {RML(FRENCH,FRENCH_SWISS), "fr_CH"},
-/*{RML(GAELIC,GAELIC), "ga_IE"},*/
-/*{RML(GAELIC,GAELIC_MANX), "gv_GB"},*/
-/*{RML(GAELIC,GAELIC_SCOTTISH), "gd_GB"},*/
-/*{RML(GALICIAN,DEFAULT), "gl_ES"},*/
- {RML(GEORGIAN,DEFAULT), "ka_GE"},
- {RML(GERMAN,GERMAN), "de_DE"},
- {RML(GERMAN,GERMAN_AUSTRIAN), "de_AT"},
- {RML(GERMAN,GERMAN_LIECHTENSTEIN), "de_LI"},
- {RML(GERMAN,GERMAN_LUXEMBOURG), "de_LU"},
- {RML(GERMAN,GERMAN_SWISS), "de_CH"},
- {RML(GREEK,DEFAULT), "el_GR"},
- {RML(GUJARATI,DEFAULT), "gu_IN"},
- {RML(HEBREW,DEFAULT), "he_IL"},
- {RML(HINDI,DEFAULT), "hi_IN"},
- {RML(HUNGARIAN,DEFAULT), "hu_HU"},
- {RML(ICELANDIC,DEFAULT), "is_IS"},
- {RML(INDONESIAN,DEFAULT), "id_ID"},
- {RML(ITALIAN,ITALIAN), "it_IT"},
- {RML(ITALIAN,ITALIAN_SWISS), "it_CH"},
- {RML(JAPANESE,DEFAULT), "ja_JP"},
- {RML(KANNADA,DEFAULT), "kn_IN"},
- {RML(KAZAK,DEFAULT), "kk_KZ"},
- {RML(KONKANI,DEFAULT), "kok_IN"},
- {RML(KOREAN,KOREAN), "ko_KR"},
-/*{RML(KYRGYZ,DEFAULT), "ky_KG"},*/
- {RML(LATVIAN,DEFAULT), "lv_LV"},
- {RML(LITHUANIAN,LITHUANIAN), "lt_LT"},
- {RML(MACEDONIAN,DEFAULT), "mk_MK"},
- {RML(MALAY,MALAY_BRUNEI_DARUSSALAM), "ms_BN"},
- {RML(MALAY,MALAY_MALAYSIA), "ms_MY"},
- {RML(MARATHI,DEFAULT), "mr_IN"},
-/*{RML(MONGOLIAN,DEFAULT), "mn_MN"},*/
- {RML(NORWEGIAN,NORWEGIAN_BOKMAL), "nb_NO"},
- {RML(NORWEGIAN,NORWEGIAN_NYNORSK), "nn_NO"},
- {RML(POLISH,DEFAULT), "pl_PL"},
- {RML(PORTUGUESE,PORTUGUESE), "pt_PT"},
- {RML(PORTUGUESE,PORTUGUESE_BRAZILIAN), "pt_BR"},
- {RML(PUNJABI,DEFAULT), "pa_IN"},
- {RML(ROMANIAN,DEFAULT), "ro_RO"},
- {RML(RUSSIAN,DEFAULT), "ru_RU"},
- {RML(SANSKRIT,DEFAULT), "sa_IN"},
- {RML(SERBIAN,DEFAULT), "hr_HR"},
- {RML(SERBIAN,SERBIAN_CYRILLIC), "sr_SP"},
- {RML(SERBIAN,SERBIAN_LATIN), "sr_SP"},
- {RML(SLOVAK,DEFAULT), "sk_SK"},
- {RML(SLOVENIAN,DEFAULT), "sl_SI"},
- {RML(SPANISH,SPANISH), "es_ES"},
- {RML(SPANISH,SPANISH_ARGENTINA), "es_AR"},
- {RML(SPANISH,SPANISH_BOLIVIA), "es_BO"},
- {RML(SPANISH,SPANISH_CHILE), "es_CL"},
- {RML(SPANISH,SPANISH_COLOMBIA), "es_CO"},
- {RML(SPANISH,SPANISH_COSTA_RICA), "es_CR"},
- {RML(SPANISH,SPANISH_DOMINICAN_REPUBLIC), "es_DO"},
- {RML(SPANISH,SPANISH_ECUADOR), "es_EC"},
- {RML(SPANISH,SPANISH_EL_SALVADOR), "es_SV"},
- {RML(SPANISH,SPANISH_GUATEMALA), "es_GT"},
- {RML(SPANISH,SPANISH_HONDURAS), "es_HN"},
- {RML(SPANISH,SPANISH_MEXICAN), "es_MX"},
- {RML(SPANISH,SPANISH_MODERN), "es_ES"},
- {RML(SPANISH,SPANISH_NICARAGUA), "es_NI"},
- {RML(SPANISH,SPANISH_PANAMA), "es_PA"},
- {RML(SPANISH,SPANISH_PARAGUAY), "es_PY"},
- {RML(SPANISH,SPANISH_PERU), "es_PE"},
- {RML(SPANISH,SPANISH_PUERTO_RICO), "es_PR"},
- {RML(SPANISH,SPANISH_URUGUAY), "es_UY"},
- {RML(SPANISH,SPANISH_VENEZUELA), "es_VE"},
- {RML(SWAHILI,DEFAULT), "sw_KE"},
- {RML(SWEDISH,SWEDISH), "sv_SE"},
- {RML(SWEDISH,SWEDISH_FINLAND), "sv_FI"},
-/*{RML(SYRIAC,DEFAULT), "syr_SY"},*/
- {RML(TAMIL,DEFAULT), "ta_IN"},
- {RML(TATAR,DEFAULT), "tt_TA"},
- {RML(TELUGU,DEFAULT), "te_IN"},
- {RML(THAI,DEFAULT), "th_TH"},
- {RML(TURKISH,DEFAULT), "tr_TR"},
- {RML(UKRAINIAN,DEFAULT), "uk_UA"},
- {RML(URDU,URDU_PAKISTAN), "ur_PK"},
- {RML(UZBEK,UZBEK_CYRILLIC), "uz_UZ"},
- {RML(UZBEK,UZBEK_LATIN), "uz_UZ"},
- {RML(VIETNAMESE,DEFAULT), "vi_VN"},
-/*{RML(WALON,DEFAULT), "wa_BE"},*/
-/*{RML(WELSH,DEFAULT), "cy_GB"},*/
-};
-static const IDToCode primary_to_code[] = {
- {LANG_AFRIKAANS, "af"},
- {LANG_ARABIC, "ar"},
- {LANG_AZERI, "az"},
- {LANG_BULGARIAN, "bg"},
-/*{LANG_BRETON, "br"},*/
- {LANG_BELARUSIAN, "by"},
- {LANG_CATALAN, "ca"},
- {LANG_CZECH, "cs"},
-/*{LANG_WELSH, "cy"},*/
- {LANG_DANISH, "da"},
- {LANG_GERMAN, "de"},
- {LANG_GREEK, "el"},
- {LANG_ENGLISH, "en"},
-/*{LANG_ESPERANTO, "eo"},*/
- {LANG_SPANISH, "es"},
- {LANG_ESTONIAN, "et"},
- {LANG_BASQUE, "eu"},
- {LANG_FARSI, "fa"},
- {LANG_FINNISH, "fi"},
- {LANG_FAEROESE, "fo"},
- {LANG_FRENCH, "fr"},
-/*{LANG_GAELIC, "ga"},*/
-/*{LANG_GALICIAN, "gl"},*/
- {LANG_GUJARATI, "gu"},
- {LANG_HEBREW, "he"},
- {LANG_HINDI, "hi"},
- {LANG_SERBIAN, "hr"},
- {LANG_HUNGARIAN, "hu"},
- {LANG_ARMENIAN, "hy"},
- {LANG_INDONESIAN, "id"},
- {LANG_ITALIAN, "it"},
- {LANG_JAPANESE, "ja"},
- {LANG_GEORGIAN, "ka"},
- {LANG_KAZAK, "kk"},
- {LANG_KANNADA, "kn"},
- {LANG_KOREAN, "ko"},
-/*{LANG_KYRGYZ, "ky"},*/
- {LANG_LITHUANIAN, "lt"},
- {LANG_LATVIAN, "lv"},
- {LANG_MACEDONIAN, "mk"},
-/*{LANG_MONGOLIAN, "mn"},*/
- {LANG_MARATHI, "mr"},
- {LANG_MALAY, "ms"},
- {LANG_NORWEGIAN, "nb"},
- {LANG_DUTCH, "nl"},
- {LANG_NORWEGIAN, "nn"},
- {LANG_NORWEGIAN, "no"},/* unofficial? */
- {LANG_PUNJABI, "pa"},
- {LANG_POLISH, "pl"},
- {LANG_PORTUGUESE, "pt"},
- {LANG_ROMANIAN, "ro"},
- {LANG_RUSSIAN, "ru"},
- {LANG_SLOVAK, "sk"},
- {LANG_SLOVENIAN, "sl"},
- {LANG_ALBANIAN, "sq"},
- {LANG_SERBIAN, "sr"},
- {LANG_SWEDISH, "sv"},
- {LANG_SWAHILI, "sw"},
- {LANG_TAMIL, "ta"},
- {LANG_THAI, "th"},
- {LANG_TURKISH, "tr"},
- {LANG_TATAR, "tt"},
- {LANG_UKRAINIAN, "uk"},
- {LANG_URDU, "ur"},
- {LANG_UZBEK, "uz"},
- {LANG_VIETNAMESE, "vi"},
-/*{LANG_WALON, "wa"},*/
- {LANG_CHINESE, "zh"},
-};
-static int num_primary_to_code =
- sizeof(primary_to_code) / sizeof(*primary_to_code);
-static int num_both_to_code =
- sizeof(both_to_code) / sizeof(*both_to_code);
-
-static const int
-lcid_to_fl(LCID lcid,
- FL_Locale *rtn) {
- LANGID langid = LANGIDFROMLCID(lcid);
- LANGID primary_lang = PRIMARYLANGID(langid);
-#if 0
- LANGID sub_lang = SUBLANGID(langid);
-#endif
- int i;
- /* try to find an exact primary/sublanguage combo that we know about */
- for (i=0; i<num_both_to_code; ++i) {
- if (both_to_code[i].id == langid) {
- accumulate_locstring(both_to_code[i].code, rtn);
- return 1;
- }
- }
- /* fallback to just checking the primary language id */
- for (i=0; i<num_primary_to_code; ++i) {
- if (primary_to_code[i].id == primary_lang) {
- accumulate_locstring(primary_to_code[i].code, rtn);
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-
-FL_Success
-FL_FindLocale(FL_Locale **locale, FL_Domain /*domain*/) {
- FL_Success success = FL_FAILED;
- FL_Locale *rtn = (FL_Locale*) malloc(sizeof(FL_Locale));
- rtn->lang = NULL;
- rtn->country = NULL;
- rtn->variant = NULL;
-
-#ifdef WIN32
- /* win32 >= mswindows95 */
- {
- LCID lcid = GetThreadLocale();
- if (lcid_to_fl(lcid, rtn)) {
- success = FL_CONFIDENT;
- }
- if (success == FL_FAILED) {
- /* assume US English on mswindows systems unless we know otherwise */
- if (accumulate_locstring("en_US.ISO_8859-1", rtn)) {
- success = FL_DEFAULT_GUESS;
- }
- }
- }
-#else
- /* assume unixoid */
- {
-#ifdef MACOSX
- CFIndex sz;
- CFArrayRef languages;
- CFStringRef uxstylelangs;
- char *uxsl;
-
- /* get the languages from the user's presets */
- languages = (CFArrayRef)CFPreferencesCopyValue(CFSTR("AppleLanguages"),
- kCFPreferencesAnyApplication, kCFPreferencesCurrentUser,
- kCFPreferencesAnyHost);
-
- /* join the returned string array into a string separated by colons */
- uxstylelangs = CFStringCreateByCombiningStrings(kCFAllocatorDefault,
- languages, CFSTR(":"));
-
- /* convert this string into a C string */
- sz = CFStringGetLength(uxstylelangs) + 1;
- uxsl = (char*)malloc(sz);
- CFStringGetCString(uxstylelangs, uxsl, sz, kCFStringEncodingISOLatin1);
-
- /* add it to the list */
- if (accumulate_locstring(uxsl, rtn)) {
- success = FL_CONFIDENT;
- }
- /* continue the UNIX method */
-#endif
- /* examples: */
- /* sv_SE.ISO_8859-1 */
- /* fr_FR.ISO8859-1 */
- /* no_NO_NB */
- /* no_NO_NY */
- /* no_NO */
- /* de_DE */
- /* try the various vars in decreasing order of authority */
- if (accumulate_env("LC_ALL", rtn) ||
- accumulate_env("LC_MESSAGES", rtn) ||
- accumulate_env("LANG", rtn) ||
- accumulate_env("LANGUAGE", rtn)) {
- success = FL_CONFIDENT;
- }
- if (success == FL_FAILED) {
- /* assume US English on unixoid systems unless we know otherwise */
- if (accumulate_locstring("en_US.ISO_8859-1", rtn)) {
- success = FL_DEFAULT_GUESS;
- }
- }
- }
-#endif
-
- if (success != FL_FAILED) {
- canonize_fl(rtn);
- }
-
- *locale = rtn;
- return success;
-}
-
-
-void
-FL_FreeLocale(FL_Locale **locale) {
- if (locale) {
- FL_Locale *l = *locale;
- if (l) {
- if (l->lang) {
- free((void*)l->lang);
- }
- if (l->country) {
- free((void*)l->country);
- }
- if (l->variant) {
- free((void*)l->variant);
- }
- free(l);
- *locale = NULL;
- }
- }
-}
+++ /dev/null
-/*
- findlocale-0.46.tar.gz from http://icculus.org/~aspirin/findlocale/
-
-Copyright (C) 2004 Adam D. Moss (the "Author"). All Rights Reserved.
-
-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 fur-
-nished 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, FIT-
-NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
-NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the Author of the
-Software shall not be used in advertising or otherwise to promote the sale,
-use or other dealings in this Software without prior written authorization
-from the Author.
-
-*/
-
-#ifndef __findlocale_h_
-#define __findlocale_h_
-
-typedef const char* FL_Lang;
-typedef const char* FL_Country;
-typedef const char* FL_Variant;
-
-typedef struct {
- FL_Lang lang;
- FL_Country country;
- FL_Variant variant;
-} FL_Locale;
-
-typedef enum {
- /* for some reason we failed to even guess: this should never happen */
- FL_FAILED = 0,
- /* couldn't query locale -- returning a guess (almost always English) */
- FL_DEFAULT_GUESS = 1,
- /* the returned locale type was found by successfully asking the system */
- FL_CONFIDENT = 2
-} FL_Success;
-
-typedef enum {
- FL_MESSAGES = 0
-} FL_Domain;
-
-/* This allocates/fills in a FL_Locale structure with pointers to
- strings (which should be treated as static), or NULL for inappropriate /
- undetected fields. */
-FL_Success FL_FindLocale(FL_Locale **locale, FL_Domain domain);
-/* This should be used to free the struct written by FL_FindLocale */
-void FL_FreeLocale(FL_Locale **locale);
-
-#endif /*__findlocale_h_*/
+++ /dev/null
-// $Id$
-//
-// TinyGetText
-// Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <fstream>
-#include <iostream>
-#include <algorithm>
-#include <ctype.h>
-#include <errno.h>
-
-#include <SDL.h>
-
-#ifndef GP2X
-#include <SDL_stdinc.h>
-#endif
-
-#include "tinygettext.hpp"
-#include "log.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "findlocale.hpp"
-
-//#define TRANSLATION_DEBUG
-
-namespace TinyGetText {
-
-/** Convert \a which is in \a from_charset to \a to_charset and return it */
-std::string convert(const std::string& text,
- const std::string& from_charset,
- const std::string& to_charset)
-{
-#ifndef GP2X
- if (from_charset == to_charset)
- return text;
-
- char *in = new char[text.length() + 1];
- strcpy(in, text.c_str());
- char *out = SDL_iconv_string(to_charset.c_str(), from_charset.c_str(), in, text.length() + 1);
- delete[] in;
- if(out == 0)
- {
- log_warning << "Error: conversion from " << from_charset << " to " << to_charset << " failed" << std::endl;
- return "";
- }
- std::string ret(out);
- SDL_free(out);
- return ret;
-#else
- log_warning << "FIXME: Char conversion not supported on GP2X!" << std::endl;
- return "";
-#endif
-#if 0
- iconv_t cd = SDL_iconv_open(to_charset.c_str(), from_charset.c_str());
-
- size_t in_len = text.length();
- size_t out_len = text.length()*3; // FIXME: cross fingers that this is enough
-
- char* out_orig = new char[out_len];
- char* in_orig = new char[in_len+1];
- strcpy(in_orig, text.c_str());
-
- char* out = out_orig;
- ICONV_CONST char* in = in_orig;
- size_t out_len_temp = out_len; // iconv is counting down the bytes it has
- // written from this...
-
- size_t retval = SDL_iconv(cd, &in, &in_len, &out, &out_len_temp);
- out_len -= out_len_temp; // see above
- if (retval == (size_t) -1)
- {
- log_warning << strerror(errno) << std::endl;
- log_warning << "Error: conversion from " << from_charset << " to " << to_charset << " went wrong: " << retval << std::endl;
- return "";
- }
- SDL_iconv_close(cd);
-
- std::string ret(out_orig, out_len);
- delete[] out_orig;
- delete[] in_orig;
- return ret;
-#endif
-}
-
-bool has_suffix(const std::string& lhs, const std::string rhs)
-{
- if (lhs.length() < rhs.length())
- return false;
- else
- return lhs.compare(lhs.length() - rhs.length(), rhs.length(), rhs) == 0;
-}
-
-bool has_prefix(const std::string& lhs, const std::string rhs)
-{
- if (lhs.length() < rhs.length())
- return false;
- else
- return lhs.compare(0, rhs.length(), rhs) == 0;
-}
-
-int plural1(int ) { return 0; }
-int plural2_1(int n) { return (n != 1); }
-int plural2_2(int n) { return (n > 1); }
-int plural3_lv(int n) { return (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2); }
-int plural3_ga(int n) { return n==1 ? 0 : n==2 ? 1 : 2; }
-int plural3_lt(int n) { return (n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_1(int n) { return (n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_sk(int n) { return (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2; }
-int plural3_pl(int n) { return (n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
-int plural3_sl(int n) { return (n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3); }
-
-/** Language Definitions */
-//*{
-LanguageDef lang_hu("hu", "Hungarian", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_ja("ja", "Japanese", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_ko("ko", "Korean", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_tr("tr", "Turkish", 1, plural1); // "nplurals=1; plural=0;"
-LanguageDef lang_da("da", "Danish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_nl("nl", "Dutch", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_en("en", "English", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_fo("fo", "Faroese", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_de("de", "German", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_nb("nb", "Norwegian Bokmal", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_no("no", "Norwegian", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_nn("nn", "Norwegian Nynorsk", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_sv("sv", "Swedish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_et("et", "Estonian", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_fi("fi", "Finnish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_el("el", "Greek", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_he("he", "Hebrew", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_it("it", "Italian", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_pt("pt", "Portuguese", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_es("es", "Spanish", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_eo("eo", "Esperanto", 2, plural2_1); // "nplurals=2; plural=(n != 1);"
-LanguageDef lang_fr("fr", "French", 2, plural2_2); // "nplurals=2; plural=(n > 1);"
-LanguageDef lang_pt_BR("pt_BR", "Brazilian", 2, plural2_2); // "nplurals=2; plural=(n > 1);"
-LanguageDef lang_lv("lv", "Latvian", 3, plural3_lv); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
-LanguageDef lang_ga("ga", "Irish", 3, plural3_ga); // "nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;"
-LanguageDef lang_lt("lt", "Lithuanian", 3, plural3_lt); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_hr("hr", "Croatian", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_cs("cs", "Czech", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_ru("ru", "Russian", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_uk("uk", "Ukrainian", 3, plural3_1); // "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
-LanguageDef lang_sk("sk", "Slovak", 3, plural3_sk); // "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
-LanguageDef lang_pl("pl", "Polish", 3, plural3_pl); // "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
-LanguageDef lang_sl("sl", "Slovenian", 3, plural3_sl); // "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
-//*}
-
-LanguageDef&
-get_language_def(const std::string& name)
-{
- if (name == "hu") return lang_hu;
- else if (name == "ja") return lang_ja;
- else if (name == "ko") return lang_ko;
- else if (name == "tr") return lang_tr;
- else if (name == "da") return lang_da;
- else if (name == "nl") return lang_nl;
- else if (name == "en") return lang_en;
- else if (name == "fo") return lang_fo;
- else if (name == "de") return lang_de;
- else if (name == "nb") return lang_nb;
- else if (name == "no") return lang_no;
- else if (name == "nn") return lang_nn;
- else if (name == "sv") return lang_sv;
- else if (name == "et") return lang_et;
- else if (name == "fi") return lang_fi;
- else if (name == "el") return lang_el;
- else if (name == "he") return lang_he;
- else if (name == "it") return lang_it;
- else if (name == "pt") return lang_pt;
- else if (name == "es") return lang_es;
- else if (name == "eo") return lang_eo;
- else if (name == "fr") return lang_fr;
- else if (name == "pt_BR") return lang_pt_BR;
- else if (name == "lv") return lang_lv;
- else if (name == "ga") return lang_ga;
- else if (name == "lt") return lang_lt;
- else if (name == "hr") return lang_hr;
- else if (name == "cs") return lang_cs;
- else if (name == "ru") return lang_ru;
- else if (name == "uk") return lang_uk;
- else if (name == "sk") return lang_sk;
- else if (name == "pl") return lang_pl;
- else if (name == "sl") return lang_sl;
- else return lang_en;
-}
-
-DictionaryManager::DictionaryManager()
- : current_dict(&empty_dict)
-{
- parseLocaleAliases();
- // Environment variable SUPERTUX_LANG overrides language settings.
- const char* lang = getenv( "SUPERTUX_LANG" );
- if( lang ){
- set_language( lang );
- return;
- }
- // use findlocale to setup language
- FL_Locale *locale;
- FL_FindLocale( &locale, FL_MESSAGES );
- if(locale->lang) {
- if (locale->country) {
- set_language( std::string(locale->lang)+"_"+std::string(locale->country) );
- } else {
- set_language( std::string(locale->lang) );
- }
- }
- FL_FreeLocale( &locale );
-}
-
-void
-DictionaryManager::parseLocaleAliases()
-{
- // try to parse language alias list
- std::ifstream in("/usr/share/locale/locale.alias");
-
- char c = ' ';
- while(in.good() && !in.eof()) {
- while(isspace(static_cast<unsigned char>(c)) && !in.eof())
- in.get(c);
-
- if(c == '#') { // skip comments
- while(c != '\n' && !in.eof())
- in.get(c);
- continue;
- }
-
- std::string alias;
- while(!isspace(static_cast<unsigned char>(c)) && !in.eof()) {
- alias += c;
- in.get(c);
- }
- while(isspace(static_cast<unsigned char>(c)) && !in.eof())
- in.get(c);
- std::string language;
- while(!isspace(static_cast<unsigned char>(c)) && !in.eof()) {
- language += c;
- in.get(c);
- }
-
- if(in.eof())
- break;
- set_language_alias(alias, language);
- }
-}
-
-Dictionary&
-DictionaryManager::get_dictionary(const std::string& spec)
-{
-
- //log_debug << "Dictionary for language \"" << spec << "\" requested" << std::endl;
-
- std::string lang = get_language_from_spec(spec);
-
- //log_debug << "...normalized as \"" << lang << "\"" << std::endl;
-
- Dictionaries::iterator i = dictionaries.find(get_language_from_spec(lang));
- if (i != dictionaries.end())
- {
- return i->second;
- }
- else // Dictionary for languages lang isn't loaded, so we load it
- {
- //log_debug << "get_dictionary: " << lang << std::endl;
- Dictionary& dict = dictionaries[lang];
-
- dict.set_language(get_language_def(lang));
- if(charset != "")
- dict.set_charset(charset);
-
- for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
- {
- char** files = PHYSFS_enumerateFiles(p->c_str());
- if(!files)
- {
- log_warning << "Error: enumerateFiles() failed on " << *p << std::endl;
- }
- else
- {
- for(const char* const* filename = files;
- *filename != 0; filename++) {
-
- // check if filename matches requested language
- std::string fname = std::string(*filename);
- std::string load_from_file = "";
- if(fname == lang + ".po") {
- load_from_file = fname;
- } else {
- std::string::size_type s = lang.find("_");
- if(s != std::string::npos) {
- std::string lang_short = std::string(lang, 0, s);
- if (fname == lang_short + ".po") {
- load_from_file = lang_short;
- }
- }
- }
-
- // if it matched, load dictionary
- if (load_from_file != "") {
- //log_debug << "Loading dictionary for language \"" << lang << "\" from \"" << filename << "\"" << std::endl;
- std::string pofile = *p + "/" + *filename;
- try {
- IFileStream in(pofile);
- read_po_file(dict, in);
- } catch(std::exception& e) {
- log_warning << "Error: Failure file opening: " << pofile << std::endl;
- log_warning << e.what() << "" << std::endl;
- }
- }
-
- }
- PHYSFS_freeList(files);
- }
- }
-
- return dict;
- }
-}
-
-std::set<std::string>
-DictionaryManager::get_languages()
-{
- std::set<std::string> languages;
-
- for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
- {
- char** files = PHYSFS_enumerateFiles(p->c_str());
- if (!files)
- {
- log_warning << "Error: opendir() failed on " << *p << std::endl;
- }
- else
- {
- for(const char* const* file = files; *file != 0; file++) {
- if(has_suffix(*file, ".po")) {
- std::string filename = *file;
- languages.insert(filename.substr(0, filename.length()-3));
- }
- }
- PHYSFS_freeList(files);
- }
- }
- return languages;
-}
-
-void
-DictionaryManager::set_language(const std::string& lang)
-{
- //log_debug << "set_language \"" << lang << "\"" << std::endl;
- language = get_language_from_spec(lang);
- //log_debug << "==> \"" << language << "\"" << std::endl;
- current_dict = & (get_dictionary(language));
-}
-
-const std::string&
-DictionaryManager::get_language() const
-{
- return language;
-}
-
-void
-DictionaryManager::set_charset(const std::string& charset)
-{
- dictionaries.clear(); // changing charset invalidates cache
- this->charset = charset;
- set_language(language);
-}
-
-void
-DictionaryManager::set_language_alias(const std::string& alias,
- const std::string& language)
-{
- language_aliases.insert(std::make_pair(alias, language));
-}
-
-std::string
-DictionaryManager::get_language_from_spec(const std::string& spec)
-{
- std::string lang = spec;
- Aliases::iterator i = language_aliases.find(lang);
- if(i != language_aliases.end()) {
- lang = i->second;
- }
-
- std::string::size_type s = lang.find(".");
- if(s != std::string::npos) {
- lang = std::string(lang, 0, s);
- }
-
- s = lang.find("_");
- if(s == std::string::npos) {
- std::string lang_big = lang;
- std::transform (lang_big.begin(), lang_big.end(), lang_big.begin(), toupper);
- lang += "_" + lang_big;
- }
-
- return lang;
-
-}
-
-void
-DictionaryManager::add_directory(const std::string& pathname)
-{
- dictionaries.clear(); // adding directories invalidates cache
- search_path.push_back(pathname);
- set_language(language);
-}
-
-//---------------------------------------------------------------------------
-
-Dictionary::Dictionary(const LanguageDef& language_, const std::string& charset_)
- : language(language_), charset(charset_)
-{
-}
-
-Dictionary::Dictionary()
- : language(lang_en)
-{
-}
-
-std::string
-Dictionary::get_charset() const
-{
- return charset;
-}
-
-void
-Dictionary::set_charset(const std::string& charset_)
-{
- charset = charset_;
-}
-
-void
-Dictionary::set_language(const LanguageDef& lang)
-{
- language = lang;
-}
-
-std::string
-Dictionary::translate(const std::string& msgid, const std::string& msgid2, int num)
-{
- PluralEntries::iterator i = plural_entries.find(msgid);
- std::map<int, std::string>& msgstrs = i->second;
-
- if (i != plural_entries.end() && !msgstrs.empty())
- {
- int g = language.plural(num);
- std::map<int, std::string>::iterator j = msgstrs.find(g);
- if (j != msgstrs.end())
- {
- return j->second;
- }
- else
- {
- // Return the first translation, in case we can't translate the specific number
- return msgstrs.begin()->second;
- }
- }
- else
- {
-#ifdef TRANSLATION_DEBUG
- log_warning << "Couldn't translate: " << msgid << std::endl;
- log_warning << "Candidates: " << std::endl;
- for (PluralEntries::iterator i = plural_entries.begin(); i != plural_entries.end(); ++i)
- log_debug << "'" << i->first << "'" << std::endl;
-#endif
-
- if (plural2_1(num)) // default to english rules
- return msgid2;
- else
- return msgid;
- }
-}
-
-const char*
-Dictionary::translate(const char* msgid)
-{
- Entries::iterator i = entries.find(msgid);
- if (i != entries.end() && !i->second.empty())
- {
- return i->second.c_str();
- }
- else
- {
-#ifdef TRANSLATION_DEBUG
- log_warning << "Couldn't translate: " << msgid << std::endl;
-#endif
- return msgid;
- }
-}
-
-std::string
-Dictionary::translate(const std::string& msgid)
-{
- Entries::iterator i = entries.find(msgid);
- if (i != entries.end() && !i->second.empty())
- {
- return i->second;
- }
- else
- {
-#ifdef TRANSLATION_DEBUG
- log_warning << "Couldn't translate: " << msgid << std::endl;
-#endif
- return msgid;
- }
-}
-
-void
-Dictionary::add_translation(const std::string& msgid, const std::string& ,
- const std::map<int, std::string>& msgstrs)
-{
- // Do we need msgid2 for anything? its after all supplied to the
- // translate call, so we just throw it away
- plural_entries[msgid] = msgstrs;
-}
-
-void
-Dictionary::add_translation(const std::string& msgid, const std::string& msgstr)
-{
- entries[msgid] = msgstr;
-}
-
-class POFileReader
-{
-private:
- Dictionary& dict;
- std::istream& in;
-
- std::string from_charset;
- std::string to_charset;
-
- int line_num;
- int c; //TODO: char c? unsigned char c?
- enum Token {
- TOKEN_KEYWORD, //msgstr, msgid, etc.
- TOKEN_CONTENT, //string literals, concatenated ("" "foo\n" "bar\n" -> "foo\nbar\n")
- TOKEN_EOF //ran out of tokens
- };
- Token token;
- std::string tokenContent; //current contents of the keyword or string literal(s)
-
-public:
- POFileReader(std::istream& in_, Dictionary& dict_)
- : in(in_), dict(dict_)
- {
- line_num = 0;
- nextChar();
- if(c == 0xef) { // skip UTF-8 intro that some text editors produce
- nextChar();
- nextChar();
- nextChar();
- }
- tokenize_po();
- }
-
- void parse_header(const std::string& header)
- {
- // Separate the header in lines
- typedef std::vector<std::string> Lines;
- Lines lines;
-
- std::string::size_type start = 0;
- for(std::string::size_type i = 0; i < header.length(); ++i)
- {
- if (header[i] == '\n')
- {
- lines.push_back(header.substr(start, i - start));
- start = i+1;
- }
- }
-
- for(Lines::iterator i = lines.begin(); i != lines.end(); ++i)
- {
- if (has_prefix(*i, "Content-Type: text/plain; charset=")) {
- from_charset = i->substr(strlen("Content-Type: text/plain; charset="));
- }
- }
-
- if (from_charset.empty() || from_charset == "CHARSET")
- {
- log_warning << "Error: Charset not specified for .po, fallback to ISO-8859-1" << std::endl;
- from_charset = "ISO-8859-1";
- }
-
- to_charset = dict.get_charset();
- if (to_charset.empty())
- { // No charset requested from the dict, use utf-8
- to_charset = "utf-8";
- dict.set_charset(from_charset);
- }
- }
-
- inline void nextChar()
- {
- c = in.get();
- if (c == '\n')
- line_num++;
- }
-
- inline void skipSpace()
- {
- if(c == EOF)
- return;
-
- while(c == '#' || isspace(static_cast<unsigned char>(c))) {
- if(c == '#') {
- while(c != '\n' && c != EOF) nextChar();
- }
- nextChar();
- }
- }
-
- inline bool expectToken(std::string type, Token wanted) {
- if(token != wanted) {
- log_warning << "Expected " << type << ", got ";
- if(token == TOKEN_EOF)
- log_warning << "EOF";
- else if(token == TOKEN_KEYWORD)
- log_warning << "keyword '" << tokenContent << "'";
- else
- log_warning << "string \"" << tokenContent << '"';
-
- log_warning << " at line " << line_num << std::endl;
- return false;
- }
- return true;
- }
-
- inline bool expectContent(std::string type, std::string wanted) {
- if(tokenContent != wanted) {
- log_warning << "Expected " << type << ", got ";
- if(token == TOKEN_EOF)
- log_warning << "EOF";
- else if(token == TOKEN_KEYWORD)
- log_warning << "keyword '" << tokenContent << "'";
- else
- log_warning << "string \"" << tokenContent << '"';
-
- log_warning << " at line " << line_num << std::endl;
- return false;
- }
- return true;
- }
-
- void tokenize_po()
- {
- while((token = nextToken()) != TOKEN_EOF)
- {
- if(!expectToken("'msgid' keyword", TOKEN_KEYWORD) || !expectContent("'msgid' keyword", "msgid")) break;
-
- token = nextToken();
- if(!expectToken("name after msgid", TOKEN_CONTENT)) break;
- std::string current_msgid = tokenContent;
-
- token = nextToken();
- if(!expectToken("msgstr or msgid_plural", TOKEN_KEYWORD)) break;
- if(tokenContent == "msgid_plural")
- {
- //Plural form
- token = nextToken();
- if(!expectToken("msgid_plural content", TOKEN_CONTENT)) break;
- std::string current_msgid_plural = tokenContent;
-
- std::map<int, std::string> msgstr_plural;
- while((token = nextToken()) == TOKEN_KEYWORD && has_prefix(tokenContent, "msgstr["))
- {
- int num;
- if (sscanf(tokenContent.c_str(), "msgstr[%d]", &num) != 1)
- {
- log_warning << "Error: Couldn't parse: " << tokenContent << std::endl;
- }
-
- token = nextToken();
- if(!expectToken("msgstr[x] content", TOKEN_CONTENT)) break;
- msgstr_plural[num] = convert(tokenContent, from_charset, to_charset);
- }
- dict.add_translation(current_msgid, current_msgid_plural, msgstr_plural);
- }
- else
- {
- // "Ordinary" translation
- if(!expectContent("'msgstr' keyword", "msgstr")) break;
-
- token = nextToken();
- if(!expectToken("translation in msgstr", TOKEN_CONTENT)) break;
-
- if (current_msgid == "")
- { // .po Header is hidden in the msgid with the empty string
- parse_header(tokenContent);
- }
- else
- {
- dict.add_translation(current_msgid, convert(tokenContent, from_charset, to_charset));
- }
- }
- }
- }
-
- Token nextToken()
- {
- //Clear token contents
- tokenContent = "";
-
- skipSpace();
-
- if(c == EOF)
- return TOKEN_EOF;
- else if(c != '"')
- {
- // Read a keyword
- do {
- tokenContent += c;
- nextChar();
- } while(c != EOF && !isspace(static_cast<unsigned char>(c)));
- return TOKEN_KEYWORD;
- }
- else
- {
- do {
- nextChar();
- // Read content
- while(c != EOF && c != '"') {
- if (c == '\\') {
- nextChar();
- if (c == 'n') c = '\n';
- else if (c == 't') c = '\t';
- else if (c == 'r') c = '\r';
- else if (c == '"') c = '"';
- else if (c == '\\') c = '\\';
- else
- {
- log_warning << "Unhandled escape character: " << char(c) << std::endl;
- c = ' ';
- }
- }
- tokenContent += c;
- nextChar();
- }
- if(c == EOF) {
- log_warning << "Unclosed string literal: " << tokenContent << std::endl;
- return TOKEN_CONTENT;
- }
-
- // Read more strings?
- skipSpace();
- } while(c == '"');
- return TOKEN_CONTENT;
- }
- }
-};
-
-void read_po_file(Dictionary& dict_, std::istream& in)
-{
- POFileReader reader(in, dict_);
-}
-
-} // namespace TinyGetText
-
-/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef HEADER_TINYGETTEXT_H
-#define HEADER_TINYGETTEXT_H
-
-#include <map>
-#include <vector>
-#include <set>
-#include <string>
-
-namespace TinyGetText {
-
-typedef int (*PluralFunc)(int n);
-
-struct LanguageDef {
- const char* code;
- const char* name;
- int nplural;
- PluralFunc plural;
-
- LanguageDef(const char* code_, const char* name_, int nplural_, PluralFunc plural_)
- : code(code_), name(name_), nplural(nplural_), plural(plural_)
- {}
-};
-
-/** A simple dictionary class that mimics gettext() behaviour. Each
- Dictionary only works for a single language, for managing multiple
- languages and .po files at once use the DictionaryManager. */
-class Dictionary
-{
-private:
- typedef std::map<std::string, std::string> Entries;
- Entries entries;
-
- typedef std::map<std::string, std::map<int, std::string> > PluralEntries;
- PluralEntries plural_entries;
-
- LanguageDef language;
- std::string charset;
-public:
- /** */
- Dictionary(const LanguageDef& language_, const std::string& charset = "");
-
- Dictionary();
-
- /** Return the charset used for this dictionary */
- std::string get_charset() const;
-
- /** Set a charset for this dictionary, this will NOT convert stuff,
- it is for information only, you have to convert stuff yourself
- when you add it with \a add_translation() */
- void set_charset(const std::string& charset);
-
- /** Set the language that is used for this dictionary, this is
- mainly needed to evaluate plural forms */
- void set_language(const LanguageDef& lang);
-
- /** Translate the string \a msgid to its correct plural form, based
- on the number of items given by \a num. \a msgid2 is \a msgid in
- plural form. */
- std::string translate(const std::string& msgid, const std::string& msgid2, int num);
-
- /** Translate the string \a msgid. */
- std::string translate(const std::string& msgid);
- /** Translate the string \a msgid. */
- const char* translate(const char* msgid);
-
- /** Add a translation from \a msgid to \a msgstr to the dictionary,
- where \a msgid is the singular form of the message, msgid2 the
- plural form and msgstrs a table of translations. The right
- translation will be calculated based on the \a num argument to
- translate(). */
- void add_translation(const std::string& msgid, const std::string& msgid2,
- const std::map<int, std::string>& msgstrs);
-
- /** Add a translation from \a msgid to \a msgstr to the
- dictionary */
- void add_translation(const std::string& msgid, const std::string& msgstr);
-};
-
-/** Manager class for dictionaries, you give it a bunch of directories
- with .po files and it will then automatically load the right file
- on demand depending on which language was set. */
-class DictionaryManager
-{
-private:
- typedef std::map<std::string, Dictionary> Dictionaries;
- Dictionaries dictionaries;
- typedef std::vector<std::string> SearchPath;
- SearchPath search_path;
- typedef std::map<std::string, std::string> Aliases;
- Aliases language_aliases;
- std::string charset;
- std::string language;
- Dictionary* current_dict;
- Dictionary empty_dict;
-
-public:
- DictionaryManager();
-
- /** Return the currently active dictionary, if none is set, an empty
- dictionary is returned. */
- Dictionary& get_dictionary()
- { return *current_dict; }
-
- /** Get dictionary for lang */
- Dictionary& get_dictionary(const std::string& langspec);
-
- /** Set a language based on a four? letter country code */
- void set_language(const std::string& langspec);
-
- /** returns the (normalized) country code of the currently used language */
- const std::string& get_language() const;
-
- /** Set a charset that will be set on the returned dictionaries */
- void set_charset(const std::string& charset);
-
- /** Define an alias for a language */
- void set_language_alias(const std::string& alias, const std::string& lang);
-
- /** Add a directory to the search path for dictionaries */
- void add_directory(const std::string& pathname);
-
- /** Return a set of the available languages in their country code */
- std::set<std::string> get_languages();
-
-private:
- void parseLocaleAliases();
- /// returns the language part in a language spec (like de_DE.UTF-8 -> de)
- std::string get_language_from_spec(const std::string& spec);
-};
-
-/** Read the content of the .po file given as \a in into the
- dictionary given as \a dict */
-void read_po_file(Dictionary& dict, std::istream& in);
-LanguageDef& get_language_def(const std::string& name);
-
-} // namespace TinyGetText
-
-#endif
-
-/* EOF */