Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/translations.c
Parent Directory
|
Revision Log
Revision 363 -
(hide annotations)
(download)
(as text)
Sun Apr 11 13:01:38 2010 UTC (14 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 16122 byte(s)
Sun Apr 11 13:01:38 2010 UTC (14 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 16122 byte(s)
Added helper functions for parsing strings into numbers. Added macros to perform common error checking. Change XML parser callback functions to return an error status.
1 | amb | 361 | /*************************************** |
2 | amb | 363 | $Header: /home/amb/CVS/routino/src/translations.c,v 1.2 2010-04-11 13:01:24 amb Exp $ |
3 | amb | 361 | |
4 | Load the translations from a file and the functions for handling them. | ||
5 | |||
6 | Part of the Routino routing software. | ||
7 | ******************/ /****************** | ||
8 | This file Copyright 2010 Andrew M. Bishop | ||
9 | |||
10 | This program is free software: you can redistribute it and/or modify | ||
11 | it under the terms of the GNU Affero General Public License as published by | ||
12 | the Free Software Foundation, either version 3 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU Affero General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU Affero General Public License | ||
21 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
22 | ***************************************/ | ||
23 | |||
24 | |||
25 | #include <stdio.h> | ||
26 | #include <string.h> | ||
27 | #include <stdlib.h> | ||
28 | |||
29 | #include "functions.h" | ||
30 | #include "translations.h" | ||
31 | #include "xmlparse.h" | ||
32 | |||
33 | |||
34 | /* Global variables - default English values */ | ||
35 | |||
36 | char *translate_heading[9] ={"South","South-West","West","North-West","North","North-East","East","South-East","South"}; | ||
37 | char *translate_turn[9] ={"Very sharp left","Sharp left","Left","Slight left","Straight on","Slight right","Right","Sharp right","Very sharp right"}; | ||
38 | |||
39 | char *translate_gpx_desc ="%s between 'start' and 'finish' waypoints"; | ||
40 | char *translate_gpx_name ="%s Route"; | ||
41 | char *translate_gpx_step ="%s on '%s' for %.3f km, %.1 min"; | ||
42 | char *translate_gpx_final="Total Journey %.1f km, %d minutes"; | ||
43 | |||
44 | char *translate_gpx_shortest="Shortest"; | ||
45 | char *translate_gpx_quickest="Quickest"; | ||
46 | |||
47 | char *translate_gpx_start="START"; | ||
48 | char *translate_gpx_inter="INTER"; | ||
49 | char *translate_gpx_trip="TRIP"; | ||
50 | char *translate_gpx_finish="FINISH"; | ||
51 | |||
52 | |||
53 | /* Local variables */ | ||
54 | |||
55 | /*+ The language that is to be stored. +*/ | ||
56 | static const char *store_lang=NULL; | ||
57 | |||
58 | /*+ This current language is to be stored. +*/ | ||
59 | static int store=0; | ||
60 | |||
61 | /*+ The chosen language has been stored. +*/ | ||
62 | static int stored=0; | ||
63 | |||
64 | |||
65 | /* The XML tag processing function prototypes */ | ||
66 | |||
67 | amb | 363 | //static int xml_function(int _type_,const char *version,const char *encoding); |
68 | //static int routino_translations_function(int _type_); | ||
69 | static int language_function(int _type_,const char *lang); | ||
70 | //static int output_gpx_function(int _type_); | ||
71 | static int gpx_final_function(int _type_,const char *text); | ||
72 | static int gpx_step_function(int _type_,const char *text); | ||
73 | static int gpx_name_function(int _type_,const char *text); | ||
74 | static int gpx_desc_function(int _type_,const char *text); | ||
75 | static int gpx_waypoint_function(int _type_,const char *type,const char *string); | ||
76 | static int gpx_route_function(int _type_,const char *type,const char *string); | ||
77 | //static int output_html_function(int _type_); | ||
78 | static int heading_function(int _type_,const char *direction,const char *string); | ||
79 | static int turn_function(int _type_,const char *direction,const char *string); | ||
80 | amb | 361 | |
81 | |||
82 | /* The XML tag definitions */ | ||
83 | |||
84 | /*+ The TurnType type tag. +*/ | ||
85 | static xmltag turn_tag= | ||
86 | {"turn", | ||
87 | 2, {"direction","string"}, | ||
88 | turn_function, | ||
89 | {NULL}}; | ||
90 | |||
91 | /*+ The HeadingType type tag. +*/ | ||
92 | static xmltag heading_tag= | ||
93 | {"heading", | ||
94 | 2, {"direction","string"}, | ||
95 | heading_function, | ||
96 | {NULL}}; | ||
97 | |||
98 | /*+ The HTMLType type tag. +*/ | ||
99 | static xmltag output_html_tag= | ||
100 | {"output-html", | ||
101 | 0, {NULL}, | ||
102 | NULL, | ||
103 | {NULL}}; | ||
104 | |||
105 | /*+ The GPXRouteType type tag. +*/ | ||
106 | static xmltag gpx_route_tag= | ||
107 | {"route", | ||
108 | 2, {"type","string"}, | ||
109 | gpx_route_function, | ||
110 | {NULL}}; | ||
111 | |||
112 | /*+ The GPXWaypointType type tag. +*/ | ||
113 | static xmltag gpx_waypoint_tag= | ||
114 | {"waypoint", | ||
115 | 2, {"type","string"}, | ||
116 | gpx_waypoint_function, | ||
117 | {NULL}}; | ||
118 | |||
119 | /*+ The GPXDescType type tag. +*/ | ||
120 | static xmltag gpx_desc_tag= | ||
121 | {"desc", | ||
122 | 1, {"text"}, | ||
123 | gpx_desc_function, | ||
124 | {NULL}}; | ||
125 | |||
126 | /*+ The GPXNameType type tag. +*/ | ||
127 | static xmltag gpx_name_tag= | ||
128 | {"name", | ||
129 | 1, {"text"}, | ||
130 | gpx_name_function, | ||
131 | {NULL}}; | ||
132 | |||
133 | /*+ The GPXStepType type tag. +*/ | ||
134 | static xmltag gpx_step_tag= | ||
135 | {"step", | ||
136 | 1, {"text"}, | ||
137 | gpx_step_function, | ||
138 | {NULL}}; | ||
139 | |||
140 | /*+ The GPXFinalType type tag. +*/ | ||
141 | static xmltag gpx_final_tag= | ||
142 | {"final", | ||
143 | 1, {"text"}, | ||
144 | gpx_final_function, | ||
145 | {NULL}}; | ||
146 | |||
147 | /*+ The GPXType type tag. +*/ | ||
148 | static xmltag output_gpx_tag= | ||
149 | {"output-gpx", | ||
150 | 0, {NULL}, | ||
151 | NULL, | ||
152 | {&gpx_route_tag,&gpx_waypoint_tag,&gpx_desc_tag,&gpx_name_tag,&gpx_step_tag,&gpx_final_tag,NULL}}; | ||
153 | |||
154 | /*+ The languageType type tag. +*/ | ||
155 | static xmltag language_tag= | ||
156 | {"language", | ||
157 | 1, {"lang"}, | ||
158 | language_function, | ||
159 | {&turn_tag,&heading_tag,&output_html_tag,&output_gpx_tag,NULL}}; | ||
160 | |||
161 | /*+ The RoutinoTranslationsType type tag. +*/ | ||
162 | static xmltag routino_translations_tag= | ||
163 | {"routino-translations", | ||
164 | 0, {NULL}, | ||
165 | NULL, | ||
166 | {&language_tag,NULL}}; | ||
167 | |||
168 | /*+ The xmlType type tag. +*/ | ||
169 | static xmltag xml_tag= | ||
170 | {"xml", | ||
171 | 2, {"version","encoding"}, | ||
172 | NULL, | ||
173 | {NULL}}; | ||
174 | |||
175 | |||
176 | /*+ The complete set of tags at the top level. +*/ | ||
177 | static xmltag *xml_toplevel_tags[]={&xml_tag,&routino_translations_tag,NULL}; | ||
178 | |||
179 | |||
180 | /* The XML tag processing functions */ | ||
181 | |||
182 | |||
183 | /*++++++++++++++++++++++++++++++++++++++ | ||
184 | The function that is called when the TurnType XSD type is seen | ||
185 | |||
186 | amb | 363 | int turn_function Returns 0 if no error occured or something else otherwise. |
187 | |||
188 | amb | 361 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
189 | |||
190 | const char *direction The contents of the 'direction' attribute (or NULL if not defined). | ||
191 | |||
192 | const char *string The contents of the 'string' attribute (or NULL if not defined). | ||
193 | ++++++++++++++++++++++++++++++++++++++*/ | ||
194 | |||
195 | amb | 363 | static int turn_function(int _type_,const char *direction,const char *string) |
196 | amb | 361 | { |
197 | if(_type_&XMLPARSE_TAG_START && store) | ||
198 | { | ||
199 | int d; | ||
200 | |||
201 | amb | 363 | XMLPARSE_ASSERT_INTEGER("turn",direction,d); |
202 | XMLPARSE_ASSERT_STRING("turn",string); | ||
203 | amb | 361 | |
204 | amb | 363 | d+=4; |
205 | amb | 361 | |
206 | if(d<0 || d>8) | ||
207 | amb | 363 | XMLPARSE_INVALID("turn",direction); |
208 | amb | 361 | |
209 | translate_turn[d]=strcpy(malloc(strlen(string)+1),string); | ||
210 | } | ||
211 | amb | 363 | |
212 | return(0); | ||
213 | amb | 361 | } |
214 | |||
215 | |||
216 | /*++++++++++++++++++++++++++++++++++++++ | ||
217 | The function that is called when the HeadingType XSD type is seen | ||
218 | |||
219 | amb | 363 | int heading_function Returns 0 if no error occured or something else otherwise. |
220 | |||
221 | amb | 361 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
222 | |||
223 | const char *direction The contents of the 'direction' attribute (or NULL if not defined). | ||
224 | |||
225 | const char *string The contents of the 'string' attribute (or NULL if not defined). | ||
226 | ++++++++++++++++++++++++++++++++++++++*/ | ||
227 | |||
228 | amb | 363 | static int heading_function(int _type_,const char *direction,const char *string) |
229 | amb | 361 | { |
230 | if(_type_&XMLPARSE_TAG_START && store) | ||
231 | { | ||
232 | int d; | ||
233 | |||
234 | amb | 363 | XMLPARSE_ASSERT_INTEGER("heading",direction,d); |
235 | XMLPARSE_ASSERT_STRING("heading",string); | ||
236 | amb | 361 | |
237 | amb | 363 | d+=4; |
238 | amb | 361 | |
239 | if(d<0 || d>8) | ||
240 | amb | 363 | XMLPARSE_INVALID("heading",direction); |
241 | amb | 361 | |
242 | translate_heading[d]=strcpy(malloc(strlen(string)+1),string); | ||
243 | } | ||
244 | amb | 363 | |
245 | return(0); | ||
246 | amb | 361 | } |
247 | |||
248 | |||
249 | /*++++++++++++++++++++++++++++++++++++++ | ||
250 | amb | 363 | The function that is called when the HTMLType XSD type is seen |
251 | |||
252 | int output_html_function Returns 0 if no error occured or something else otherwise. | ||
253 | |||
254 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
255 | ++++++++++++++++++++++++++++++++++++++*/ | ||
256 | |||
257 | //static int output_html_function(int _type_) | ||
258 | //{ | ||
259 | // return(0); | ||
260 | //} | ||
261 | |||
262 | |||
263 | /*++++++++++++++++++++++++++++++++++++++ | ||
264 | amb | 361 | The function that is called when the GPXRouteType XSD type is seen |
265 | |||
266 | amb | 363 | int gpx_route_function Returns 0 if no error occured or something else otherwise. |
267 | |||
268 | amb | 361 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
269 | |||
270 | const char *type The contents of the 'type' attribute (or NULL if not defined). | ||
271 | |||
272 | const char *string The contents of the 'string' attribute (or NULL if not defined). | ||
273 | ++++++++++++++++++++++++++++++++++++++*/ | ||
274 | |||
275 | amb | 363 | static int gpx_route_function(int _type_,const char *type,const char *string) |
276 | amb | 361 | { |
277 | if(_type_&XMLPARSE_TAG_START && store) | ||
278 | { | ||
279 | amb | 363 | XMLPARSE_ASSERT_STRING("route",type); |
280 | XMLPARSE_ASSERT_STRING("route",string); | ||
281 | amb | 361 | |
282 | if(!strcmp(type,"shortest")) | ||
283 | translate_gpx_shortest=strcpy(malloc(strlen(string)+1),string); | ||
284 | else if(!strcmp(type,"quickest")) | ||
285 | translate_gpx_quickest=strcpy(malloc(strlen(string)+1),string); | ||
286 | else | ||
287 | amb | 363 | XMLPARSE_INVALID("route",type); |
288 | amb | 361 | } |
289 | amb | 363 | |
290 | return(0); | ||
291 | amb | 361 | } |
292 | |||
293 | |||
294 | /*++++++++++++++++++++++++++++++++++++++ | ||
295 | The function that is called when the GPXWaypointType XSD type is seen | ||
296 | |||
297 | amb | 363 | int gpx_waypoint_function Returns 0 if no error occured or something else otherwise. |
298 | |||
299 | amb | 361 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
300 | |||
301 | const char *type The contents of the 'type' attribute (or NULL if not defined). | ||
302 | |||
303 | const char *string The contents of the 'string' attribute (or NULL if not defined). | ||
304 | ++++++++++++++++++++++++++++++++++++++*/ | ||
305 | |||
306 | amb | 363 | static int gpx_waypoint_function(int _type_,const char *type,const char *string) |
307 | amb | 361 | { |
308 | if(_type_&XMLPARSE_TAG_START && store) | ||
309 | { | ||
310 | amb | 363 | XMLPARSE_ASSERT_STRING("waypoint",type); |
311 | XMLPARSE_ASSERT_STRING("waypoint",string); | ||
312 | amb | 361 | |
313 | if(!strcmp(type,"start")) | ||
314 | translate_gpx_start=strcpy(malloc(strlen(string)+1),string); | ||
315 | else if(!strcmp(type,"inter")) | ||
316 | translate_gpx_inter=strcpy(malloc(strlen(string)+1),string); | ||
317 | else if(!strcmp(type,"trip")) | ||
318 | translate_gpx_trip=strcpy(malloc(strlen(string)+1),string); | ||
319 | else if(!strcmp(type,"finish")) | ||
320 | translate_gpx_finish=strcpy(malloc(strlen(string)+1),string); | ||
321 | else | ||
322 | amb | 363 | XMLPARSE_INVALID("waypoint",type); |
323 | amb | 361 | } |
324 | amb | 363 | |
325 | return(0); | ||
326 | amb | 361 | } |
327 | |||
328 | |||
329 | /*++++++++++++++++++++++++++++++++++++++ | ||
330 | The function that is called when the GPXDescType XSD type is seen | ||
331 | |||
332 | amb | 363 | int gpx_desc_function Returns 0 if no error occured or something else otherwise. |
333 | |||
334 | amb | 361 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
335 | |||
336 | const char *text The contents of the 'text' attribute (or NULL if not defined). | ||
337 | ++++++++++++++++++++++++++++++++++++++*/ | ||
338 | |||
339 | amb | 363 | static int gpx_desc_function(int _type_,const char *text) |
340 | amb | 361 | { |
341 | if(_type_&XMLPARSE_TAG_START && store) | ||
342 | { | ||
343 | amb | 363 | XMLPARSE_ASSERT_STRING("desc",text); |
344 | amb | 361 | |
345 | translate_gpx_desc=strcpy(malloc(strlen(text)+1),text); | ||
346 | } | ||
347 | amb | 363 | |
348 | return(0); | ||
349 | amb | 361 | } |
350 | |||
351 | |||
352 | /*++++++++++++++++++++++++++++++++++++++ | ||
353 | The function that is called when the GPXNameType XSD type is seen | ||
354 | |||
355 | amb | 363 | int gpx_name_function Returns 0 if no error occured or something else otherwise. |
356 | |||
357 | amb | 361 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
358 | |||
359 | const char *text The contents of the 'text' attribute (or NULL if not defined). | ||
360 | ++++++++++++++++++++++++++++++++++++++*/ | ||
361 | |||
362 | amb | 363 | static int gpx_name_function(int _type_,const char *text) |
363 | amb | 361 | { |
364 | if(_type_&XMLPARSE_TAG_START && store) | ||
365 | { | ||
366 | amb | 363 | XMLPARSE_ASSERT_STRING("name",text); |
367 | amb | 361 | |
368 | translate_gpx_name=strcpy(malloc(strlen(text)+1),text); | ||
369 | } | ||
370 | amb | 363 | |
371 | return(0); | ||
372 | amb | 361 | } |
373 | |||
374 | |||
375 | /*++++++++++++++++++++++++++++++++++++++ | ||
376 | The function that is called when the GPXStepType XSD type is seen | ||
377 | |||
378 | amb | 363 | int gpx_step_function Returns 0 if no error occured or something else otherwise. |
379 | |||
380 | amb | 361 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
381 | |||
382 | const char *text The contents of the 'text' attribute (or NULL if not defined). | ||
383 | ++++++++++++++++++++++++++++++++++++++*/ | ||
384 | |||
385 | amb | 363 | static int gpx_step_function(int _type_,const char *text) |
386 | amb | 361 | { |
387 | if(_type_&XMLPARSE_TAG_START && store) | ||
388 | { | ||
389 | amb | 363 | XMLPARSE_ASSERT_STRING("step",text); |
390 | amb | 361 | |
391 | translate_gpx_step=strcpy(malloc(strlen(text)+1),text); | ||
392 | } | ||
393 | amb | 363 | |
394 | return(0); | ||
395 | amb | 361 | } |
396 | |||
397 | |||
398 | /*++++++++++++++++++++++++++++++++++++++ | ||
399 | The function that is called when the GPXFinalType XSD type is seen | ||
400 | |||
401 | amb | 363 | int gpx_final_function Returns 0 if no error occured or something else otherwise. |
402 | |||
403 | amb | 361 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
404 | |||
405 | const char *text The contents of the 'text' attribute (or NULL if not defined). | ||
406 | ++++++++++++++++++++++++++++++++++++++*/ | ||
407 | |||
408 | amb | 363 | static int gpx_final_function(int _type_,const char *text) |
409 | amb | 361 | { |
410 | if(_type_&XMLPARSE_TAG_START && store) | ||
411 | { | ||
412 | amb | 363 | XMLPARSE_ASSERT_STRING("final",text); |
413 | amb | 361 | |
414 | translate_gpx_final=strcpy(malloc(strlen(text)+1),text); | ||
415 | } | ||
416 | amb | 363 | |
417 | return(0); | ||
418 | amb | 361 | } |
419 | |||
420 | |||
421 | /*++++++++++++++++++++++++++++++++++++++ | ||
422 | amb | 363 | The function that is called when the GPXType XSD type is seen |
423 | |||
424 | int output_gpx_function Returns 0 if no error occured or something else otherwise. | ||
425 | |||
426 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
427 | ++++++++++++++++++++++++++++++++++++++*/ | ||
428 | |||
429 | //static int output_gpx_function(int _type_) | ||
430 | //{ | ||
431 | // return(0); | ||
432 | //} | ||
433 | |||
434 | |||
435 | /*++++++++++++++++++++++++++++++++++++++ | ||
436 | amb | 361 | The function that is called when the languageType XSD type is seen |
437 | |||
438 | amb | 363 | int language_function Returns 0 if no error occured or something else otherwise. |
439 | |||
440 | amb | 361 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. |
441 | |||
442 | const char *lang The contents of the 'lang' attribute (or NULL if not defined). | ||
443 | ++++++++++++++++++++++++++++++++++++++*/ | ||
444 | |||
445 | amb | 363 | static int language_function(int _type_,const char *lang) |
446 | amb | 361 | { |
447 | static int first=1; | ||
448 | |||
449 | if(_type_&XMLPARSE_TAG_START) | ||
450 | { | ||
451 | amb | 363 | XMLPARSE_ASSERT_STRING("language",lang); |
452 | amb | 361 | |
453 | if(!store_lang && first) | ||
454 | store=1; | ||
455 | else if(!strcmp(store_lang,lang)) | ||
456 | store=1; | ||
457 | else | ||
458 | store=0; | ||
459 | |||
460 | first=0; | ||
461 | } | ||
462 | |||
463 | if(_type_&XMLPARSE_TAG_END && store) | ||
464 | { | ||
465 | store=0; | ||
466 | stored=1; | ||
467 | } | ||
468 | amb | 363 | |
469 | return(0); | ||
470 | amb | 361 | } |
471 | |||
472 | |||
473 | /*++++++++++++++++++++++++++++++++++++++ | ||
474 | amb | 363 | The function that is called when the RoutinoTranslationsType XSD type is seen |
475 | |||
476 | int routino_translations_function Returns 0 if no error occured or something else otherwise. | ||
477 | |||
478 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
479 | ++++++++++++++++++++++++++++++++++++++*/ | ||
480 | |||
481 | //static int routino_translations_function(int _type_) | ||
482 | //{ | ||
483 | // return(0); | ||
484 | //} | ||
485 | |||
486 | |||
487 | /*++++++++++++++++++++++++++++++++++++++ | ||
488 | The function that is called when the xmlType XSD type is seen | ||
489 | |||
490 | int xml_function Returns 0 if no error occured or something else otherwise. | ||
491 | |||
492 | int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. | ||
493 | |||
494 | const char *version The contents of the 'version' attribute (or NULL if not defined). | ||
495 | |||
496 | const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). | ||
497 | ++++++++++++++++++++++++++++++++++++++*/ | ||
498 | |||
499 | //static int xml_function(int _type_,const char *version,const char *encoding) | ||
500 | //{ | ||
501 | // return(0); | ||
502 | //} | ||
503 | |||
504 | |||
505 | /*++++++++++++++++++++++++++++++++++++++ | ||
506 | amb | 361 | The XML translation parser. |
507 | |||
508 | int ParseXMLTranslations Returns 0 if OK or something else in case of an error. | ||
509 | |||
510 | const char *filename The name of the file to read. | ||
511 | |||
512 | const char *language The language to search for (NULL means first in file). | ||
513 | ++++++++++++++++++++++++++++++++++++++*/ | ||
514 | |||
515 | int ParseXMLTranslations(const char *filename,const char *language) | ||
516 | { | ||
517 | int retval; | ||
518 | |||
519 | store_lang=language; | ||
520 | |||
521 | if(!ExistsFile(filename)) | ||
522 | { | ||
523 | fprintf(stderr,"Error: Specified translations file '%s' does not exist.\n",filename); | ||
524 | return(1); | ||
525 | } | ||
526 | |||
527 | FILE *file=fopen(filename,"r"); | ||
528 | |||
529 | if(!file) | ||
530 | { | ||
531 | fprintf(stderr,"Error: Cannot open translations file '%s' for reading.\n",filename); | ||
532 | return(1); | ||
533 | } | ||
534 | |||
535 | retval=ParseXML(file,xml_toplevel_tags,2); | ||
536 | |||
537 | fclose(file); | ||
538 | |||
539 | amb | 363 | if(retval) |
540 | amb | 361 | return(1); |
541 | |||
542 | if(language && !stored) | ||
543 | fprintf(stderr,"Warning: Cannot find translations for language '%s' using English instead.\n",language); | ||
544 | |||
545 | return(0); | ||
546 | } |
Properties
Name | Value |
---|---|
cvs:description | File containing translation parsing functions. |