+ codes.push_back("en");
+ allCodes = codes;
+ for (std::vector<string>::const_iterator b = builtin.begin();
+ b != builtin.end(); ++b)
+ if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end())
+ allCodes.push_back(*b);
+ if (All == true)
+ return allCodes;
+ else
+ return codes;
+ }
+
+ // get the environment language codes: LC_MESSAGES (and later LANGUAGE)
+ // we extract both, a long and a short code and then we will
+ // check if we actually need both (rare) or if the short is enough
+ string const envMsg = string(Locale == 0 ? std::setlocale(LC_MESSAGES, NULL) : *Locale);
+ size_t const lenShort = (envMsg.find('_') != string::npos) ? envMsg.find('_') : 2;
+ size_t const lenLong = (envMsg.find_first_of(".@") != string::npos) ? envMsg.find_first_of(".@") : (lenShort + 3);
+
+ string const envLong = envMsg.substr(0,lenLong);
+ string const envShort = envLong.substr(0,lenShort);
+
+ // It is very likely we will need the environment codes later,
+ // so let us generate them now from LC_MESSAGES and LANGUAGE
+ std::vector<string> environment;
+ if (envShort != "C") {
+ // take care of LC_MESSAGES
+ if (envLong != envShort)
+ environment.push_back(envLong);
+ environment.push_back(envShort);
+ // take care of LANGUAGE
+ const char *language_env = getenv("LANGUAGE") == 0 ? "" : getenv("LANGUAGE");
+ string envLang = Locale == 0 ? language_env : *(Locale+1);
+ if (envLang.empty() == false) {
+ std::vector<string> env = VectorizeString(envLang,':');
+ short addedLangs = 0; // add a maximum of 3 fallbacks from the environment
+ for (std::vector<string>::const_iterator e = env.begin();
+ e != env.end() && addedLangs < 3; ++e) {
+ if (unlikely(e->empty() == true) || *e == "en")
+ continue;
+ if (*e == envLong || *e == envShort)
+ continue;
+ if (std::find(environment.begin(), environment.end(), *e) != environment.end())
+ continue;
+ ++addedLangs;
+ environment.push_back(*e);
+ }
+ }
+ } else {
+ environment.push_back("en");