[TXT2NLS] TransUniDefaultChar has to be received from WideCharTable. TransDefaultChar...
[reactos.git] / rosapps / applications / devutils / txt2nls / txt.c
1 /*
2 * PROJECT: ReactOS TXT to NLS Converter
3 * LICENSE: GNU General Public License Version 2.0 or any later version
4 * FILE: devutils/txt2nls/txt.c
5 * COPYRIGHT: Copyright 2016 Dmitry Chapyshev <dmitry@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 int
11 txt_get_header(const char *file_path, NLS_FILE_HEADER *header)
12 {
13 FILE *file;
14 char *p;
15 char buf[256];
16 uint32_t line = 0;
17 int res = 0;
18 int found;
19 uint32_t val;
20
21 file = fopen(file_path, "r");
22 if (!file)
23 {
24 printf("Unable to read TXT file.\n");
25 return 0;
26 }
27
28 /* Find CODEPAGE entry */
29 found = 0;
30 while (fgets(buf, sizeof(buf), file))
31 {
32 ++line;
33
34 p = strstr(buf, "CODEPAGE");
35 if (p)
36 {
37 /* Length of CODEPAGE string is 8 chars */
38 p += 8;
39
40 /* Skip all spaces after CODEPAGE */
41 while (isspace(*p)) ++p;
42
43 /* Convert string to uint32_t */
44 val = strtoul(p, &p, 10);
45
46 /* Validate codepage value */
47 if (val > 0xFFFF)
48 {
49 printf("Wrong codepage: %u (line: %u)\n", val, line);
50 goto Cleanup;
51 }
52
53 header->CodePage = (uint16_t)val;
54
55 found = 1;
56 break;
57 }
58 }
59
60 if (!found)
61 {
62 printf("CODEPAGE not found.\n");
63 goto Cleanup;
64 }
65
66 /* Find CPINFO entry */
67 found = 0;
68 while (fgets(buf, sizeof(buf), file))
69 {
70 ++line;
71
72 p = strstr(buf, "CPINFO");
73 if (p)
74 {
75 /* Length of CPINFO string is 6 chars */
76 p += 6;
77
78 /* Skip all spaces after CPINFO */
79 while (isspace(*p)) ++p;
80
81 /* Convert string to uint32_t */
82 val = strtoul(p, &p, 10);
83
84 /* Validate value */
85 if (val != 1 && val != 2)
86 {
87 printf("Wrong character size: %u (line: %u)\n", val, line);
88 goto Cleanup;
89 }
90
91 header->MaximumCharacterSize = (uint16_t)val;
92
93 /* Skip all spaces after character size */
94 while (isspace(*p)) ++p;
95
96 /* Convert string to uint32_t */
97 val = strtoul(p, &p, 16);
98 header->DefaultChar = (uint16_t)val;
99 /* By default set value as DefaultChar */
100 header->TransDefaultChar = (uint16_t)val;
101
102 /* Skip all spaces after default char */
103 while (isspace(*p)) ++p;
104
105 /* Convert string to uint32_t */
106 val = strtoul(p, &p, 16);
107 header->UniDefaultChar = (uint16_t)val;
108 /* By default set value as UniDefaultChar */
109 header->TransUniDefaultChar = (uint16_t)val;
110
111 found = 1;
112 break;
113 }
114 }
115
116 if (!found)
117 {
118 printf("CPINFO not found.\n");
119 goto Cleanup;
120 }
121
122 header->HeaderSize = sizeof(NLS_FILE_HEADER) / sizeof(uint16_t);
123
124 res = 1;
125
126 Cleanup:
127 fclose(file);
128
129 return res;
130 }
131
132 uint16_t*
133 txt_get_mb_table(const char *file_path, uint16_t uni_default_char)
134 {
135 uint16_t *table;
136 char buf[256];
137 char *p;
138 uint32_t count = 0;
139 uint32_t index;
140 uint32_t line = 0;
141 int found;
142 int res = 0;
143 FILE *file;
144
145 table = malloc(256 * sizeof(uint16_t));
146 if (!table)
147 {
148 printf("Memory allocation failure\n");
149 return NULL;
150 }
151
152 /* Set default value for all table items */
153 for (index = 0; index <= 255; index++)
154 table[index] = uni_default_char;
155
156 file = fopen(file_path, "r");
157 if (!file)
158 {
159 printf("Unable to read TXT file.\n");
160 goto Cleanup;
161 }
162
163 /* Find MBTABLE entry */
164 found = 0;
165 while (fgets(buf, sizeof(buf), file))
166 {
167 ++line;
168
169 p = strstr(buf, "MBTABLE");
170 if (p)
171 {
172 p += 7;
173
174 /* Skip spaces */
175 while (isspace(*p)) ++p;
176
177 count = strtoul(p, &p, 10);
178 if (count == 0 || count > 256)
179 {
180 printf("Wrong MBTABLE size: %u (line: %u)\n", count, line);
181 goto Cleanup;
182 }
183
184 found = 1;
185 break;
186 }
187 }
188
189 if (!found)
190 {
191 printf("MBTABLE not found.\n");
192 goto Cleanup;
193 }
194
195 /* Parse next line */
196 while (fgets(buf, sizeof(buf), file) && count)
197 {
198 uint32_t cp_char;
199 uint32_t uni_char;
200
201 ++line;
202
203 p = buf;
204
205 /* Skip spaces */
206 while (isspace(*p)) ++p;
207
208 if (!*p || p[0] == ';')
209 continue;
210
211 cp_char = strtoul(p, &p, 16);
212 if (cp_char > 0xFF)
213 {
214 printf("Wrong char value: %u (line: %u)\n", cp_char, line);
215 goto Cleanup;
216 }
217
218 /* Skip spaces */
219 while (isspace(*p)) ++p;
220
221 uni_char = strtoul(p, &p, 16);
222 if (uni_char > 0xFFFF)
223 {
224 printf("Wrong unicode char value: %u (line: %u)\n", uni_char, line);
225 goto Cleanup;
226 }
227
228 table[cp_char] = uni_char;
229 --count;
230 }
231
232 res = 1;
233
234 Cleanup:
235 if (!res)
236 {
237 free(table);
238 table = NULL;
239 }
240
241 fclose(file);
242
243 return table;
244 }
245
246 uint16_t*
247 txt_get_wc_table(const char *file_path, uint16_t default_char, int is_dbcs)
248 {
249 char buf[256];
250 char *p;
251 uint16_t *table;
252 uint32_t index;
253 uint32_t count = 0;
254 uint32_t line = 0;
255 int res = 0;
256 int found;
257 FILE *file;
258
259 table = malloc(65536 * (is_dbcs ? sizeof(uint16_t) : sizeof(uint8_t)));
260 if (!table)
261 {
262 printf("Memory allocation failure\n");
263 return NULL;
264 }
265
266 /* Set default value for all table items */
267 for (index = 0; index <= 65535; index++)
268 {
269 /* DBCS code page */
270 if (is_dbcs)
271 {
272 uint16_t *tmp = (uint16_t*)table;
273 tmp[index] = default_char;
274 }
275 /* SBCS code page */
276 else
277 {
278 uint8_t *tmp = (uint8_t*)table;
279 tmp[index] = default_char;
280 }
281 }
282
283 file = fopen(file_path, "r");
284 if (!file)
285 {
286 printf("Unable to read TXT file.\n");
287 goto Cleanup;
288 }
289
290 /* Find WCTABLE entry */
291 found = 0;
292 while (fgets(buf, sizeof(buf), file))
293 {
294 ++line;
295
296 p = strstr(buf, "WCTABLE");
297 if (p)
298 {
299 p += 7;
300
301 /* Skip spaces */
302 while (isspace(*p)) ++p;
303
304 count = strtoul(p, &p, 10);
305 if (count == 0 || count > 65536)
306 {
307 printf("Wrong WCTABLE size: %u (line: %u)\n", count, line);
308 goto Cleanup;
309 }
310
311 found = 1;
312 break;
313 }
314 }
315
316 if (!found)
317 {
318 printf("WCTABLE not found.\n");
319 goto Cleanup;
320 }
321
322 /* Parse next line */
323 while (fgets(buf, sizeof(buf), file) && count)
324 {
325 uint32_t cp_char;
326 uint32_t uni_char;
327
328 ++line;
329
330 p = buf;
331
332 /* Skip spaces */
333 while (isspace(*p)) ++p;
334
335 if (!*p || p[0] == ';')
336 continue;
337
338 uni_char = strtoul(p, &p, 16);
339 if (uni_char > 0xFFFF)
340 {
341 printf("Wrong unicode char value: %u (line: %u)\n", uni_char, line);
342 goto Cleanup;
343 }
344
345 /* Skip spaces */
346 while (isspace(*p)) ++p;
347
348 cp_char = strtoul(p, &p, 16);
349 if ((is_dbcs && cp_char > 0xFFFF) || (!is_dbcs && cp_char > 0xFF))
350 {
351 printf("Wrong char value: %u (line: %u)\n", cp_char, line);
352 goto Cleanup;
353 }
354
355 /* DBCS code page */
356 if (is_dbcs)
357 {
358 uint16_t *tmp = (uint16_t*)table;
359 tmp[uni_char] = cp_char;
360 }
361 /* SBCS code page */
362 else
363 {
364 uint8_t *tmp = (uint8_t*)table;
365 tmp[uni_char] = cp_char;
366 }
367
368 --count;
369 }
370
371 res = 1;
372
373 Cleanup:
374 if (!res)
375 {
376 free(table);
377 table = NULL;
378 }
379
380 fclose(file);
381
382 return table;
383 }
384
385 uint16_t*
386 txt_get_glyph_table(const char *file_path, uint16_t uni_default_char)
387 {
388 uint16_t *table;
389 char buf[256];
390 char *p;
391 uint32_t count = 0;
392 uint32_t index;
393 uint32_t line = 0;
394 int found;
395 int res = 0;
396 FILE *file;
397
398 table = malloc(256 * sizeof(uint16_t));
399 if (!table)
400 {
401 printf("Memory allocation failure\n");
402 return NULL;
403 }
404
405 /* Set default value for all table items */
406 for (index = 0; index <= 255; index++)
407 table[index] = uni_default_char;
408
409 file = fopen(file_path, "r");
410 if (!file)
411 {
412 printf("Unable to read TXT file.\n");
413 goto Cleanup;
414 }
415
416 /* Find GLYPHTABLE entry */
417 found = 0;
418 while (fgets(buf, sizeof(buf), file))
419 {
420 ++line;
421
422 p = strstr(buf, "GLYPHTABLE");
423 if (p)
424 {
425 p += 10;
426
427 /* Skip spaces */
428 while (isspace(*p)) ++p;
429
430 count = strtoul(p, &p, 10);
431 if (count == 0 || count > 256)
432 {
433 printf("Wrong GLYPHTABLE size: %u (line: %u)\n", count, line);
434 goto Cleanup;
435 }
436
437 found = 1;
438 break;
439 }
440 }
441
442 if (!found)
443 {
444 printf("GLYPHTABLE not found.\n");
445 goto Cleanup;
446 }
447
448 /* Parse next line */
449 while (fgets(buf, sizeof(buf), file) && count)
450 {
451 uint32_t cp_char;
452 uint32_t uni_char;
453
454 ++line;
455
456 p = buf;
457
458 /* Skip spaces */
459 while (isspace(*p)) ++p;
460
461 if (!*p || p[0] == ';')
462 continue;
463
464 cp_char = strtoul(p, &p, 16);
465 if (cp_char > 0xFF)
466 {
467 printf("Wrong char value: %u (line: %u)\n", cp_char, line);
468 goto Cleanup;
469 }
470
471 /* Skip spaces */
472 while (isspace(*p)) ++p;
473
474 uni_char = strtoul(p, &p, 16);
475 if (uni_char > 0xFFFF)
476 {
477 printf("Wrong unicode char value: %u (line: %u)\n", uni_char, line);
478 goto Cleanup;
479 }
480
481 table[cp_char] = uni_char;
482 --count;
483 }
484
485 res = 1;
486
487 Cleanup:
488 if (!res)
489 {
490 free(table);
491 table = NULL;
492 }
493
494 fclose(file);
495
496 return table;
497 }