/[winpt]/trunk/Src/wptNLS.cpp
ViewVC logotype

Diff of /trunk/Src/wptNLS.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 366 by twoaday, Tue Dec 6 12:32:08 2011 UTC revision 372 by twoaday, Fri Dec 9 10:59:16 2011 UTC
# Line 64  struct string_desc { Line 64  struct string_desc {
64  };  };
65    
66  struct loaded_domain_s {  struct loaded_domain_s {
67        /* Full file name to the MO file */
68      char *file_name;      char *file_name;
69        /* Last modification date of the MO file */
70      time_t modify_time;      time_t modify_time;
71        
72      char *data;      char *data;
73      int must_swap;      int must_swap;
74      DWORD nstrings;      DWORD nstrings;
# Line 90  struct lang_table_s lang_list[] = { Line 93  struct lang_table_s lang_list[] = {
93  static gettext_domain_t the_domain;  static gettext_domain_t the_domain;
94    
95    
96    /* Return TRUE if the native user language is not English
97       and thus, gettext support is available */
98    static bool
99    gettext_is_required (void)
100    {
101        LANGID lang = GetUserDefaultLangID ();
102        if (PRIMARYLANGID (lang) == LANG_ENGLISH)
103            return false;
104        return true;
105    }
106    
107    
108  static DWORD  static DWORD
109  do_swap_u32 (DWORD i)  do_swap_u32 (DWORD i)
110  {  {
# Line 120  hash_string (const char *str_param) Line 135  hash_string (const char *str_param)
135  }  }
136    
137    
 /* Missing W32 functions. */  
 static char*  
 w32_stpcpy (char *a, const char *b)  
 {  
     while (*b)  
         *a++ = *b++;  
     *a = 0;  
     return (char*)a;  
 }  
   
   
138  static gettext_domain_t  static gettext_domain_t
139  load_domain (const char *filename)  load_domain (const char *filename)
140  {  {
# Line 163  load_domain (const char *filename) Line 167  load_domain (const char *filename)
167          size_t nb = fread (read_ptr, 1, to_read, fp);          size_t nb = fread (read_ptr, 1, to_read, fp);
168          if (nb < to_read) {          if (nb < to_read) {
169              fclose (fp);              fclose (fp);
170              free(data);              free (data);        
171              return NULL; /* read error */                            return NULL; /* read error */              
172          }          }
173          read_ptr += nb;          read_ptr += nb;
# Line 171  load_domain (const char *filename) Line 175  load_domain (const char *filename)
175      } while (to_read > 0);      } while (to_read > 0);
176      fclose (fp);      fclose (fp);
177    
178      /* Using the magic number we can test whether it really is a message      /* Using the magic number we can test whether it really is a message catalog file.  */
      * catalog file.  */  
179      if (data->magic != MAGIC && data->magic != MAGIC_SWAPPED) {      if (data->magic != MAGIC && data->magic != MAGIC_SWAPPED) {
180          /* The magic number is wrong: not a message catalog file.  */          /* The magic number is wrong: not a message catalog file.  */
181          free (data);          free (data);
# Line 205  load_domain (const char *filename) Line 208  load_domain (const char *filename)
208      }      }
209    
210      /* allocate an array to keep track of code page mappings */      /* allocate an array to keep track of code page mappings */
211      domain->mapped = (char *)calloc( 1, domain->nstrings );      domain->mapped = (char *)calloc (1, domain->nstrings);
212      if (!domain->mapped)      if (!domain->mapped)
213          BUG (0);          BUG (0);
214            
# Line 215  load_domain (const char *filename) Line 218  load_domain (const char *filename)
218  }  }
219    
220    
 /* Returns a string representation of the users system language  
  * if we support it, 'en' otherwise.  
  */  
 static const char*  
 get_user_langid (void)  
 {  
     int lang = GetUserDefaultLangID() & 511;  
       
     for (int i=0; lang_list[i].id != NULL; i++) {  
         if (lang == lang_list[i].langid)  
             return lang_list[i].id;  
     }  
     return "en";  
 }  
   
   
221  /* To avoid problems that the current directory is not the  /* To avoid problems that the current directory is not the
222   * same folder the WinPT.exe is located in, we extract the   * same folder the WinPT.exe is located in, we extract the
223   * module directory.   * module directory.
# Line 238  get_user_langid (void) Line 225  get_user_langid (void)
225  char*  char*
226  get_module_dir (char *buf, DWORD buflen)  get_module_dir (char *buf, DWORD buflen)
227  {  {
     int pos;  
       
228      if (buflen < 1 || !GetModuleFileName (glob_hinst, buf, buflen-1))      if (buflen < 1 || !GetModuleFileName (glob_hinst, buf, buflen-1))
229          return NULL;          return NULL;
230    
231      pos = strlen (buf);      size_t pos = strlen (buf);
232      while (pos > 0 && buf[--pos] != '\\')      while (pos > 0 && buf[--pos] != '\\')
233          ;          ;
234      buf[pos+1] = '\0';      buf[pos + 1] = '\0';
235      return buf;      return buf;
236  }  }
237    
238    
239  /* Returns a localisation name for a specific resource (file).  /* Returns a localisation name for a specific resource (file).
240   * For instance, lang=DE and file=winpt.chm will become   * For instance, lang=DE and file=winpt.chm will become winpt.DE.chm
  * winpt.DE.chm  
241   */   */
242  char*  char*
243  get_locale_name (const char *file)  get_locale_name (const char *file)
244  {  {
245      const char *lang = get_user_langid();      const char *lang = gettext_get_langid ();
246      char *name, *ext;      char buf[MAX_PATH+1];
     char *p, buf[MAX_PATH+1];  
247            
248      p = strrchr (file, '.');      char *p = strrchr (file, '.');
249      if (p == NULL) {      if (p == NULL) {
250          p = new char[strlen(file)+strlen(lang)+2+1];          p = new char[strlen(file)+strlen(lang)+2+1];
251          sprintf (p, "%s.%s", file, lang);          sprintf (p, "%s.%s", file, lang);
252          return p;          return p;
253      }      }
254      name = substr (file, 0, p-file);      char *name = substr (file, 0, p - file);
255      ext = substr (file, p-file+1, strlen(file));      char *ext = substr (file, p - file + 1, strlen(file));
256      p = get_module_dir (buf, MAX_PATH);      p = get_module_dir (buf, MAX_PATH);
257      if (!p)      if (!p)
258          BUG (NULL);          BUG (NULL);
# Line 296  gettext_free_current_domain (void) Line 279  gettext_free_current_domain (void)
279  }  }
280    
281    
282    /* Replace and release the old domain and assign a new domain then */
283    static void
284    gettext_update_domain (gettext_domain_t new_dom)
285    {
286        gettext_free_current_domain ();
287        the_domain = new_dom;
288    }
289    
290    
291  char* get_reg_entry_mo (void);  char* get_reg_entry_mo (void);
292    
293  /* Fallback code which is used when no new NLS file  /* Fallback code which is used when no new NLS file were found.
294   * were found. Then we read the MODir registry key     Then we read the MODir registry key and check if a file named
295   * and check if a file named 'winpt.mo' exists in this     'winpt.mo' exists in this directory. */
  * directory.  
  */  
296  static gettext_domain_t  static gettext_domain_t
297  load_modir_domain (void)  load_modir_domain (void)
298  {  {        
     gettext_domain_t domain = NULL;  
       
299      char *modir = get_reg_entry_mo ();      char *modir = get_reg_entry_mo ();
300      if (!modir)      if (!modir)
301          return NULL;          return NULL;
# Line 320  load_modir_domain (void) Line 308  load_modir_domain (void)
308          s += "\\";          s += "\\";
309      s += "winpt.mo";      s += "winpt.mo";
310            
311        gettext_domain_t domain = NULL;
312      const char *fname = s.getBuffer();      const char *fname = s.getBuffer();
313      if (!file_exist_check (fname))      if (!file_exist_check (fname))
314          domain = load_domain (fname);          domain = load_domain (fname);
# Line 328  load_modir_domain (void) Line 317  load_modir_domain (void)
317  }  }
318    
319    
320  int  /* Try to load the user domain, either from
321       the WinPT.exe directory or from the registry */
322    void
323  gettext_set_user_domain (void)  gettext_set_user_domain (void)
324  {  {
325        if (!gettext_is_required ())
326            return;
327        
328      gettext_domain_t domain = NULL;      gettext_domain_t domain = NULL;
329      char *file = get_locale_name ("winpt.mo");      char *file = get_locale_name ("winpt.mo");
330      if (file && !file_exist_check (file))      if (file && !file_exist_check (file))
# Line 338  gettext_set_user_domain (void) Line 332  gettext_set_user_domain (void)
332      else      else
333          domain = load_modir_domain ();          domain = load_modir_domain ();
334      free_if_alloc (file);      free_if_alloc (file);
335      gettext_free_current_domain ();          gettext_update_domain (domain);
     the_domain = domain;  
     return 0;  
336  }  }
337    
338    
# Line 359  gettext_domain_needs_refresh (void) Line 351  gettext_domain_needs_refresh (void)
351      return 0;      return 0;
352  }  }
353    
 /* Set the file used for translations. Pass a NULL to disable translation.  
    A new filename may be set at anytime. */  
 int  
 gettext_set_file (const char *filename, const char *nls_dir)  
 {  
     gettext_domain_t domain = NULL;  
   
     if (filename && *filename) {  
         if (filename[1] == ':' && filename[2] == '\\')  
             domain = load_domain (filename); /* absolute path - use it as is */  
         else { /* relative path - append ".mo" and get dir from the environment */  
             char *buf, *dir;  
                   
             dir = strdup (nls_dir);  
             if (!dir)  
                 BUG (0);  
             buf= (char *)malloc (strlen (dir) + strlen (filename)+1+3+1);  
             strcpy (w32_stpcpy (w32_stpcpy (  
                     w32_stpcpy (buf, dir), "\\"), filename),".mo");  
             domain = load_domain(buf);  
             free (buf);  
             free (dir);  
         }  
         if (!domain)  
             return -1;  
     }  
   
     gettext_free_current_domain ();  
     the_domain = domain;  
     return 0;  
 }  
   
   
354  static const char*  static const char*
355  get_string (gettext_domain_t domain, DWORD idx)  get_string (gettext_domain_t domain, DWORD idx)
356  {  {
# Line 399  get_string (gettext_domain_t domain, DWO Line 358  get_string (gettext_domain_t domain, DWO
358                                      domain->trans_tab[idx].offset);                                      domain->trans_tab[idx].offset);
359      if (!domain->mapped[idx])      if (!domain->mapped[idx])
360          domain->mapped[idx] = 1;          domain->mapped[idx] = 1;
361        /* FIXME: all text is in UTF-8 and need to be converted to
362           the locale charset. But the caller does not free the data and
363           thus we will get a leak */
364      return (const char *)p;      return (const char *)p;
365  }  }
366    
# Line 471  not_found: Line 433  not_found:
433  }  }
434    
435    
436    
437  /* Map the user specific language ID to a gettext conform language string.  /* Map the user specific language ID to a gettext conform language string.
438       English "en" is defined as the fallback.
439     Example: LANG_GERMAN -> "de" */     Example: LANG_GERMAN -> "de" */
440  const char*  const char*
441  gettext_get_langid (void)  gettext_get_langid (void)
442  {  {
443      LANGID lang = GetUserDefaultLangID ();      LANGID lang = GetUserDefaultLangID ();
444      if (PRIMARYLANGID (lang) == LANG_ENGLISH)      
         return NULL;  
   
445      for (int i=0; lang_list[i].id; i++) {      for (int i=0; lang_list[i].id; i++) {
446          if (PRIMARYLANGID (lang) == lang_list[i].langid)          if (PRIMARYLANGID (lang) == lang_list[i].langid)
447              return lang_list[i].id;              return lang_list[i].id;
448      }      }
449      return NULL;      
450        return "en";
451  }  }
452    
453    

Legend:
Removed from v.366  
changed lines
  Added in v.372

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26