1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
/* language.c
* (c) 2002 Mikulas Patocka
* This file is a part of the Links program, released under GPL.
*/
#include "links.h"
struct translation {
int code;
unsigned char *name;
};
struct translation_desc {
struct translation *t;
};
unsigned char dummyarray[T__N_TEXTS];
#include "language.inc"
static unsigned char **translation_array[N_LANGUAGES][N_CODEPAGES];
int current_language;
static int current_lang_charset;
void init_trans(void)
{
int i, j;
for (i = 0; i < N_LANGUAGES; i++)
for (j = 0; j < N_CODEPAGES; j++)
translation_array[i][j] = NULL;
current_language = 0;
current_lang_charset = 0;
}
void shutdown_trans(void)
{
int i, j, k;
for (i = 0; i < N_LANGUAGES; i++)
for (j = 0; j < N_CODEPAGES; j++) if (translation_array[i][j]) {
for (k = 0; k < T__N_TEXTS; k++) {
unsigned char *txt = translation_array[i][j][k];
if (txt &&
txt != translations[i].t[k].name &&
txt != translations[0].t[k].name)
mem_free(txt);
}
mem_free(translation_array[i][j]);
}
}
static inline int is_direct_text(unsigned char *text)
{
/* Do not compare to dummyarray directly - thwart some misoptimizations */
unsigned char * volatile dm = dummyarray;
return !(text >= dm && text < dm + T__N_TEXTS);
}
unsigned char *get_text_translation(unsigned char *text, struct terminal *term)
{
unsigned char **current_tra;
struct conv_table *conv_table;
unsigned char *trn;
int charset;
if (!term) charset = 0;
else if (term->spec) charset = term->spec->charset;
else charset = utf8_table;
if (is_direct_text(text)) return text;
if ((current_tra = translation_array[current_language][charset])) {
unsigned char *tt;
if ((trn = current_tra[text - dummyarray])) return trn;
tr:
if (!(tt = translations[current_language].t[text - dummyarray].name)) {
trn = translation_english[text - dummyarray].name;
} else {
struct document_options l_opt;
memset(&l_opt, 0, sizeof(l_opt));
l_opt.plain = 0;
l_opt.cp = charset;
conv_table = get_translation_table(current_lang_charset, charset);
trn = convert_string(conv_table, tt, strlen(tt), &l_opt);
if (!strcmp(trn, tt)) {
mem_free(trn);
trn = tt;
}
}
current_tra[text - dummyarray] = trn;
} else {
if (current_lang_charset && charset != current_lang_charset) {
current_tra = translation_array[current_language][charset] = mem_alloc(sizeof (unsigned char **) * T__N_TEXTS);
memset(current_tra, 0, sizeof (unsigned char **) * T__N_TEXTS);
goto tr;
}
if (!(trn = translations[current_language].t[text - dummyarray].name)) {
trn = translations[current_language].t[text - dummyarray].name = translation_english[text - dummyarray].name; /* modifying translation structure */
}
}
return trn;
}
unsigned char *get_english_translation(unsigned char *text)
{
if (is_direct_text(text)) return text;
return translation_english[text - dummyarray].name;
}
int n_languages(void)
{
return N_LANGUAGES;
}
unsigned char *language_name(int l)
{
return translations[l].t[T__LANGUAGE].name;
}
void set_language(int l)
{
int i;
unsigned char *cp;
for (i = 0; i < T__N_TEXTS; i++) if (translations[l].t[i].code != i) {
internal("Bad table for language %s. Run script synclang.", translations[l].t[T__LANGUAGE].name);
return;
}
current_language = l;
cp = translations[l].t[T__CHAR_SET].name;
i = get_cp_index(cp);
if (i == -1) {
internal("Unknown charset for language %s.", translations[l].t[T__LANGUAGE].name);
i = 0;
}
current_lang_charset = i;
}
|