Switched from tinygettext/tags/tinygetext-supertux/ to tinygettext/trunk/
authorIngo Ruhnke <grumbel@gmx.de>
Wed, 18 Nov 2009 17:44:46 +0000 (17:44 +0000)
committerIngo Ruhnke <grumbel@gmx.de>
Wed, 18 Nov 2009 17:44:46 +0000 (17:44 +0000)
SVN-Revision: 6032

16 files changed:
CMakeLists.txt
SConscript
external/README [new file with mode: 0644]
external/findlocale/LICENSE [new file with mode: 0644]
external/findlocale/Makefile [new file with mode: 0644]
external/findlocale/README.findlocale [new file with mode: 0644]
external/findlocale/VERSION [new file with mode: 0644]
external/findlocale/example.c [new file with mode: 0644]
external/findlocale/findlocale.c [new file with mode: 0644]
external/findlocale/findlocale.h [new file with mode: 0644]
src/lisp/parser.cpp
src/lisp/parser.hpp
src/supertux/globals.cpp
src/supertux/language_menu.cpp
src/supertux/main.cpp
src/util/gettext.hpp

index 0db5337..b2d1e08 100644 (file)
@@ -163,11 +163,12 @@ LINK_DIRECTORIES(external/squirrel)
 include_directories (${SUPERTUX_SOURCE_DIR}/src/)
 include_directories (${SUPERTUX_SOURCE_DIR}/external/squirrel/include/)
 include_directories (${SUPERTUX_SOURCE_DIR}/external/)
+include_directories (${SUPERTUX_SOURCE_DIR}/external/findlocale/)
 include_directories (${SUPERTUX_SOURCE_DIR}/external/obstack/)
 
 ## Build list of sources for supertux binary
 
-FILE(GLOB SUPERTUX_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} src/*.cpp src/*/*.cpp src/video/sdl/*.cpp external/obstack/*.c external/tinygettext/*.cpp)
+FILE(GLOB SUPERTUX_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} src/*.cpp src/*/*.cpp src/video/sdl/*.cpp external/obstack/*.c external/tinygettext/*.cpp external/findlocale/findlocale.c)
 
 IF(HAVE_OPENGL)
   FILE(GLOB SUPERTUX_OPENGL_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} src/video/gl/*.cpp)
index 13b6d4d..2f2e4ee 100644 (file)
@@ -19,6 +19,7 @@ class Project:
         self.build_squirrel()
         self.build_tinygettext()
         self.build_binreloc()
+        self.build_findlocale()
         self.build_supertux()
         self.build_tests()
 
@@ -34,6 +35,10 @@ class Project:
         env = Environment(CPPPATH=["external/binreloc/", "."])
         self.libbinreloc = env.StaticLibrary("binreloc", "external/binreloc/binreloc.c")
 
+    def build_findlocale(self):
+        env = Environment(CPPPATH=["external/findlocale/", "."])
+        self.libfindlocale = env.StaticLibrary("findlocale", "external/findlocale/findlocale.c")
+
     def build_squirrel(self):
         env = Environment(CPPPATH=["external/squirrel/include/"])
         self.libsquirrel = env.StaticLibrary("squirrel",
@@ -43,6 +48,7 @@ class Project:
 
     def build_supertux(self):
         self.env = Environment(CPPPATH=["external/squirrel/include/",
+                                        "external/findlocale/",
                                         "external/",
                                         "external/obstack",
                                         "src/",
@@ -66,7 +72,7 @@ class Project:
         self.env.ParseConfig("sdl-config --libs --cflags")
         self.env.ParseConfig("pkg-config --libs --cflags openal")
         self.env.ParseConfig("pkg-config --libs --cflags vorbis vorbisfile ogg")
-        self.env.Append(LIBS=[self.libsquirrel, self.libbinreloc, self.libtinygettext])
+        self.env.Append(LIBS=[self.libsquirrel, self.libbinreloc, self.libtinygettext, self.libfindlocale])
         self.env.Append(LIBS=["SDL_image", "curl", "GL", "physfs"])
 
         # Create config.h
diff --git a/external/README b/external/README
new file mode 100644 (file)
index 0000000..a839193
--- /dev/null
@@ -0,0 +1,4 @@
+findlocale/
+ * findlocale-0.46.tar.gz from http://icculus.org/~aspirin/findlocale/
+
+# EOF #
diff --git a/external/findlocale/LICENSE b/external/findlocale/LICENSE
new file mode 100644 (file)
index 0000000..5260473
--- /dev/null
@@ -0,0 +1,23 @@
+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.
diff --git a/external/findlocale/Makefile b/external/findlocale/Makefile
new file mode 100644 (file)
index 0000000..12fff75
--- /dev/null
@@ -0,0 +1,16 @@
+CC = cc
+CFLAGS = -Os -Wall
+
+all: example
+
+example: findlocale.o example.o
+       $(CC) example.o findlocale.o -o example
+
+findlocale.o: findlocale.c findlocale.h
+       $(CC) $(CFLAGS) -c findlocale.c
+
+example.o: example.c findlocale.h
+       $(CC) $(CFLAGS) -c example.c
+
+clean:
+       $(RM) findlocale.o example.o example
diff --git a/external/findlocale/README.findlocale b/external/findlocale/README.findlocale
new file mode 100644 (file)
index 0000000..c98d413
--- /dev/null
@@ -0,0 +1,19 @@
+FindLocale -- a cross-platform C module for detecting the user's language
+Adam D. Moss / adam at steambird.com / adam at gimp.org
+
+This is an early release of a straightforward API which can be used to
+detect the user's current preferred (language,country,variant) setting
+in a uniform manner across multiple platforms.  It is not intended
+to provide localization functions, but rather it is a basis on which to
+make localization decisions.
+
+Currently, win32 (win95+) and unix-alikes are supported.
+
+Please see example.c and findlocale.h for illumination of this API.
+
+Ports and patches are always welcome.
+
+License: Completely free; see the LICENSE file.
+
+--adam
+
diff --git a/external/findlocale/VERSION b/external/findlocale/VERSION
new file mode 100644 (file)
index 0000000..98057b3
--- /dev/null
@@ -0,0 +1,14 @@
+v0.46 -- 2005-04-06
+
+        * example.c crash-avoidance for C runtimes who hate printfing
+        NULL strings.
+
+v0.45 -- 2004-10-19
+
+       * considerably more comprehensive LCID/LANGID to
+        (language,country,variant) mapping on win32.
+
+v0.4  -- 2004-10-01
+
+       * initial release
+
diff --git a/external/findlocale/example.c b/external/findlocale/example.c
new file mode 100644 (file)
index 0000000..5c1f313
--- /dev/null
@@ -0,0 +1,19 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "findlocale.h"
+
+int
+main(int in_argc, char **in_argv) {
+  FL_Locale *locale;
+  FL_FindLocale(&locale, FL_MESSAGES);
+  printf("I think that your current settings are...\n"
+         "Language = '%s'\nCountry = '%s'\nVariant = '%s'\n",
+         locale->lang ? locale->lang : "(null)",
+         locale->country ? locale->country : "(null)",
+         locale->variant ? locale->variant : "(null)");
+  FL_FreeLocale(&locale);
+  return 0;
+}
+
diff --git a/external/findlocale/findlocale.c b/external/findlocale/findlocale.c
new file mode 100644 (file)
index 0000000..4b5c816
--- /dev/null
@@ -0,0 +1,491 @@
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef WIN32
+#include <windows.h>
+#include <winnt.h>
+#endif
+
+#include "findlocale.h"
+
+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 = 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 = 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 = 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;
+}
+
+
+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;
+}
+
+
+static void
+canonise_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;
+  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);
+  LANGID sub_lang     = SUBLANGID(langid);
+  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 = 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 */
+  {
+    /* 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) {
+    canonise_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;
+    }
+  }
+}
diff --git a/external/findlocale/findlocale.h b/external/findlocale/findlocale.h
new file mode 100644 (file)
index 0000000..c388dee
--- /dev/null
@@ -0,0 +1,34 @@
+#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_*/
index b921003..c782551 100644 (file)
@@ -37,10 +37,10 @@ Parser::Parser(bool translate) :
   obst()
 {
   if(translate) {
-    dictionary_manager = new TinyGetText::DictionaryManager();
+    dictionary_manager = new tinygettext::DictionaryManager();
     dictionary_manager->set_charset("UTF-8");
     if (g_config && (g_config->locale != "")) 
-      dictionary_manager->set_language(g_config->locale);
+      dictionary_manager->set_language(tinygettext::Language::from_name(g_config->locale));
   }
 
   obstack_init(&obst);
index cbc89af..8d3927b 100644 (file)
@@ -20,7 +20,7 @@
 #include "lisp/lexer.hpp"
 #include "obstack/obstack.h"
 
-namespace TinyGetText {
+namespace tinygettext {
 class Dictionary;
 class DictionaryManager;
 }
@@ -56,8 +56,8 @@ private:
 private:
   Lexer* lexer;
   std::string filename;
-  TinyGetText::DictionaryManager* dictionary_manager;
-  TinyGetText::Dictionary* dictionary;
+  tinygettext::DictionaryManager* dictionary_manager;
+  tinygettext::Dictionary* dictionary;
   Lexer::TokenType token;
 
   struct obstack obst;
index 1089c13..22a7311 100644 (file)
@@ -19,7 +19,7 @@
 
 SDL_Surface* g_screen;
 JoystickKeyboardController* g_main_controller = 0;
-TinyGetText::DictionaryManager dictionary_manager;
+tinygettext::DictionaryManager dictionary_manager;
 
 int SCREEN_WIDTH;
 int SCREEN_HEIGHT;
index d7a0fb1..ed13ada 100644 (file)
 
 #include "supertux/language_menu.hpp"
 
+extern "C" {
+#include "findlocale.h"
+}
 #include "gui/menu_item.hpp"
 #include "supertux/gameconfig.hpp"
 
+enum {
+  MNID_LANGUAGE_AUTO_DETECT = 0,
+  MNID_LANGUAGE_ENGLISH     = 1,
+  MNID_LANGUAGE_NEXT        = 10
+};
+
 LanguageMenu::LanguageMenu() 
 {
   add_label(_("Language"));
   add_hl();
-  add_entry(0, std::string("<")+_("auto-detect")+">");
-  add_entry(1, "English");
+  add_entry(MNID_LANGUAGE_AUTO_DETECT, _("<auto-detect>"));
+  add_entry(MNID_LANGUAGE_ENGLISH, "English");
 
-  int mnid = 10;    
-  std::set<std::string> languages = dictionary_manager.get_languages();
-  for (std::set<std::string>::iterator i = languages.begin(); i != languages.end(); i++) {
-    std::string locale_name = *i;
-    TinyGetText::LanguageDef ldef = TinyGetText::get_language_def(locale_name);
-    std::string locale_fullname = locale_name;
-    if (std::string(ldef.code) == locale_name) {
-      locale_fullname = ldef.name;
-    }
-    add_entry(mnid++, locale_fullname);
-  } 
+  int mnid = MNID_LANGUAGE_NEXT;
+  std::set<tinygettext::Language> languages = dictionary_manager.get_languages();
+  for (std::set<tinygettext::Language>::iterator i = languages.begin(); i != languages.end(); i++) 
+  {
+    add_entry(mnid++, i->get_name());
+  }
 
   add_hl();
   add_back(_("Back"));
@@ -46,27 +50,40 @@ LanguageMenu::LanguageMenu()
 void
 LanguageMenu::menu_action(MenuItem* item) 
 {
-  if (item->id == 0) {
-    g_config->locale = "";
-    dictionary_manager.set_language(g_config->locale);
-    g_config->save();
-    Menu::pop_current();
+  if (item->id == MNID_LANGUAGE_AUTO_DETECT) // auto detect
+  {
+      FL_Locale *locale;
+      FL_FindLocale(&locale, FL_MESSAGES);
+      tinygettext::Language language = tinygettext::Language::from_spec(locale->lang, locale->country, locale->variant);
+      FL_FreeLocale(&locale);
+
+      dictionary_manager.set_language(language);
+      g_config->locale = language.str();
+      g_config->save();
+      Menu::pop_current();
   }
-  else if (item->id == 1) {
+  else if (item->id == MNID_LANGUAGE_ENGLISH) // english
+  {
     g_config->locale = "en";
-    dictionary_manager.set_language(g_config->locale);
+    dictionary_manager.set_language(tinygettext::Language::from_name(g_config->locale));
     g_config->save();
     Menu::pop_current();
   }
-  int mnid = 10;    
-  std::set<std::string> languages = dictionary_manager.get_languages();
-  for (std::set<std::string>::iterator i = languages.begin(); i != languages.end(); i++) {
-    std::string locale_name = *i;
-    if (item->id == mnid++) {
-      g_config->locale = locale_name;
-      dictionary_manager.set_language(g_config->locale);
-      g_config->save();
-      Menu::pop_current();
+  else
+  {
+    int mnid = MNID_LANGUAGE_NEXT;
+    std::set<tinygettext::Language> languages = dictionary_manager.get_languages();
+
+    for (std::set<tinygettext::Language>::iterator i = languages.begin(); i != languages.end(); i++) 
+    {
+      if (item->id == mnid++) 
+      {
+        g_config->locale = i->str();
+        dictionary_manager.set_language(*i);
+        g_config->save();
+        Menu::pop_current();
+        break;
+      }
     }
   }
 }
index 91943bd..b7219f5 100644 (file)
@@ -23,7 +23,8 @@
 
 #ifdef MACOSX
 namespace supertux_apple {
-}
+#  include <CoreFoundation/CoreFoundation.h>
+} // namespace supertux_apple
 #endif
 
 #include "addon/addon_manager.hpp"
@@ -31,17 +32,17 @@ namespace supertux_apple {
 #include "binreloc/binreloc.h"
 #include "control/joystickkeyboardcontroller.hpp"
 #include "math/random_generator.hpp"
+#include "physfs/ifile_stream.hpp"
 #include "physfs/physfs_sdl.hpp"
 #include "scripting/squirrel_util.hpp"
 #include "supertux/gameconfig.hpp"
+#include "supertux/globals.hpp"
 #include "supertux/mainloop.hpp"
 #include "supertux/resources.hpp"
-#include "supertux/globals.hpp"
 #include "supertux/title_screen.hpp"
 #include "util/file_system.hpp"
 #include "util/gettext.hpp"
 #include "video/drawing_context.hpp"
-#include "supertux/globals.hpp"
 #include "worldmap/worldmap.hpp"
 
 namespace { DrawingContext *context_pointer; }
@@ -63,7 +64,7 @@ static void init_tinygettext()
 
   // Config setting "locale" overrides language detection
   if (g_config->locale != "") {
-    dictionary_manager.set_language( g_config->locale );
+    dictionary_manager.set_language(tinygettext::Language::from_name(g_config->locale));
   }
 }
 
@@ -514,6 +515,16 @@ static inline void timelog(const char* )
 }
 #endif
 
+std::istream* physfs_open_file(const char* name)
+{
+  return new IFileStream(name);
+}
+
+void physfs_free_list(char** name)
+{
+  PHYSFS_freeList(name);
+}
+
 int supertux_main(int argc, char** argv)
 {
   int result = 0;
@@ -527,6 +538,15 @@ int supertux_main(int argc, char** argv)
     init_physfs(argv[0]);
     init_sdl();
 
+    { // Let tinygettext use PhysFS
+      tinygettext::DirOp dir_op;
+      dir_op.enumerate_files = &PHYSFS_enumerateFiles;
+      dir_op.free_list       = &physfs_free_list;
+      dir_op.open_file       = &physfs_open_file;
+      
+      dictionary_manager.set_dir_op(dir_op);
+    }
+
     timelog("controller");
     g_main_controller = new JoystickKeyboardController();
 
index ba16756..876ce03 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "tinygettext/tinygettext.hpp"
 
-extern TinyGetText::DictionaryManager dictionary_manager;
+extern tinygettext::DictionaryManager dictionary_manager;
 
 static inline const char* _(const char* message)
 {
@@ -31,11 +31,6 @@ static inline std::string _(const std::string& message)
   return dictionary_manager.get_dictionary().translate(message);
 }
 
-static inline const char* N_(const char* id, const char* id2, int num)
-{
-  return dictionary_manager.get_dictionary().translate(id, id2, num).c_str();
-}
-
 #endif /* _LIBGETTEXT_H */
 
 /* EOF */