i18n: (#858) Handling localization for libraries within static executables
[sdk] / ecere / src / sys / i18n.ec
index 8ce51dd..6bad435 100644 (file)
@@ -21,7 +21,7 @@ static Map<String, Map<String, String>> moduleMaps { };
                          | (((unsigned int)(dword) & 0x00ff0000) >>  8) \
                          | (((unsigned int)(dword) & 0xff000000) >> 24))
 
-public dllexport void LoadTranslatedStrings(Module module, char * name)
+public dllexport void LoadTranslatedStrings(String moduleName, char * name)
 {
 #ifndef ECERE_NOFILE
    File f;
@@ -32,6 +32,9 @@ public dllexport void LoadTranslatedStrings(Module module, char * name)
    char lang[256];
    char lcMessages[256];
    char * locale = null;
+   char genericLocale[256];
+
+   genericLocale[0] = 0;
 
    if(GetEnvironment("LANGUAGE", language, sizeof(language)))
       locale = language;
@@ -51,14 +54,30 @@ public dllexport void LoadTranslatedStrings(Module module, char * name)
       if(dot) *dot = 0;
       locale = language;
    }
+   if(locale)
+   {
+      char * under;
+      strcpy(genericLocale, locale);
+      under = strchr(genericLocale, '_');
+      if(under)
+         *under = 0;
+   }
 
-   if(module.name)
-      sprintf(fileName, "<:%s>locale/%s/LC_MESSAGES/%s.mo", module.name, locale, name);
+   if(moduleName)
+      sprintf(fileName, "<:%s>locale/%s.mo", moduleName, locale);
    else
-      sprintf(fileName, ":locale/%s/LC_MESSAGES/%s.mo", locale, name);
+      sprintf(fileName, ":locale/%s.mo", locale);
    f = FileOpen(fileName, read);
    if(!f)
    {
+      if(moduleName)
+         sprintf(fileName, "<:%s>locale/%s/LC_MESSAGES/%s.mo", moduleName, locale, name);
+      else
+         sprintf(fileName, ":locale/%s/LC_MESSAGES/%s.mo", locale, name);
+      f = FileOpen(fileName, read);
+   }
+   if(!f)
+   {
       sprintf(fileName, "locale/%s/LC_MESSAGES/%s.mo", locale, name);
       f = FileOpen(fileName, read);
    }
@@ -67,6 +86,35 @@ public dllexport void LoadTranslatedStrings(Module module, char * name)
       sprintf(fileName, "/usr/share/locale/%s/LC_MESSAGES/%s.mo", locale, name);
       f = FileOpen(fileName, read);
    }
+
+   if(!f && locale && strcmpi(locale, genericLocale))
+   {
+      // Attempt with generic language
+      if(moduleName)
+         sprintf(fileName, "<:%s>locale/%s.mo", moduleName, genericLocale);
+      else
+         sprintf(fileName, ":locale/%s.mo", name, genericLocale);
+      f = FileOpen(fileName, read);
+      if(!f)
+      {
+         if(moduleName)
+            sprintf(fileName, "<:%s>locale/%s/LC_MESSAGES/%s.mo", moduleName, genericLocale, name);
+         else
+            sprintf(fileName, ":locale/%s/LC_MESSAGES/%s.mo", genericLocale, name);
+         f = FileOpen(fileName, read);
+      }
+      if(!f)
+      {
+         sprintf(fileName, "locale/%s/LC_MESSAGES/%s.mo", genericLocale, name);
+         f = FileOpen(fileName, read);
+      }
+      if(!f)
+      {
+         sprintf(fileName, "/usr/share/locale/%s/LC_MESSAGES/%s.mo", genericLocale, name);
+         f = FileOpen(fileName, read);
+      }
+   }
+
    if(f)
    {
       uint magic = 0;
@@ -91,11 +139,11 @@ public dllexport void LoadTranslatedStrings(Module module, char * name)
             moduleMaps = { };
          {
             MapIterator<String, Map<String, String>> it { map = moduleMaps };
-            if(it.Index(module.name, false))
+            if(it.Index(name, false))
                delete it.data;
             // TOFIX: delete moduleMaps[module];
          }
-         moduleMaps[module.name] = textMap = { };
+         moduleMaps[name] = textMap = { };
          for(c = 0; c < numStrings; c++)
          {
             uint len = 0, offset = 0;
@@ -141,19 +189,19 @@ public dllexport void LoadTranslatedStrings(Module module, char * name)
 #endif
 }
 
-public dllexport void UnloadTranslatedStrings(Module module)
+public dllexport void UnloadTranslatedStrings(String name)
 {
    MapIterator<String, Map<String, String>> it { map = moduleMaps };
-   if(it.Index(module.name, false))
+   if(it.Index(name, false))
    {
       it.data.Free();
       moduleMaps.Delete(it.pointer);
    }
 }
 
-public dllexport char * GetTranslatedString(Module module, char * string, char * stringAndContext)
+public dllexport char * GetTranslatedString(String name, char * string, char * stringAndContext)
 {
-   Map<String, String> textMap = moduleMaps ? moduleMaps[module.name] : null;
+   Map<String, String> textMap = moduleMaps ? moduleMaps[name] : null;
    char * result = textMap ? textMap[stringAndContext ? stringAndContext : string] : string;
    return (result && result[0]) ? result : string;
 }