This source file includes following definitions.
- lang_init
- placelstr
- lang_add_string
- lang_parse_from_mem
- load_builtin_lang_strings
- lang_map_preparsed_from_mem
- lang_load_from_file
- lang_str
- lang_strhash31
1 #include "stdlib.h"
2 #include "stddef.h"
3 #include "string.h"
4 #include "lang.h"
5 #include "fileutil.h"
6
7 static char* preparsed_lang_default_start=0;
8
9
10
11 #define MAX_LANGID 0x1000
12
13
14
15
16
17
18
19
20
21
22
23
24
25 static short* strings = NULL;
26 static int count = 0;
27 static char* langbuf = NULL;
28 static int langbuflen = 0;
29 static int lbpointer;
30
31
32 void lang_init(int num) {
33
34 if (strings) {
35 free(strings);
36 count = 0;
37 }
38
39 ++num;
40 strings = malloc(num*sizeof(short));
41 if (strings) {
42 memset(strings, 0, num*sizeof(short));
43 count = num;
44 }
45
46 }
47
48
49
50 static char* placelstr(int size) {
51 char *ret = langbuf + lbpointer;
52 lbpointer += size;
53 if (lbpointer <= langbuflen) {
54 return ret;
55 }
56 return 0;
57 }
58
59
60
61 static void lang_add_string(int num, const char *str) {
62 int f=0;
63 char *p;
64
65 if (strings && num<count) {
66
67 p = placelstr(strlen(str)+1);
68 if (p) {
69 strings[num] = -(1 + p - langbuf);
70 for (; *str; ++str) {
71 if (f) {
72 if (*str == '"' || *str == '\\') *(p-1)=*str;
73 else if (*str == 'n') *(p-1)='\n';
74 else *p++=*str;
75 f = 0;
76 } else {
77 *p++=*str;
78 if (*str == '\\') {
79 f = 1;
80 }
81 }
82 }
83 *p=0;
84 }
85 }
86 }
87
88
89
90
91 int lang_parse_from_mem(char *buf, int size) {
92 char *p, *s, *e, *b;
93 int i, langbufneed;
94 char** pstrtmp;
95
96 if ( size <= 0 )
97 return 0;
98
99 langbufneed = 0;
100 lbpointer = 0;
101
102 pstrtmp = malloc(count*sizeof(char*));
103 if (!pstrtmp) {
104 return 0;
105 }
106
107 memset(pstrtmp, 0, count*sizeof(char*));
108
109
110 char* load_builtin_lang_strings(int, short*);
111 load_builtin_lang_strings(count-1, strings);
112
113 e = buf-1;
114 while(e) {
115 p = e+1;
116 while (*p && (*p=='\r' || *p=='\n')) ++p;
117 i = strtol(p, &e, 0);
118 if (e!=p) {
119 p = e;
120 e = strpbrk(p, "\r\n");
121 if (e) *e=0;
122
123 while (*p && *p!='\"') ++p;
124 if (*p) ++p;
125 s = p;
126 while (*p && (*p!='\"' || *(p-1)=='\\')) ++p;
127 *p=0;
128
129
130 if ((i > 0) && (i<count)) {
131
132
133
134
135
136 b = lang_str(i);
137 if (b && b[0]!=0) {
138 langbufneed += strlen(s) + 1;
139 pstrtmp[i] = s;
140 }
141 }
142 } else {
143 e = strpbrk(p, "\r\n");
144 if (e) *e=0;
145 }
146 }
147
148 if ((langbufneed>langbuflen)||(!langbuf)) {
149 if (langbuf) {
150 free(langbuf);
151 }
152 langbuf = malloc(langbufneed);
153 if (langbuf) {
154 langbuflen = langbufneed;
155 }
156 else {
157 langbuflen = 0;
158 }
159 }
160
161
162
163 for (i=1; i<count; i++) {
164 if (pstrtmp[i]) {
165 lang_add_string(i, pstrtmp[i]);
166 }
167 }
168
169 free(pstrtmp);
170 return 1;
171 }
172
173
174
175 char* load_builtin_lang_strings(int cnt, short* array) {
176 int i;
177 char *p = preparsed_lang_default_start;
178
179 for ( i = 1; i<=cnt; i++ )
180 {
181 array[i] = 1 + p - preparsed_lang_default_start;
182 while (*p) p++;
183 p++;
184 }
185 return p;
186 }
187
188
189
190 void lang_map_preparsed_from_mem( char* gui_lang_default, int num )
191 {
192
193 preparsed_lang_default_start = gui_lang_default;
194 lang_init( num );
195
196 load_builtin_lang_strings(num, strings);
197
198 }
199
200
201 void lang_load_from_file(const char *filename) {
202 process_file(filename, lang_parse_from_mem, 1);
203 }
204
205
206
207 char* lang_str(int str) {
208 if (str && str<MAX_LANGID) {
209 if (strings && str<count && strings[str]) {
210 if (strings[str]>0) {
211
212 return preparsed_lang_default_start + strings[str] - 1;
213 }
214 else if (langbuf) {
215
216 return langbuf - strings[str] - 1;
217 }
218 }
219 } else {
220 return (char*)str;
221 }
222 return "";
223 }
224
225
226
227 unsigned int lang_strhash31(int langid)
228 {
229 if ( langid<MAX_LANGID )
230 return langid;
231
232 unsigned char* str = (unsigned char*)langid;
233 unsigned hash=0;
234 for ( ; *str; str++ )
235 hash = *str ^ (hash<<6) ^ (hash>>25);
236 if ( hash<MAX_LANGID )
237 hash |= (1<<31);
238 return hash;
239 }