X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Ftinygettext%2Ftinygettext.cpp;h=ffaaf710da3c97c1271039980d99abb2e8ccfb43;hb=5ee161985d711c1cbe18b51b6db0076e34ddf613;hp=a9bb9641fe0c39d7a55093cb3efe4214464e3b31;hpb=a113d3bd1feddd510e3b2852b0d42522735eee40;p=supertux.git diff --git a/src/tinygettext/tinygettext.cpp b/src/tinygettext/tinygettext.cpp index a9bb9641f..ffaaf710d 100644 --- a/src/tinygettext/tinygettext.cpp +++ b/src/tinygettext/tinygettext.cpp @@ -20,16 +20,17 @@ #include #include -#include #include #include +#include #include #include +#include "SDL.h" + #include "tinygettext.hpp" #include "log.hpp" #include "physfs/physfs_stream.hpp" -#include "log.hpp" #include "findlocale.hpp" //#define TRANSLATION_DEBUG @@ -44,7 +45,20 @@ std::string convert(const std::string& text, if (from_charset == to_charset) return text; - iconv_t cd = iconv_open(to_charset.c_str(), from_charset.c_str()); + 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; +#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 @@ -58,7 +72,7 @@ std::string convert(const std::string& text, size_t out_len_temp = out_len; // iconv is counting down the bytes it has // written from this... - size_t retval = iconv(cd, &in, &in_len, &out, &out_len_temp); + 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) { @@ -66,12 +80,13 @@ std::string convert(const std::string& text, log_warning << "Error: conversion from " << from_charset << " to " << to_charset << " went wrong: " << retval << std::endl; return ""; } - iconv_close(cd); + 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) @@ -190,8 +205,13 @@ DictionaryManager::DictionaryManager() // use findlocale to setup language FL_Locale *locale; FL_FindLocale( &locale, FL_MESSAGES ); - if( locale->lang) - set_language( locale->lang ); + 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 ); } @@ -203,7 +223,7 @@ DictionaryManager::parseLocaleAliases() char c = ' '; while(in.good() && !in.eof()) { - while(isspace(c) && !in.eof()) + while(isspace(static_cast(c)) && !in.eof()) in.get(c); if(c == '#') { // skip comments @@ -213,14 +233,14 @@ DictionaryManager::parseLocaleAliases() } std::string alias; - while(!isspace(c) && !in.eof()) { + while(!isspace(static_cast(c)) && !in.eof()) { alias += c; in.get(c); } - while(isspace(c) && !in.eof()) + while(isspace(static_cast(c)) && !in.eof()) in.get(c); std::string language; - while(!isspace(c) && !in.eof()) { + while(!isspace(static_cast(c)) && !in.eof()) { language += c; in.get(c); } @@ -234,7 +254,13 @@ DictionaryManager::parseLocaleAliases() 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()) { @@ -260,7 +286,25 @@ DictionaryManager::get_dictionary(const std::string& spec) { for(const char* const* filename = files; *filename != 0; filename++) { - if(std::string(*filename) == lang + ".po") { + + // 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); @@ -270,6 +314,7 @@ DictionaryManager::get_dictionary(const std::string& spec) log_warning << e.what() << "" << std::endl; } } + } PHYSFS_freeList(files); } @@ -308,7 +353,9 @@ DictionaryManager::get_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)); } @@ -342,11 +389,20 @@ DictionaryManager::get_language_from_spec(const std::string& spec) lang = i->second; } - std::string::size_type s = lang.find_first_of("_."); - if(s == std::string::npos) - return lang; + 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; - return std::string(lang, 0, s); } void @@ -652,6 +708,9 @@ public: { state = SKIP_COMMENT; } + else if (c == '\n') + { + } else { // Read a new token @@ -659,7 +718,7 @@ public: do { // Read keyword token.keyword += c; - } while((c = getchar(in)) != EOF && !isspace(c)); + } while((c = getchar(in)) != EOF && !isspace(static_cast(c))); in.unget(); state = READ_CONTENT; @@ -673,12 +732,13 @@ public: // Found start of content state = READ_CONTENT_IN_STRING; break; - } else if (isspace(c)) { + } else if (isspace(static_cast(c))) { // skip } else { // Read something that may be a keyword in.unget(); state = READ_KEYWORD; add_token(token); + token = Token(); break; } } @@ -693,6 +753,7 @@ public: else if (c == 't') token.content += '\t'; else if (c == 'r') token.content += '\r'; else if (c == '"') token.content += '"'; + else if (c == '\\') token.content += '\\'; else { log_warning << "Unhandled escape character: " << char(c) << std::endl; @@ -716,6 +777,7 @@ public: } } add_token(token); + token = Token(); } };