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

Diff of /trunk/Src/wptNLS.c

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

revision 76 by twoaday, Thu Nov 10 14:07:06 2005 UTC revision 205 by twoaday, Thu Apr 27 12:46:03 2006 UTC
# Line 1  Line 1 
1  /* wptNLS.cpp - W32 Native Language Support  /* wptNLS.cpp - W32 Native Language Support
2   *      Copyright (C) 2001, 2002, 2003 Timo Schulz   *      Copyright (C) 2001, 2002, 2003, 2006 Timo Schulz
3   *      Copyright (C) 1995-1999 Free Software Foundation, Inc.   *      Copyright (C) 1995-1999 Free Software Foundation, Inc.
4   *   *
5   * This code based on the simple-gettext.c code from the GnuPG   * This code based on the simple-gettext.c code from the GnuPG
# Line 25  Line 25 
25  #endif  #endif
26    
27  #include <stdio.h>  #include <stdio.h>
 #include <stdio.h>  
28  #include <string.h>  #include <string.h>
29  #include <ctype.h>  #include <ctype.h>
30  #include <errno.h>  #include <errno.h>
# Line 33  Line 32 
32  #include <sys/stat.h>  #include <sys/stat.h>
33  #include <windows.h>  #include <windows.h>
34    
 #include "wptTypes.h"  
35  #include "wptNLS.h"  #include "wptNLS.h"
36    
 /* Missing W32 functions. */  
 static char *  
 w32_stpcpy (char *a,const char *b)  
 {  
     while (*b)  
         *a++ = *b++;  
     *a = 0;  
     return (char*)a;  
 }  
   
37    
38  /* The magic number of the GNU message catalog format.  */  /* The magic number of the GNU message catalog format.  */
39  #define MAGIC         0x950412de  #define MAGIC         0x950412de
# Line 54  w32_stpcpy (char *a,const char *b) Line 42  w32_stpcpy (char *a,const char *b)
42  /* Revision number of the currently used .mo (binary) file format.  */  /* Revision number of the currently used .mo (binary) file format.  */
43  #define MO_REVISION_NUMBER 0  #define MO_REVISION_NUMBER 0
44    
45    #define SWAPIT(flag, data) ((flag) ? do_swap_u32(data) : (data) )
46    
47    
48    /* We assume to have `unsigned long int' value with at least 32 bits.  */
49    #define HASHWORDBITS 32
50    
51  /* Header for binary .mo file format.  */  /* Header for binary .mo file format.  */
52  struct mo_file_header {  struct mo_file_header {
53    u32 magic; /* The magic number.       */        DWORD magic;            /* The magic number.        */
54    u32 revision; /* The revision number of the file format.  */      DWORD revision;         /* The revision number of the file format.  */
55    u32 nstrings; /* The number of strings pairs.  */        DWORD nstrings;         /* The number of strings pairs.  */
56    u32 orig_tab_offset; /* Offset of table with start offsets of original      DWORD orig_tab_offset;  /* Offset of table with start offsets of original
57                            strings.  */                                  strings.  */
58    u32 trans_tab_offset; /* Offset of table with start offsets of translation      DWORD trans_tab_offset;   /* Offset of table with start offsets of translation
59                             strings.  */                                 strings.  */
60    u32 hash_tab_size; /* Size of hashing table.  */        DWORD hash_tab_size;        /* Size of hashing table.  */
61    u32 hash_tab_offset; /* Offset of first hashing entry.  */      DWORD hash_tab_offset;    /* Offset of first hashing entry.  */
62  };  };
63    
64  struct string_desc {  struct string_desc {
65    u32 length; /* Length of addressed string.  */        DWORD length; /* Length of addressed string.  */  
66    u32 offset; /* Offset of string in file.      */      DWORD offset; /* Offset of string in file.  */
67  };  };
68    
69  struct loaded_domain {  struct loaded_domain {
70    char *data;    char *data;
71    int must_swap;    int must_swap;
72    u32 nstrings;    DWORD nstrings;
73    char *mapped;    char *mapped;
74    struct string_desc *orig_tab;    struct string_desc *orig_tab;
75    struct string_desc *trans_tab;    struct string_desc *trans_tab;
76    u32 hash_size;    DWORD hash_size;
77    u32 *hash_tab;    DWORD *hash_tab;
78  };  };
79    
80    /* List of all available languages. */
81    struct lang_table_s lang_list[] = {
82        {"en", "English",   LANG_ENGLISH},
83        {"de", "German",    LANG_GERMAN},
84        {"fr", "French",    LANG_FRENCH},
85        {"jp", "Japanese",  LANG_JAPANESE},
86        {NULL, 0}
87    };
88    
89    /* The current domain. */
90  static struct loaded_domain *the_domain;  static struct loaded_domain *the_domain;
91    
92  static u32  
93  do_swap_u32( u32 i )  static DWORD
94    do_swap_u32 (DWORD i)
95  {  {
96    return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);      return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
97  }  }
98    
 #define SWAPIT(flag, data) ((flag) ? do_swap_u32(data) : (data) )  
   
   
 /* We assume to have `unsigned long int' value with at least 32 bits.  */  
 #define HASHWORDBITS 32  
99    
100  /* The so called `hashpjw' function by P.J. Weinberger  /* The so called `hashpjw' function by P.J. Weinberger
101     [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,     [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
102     1986, 1987 Bell Telephone Laboratories, Inc.]  */     1986, 1987 Bell Telephone Laboratories, Inc.]  */
103    
104  static u32  static DWORD
105  hash_string( const char *str_param )  hash_string (const char *str_param)
106  {  {
107      unsigned long int hval, g;      unsigned long int hval, g;
108      const char *str = str_param;      const char *str = str_param;
# Line 119  hash_string( const char *str_param ) Line 118  hash_string( const char *str_param )
118          }          }
119      }      }
120      return hval;      return hval;
121  } /* hash_string */  }
122    
123    /* Missing W32 functions. */
124    static char*
125    w32_stpcpy (char *a,const char *b)
126    {
127        while (*b)
128            *a++ = *b++;
129        *a = 0;
130        return (char*)a;
131    }
132    
133    
134    
135  static struct loaded_domain *  static struct loaded_domain *
# Line 138  load_domain( const char *filename ) Line 148  load_domain( const char *filename )
148         return NULL; /* can't open the file */         return NULL; /* can't open the file */
149      /* we must know about the size of the file */      /* we must know about the size of the file */
150      if( fstat( fileno(fp ), &st )      if( fstat( fileno(fp ), &st )
151          || (size = (size_t)st.st_size) != st.st_size          || (size = (size_t)st.st_size) != (size_t)st.st_size
152          || size < sizeof (struct mo_file_header) ) {          || size < sizeof (struct mo_file_header) ) {
153          fclose( fp );            fclose( fp );  
154          return NULL;          return NULL;
# Line 153  load_domain( const char *filename ) Line 163  load_domain( const char *filename )
163      to_read = size;      to_read = size;
164      read_ptr = (char *) data;      read_ptr = (char *) data;
165      do {      do {
166          long int nb = fread( read_ptr, 1, to_read, fp );          size_t nb = fread( read_ptr, 1, to_read, fp );
167          if( nb < to_read ) {          if( nb < to_read ) {
168              fclose (fp);              fclose (fp);
169              free(data);              free(data);
# Line 190  load_domain( const char *filename ) Line 200  load_domain( const char *filename )
200            domain->trans_tab = (struct string_desc *)            domain->trans_tab = (struct string_desc *)
201                ((char *) data + SWAPIT(domain->must_swap, data->trans_tab_offset));                ((char *) data + SWAPIT(domain->must_swap, data->trans_tab_offset));
202            domain->hash_size = SWAPIT(domain->must_swap, data->hash_tab_size);              domain->hash_size = SWAPIT(domain->must_swap, data->hash_tab_size);  
203            domain->hash_tab = (u32 *)                domain->hash_tab = (DWORD *)  
204                ((char *) data + SWAPIT(domain->must_swap, data->hash_tab_offset));                      ((char *) data + SWAPIT(domain->must_swap, data->hash_tab_offset));      
205            break;            break;
206    
# Line 212  load_domain( const char *filename ) Line 222  load_domain( const char *filename )
222  } /* load_domain */  } /* load_domain */
223    
224    
225  /****************  /* Set the file used for translations. Pass a NULL to disable translation.
226   * Set the file used for translations.  Pass a NULL to disable     A new filename may be set at anytime. */
  * translation.  A new filename may be set at anytime.  
  * WARNING: After changing the filename you shoudl not access any data  
  *          retrieved by gettext().  
  */  
227  int  int
228  set_gettext_file( const char *filename, const char *nls_dir )  set_gettext_file( const char *filename, const char *nls_dir )
229  {  {
# Line 256  set_gettext_file( const char *filename, Line 262  set_gettext_file( const char *filename,
262      }      }
263      the_domain = domain;      the_domain = domain;
264      return 0;      return 0;
265  } /* set_gettext_file */  }
266    
267    
268  static const char*  static const char*
269  get_string( struct loaded_domain *domain, u32 idx )  get_string( struct loaded_domain *domain, DWORD idx )
270  {  {
271      char *p = domain->data + SWAPIT(domain->must_swap,      char *p = domain->data + SWAPIT(domain->must_swap,
272                                      domain->trans_tab[idx].offset);                                      domain->trans_tab[idx].offset);
# Line 268  get_string( struct loaded_domain *domain Line 274  get_string( struct loaded_domain *domain
274          domain->mapped[idx] = 1;                          domain->mapped[idx] = 1;                
275      }      }
276      return (const char*)p;      return (const char*)p;
277  } /* get_string */  }
278    
279    
280  const char *  const char *
# Line 278  gettext( const char *msgid ) Line 284  gettext( const char *msgid )
284      size_t act = 0;      size_t act = 0;
285      size_t top, bottom;      size_t top, bottom;
286    
287      if( !(domain = the_domain) )              if (!(domain = the_domain))
288          goto not_found;          goto not_found;
289    
290      /* Locate the MSGID and its translation.  */      /* Locate the MSGID and its translation.  */
291      if( domain->hash_size > 2 && domain->hash_tab ) {                if( domain->hash_size > 2 && domain->hash_tab ) {          
292          /* Use the hashing table.  */                    /* Use the hashing table.  */          
293          u32 len = strlen (msgid);                DWORD len = strlen (msgid);    
294          u32 hash_val = hash_string (msgid);              DWORD hash_val = hash_string (msgid);  
295          u32 idx = hash_val % domain->hash_size;          DWORD idx = hash_val % domain->hash_size;      
296          u32 incr = 1 + (hash_val % (domain->hash_size - 2));              DWORD incr = 1 + (hash_val % (domain->hash_size - 2));  
297          u32 nstr = SWAPIT (domain->must_swap, domain->hash_tab[idx]);          DWORD nstr = SWAPIT (domain->must_swap, domain->hash_tab[idx]);
298    
299          if ( !nstr ) /* Hash table entry is empty.  */            if ( !nstr ) /* Hash table entry is empty.  */  
300              goto not_found;              goto not_found;
# Line 341  not_found: Line 347  not_found:
347      return msgid;      return msgid;
348  } /* gettext */  } /* gettext */
349    
350  /* Map the user specific language ID to a  
351     gettext conform language string.  /* Map the user specific language ID to a gettext conform language string.
352     Example: LANG_GERMAN -> "de" */     Example: LANG_GERMAN -> "de" */
353  const char*  const char*
354  get_gettext_langid (void)  get_gettext_langid (void)
355  {  {
     struct {  
         const char *id;  
         int langid;  
     } lang_table[] = {  
         {"de", LANG_GERMAN},  
         {NULL, 0},  
     };  
356      LANGID lang;      LANGID lang;
357      int i;      int i;
358        
359      lang = GetUserDefaultLangID ();      lang = GetUserDefaultLangID ();
360            if (PRIMARYLANGID (lang) == LANG_ENGLISH)
361      for (i=0; lang_table[i].id; i++) {          return NULL;
362          if (PRIMARYLANGID (lang) == lang_table[i].langid)  
363              return lang_table[i].id;      for (i=0; lang_list[i].id; i++) {
364            if (PRIMARYLANGID (lang) == lang_list[i].langid)
365                return lang_list[i].id;
366      }      }
367      return NULL;      return NULL;
368  }  }
369    
370    
371    /* Take a table with control item IDs and their translation
372       and set each text to the translated value. */
373    void
374    gettext_localize_dialog (HWND dlg, struct gettext_tab_s *tab,
375                             const char *title)
376    {
377        int i;
378    
379        for (i=0; tab[i].trans != NULL; i++)
380            SetDlgItemText (dlg, tab[i].ctlid, tab[i].trans);
381        if (title)
382            SetWindowText (dlg, title);
383    }
384    
385    
386  /* XXX: this has to be placed in a .c file but not here */  /* XXX: this has to be placed in a .c file but not here */
387  #include <shlobj.h>  #include <shlobj.h>
388    

Legend:
Removed from v.76  
changed lines
  Added in v.205

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26