~ubuntu-branches/debian/sid/freeciv/sid

« back to all changes in this revision

Viewing changes to amiga/gettext.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2010-02-23 22:09:02 UTC
  • mfrom: (7.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100223220902-s3spqi1x4e190y0t
[ Karl Goetz ]
* Remove civserver files in /etc/ggzd/ (Closes: 523772, 517787)
* Adding ${misc:Depends} to all binary packages (lintian warnings)

[ Clint Adams ]
* New upstream version.
  - Drop data_dsc_use_bindir.diff (binary pathnames have changed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* This file is based on gettext sources, but specialiced for freeciv.
2
 
It may not work with other programs, as the functions do not do the
3
 
stuff of gettext package. Also client and server cannot use one data file,
4
 
but need to load it individually.
5
 
 
6
 
And I did not want to port gettext completely, which would have been
7
 
much more work!
8
 
 
9
 
Modification history;
10
 
08.08.2000 : Dirk Stöcker <stoecker@epost.de>
11
 
  Initial version
12
 
27.08.2000 : Dirk Stöcker <stoecker@epost.de>
13
 
  fixes to match changed calling mechanism
14
 
26.09.2000 : Oliver Gantert <lucyg@t-online.de>
15
 
  changed includes to work with vbcc WarpOS
16
 
16.12.2000 : Dirk Stöcker <stoecker@epost.de>
17
 
  removed changes, as it works without also
18
 
26.12.2001 : Sebastian Bauer <sebauer@t-online.de>
19
 
  uses now the prefered languages to determine the gmostr
20
 
26.12.2001 : Sebastian Bauer <sebauer@t-online.de>
21
 
  lets SAS open the locale library for us now
22
 
19.02.2002 : Sebastian Bauer <sebauer@t-online.de>
23
 
  added ngettext, but not fully working, only a dummy
24
 
12.04.2002 : Sebastian Bauer <sebauer@t-online.de>
25
 
  convert KOI8-R charset to the chareset used on Amiga
26
 
*/
27
 
 
28
 
#ifdef HAVE_CONFIG_H
29
 
#include <config.h>
30
 
#endif
31
 
 
32
 
#include <stdio.h>
33
 
#include <stdlib.h>
34
 
#include <string.h>
35
 
#include <proto/exec.h>
36
 
#include <proto/locale.h>
37
 
 
38
 
/* The magic number of the GNU message catalog format.  */
39
 
#define _MAGIC 0x950412de
40
 
#define _MAGIC_SWAPPED 0xde120495
41
 
 
42
 
#define SWAP(i) (((i) << 24) | (((i) & 0xff00) << 8) | (((i) >> 8) & 0xff00) | ((i) >> 24))
43
 
#define GET(data) (domain.must_swap ? SWAP (data) : (data))
44
 
 
45
 
typedef unsigned long nls_uint32;
46
 
 
47
 
/* Header for binary .mo file format.  */
48
 
struct mo_file_header
49
 
{
50
 
  nls_uint32 magic;  /* The magic number.  */
51
 
  nls_uint32 revision;  /* The revision number of the file format.  */
52
 
  nls_uint32 nstrings;  /* The number of strings pairs.  */
53
 
  nls_uint32 orig_tab_offset;  /* Offset of table with start offsets of original strings.  */
54
 
  nls_uint32 trans_tab_offset;  /* Offset of table with start offsets of translation strings.  */
55
 
  nls_uint32 hash_tab_size;  /* Size of hashing table.  */
56
 
  nls_uint32 hash_tab_offset;  /* Offset of first hashing entry.  */
57
 
};
58
 
 
59
 
struct string_desc
60
 
{
61
 
  nls_uint32 length;  /* Length of addressed string.  */
62
 
  nls_uint32 offset;  /* Offset of string in file.  */
63
 
};
64
 
 
65
 
struct loaded_domain
66
 
{
67
 
  const char *data;
68
 
  int must_swap;
69
 
  nls_uint32 nstrings;
70
 
  struct string_desc *orig_tab;
71
 
  struct string_desc *trans_tab;
72
 
  nls_uint32 hash_size;
73
 
  nls_uint32 *hash_tab;
74
 
};
75
 
 
76
 
static struct loaded_domain domain = {0, 0, 0, 0, 0, 0, 0};
77
 
 
78
 
char *gettext(const char *msgid);
79
 
 
80
 
static long openmo(char *dir, char *loc)
81
 
{
82
 
  char filename[512];
83
 
  FILE *fd;
84
 
  long size;
85
 
  struct mo_file_header *data;
86
 
 
87
 
  if(!dir || !loc)
88
 
    return 0;
89
 
 
90
 
  sprintf(filename, "%s/%s.mo", dir, loc);
91
 
#ifdef DEBUG
92
 
  printf("locale file name: %s\n", filename);
93
 
#endif
94
 
 
95
 
  if((fd = fopen(filename, "rb")))
96
 
  {
97
 
    if(!fseek(fd, 0, SEEK_END))
98
 
    {
99
 
      if((size = ftell(fd)) != EOF)
100
 
      {
101
 
        if(!fseek(fd, 0, SEEK_SET))
102
 
        {
103
 
          if((data = (struct mo_file_header *) malloc(size)))
104
 
          {
105
 
            if(fread(data, size, 1, fd) == 1)
106
 
            {
107
 
              if((data->magic == _MAGIC || data->magic == _MAGIC_SWAPPED) && !data->revision) /* no need to swap! */
108
 
              {
109
 
                domain.data = (const char *) data;
110
 
                domain.must_swap = data->magic != _MAGIC;
111
 
                domain.nstrings = GET(data->nstrings);
112
 
                domain.orig_tab = (struct string_desc *) ((char *) data + GET(data->orig_tab_offset));
113
 
                domain.trans_tab = (struct string_desc *) ((char *) data + GET(data->trans_tab_offset));
114
 
                domain.hash_size = GET(data->hash_tab_size);
115
 
                domain.hash_tab = (nls_uint32 *) ((char *) data + GET(data->hash_tab_offset));
116
 
 
117
 
                if (strstr(gettext(""),"charset=KOI8-R") /* This somehow doesn't work so we check for the ru string also */ || !strcmp("ru",loc))
118
 
                {
119
 
                  int i;
120
 
 
121
 
                  /* convert the charset to AMI1251, this is the table */
122
 
                  static const unsigned char table[] = {
123
 
                    0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
124
 
                    0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
125
 
                    0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
126
 
                    0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
127
 
                    0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
128
 
                    0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
129
 
                    0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
130
 
                    0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
131
 
                    0xBF,0xB6,0xBE,0xAA,0xA1,0xB5,0x8D,0x8E,0x93,0x90,0x98,0x96,0x99,0x94,0x9A,0x80,
132
 
                    0x81,0x82,0x87,0x88,0x89,0x8A,0x8F,0x9E,0x9F,0xB4,0xAD,0xAC,0xAC,0xAC,0xAC,0xAC,
133
 
                    0xAC,0xAC,0xAC,0xB8,0xAC,0xAC,0xAC,0xBA,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAB,0xBB,
134
 
                    0x9B,0x9C,0x9E,0xA8,0xA5,0x83,0x84,0x85,0x86,0x97,0x95,0x91,0x92,0x8B,0x8C,0xAF,
135
 
                    0xFE,0xE0,0xE1,0xF6,0xE4,0xE5,0xF4,0xE3,0xF5,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,
136
 
                    0xEF,0xFF,0xF0,0xF1,0xF2,0xF3,0xE6,0xE2,0xFC,0xFB,0xE7,0xF8,0xFD,0xF9,0xF7,0xFA,
137
 
                    0xDE,0xC0,0xC1,0xD6,0xC4,0xC5,0xD4,0xC3,0xD5,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,
138
 
                    0xCF,0xDF,0xD0,0xD1,0xD2,0xD3,0xC6,0xC2,0xDC,0xDB,0xC7,0xD8,0xDD,0xD9,0xD7,0xDA
139
 
                  };
140
 
 
141
 
                  for (i=0;i<domain.nstrings;i++)
142
 
                  {
143
 
                    int j;
144
 
                    int off = GET(domain.trans_tab[i].offset);
145
 
                    char *trans_string = domain.data + off;
146
 
 
147
 
                    /* Now convert every char in size the string */
148
 
                    for (j=0;j<GET(domain.trans_tab[i].length) && j+off<size;j++)
149
 
                    {
150
 
                      trans_string[j] = table[trans_string[j]];
151
 
                    }
152
 
                  }
153
 
                }
154
 
              }
155
 
              else
156
 
                free(data);
157
 
            }
158
 
            else
159
 
              free(data);
160
 
          }
161
 
        }
162
 
      }
163
 
    }
164
 
    fclose(fd);
165
 
  }
166
 
  return (long) domain.data;
167
 
}
168
 
 
169
 
/* languages supported by freeciv */
170
 
struct LocaleConv {
171
 
  char *langstr;
172
 
  char *gmostr;
173
 
} LocaleConvTab[] = {
174
 
{"deutsch", "de"},
175
 
/*{"", "en_GB"}, does not exist on Amiga */
176
 
{"español", "es"},
177
 
{"français", "fr"},
178
 
{"hrvatski", "hu"},
179
 
{"italiano", "it"},
180
 
{"nihongo", "ja"},
181
 
{"nederlands", "nl"},
182
 
{"norsk", "no"},
183
 
{"polski", "pl"},
184
 
{"português" , "pt"},
185
 
{"português-brasil", "pt_BR"},
186
 
{"russian", "ru"},
187
 
{"svenska", "sv"},
188
 
{"suomi","fi"},
189
 
{0, 0},
190
 
};
191
 
 
192
 
/* Returns NULL if is not in the list */
193
 
static char *find_gmostr(char *lang)
194
 
{
195
 
        int i;
196
 
        if (!lang) return NULL;
197
 
        for (i=0;LocaleConvTab[i].langstr;i++)
198
 
        {
199
 
                if (!strcmp(LocaleConvTab[i].langstr,lang)) return LocaleConvTab[i].gmostr;
200
 
        }
201
 
        return NULL;
202
 
}
203
 
 
204
 
void bindtextdomain(char * pack, char * dir)
205
 
{
206
 
        struct Locale *l;
207
 
  int i;
208
 
 
209
 
  if(openmo(dir, getenv("LANG")))
210
 
    return;
211
 
 
212
 
  if(openmo(dir, getenv("LANGUAGE")))
213
 
    return;
214
 
 
215
 
        if((l = OpenLocale(0)))
216
 
        {
217
 
                for (i=0;i<10;i++)
218
 
                {
219
 
                        if (!openmo(dir,find_gmostr(l->loc_PrefLanguages[i])))
220
 
                        {
221
 
                                if (openmo(dir,l->loc_PrefLanguages[i])) break;
222
 
                        } else break;
223
 
                }
224
 
 
225
 
                CloseLocale(l);
226
 
        }
227
 
}
228
 
 
229
 
#define HASHWORDBITS 32
230
 
static unsigned long hash_string(const char *str_param)
231
 
{
232
 
  unsigned long int hval, g;
233
 
  const char *str = str_param;
234
 
 
235
 
  /* Compute the hash value for the given string.  */
236
 
  hval = 0;
237
 
  while (*str != '\0')
238
 
  {
239
 
    hval <<= 4;
240
 
    hval += (unsigned long) *str++;
241
 
    g = hval & ((unsigned long) 0xf << (HASHWORDBITS - 4));
242
 
    if (g != 0)
243
 
    {
244
 
      hval ^= g >> (HASHWORDBITS - 8);
245
 
      hval ^= g;
246
 
    }
247
 
  }
248
 
  return hval;
249
 
}
250
 
 
251
 
static char *find_msg(const char * msgid)
252
 
{
253
 
  long top, act, bottom;
254
 
 
255
 
  if(!domain.data || !msgid)
256
 
    return NULL;
257
 
 
258
 
  /* Locate the MSGID and its translation.  */
259
 
  if(domain.hash_size > 2 && domain.hash_tab != NULL)
260
 
  {
261
 
    /* Use the hashing table.  */
262
 
    nls_uint32 len = strlen (msgid);
263
 
    nls_uint32 hash_val = hash_string (msgid);
264
 
    nls_uint32 idx = hash_val % domain.hash_size;
265
 
    nls_uint32 incr = 1 + (hash_val % (domain.hash_size - 2));
266
 
    nls_uint32 nstr;
267
 
 
268
 
    for(;;)
269
 
    {
270
 
      if(!(nstr = GET(domain.hash_tab[idx]))) /* Hash table entry is empty.  */
271
 
        return NULL;
272
 
 
273
 
      if(GET(domain.orig_tab[nstr - 1].length) == len && strcmp(msgid, domain.data +
274
 
      GET(domain.orig_tab[nstr - 1].offset)) == 0)
275
 
        return (char *) domain.data + GET(domain.trans_tab[nstr - 1].offset);
276
 
 
277
 
      if(idx >= domain.hash_size - incr)
278
 
        idx -= domain.hash_size - incr;
279
 
      else
280
 
        idx += incr;
281
 
    }
282
 
  }
283
 
 
284
 
  /* Now we try the default method:  binary search in the sorted
285
 
     array of messages.  */
286
 
  bottom = act = 0;
287
 
  top = domain.nstrings;
288
 
  while(bottom < top)
289
 
  {
290
 
    int cmp_val;
291
 
 
292
 
    act = (bottom + top) / 2;
293
 
    cmp_val = strcmp(msgid, domain.data + GET(domain.orig_tab[act].offset));
294
 
    if(cmp_val < 0)
295
 
      top = act;
296
 
    else if(cmp_val > 0)
297
 
      bottom = act + 1;
298
 
    else
299
 
      break;
300
 
  }
301
 
 
302
 
  /* If an translation is found return this.  */
303
 
  return bottom >= top ? NULL : (char *) domain.data + GET(domain.trans_tab[act].offset);
304
 
}
305
 
 
306
 
 
307
 
char *gettext(const char *msgid)
308
 
{
309
 
  char *res;
310
 
 
311
 
  if(!(res = find_msg(msgid)))
312
 
  {
313
 
    res = (char *) msgid;
314
 
#ifdef DEBUG
315
 
    Printf("Did not find: '%s'\n", res);
316
 
#endif
317
 
  }
318
 
 
319
 
  return res;
320
 
}
321
 
 
322
 
char *ngettext(const char *msgid1, const char *msgid2, unsigned long int n)
323
 
{
324
 
        return (n==1?msgid1:msgid2);
325
 
}
326
 
 
327
 
char *setlocale(int a, char *b)
328
 
{
329
 
  return "C";
330
 
}
331
 
 
332
 
void textdomain(char *package)
333
 
{
334
 
}