src/tinygettext/findlocale.cpp

Go to the documentation of this file.
00001 /*
00002  findlocale-0.46.tar.gz from http://icculus.org/~aspirin/findlocale/
00003 
00004 Copyright (C) 2004 Adam D. Moss (the "Author").  All Rights Reserved.
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a copy
00007 of this software and associated documentation files (the "Software"), to deal
00008 in the Software without restriction, including without limitation the rights
00009 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is fur-
00011 nished to do so, subject to the following conditions:
00012 
00013 The above copyright notice and this permission notice shall be included in
00014 all copies or substantial portions of the Software.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
00018 NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00019 AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00020 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
00021 NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022 
00023 Except as contained in this notice, the name of the Author of the
00024 Software shall not be used in advertising or otherwise to promote the sale,
00025 use or other dealings in this Software without prior written authorization
00026 from the Author.
00027 
00028 */
00029 #include <config.h>
00030 
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <ctype.h>
00034 
00035 #ifdef WIN32
00036 #include <windows.h>
00037 #include <winnt.h>
00038 #endif
00039 
00040 #ifdef MACOSX
00041 #include <CoreFoundation/CoreFoundation.h>
00042 #endif
00043 
00044 #include "findlocale.hpp"
00045 
00046 static int
00047 is_lcchar(const int c) {
00048   return isalnum(c);
00049 }
00050 
00051 static void
00052 lang_country_variant_from_envstring(const char *str,
00053                                     char **lang,
00054                                     char **country,
00055                                     char **variant) {
00056   int end = 0;
00057   int start;
00058 
00059   /* get lang, if any */
00060   start = end;
00061   while (is_lcchar(str[end])) {
00062     ++end;
00063   }
00064   if (start != end) {
00065     int i;
00066     int len = end - start;
00067     char *s = (char*) malloc(len + 1);
00068     for (i=0; i<len; ++i) {
00069       s[i] = tolower(str[start + i]);
00070     }
00071     s[i] = '\0';
00072     *lang = s;
00073   } else {
00074     *lang = NULL;
00075   }
00076 
00077   if (str[end] && str[end]!=':') { /* not at end of str */
00078     ++end;
00079   }
00080 
00081   /* get country, if any */
00082   start = end;
00083   while (is_lcchar(str[end])) {
00084     ++end;
00085   }
00086   if (start != end) {
00087     int i;
00088     int len = end - start;
00089     char *s = (char*) malloc(len + 1);
00090     for (i=0; i<len; ++i) {
00091       s[i] = toupper(str[start + i]);
00092     }
00093     s[i] = '\0';
00094     *country = s;
00095   } else {
00096     *country = NULL;
00097   }
00098 
00099   if (str[end] && str[end]!=':') { /* not at end of str */
00100     ++end;
00101   }
00102 
00103   /* get variant, if any */
00104   start = end;
00105   while (str[end] && str[end]!=':') {
00106     ++end;
00107   }
00108   if (start != end) {
00109     int i;
00110     int len = end - start;
00111     char *s = (char*) malloc(len + 1);
00112     for (i=0; i<len; ++i) {
00113       s[i] = str[start + i];
00114     }
00115     s[i] = '\0';
00116     *variant = s;
00117   } else {
00118     *variant = NULL;
00119   }
00120 }
00121 
00122 
00123 static int
00124 accumulate_locstring(const char *str, FL_Locale *l) {
00125   char *lang = NULL;
00126   char *country = NULL;
00127   char *variant = NULL;
00128   if (str) {
00129     lang_country_variant_from_envstring(str, &lang, &country, &variant);
00130     if (lang) {
00131       l->lang = lang;
00132       l->country = country;
00133       l->variant = variant;
00134       return 1;
00135     }
00136   }
00137   free(lang); free(country); free(variant);
00138   return 0;
00139 }
00140 
00141 
00142 #ifndef WIN32
00143 static int
00144 accumulate_env(const char *name, FL_Locale *l) {
00145   char *env;
00146   char *lang = NULL;
00147   char *country = NULL;
00148   char *variant = NULL;
00149   env = getenv(name);
00150   if (env) {
00151     return accumulate_locstring(env, l);
00152   }
00153   free(lang); free(country); free(variant);
00154   return 0;
00155 }
00156 #endif
00157 
00158 static void
00159 canonize_fl(FL_Locale *l) {
00160   /* this function fixes some common locale-specifying mistakes */
00161   /* en_UK -> en_GB */
00162   if (l->lang && 0 == strcmp(l->lang, "en")) {
00163     if (l->country && 0 == strcmp(l->country, "UK")) {
00164       free((void*)l->country);
00165       l->country = strdup("GB");
00166     }
00167   }
00168   /* ja_JA -> ja_JP */
00169   if (l->lang && 0 == strcmp(l->lang, "ja")) {
00170     if (l->country && 0 == strcmp(l->country, "JA")) {
00171       free((void*)l->country);
00172       l->country = strdup("JP");
00173     }
00174   }
00175 }
00176 
00177 
00178 #ifdef WIN32
00179 #include <stdio.h>
00180 #define ML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##pn##_##sn)
00181 #define MLN(pn) MAKELANGID(LANG_##pn, SUBLANG_DEFAULT)
00182 #define RML(pn,sn) MAKELANGID(LANG_##pn, SUBLANG_##sn)
00183 typedef struct {
00184   LANGID id;
00185   const char* code;
00186 } IDToCode;
00187 static const IDToCode both_to_code[] = {
00188   {ML(ENGLISH,US),           "en_US.ISO_8859-1"},
00189   {ML(ENGLISH,CAN),          "en_CA"}, /* english / canadian */
00190   {ML(ENGLISH,UK),           "en_GB"},
00191   {ML(ENGLISH,EIRE),         "en_IE"},
00192   {ML(ENGLISH,AUS),          "en_AU"},
00193   {MLN(GERMAN),              "de_DE"},
00194   {MLN(SPANISH),             "es_ES"},
00195   {ML(SPANISH,MEXICAN),      "es_MX"},
00196   {MLN(FRENCH),              "fr_FR"},
00197   {ML(FRENCH,CANADIAN),      "fr_CA"},
00198   {ML(FRENCH,BELGIAN),       "fr_BE"}, /* ? */
00199   {ML(DUTCH,BELGIAN),        "nl_BE"}, /* ? */
00200   {ML(PORTUGUESE,BRAZILIAN), "pt_BR"},
00201   {MLN(PORTUGUESE),          "pt_PT"},
00202   {MLN(SWEDISH),             "sv_SE"},
00203   {ML(CHINESE,HONGKONG),     "zh_HK"},
00204   /* these are machine-generated and not yet verified */
00205   {RML(AFRIKAANS,DEFAULT), "af_ZA"},
00206   {RML(ALBANIAN,DEFAULT), "sq_AL"},
00207   {RML(ARABIC,ARABIC_ALGERIA), "ar_DZ"},
00208   {RML(ARABIC,ARABIC_BAHRAIN), "ar_BH"},
00209   {RML(ARABIC,ARABIC_EGYPT), "ar_EG"},
00210   {RML(ARABIC,ARABIC_IRAQ), "ar_IQ"},
00211   {RML(ARABIC,ARABIC_JORDAN), "ar_JO"},
00212   {RML(ARABIC,ARABIC_KUWAIT), "ar_KW"},
00213   {RML(ARABIC,ARABIC_LEBANON), "ar_LB"},
00214   {RML(ARABIC,ARABIC_LIBYA), "ar_LY"},
00215   {RML(ARABIC,ARABIC_MOROCCO), "ar_MA"},
00216   {RML(ARABIC,ARABIC_OMAN), "ar_OM"},
00217   {RML(ARABIC,ARABIC_QATAR), "ar_QA"},
00218   {RML(ARABIC,ARABIC_SAUDI_ARABIA), "ar_SA"},
00219   {RML(ARABIC,ARABIC_SYRIA), "ar_SY"},
00220   {RML(ARABIC,ARABIC_TUNISIA), "ar_TN"},
00221   {RML(ARABIC,ARABIC_UAE), "ar_AE"},
00222   {RML(ARABIC,ARABIC_YEMEN), "ar_YE"},
00223   {RML(ARMENIAN,DEFAULT), "hy_AM"},
00224   {RML(AZERI,AZERI_CYRILLIC), "az_AZ"},
00225   {RML(AZERI,AZERI_LATIN), "az_AZ"},
00226   {RML(BASQUE,DEFAULT), "eu_ES"},
00227   {RML(BELARUSIAN,DEFAULT), "be_BY"},
00228 /*{RML(BRETON,DEFAULT), "br_FR"},*/
00229   {RML(BULGARIAN,DEFAULT), "bg_BG"},
00230   {RML(CATALAN,DEFAULT), "ca_ES"},
00231   {RML(CHINESE,CHINESE_HONGKONG), "zh_HK"},
00232   {RML(CHINESE,CHINESE_MACAU), "zh_MO"},
00233   {RML(CHINESE,CHINESE_SIMPLIFIED), "zh_CN"},
00234   {RML(CHINESE,CHINESE_SINGAPORE), "zh_SG"},
00235   {RML(CHINESE,CHINESE_TRADITIONAL), "zh_TW"},
00236 /*{RML(CORNISH,DEFAULT), "kw_GB"},*/
00237   {RML(CZECH,DEFAULT), "cs_CZ"},
00238   {RML(DANISH,DEFAULT), "da_DK"},
00239   {RML(DUTCH,DUTCH), "nl_NL"},
00240   {RML(DUTCH,DUTCH_BELGIAN), "nl_BE"},
00241 /*{RML(DUTCH,DUTCH_SURINAM), "nl_SR"},*/
00242   {RML(ENGLISH,ENGLISH_AUS), "en_AU"},
00243   {RML(ENGLISH,ENGLISH_BELIZE), "en_BZ"},
00244   {RML(ENGLISH,ENGLISH_CAN), "en_CA"},
00245   {RML(ENGLISH,ENGLISH_CARIBBEAN), "en_CB"},
00246   {RML(ENGLISH,ENGLISH_EIRE), "en_IE"},
00247   {RML(ENGLISH,ENGLISH_JAMAICA), "en_JM"},
00248   {RML(ENGLISH,ENGLISH_NZ), "en_NZ"},
00249   {RML(ENGLISH,ENGLISH_PHILIPPINES), "en_PH"},
00250   {RML(ENGLISH,ENGLISH_SOUTH_AFRICA), "en_ZA"},
00251   {RML(ENGLISH,ENGLISH_TRINIDAD), "en_TT"},
00252   {RML(ENGLISH,ENGLISH_UK), "en_GB"},
00253   {RML(ENGLISH,ENGLISH_US), "en_US"},
00254   {RML(ENGLISH,ENGLISH_ZIMBABWE), "en_ZW"},
00255 /*{RML(ESPERANTO,DEFAULT), "eo_"},*/
00256   {RML(ESTONIAN,DEFAULT), "et_EE"},
00257   {RML(FAEROESE,DEFAULT), "fo_FO"},
00258   {RML(FARSI,DEFAULT), "fa_IR"},
00259   {RML(FINNISH,DEFAULT), "fi_FI"},
00260   {RML(FRENCH,FRENCH), "fr_FR"},
00261   {RML(FRENCH,FRENCH_BELGIAN), "fr_BE"},
00262   {RML(FRENCH,FRENCH_CANADIAN), "fr_CA"},
00263   {RML(FRENCH,FRENCH_LUXEMBOURG), "fr_LU"},
00264   {RML(FRENCH,FRENCH_MONACO), "fr_MC"},
00265   {RML(FRENCH,FRENCH_SWISS), "fr_CH"},
00266 /*{RML(GAELIC,GAELIC), "ga_IE"},*/
00267 /*{RML(GAELIC,GAELIC_MANX), "gv_GB"},*/
00268 /*{RML(GAELIC,GAELIC_SCOTTISH), "gd_GB"},*/
00269 /*{RML(GALICIAN,DEFAULT), "gl_ES"},*/
00270   {RML(GEORGIAN,DEFAULT), "ka_GE"},
00271   {RML(GERMAN,GERMAN), "de_DE"},
00272   {RML(GERMAN,GERMAN_AUSTRIAN), "de_AT"},
00273   {RML(GERMAN,GERMAN_LIECHTENSTEIN), "de_LI"},
00274   {RML(GERMAN,GERMAN_LUXEMBOURG), "de_LU"},
00275   {RML(GERMAN,GERMAN_SWISS), "de_CH"},
00276   {RML(GREEK,DEFAULT), "el_GR"},
00277   {RML(GUJARATI,DEFAULT), "gu_IN"},
00278   {RML(HEBREW,DEFAULT), "he_IL"},
00279   {RML(HINDI,DEFAULT), "hi_IN"},
00280   {RML(HUNGARIAN,DEFAULT), "hu_HU"},
00281   {RML(ICELANDIC,DEFAULT), "is_IS"},
00282   {RML(INDONESIAN,DEFAULT), "id_ID"},
00283   {RML(ITALIAN,ITALIAN), "it_IT"},
00284   {RML(ITALIAN,ITALIAN_SWISS), "it_CH"},
00285   {RML(JAPANESE,DEFAULT), "ja_JP"},
00286   {RML(KANNADA,DEFAULT), "kn_IN"},
00287   {RML(KAZAK,DEFAULT), "kk_KZ"},
00288   {RML(KONKANI,DEFAULT), "kok_IN"},
00289   {RML(KOREAN,KOREAN), "ko_KR"},
00290 /*{RML(KYRGYZ,DEFAULT), "ky_KG"},*/
00291   {RML(LATVIAN,DEFAULT), "lv_LV"},
00292   {RML(LITHUANIAN,LITHUANIAN), "lt_LT"},
00293   {RML(MACEDONIAN,DEFAULT), "mk_MK"},
00294   {RML(MALAY,MALAY_BRUNEI_DARUSSALAM), "ms_BN"},
00295   {RML(MALAY,MALAY_MALAYSIA), "ms_MY"},
00296   {RML(MARATHI,DEFAULT), "mr_IN"},
00297 /*{RML(MONGOLIAN,DEFAULT), "mn_MN"},*/
00298   {RML(NORWEGIAN,NORWEGIAN_BOKMAL), "nb_NO"},
00299   {RML(NORWEGIAN,NORWEGIAN_NYNORSK), "nn_NO"},
00300   {RML(POLISH,DEFAULT), "pl_PL"},
00301   {RML(PORTUGUESE,PORTUGUESE), "pt_PT"},
00302   {RML(PORTUGUESE,PORTUGUESE_BRAZILIAN), "pt_BR"},
00303   {RML(PUNJABI,DEFAULT), "pa_IN"},
00304   {RML(ROMANIAN,DEFAULT), "ro_RO"},
00305   {RML(RUSSIAN,DEFAULT), "ru_RU"},
00306   {RML(SANSKRIT,DEFAULT), "sa_IN"},
00307   {RML(SERBIAN,DEFAULT), "hr_HR"},
00308   {RML(SERBIAN,SERBIAN_CYRILLIC), "sr_SP"},
00309   {RML(SERBIAN,SERBIAN_LATIN), "sr_SP"},
00310   {RML(SLOVAK,DEFAULT), "sk_SK"},
00311   {RML(SLOVENIAN,DEFAULT), "sl_SI"},
00312   {RML(SPANISH,SPANISH), "es_ES"},
00313   {RML(SPANISH,SPANISH_ARGENTINA), "es_AR"},
00314   {RML(SPANISH,SPANISH_BOLIVIA), "es_BO"},
00315   {RML(SPANISH,SPANISH_CHILE), "es_CL"},
00316   {RML(SPANISH,SPANISH_COLOMBIA), "es_CO"},
00317   {RML(SPANISH,SPANISH_COSTA_RICA), "es_CR"},
00318   {RML(SPANISH,SPANISH_DOMINICAN_REPUBLIC), "es_DO"},
00319   {RML(SPANISH,SPANISH_ECUADOR), "es_EC"},
00320   {RML(SPANISH,SPANISH_EL_SALVADOR), "es_SV"},
00321   {RML(SPANISH,SPANISH_GUATEMALA), "es_GT"},
00322   {RML(SPANISH,SPANISH_HONDURAS), "es_HN"},
00323   {RML(SPANISH,SPANISH_MEXICAN), "es_MX"},
00324   {RML(SPANISH,SPANISH_MODERN), "es_ES"},
00325   {RML(SPANISH,SPANISH_NICARAGUA), "es_NI"},
00326   {RML(SPANISH,SPANISH_PANAMA), "es_PA"},
00327   {RML(SPANISH,SPANISH_PARAGUAY), "es_PY"},
00328   {RML(SPANISH,SPANISH_PERU), "es_PE"},
00329   {RML(SPANISH,SPANISH_PUERTO_RICO), "es_PR"},
00330   {RML(SPANISH,SPANISH_URUGUAY), "es_UY"},
00331   {RML(SPANISH,SPANISH_VENEZUELA), "es_VE"},
00332   {RML(SWAHILI,DEFAULT), "sw_KE"},
00333   {RML(SWEDISH,SWEDISH), "sv_SE"},
00334   {RML(SWEDISH,SWEDISH_FINLAND), "sv_FI"},
00335 /*{RML(SYRIAC,DEFAULT), "syr_SY"},*/
00336   {RML(TAMIL,DEFAULT), "ta_IN"},
00337   {RML(TATAR,DEFAULT), "tt_TA"},
00338   {RML(TELUGU,DEFAULT), "te_IN"},
00339   {RML(THAI,DEFAULT), "th_TH"},
00340   {RML(TURKISH,DEFAULT), "tr_TR"},
00341   {RML(UKRAINIAN,DEFAULT), "uk_UA"},
00342   {RML(URDU,URDU_PAKISTAN), "ur_PK"},
00343   {RML(UZBEK,UZBEK_CYRILLIC), "uz_UZ"},
00344   {RML(UZBEK,UZBEK_LATIN), "uz_UZ"},
00345   {RML(VIETNAMESE,DEFAULT), "vi_VN"},
00346 /*{RML(WALON,DEFAULT), "wa_BE"},*/
00347 /*{RML(WELSH,DEFAULT), "cy_GB"},*/
00348 };
00349 static const IDToCode primary_to_code[] = {
00350   {LANG_AFRIKAANS,  "af"},
00351   {LANG_ARABIC,     "ar"},
00352   {LANG_AZERI,      "az"},
00353   {LANG_BULGARIAN,  "bg"},
00354 /*{LANG_BRETON,     "br"},*/
00355   {LANG_BELARUSIAN, "by"},
00356   {LANG_CATALAN,    "ca"},
00357   {LANG_CZECH,      "cs"},
00358 /*{LANG_WELSH,      "cy"},*/
00359   {LANG_DANISH,     "da"},
00360   {LANG_GERMAN,     "de"},
00361   {LANG_GREEK,      "el"},
00362   {LANG_ENGLISH,    "en"},
00363 /*{LANG_ESPERANTO,  "eo"},*/
00364   {LANG_SPANISH,    "es"},
00365   {LANG_ESTONIAN,   "et"},
00366   {LANG_BASQUE,     "eu"},
00367   {LANG_FARSI,      "fa"},
00368   {LANG_FINNISH,    "fi"},
00369   {LANG_FAEROESE,   "fo"},
00370   {LANG_FRENCH,     "fr"},
00371 /*{LANG_GAELIC,     "ga"},*/
00372 /*{LANG_GALICIAN,   "gl"},*/
00373   {LANG_GUJARATI,   "gu"},
00374   {LANG_HEBREW,     "he"},
00375   {LANG_HINDI,      "hi"},
00376   {LANG_SERBIAN,    "hr"},
00377   {LANG_HUNGARIAN,  "hu"},
00378   {LANG_ARMENIAN,   "hy"},
00379   {LANG_INDONESIAN, "id"},
00380   {LANG_ITALIAN,    "it"},
00381   {LANG_JAPANESE,   "ja"},
00382   {LANG_GEORGIAN,   "ka"},
00383   {LANG_KAZAK,      "kk"},
00384   {LANG_KANNADA,    "kn"},
00385   {LANG_KOREAN,     "ko"},
00386 /*{LANG_KYRGYZ,     "ky"},*/
00387   {LANG_LITHUANIAN, "lt"},
00388   {LANG_LATVIAN,    "lv"},
00389   {LANG_MACEDONIAN, "mk"},
00390 /*{LANG_MONGOLIAN,  "mn"},*/
00391   {LANG_MARATHI,    "mr"},
00392   {LANG_MALAY,      "ms"},
00393   {LANG_NORWEGIAN,  "nb"},
00394   {LANG_DUTCH,      "nl"},
00395   {LANG_NORWEGIAN,  "nn"},
00396   {LANG_NORWEGIAN,  "no"},/* unofficial? */
00397   {LANG_PUNJABI,    "pa"},
00398   {LANG_POLISH,     "pl"},
00399   {LANG_PORTUGUESE, "pt"},
00400   {LANG_ROMANIAN,   "ro"},
00401   {LANG_RUSSIAN,    "ru"},
00402   {LANG_SLOVAK,     "sk"},
00403   {LANG_SLOVENIAN,  "sl"},
00404   {LANG_ALBANIAN,   "sq"},
00405   {LANG_SERBIAN,    "sr"},
00406   {LANG_SWEDISH,    "sv"},
00407   {LANG_SWAHILI,    "sw"},
00408   {LANG_TAMIL,      "ta"},
00409   {LANG_THAI,       "th"},
00410   {LANG_TURKISH,    "tr"},
00411   {LANG_TATAR,      "tt"},
00412   {LANG_UKRAINIAN,  "uk"},
00413   {LANG_URDU,       "ur"},
00414   {LANG_UZBEK,      "uz"},
00415   {LANG_VIETNAMESE, "vi"},
00416 /*{LANG_WALON,      "wa"},*/
00417   {LANG_CHINESE,    "zh"},
00418 };
00419 static int num_primary_to_code =
00420   sizeof(primary_to_code) / sizeof(*primary_to_code);
00421 static int num_both_to_code =
00422   sizeof(both_to_code) / sizeof(*both_to_code);
00423 
00424 static const int
00425 lcid_to_fl(LCID lcid,
00426            FL_Locale *rtn) {
00427   LANGID langid       = LANGIDFROMLCID(lcid);
00428   LANGID primary_lang = PRIMARYLANGID(langid);
00429 #if 0
00430   LANGID sub_lang     = SUBLANGID(langid);
00431 #endif
00432   int i;
00433   /* try to find an exact primary/sublanguage combo that we know about */
00434   for (i=0; i<num_both_to_code; ++i) {
00435     if (both_to_code[i].id == langid) {
00436       accumulate_locstring(both_to_code[i].code, rtn);
00437       return 1;
00438     }
00439   }
00440   /* fallback to just checking the primary language id */
00441   for (i=0; i<num_primary_to_code; ++i) {
00442     if (primary_to_code[i].id == primary_lang) {
00443       accumulate_locstring(primary_to_code[i].code, rtn);
00444       return 1;
00445     }
00446   }
00447   return 0;
00448 }
00449 #endif
00450 
00451 
00452 FL_Success
00453 FL_FindLocale(FL_Locale **locale, FL_Domain /*domain*/) {
00454   FL_Success success = FL_FAILED;
00455   FL_Locale *rtn = (FL_Locale*) malloc(sizeof(FL_Locale));
00456   rtn->lang = NULL;
00457   rtn->country = NULL;
00458   rtn->variant = NULL;
00459 
00460 #ifdef WIN32
00461   /* win32 >= mswindows95 */
00462   {
00463     LCID lcid = GetThreadLocale();
00464     if (lcid_to_fl(lcid, rtn)) {
00465       success = FL_CONFIDENT;
00466     }
00467     if (success == FL_FAILED) {
00468       /* assume US English on mswindows systems unless we know otherwise */
00469       if (accumulate_locstring("en_US.ISO_8859-1", rtn)) {
00470         success = FL_DEFAULT_GUESS;
00471       }
00472     }
00473   }
00474 #else
00475   /* assume unixoid */
00476   {
00477 #ifdef MACOSX
00478     CFIndex sz;
00479     CFArrayRef languages;
00480     CFStringRef uxstylelangs;
00481     char *uxsl;
00482 
00483     /* get the languages from the user's presets */
00484     languages = (CFArrayRef)CFPreferencesCopyValue(CFSTR("AppleLanguages"),
00485       kCFPreferencesAnyApplication, kCFPreferencesCurrentUser,
00486       kCFPreferencesAnyHost);
00487 
00488     /* join the returned string array into a string separated by colons */
00489     uxstylelangs = CFStringCreateByCombiningStrings(kCFAllocatorDefault,
00490       languages, CFSTR(":"));
00491 
00492     /* convert this string into a C string */
00493     sz = CFStringGetLength(uxstylelangs) + 1;
00494     uxsl = (char*)malloc(sz);
00495     CFStringGetCString(uxstylelangs, uxsl, sz, kCFStringEncodingISOLatin1);
00496 
00497     /* add it to the list */
00498     if (accumulate_locstring(uxsl, rtn)) {
00499       success = FL_CONFIDENT;
00500     }
00501     /* continue the UNIX method */
00502 #endif
00503     /* examples: */
00504     /* sv_SE.ISO_8859-1 */
00505     /* fr_FR.ISO8859-1 */
00506     /* no_NO_NB */
00507     /* no_NO_NY */
00508     /* no_NO */
00509     /* de_DE */
00510     /* try the various vars in decreasing order of authority */
00511     if (accumulate_env("LC_ALL", rtn) ||
00512         accumulate_env("LC_MESSAGES", rtn) ||
00513         accumulate_env("LANG", rtn) ||
00514         accumulate_env("LANGUAGE", rtn)) {
00515       success = FL_CONFIDENT;
00516     }
00517     if (success == FL_FAILED) {
00518       /* assume US English on unixoid systems unless we know otherwise */
00519       if (accumulate_locstring("en_US.ISO_8859-1", rtn)) {
00520         success = FL_DEFAULT_GUESS;
00521       }
00522     }
00523   }
00524 #endif
00525 
00526   if (success != FL_FAILED) {
00527     canonize_fl(rtn);
00528   }
00529 
00530   *locale = rtn;
00531   return success;
00532 }
00533 
00534 
00535 void
00536 FL_FreeLocale(FL_Locale **locale) {
00537   if (locale) {
00538     FL_Locale *l = *locale;
00539     if (l) {
00540       if (l->lang) {
00541         free((void*)l->lang);
00542       }
00543       if (l->country) {
00544         free((void*)l->country);
00545       }
00546       if (l->variant) {
00547         free((void*)l->variant);
00548       }
00549       free(l);
00550       *locale = NULL;
00551     }
00552   }
00553 }

Generated on Mon Jun 9 03:38:23 2014 for SuperTux by  doxygen 1.5.1