msi: Add some registry reading macro functions.
[wine/wine-kai.git] / tools / wrc / translation.c
blob4a5fafbbdbb2f723d0faf78a6cf9f6b123782d6c
1 /*
2 * Copyright 2003 Vincent BĂ©ron
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdio.h>
20 #include <stdlib.h>
22 #include "dumpres.h"
23 #include "wrc.h"
25 #define MASTER_LANGUAGE LANG_ENGLISH
26 #define NB_LANG 0x94
28 enum lang_type_e {
29 lang_type_master = 0,
30 lang_type_neutral,
31 lang_type_normal
34 static int present_resources[res_usr+1];
35 static char *res_names[res_usr+1];
36 static int nb_resources[res_usr+1][lang_type_normal+1];
37 static resource_t **list_resources[res_usr+1][lang_type_normal+1];
39 static int get_language_id(resource_t *resource) {
40 switch(resource->type) {
41 case res_acc:
42 return resource->res.acc->lvc.language->id;
43 case res_bmp:
44 return resource->res.bmp->data->lvc.language->id;
45 case res_cur:
46 return resource->res.cur->lvc.language->id;
47 case res_curg:
48 return resource->res.curg->lvc.language->id;
49 case res_dlg:
50 return resource->res.dlg->lvc.language->id;
51 case res_dlgex:
52 return resource->res.dlgex->lvc.language->id;
53 case res_fnt:
54 return resource->res.fnt->data->lvc.language->id;
55 case res_fntdir:
56 return resource->res.fnd->data->lvc.language->id;
57 case res_ico:
58 return resource->res.ico->lvc.language->id;
59 case res_icog:
60 return resource->res.icog->lvc.language->id;
61 case res_men:
62 return resource->res.men->lvc.language->id;
63 case res_menex:
64 return resource->res.menex->lvc.language->id;
65 case res_rdt:
66 return resource->res.rdt->data->lvc.language->id;
67 case res_stt:
68 return resource->res.stt->lvc.language->id;
69 case res_usr:
70 return resource->res.usr->data->lvc.language->id;
71 case res_msg:
72 return resource->res.msg->data->lvc.language->id;
73 case res_ver:
74 return resource->res.ver->lvc.language->id;
75 case res_dlginit:
76 return resource->res.dlgi->data->lvc.language->id;
77 case res_toolbar:
78 return resource->res.tbt->lvc.language->id;
79 case res_anicur:
80 case res_aniico:
81 return resource->res.ani->data->lvc.language->id;
82 default:
83 /* Not supposed to reach here */
84 fprintf(stderr, "Not supposed to reach here (get_language_id())\n");
85 abort();
86 return -1;
90 static void add_resource(resource_t *resource) {
91 enum lang_type_e lang_type;
92 enum res_e res_type = resource->type;
93 int lid = get_language_id(resource);
95 if(lid == MASTER_LANGUAGE) {
96 lang_type = lang_type_master;
97 } else if(lid == LANG_NEUTRAL) {
98 lang_type = lang_type_neutral;
99 } else {
100 lang_type = lang_type_normal;
102 nb_resources[res_type][lang_type]++;
103 list_resources[res_type][lang_type] = realloc(list_resources[res_type][lang_type], nb_resources[res_type][lang_type]*sizeof(resource_t *));
104 list_resources[res_type][lang_type][nb_resources[res_type][lang_type]-1] = resource;
107 #if 0
109 #define PRETTYPRINTLANG(langid) \
110 if(LANG_##langid == lid) { \
111 return #langid; \
114 static const char *get_language_name(int lid) {
115 PRETTYPRINTLANG(NEUTRAL)
116 PRETTYPRINTLANG(AFRIKAANS)
117 PRETTYPRINTLANG(ALBANIAN)
118 PRETTYPRINTLANG(ARABIC)
119 PRETTYPRINTLANG(ARMENIAN)
120 PRETTYPRINTLANG(ASSAMESE)
121 PRETTYPRINTLANG(AZERI)
122 PRETTYPRINTLANG(BASQUE)
123 PRETTYPRINTLANG(BELARUSIAN)
124 PRETTYPRINTLANG(BENGALI)
125 PRETTYPRINTLANG(BULGARIAN)
126 PRETTYPRINTLANG(CATALAN)
127 PRETTYPRINTLANG(CHINESE)
128 PRETTYPRINTLANG(CROATIAN)
129 PRETTYPRINTLANG(CZECH)
130 PRETTYPRINTLANG(DANISH)
131 PRETTYPRINTLANG(DIVEHI)
132 PRETTYPRINTLANG(DUTCH)
133 PRETTYPRINTLANG(ENGLISH)
134 PRETTYPRINTLANG(ESTONIAN)
135 PRETTYPRINTLANG(FAEROESE)
136 PRETTYPRINTLANG(FARSI)
137 PRETTYPRINTLANG(FINNISH)
138 PRETTYPRINTLANG(FRENCH)
139 PRETTYPRINTLANG(GALICIAN)
140 PRETTYPRINTLANG(GEORGIAN)
141 PRETTYPRINTLANG(GERMAN)
142 PRETTYPRINTLANG(GREEK)
143 PRETTYPRINTLANG(GUJARATI)
144 PRETTYPRINTLANG(HEBREW)
145 PRETTYPRINTLANG(HINDI)
146 PRETTYPRINTLANG(HUNGARIAN)
147 PRETTYPRINTLANG(ICELANDIC)
148 PRETTYPRINTLANG(INDONESIAN)
149 PRETTYPRINTLANG(ITALIAN)
150 PRETTYPRINTLANG(JAPANESE)
151 PRETTYPRINTLANG(KANNADA)
152 PRETTYPRINTLANG(KASHMIRI)
153 PRETTYPRINTLANG(KAZAK)
154 PRETTYPRINTLANG(KONKANI)
155 PRETTYPRINTLANG(KOREAN)
156 PRETTYPRINTLANG(KYRGYZ)
157 PRETTYPRINTLANG(LATVIAN)
158 PRETTYPRINTLANG(LITHUANIAN)
159 PRETTYPRINTLANG(MACEDONIAN)
160 PRETTYPRINTLANG(MALAY)
161 PRETTYPRINTLANG(MALAYALAM)
162 PRETTYPRINTLANG(MANIPURI)
163 PRETTYPRINTLANG(MARATHI)
164 PRETTYPRINTLANG(MONGOLIAN)
165 PRETTYPRINTLANG(NEPALI)
166 PRETTYPRINTLANG(NORWEGIAN)
167 PRETTYPRINTLANG(ORIYA)
168 PRETTYPRINTLANG(POLISH)
169 PRETTYPRINTLANG(PORTUGUESE)
170 PRETTYPRINTLANG(PUNJABI)
171 PRETTYPRINTLANG(ROMANIAN)
172 PRETTYPRINTLANG(RUSSIAN)
173 PRETTYPRINTLANG(SANSKRIT)
174 PRETTYPRINTLANG(SERBIAN)
175 PRETTYPRINTLANG(SINDHI)
176 PRETTYPRINTLANG(SLOVAK)
177 PRETTYPRINTLANG(SLOVENIAN)
178 PRETTYPRINTLANG(SPANISH)
179 PRETTYPRINTLANG(SWAHILI)
180 PRETTYPRINTLANG(SWEDISH)
181 PRETTYPRINTLANG(SYRIAC)
182 PRETTYPRINTLANG(TAMIL)
183 PRETTYPRINTLANG(TATAR)
184 PRETTYPRINTLANG(TELUGU)
185 PRETTYPRINTLANG(THAI)
186 PRETTYPRINTLANG(TURKISH)
187 PRETTYPRINTLANG(UKRAINIAN)
188 PRETTYPRINTLANG(URDU)
189 PRETTYPRINTLANG(UZBEK)
190 PRETTYPRINTLANG(VIETNAMESE)
191 PRETTYPRINTLANG(GAELIC)
192 PRETTYPRINTLANG(MALTESE)
193 PRETTYPRINTLANG(MAORI)
194 PRETTYPRINTLANG(RHAETO_ROMANCE)
195 PRETTYPRINTLANG(SAAMI)
196 PRETTYPRINTLANG(SORBIAN)
197 PRETTYPRINTLANG(SUTU)
198 PRETTYPRINTLANG(TSONGA)
199 PRETTYPRINTLANG(TSWANA)
200 PRETTYPRINTLANG(VENDA)
201 PRETTYPRINTLANG(XHOSA)
202 PRETTYPRINTLANG(ZULU)
203 PRETTYPRINTLANG(ESPERANTO)
204 PRETTYPRINTLANG(WALON)
205 PRETTYPRINTLANG(CORNISH)
206 PRETTYPRINTLANG(WELSH)
207 PRETTYPRINTLANG(BRETON)
208 return "Unknown language";
210 #endif
212 static int compare_accelerator(accelerator_t *accelerator1, accelerator_t *accelerator2) {
213 int different = 0;
214 event_t *ev1 = NULL, *ev2 = NULL;
215 if(!different &&
216 ((accelerator1->memopt != accelerator2->memopt) ||
217 (accelerator1->lvc.version != accelerator2->lvc.version) ||
218 (accelerator1->lvc.characts != accelerator2->lvc.characts)))
219 different = 1;
220 ev1 = accelerator1->events;
221 ev2 = accelerator2->events;
222 while(!different && ev1 && ev2) {
223 if(!different &&
224 ((ev1->id != ev2->id) ||
225 (ev1->flags != ev2->flags)))
226 different = 1;
227 ev1 = ev1->next;
228 ev2 = ev2->next;
230 if(!different &&
231 ((ev1 && !ev2) || (!ev1 && ev2)))
232 different = 1;
233 return different;
236 static int compare_bitmap(bitmap_t *bitmap1, bitmap_t *bitmap2) {
237 int different = 0;
238 if(!different &&
239 ((bitmap1->memopt != bitmap2->memopt) ||
240 (bitmap1->data->lvc.version != bitmap2->data->lvc.version) ||
241 (bitmap1->data->lvc.characts != bitmap2->data->lvc.characts)))
242 different = 1;
243 return different;
246 static int compare_cursor(cursor_t *cursor1, cursor_t *cursor2) {
247 int different = 0;
248 if(!different &&
249 ((cursor1->id != cursor2->id) ||
250 (cursor1->width != cursor2->width) ||
251 (cursor1->height != cursor2->height) ||
252 (cursor1->xhot != cursor2->xhot) ||
253 (cursor1->yhot != cursor2->yhot)))
254 different = 1;
255 if(!different &&
256 ((cursor1->lvc.version != cursor2->lvc.version) ||
257 (cursor1->lvc.characts != cursor2->lvc.characts)))
258 different = 1;
259 return different;
262 static int compare_cursor_group(cursor_group_t *cursor_group1, cursor_group_t *cursor_group2) {
263 int different = 0;
264 cursor_t *cursor1 = NULL, *cursor2 = NULL;
265 if(!different &&
266 ((cursor_group1->memopt != cursor_group2->memopt) ||
267 (cursor_group1->lvc.version != cursor_group2->lvc.version) ||
268 (cursor_group1->lvc.characts != cursor_group2->lvc.characts)))
269 different = 1;
270 if(!different &&
271 (cursor_group1->ncursor != cursor_group2->ncursor))
272 different = 1;
273 if(!different) {
274 cursor1 = cursor_group1->cursorlist;
275 cursor2 = cursor_group2->cursorlist;
276 while(!different && cursor1 && cursor2) {
277 different = compare_cursor(cursor1, cursor2);
278 cursor1 = cursor1->next;
279 cursor2 = cursor2->next;
281 if(!different &&
282 ((cursor1 && !cursor2) ||
283 (!cursor1 && cursor2)))
284 different = 1;
286 return different;
289 static int compare_control(control_t *control1, control_t *control2) {
290 int different = 0;
291 char *nameid = NULL;
292 if(!different &&
293 ((control1 && !control2) ||
294 (!control1 && control2)))
295 different = 1;
296 if(different || !control1 || !control2)
297 return different;
298 nameid = strdup(get_nameid_str(control1->ctlclass));
299 if(!different && strcmp(nameid, get_nameid_str(control2->ctlclass)))
300 different = 1;
301 free(nameid);
302 if(!different &&
303 (control1->id != control2->id))
304 different = 1;
305 if(!different && control1->gotstyle && control2->gotstyle) {
306 if((!control1->style || !control2->style) ||
307 (control1->style->and_mask || control2->style->and_mask) ||
308 (control1->style->or_mask != control2->style->or_mask))
309 different = 1;
310 } else if(!different &&
311 ((control1->gotstyle && !control2->gotstyle) ||
312 (!control1->gotstyle && control2->gotstyle)))
313 different = 1;
314 if(!different && control1->gotexstyle && control2->gotexstyle) {
315 if((!control1->exstyle || !control2->exstyle) ||
316 (control1->exstyle->and_mask || control2->exstyle->and_mask) ||
317 (control1->exstyle->or_mask != control2->exstyle->or_mask))
318 different = 1;
319 } else if(!different &&
320 ((control1->gotexstyle && !control2->gotexstyle) ||
321 (!control1->gotexstyle && control2->gotexstyle)))
322 different = 1;
323 if(!different && control1->gothelpid && control2->gothelpid) {
324 if(control1->helpid != control2->helpid)
325 different = 1;
326 } else if(!different &&
327 ((control1->gothelpid && !control2->gothelpid) ||
328 (!control1->gothelpid && control2->gothelpid)))
329 different = 1;
330 return different;
333 static int compare_dialog(dialog_t *dialog1, dialog_t *dialog2) {
334 int different = 0;
335 char *nameid = NULL;
336 if(!different &&
337 ((dialog1->memopt != dialog2->memopt) ||
338 (dialog1->lvc.version != dialog2->lvc.version) ||
339 (dialog1->lvc.characts != dialog2->lvc.characts)))
340 different = 1;
341 if(!different && dialog1->gotstyle && dialog2->gotstyle) {
342 if((!dialog1->style || !dialog2->style) ||
343 (dialog1->style->and_mask || dialog2->style->and_mask) ||
344 (dialog1->style->or_mask != dialog2->style->or_mask))
345 different = 1;
346 } else if(!different &&
347 ((dialog1->gotstyle && !dialog2->gotstyle) ||
348 (!dialog1->gotstyle && dialog2->gotstyle)))
349 different = 1;
350 if(!different && dialog1->gotexstyle && dialog2->gotexstyle) {
351 if((!dialog1->exstyle || !dialog2->exstyle) ||
352 (dialog1->exstyle->and_mask || dialog2->exstyle->and_mask) ||
353 (dialog1->exstyle->or_mask != dialog2->exstyle->or_mask))
354 different = 1;
355 } else if(!different &&
356 ((dialog1->gotexstyle && !dialog2->gotexstyle) ||
357 (!dialog1->gotexstyle && dialog2->gotexstyle)))
358 different = 1;
359 nameid = strdup(get_nameid_str(dialog1->menu));
360 if(!different && strcmp(nameid, get_nameid_str(dialog2->menu)))
361 different = 1;
362 free(nameid);
363 nameid = strdup(get_nameid_str(dialog1->dlgclass));
364 if(!different && strcmp(nameid, get_nameid_str(dialog2->dlgclass)))
365 different = 1;
366 free(nameid);
367 if(!different)
368 different = compare_control(dialog1->controls, dialog2->controls);
369 return different;
372 static int compare_dialogex(dialogex_t *dialogex1, dialogex_t *dialogex2) {
373 int different = 0;
374 char *nameid = NULL;
375 if(!different &&
376 ((dialogex1->memopt != dialogex2->memopt) ||
377 (dialogex1->lvc.version != dialogex2->lvc.version) ||
378 (dialogex1->lvc.characts != dialogex2->lvc.characts)))
379 different = 1;
380 if(!different && dialogex1->gotstyle && dialogex2->gotstyle) {
381 if((!dialogex1->style || !dialogex2->style) ||
382 (dialogex1->style->and_mask || dialogex2->style->and_mask) ||
383 (dialogex1->style->or_mask != dialogex2->style->or_mask))
384 different = 1;
385 } else if(!different &&
386 ((dialogex1->gotstyle && !dialogex2->gotstyle) ||
387 (!dialogex1->gotstyle && dialogex2->gotstyle)))
388 different = 1;
389 if(!different && dialogex1->gotexstyle && dialogex2->gotexstyle) {
390 if((!dialogex1->exstyle || !dialogex2->exstyle) ||
391 (dialogex1->exstyle->and_mask || dialogex2->exstyle->and_mask) ||
392 (dialogex1->exstyle->or_mask != dialogex2->exstyle->or_mask))
393 different = 1;
394 } else if(!different &&
395 ((dialogex1->gotexstyle && !dialogex2->gotexstyle) ||
396 (!dialogex1->gotexstyle && dialogex2->gotexstyle)))
397 different = 1;
398 if(!different && dialogex1->gothelpid && dialogex2->gothelpid) {
399 if(dialogex1->helpid != dialogex2->helpid)
400 different = 1;
401 } else if(!different &&
402 ((dialogex1->gothelpid && !dialogex2->gothelpid) ||
403 (!dialogex1->gothelpid && dialogex2->gothelpid)))
404 different = 1;
405 nameid = strdup(get_nameid_str(dialogex1->menu));
406 if(!different && strcmp(nameid, get_nameid_str(dialogex2->menu)))
407 different = 1;
408 free(nameid);
409 nameid = strdup(get_nameid_str(dialogex1->dlgclass));
410 if(!different && strcmp(nameid, get_nameid_str(dialogex2->dlgclass)))
411 different = 1;
412 free(nameid);
413 if(!different)
414 different = compare_control(dialogex1->controls, dialogex2->controls);
415 return different;
418 static int compare_font(font_t *font1, font_t *font2) {
419 int different = 0;
420 if(!different &&
421 ((font1->memopt != font2->memopt) ||
422 (font1->data->lvc.version != font2->data->lvc.version) ||
423 (font1->data->lvc.characts != font2->data->lvc.characts)))
424 different = 1;
425 return different;
428 static int compare_fontdir(fontdir_t *fontdir1, fontdir_t *fontdir2) {
429 int different = 0;
430 if(!different &&
431 ((fontdir1->memopt != fontdir2->memopt) ||
432 (fontdir1->data->lvc.version != fontdir2->data->lvc.version) ||
433 (fontdir1->data->lvc.characts != fontdir2->data->lvc.characts)))
434 different = 1;
435 return different;
438 static int compare_icon(icon_t *icon1, icon_t *icon2) {
439 int different = 0;
440 if(!different &&
441 ((icon1->id != icon2->id) ||
442 (icon1->width != icon2->width) ||
443 (icon1->height != icon2->height)))
444 different = 1;
445 if(!different &&
446 ((icon1->lvc.version != icon2->lvc.version) ||
447 (icon1->lvc.characts != icon2->lvc.characts)))
448 different = 1;
449 return different;
452 static int compare_icon_group(icon_group_t *icon_group1, icon_group_t *icon_group2) {
453 int different = 0;
454 icon_t *icon1 = NULL, *icon2 = NULL;
455 if(!different &&
456 ((icon_group1->memopt != icon_group2->memopt) ||
457 (icon_group1->lvc.version != icon_group2->lvc.version) ||
458 (icon_group1->lvc.characts != icon_group2->lvc.characts)))
459 different = 1;
460 if(!different &&
461 (icon_group1->nicon != icon_group2->nicon))
462 different = 1;
463 if(!different) {
464 icon1 = icon_group1->iconlist;
465 icon2 = icon_group2->iconlist;
466 while(!different && icon1 && icon2) {
467 different = compare_icon(icon1, icon2);
468 icon1 = icon1->next;
469 icon2 = icon2->next;
471 if(!different &&
472 ((icon1 && !icon2) ||
473 (!icon1 && icon2)))
474 different = 1;
476 return different;
479 static int compare_menu_item(menu_item_t *menu_item1, menu_item_t *menu_item2) {
480 int different = 0;
481 while(!different && menu_item1 && menu_item2) {
482 if(menu_item1->popup && menu_item2->popup)
483 different = compare_menu_item(menu_item1->popup, menu_item2->popup);
484 else if(!menu_item1->popup && !menu_item2->popup) {
485 if(menu_item1->name && menu_item2->name) {
486 if((menu_item1->id != menu_item2->id) ||
487 (menu_item1->state != menu_item2->state))
488 different = 1;
489 } else if((menu_item1->name && !menu_item2->name) ||
490 (!menu_item1->name && menu_item2->name))
491 different = 1;
492 } else
493 different = 1;
494 menu_item1 = menu_item1->next;
495 menu_item2 = menu_item2->next;
497 if(!different &&
498 ((menu_item1 && !menu_item2) ||
499 (!menu_item1 && menu_item2)))
500 different = 1;
501 return different;
504 static int compare_menu(menu_t *menu1, menu_t *menu2) {
505 int different = 0;
506 if(!different &&
507 ((menu1->memopt != menu2->memopt) ||
508 (menu1->lvc.version != menu2->lvc.version) ||
509 (menu1->lvc.characts != menu2->lvc.characts)))
510 different = 1;
511 if(!different)
512 different = compare_menu_item(menu1->items, menu2->items);
513 return different;
516 static int compare_menuex_item(menuex_item_t *menuex_item1, menuex_item_t *menuex_item2) {
517 int different = 0;
518 while(!different && menuex_item1 && menuex_item2) {
519 if(menuex_item1->popup && menuex_item2->popup) {
520 if(!different && menuex_item1->gotid && menuex_item2->gotid) {
521 if(menuex_item1->id != menuex_item2->id)
522 different = 1;
523 } else if(!different &&
524 ((menuex_item1->gotid && !menuex_item2->gotid) ||
525 (!menuex_item2->gotid && menuex_item2->gotid)))
526 different = 1;
527 if(!different && menuex_item1->gottype && menuex_item2->gottype) {
528 if(menuex_item1->type != menuex_item2->type)
529 different = 1;
530 } else if(!different &&
531 ((menuex_item1->gottype && !menuex_item2->gottype) ||
532 (!menuex_item2->gottype && menuex_item2->gottype)))
533 different = 1;
534 if(!different && menuex_item1->gotstate && menuex_item2->gotstate) {
535 if(menuex_item1->state != menuex_item2->state)
536 different = 1;
537 } else if(!different &&
538 ((menuex_item1->gotstate && !menuex_item2->gotstate) ||
539 (!menuex_item2->gotstate && menuex_item2->gotstate)))
540 different = 1;
541 if(!different && menuex_item1->gothelpid && menuex_item2->gothelpid) {
542 if(menuex_item1->helpid != menuex_item2->helpid)
543 different = 1;
544 } else if(!different &&
545 ((menuex_item1->gothelpid && !menuex_item2->gothelpid) ||
546 (!menuex_item2->gothelpid && menuex_item2->gothelpid)))
547 different = 1;
548 if(!different)
549 different = compare_menuex_item(menuex_item1->popup, menuex_item2->popup);
550 } else if(!menuex_item1->popup && !menuex_item2->popup) {
551 if(menuex_item1->name && menuex_item2->name) {
552 if(!different && menuex_item1->gotid && menuex_item2->gotid) {
553 if(menuex_item1->id != menuex_item2->id)
554 different = 1;
555 } else if(!different &&
556 ((menuex_item1->gotid && !menuex_item2->gotid) ||
557 (!menuex_item2->gotid && menuex_item2->gotid)))
558 different = 1;
559 if(!different && menuex_item1->gottype && menuex_item2->gottype) {
560 if(menuex_item1->type != menuex_item2->type)
561 different = 1;
562 } else if(!different &&
563 ((menuex_item1->gottype && !menuex_item2->gottype) ||
564 (!menuex_item2->gottype && menuex_item2->gottype)))
565 different = 1;
566 if(!different && menuex_item1->gotstate && menuex_item2->gotstate) {
567 if(menuex_item1->state != menuex_item2->state)
568 different = 1;
569 } else if(!different &&
570 ((menuex_item1->gotstate && !menuex_item2->gotstate) ||
571 (!menuex_item2->gotstate && menuex_item2->gotstate)))
572 different = 1;
573 if(!different && menuex_item1->gothelpid && menuex_item2->gothelpid) {
574 if(menuex_item1->helpid != menuex_item2->helpid)
575 different = 1;
576 } else if(!different &&
577 ((menuex_item1->gothelpid && !menuex_item2->gothelpid) ||
578 (!menuex_item2->gothelpid && menuex_item2->gothelpid)))
579 different = 1;
580 } else if((menuex_item1->name && !menuex_item2->name) ||
581 (!menuex_item1->name && menuex_item2->name))
582 different = 1;
583 } else
584 different = 1;
585 menuex_item1 = menuex_item1->next;
586 menuex_item2 = menuex_item2->next;
588 if(!different &&
589 ((menuex_item1 && !menuex_item2) ||
590 (!menuex_item1 && menuex_item2)))
591 different = 1;
592 return different;
595 static int compare_menuex(menuex_t *menuex1, menuex_t *menuex2) {
596 int different = 0;
597 if(!different &&
598 ((menuex1->memopt != menuex2->memopt) ||
599 (menuex1->lvc.version != menuex2->lvc.version) ||
600 (menuex1->lvc.characts != menuex2->lvc.characts)))
601 different = 1;
602 if(!different)
603 different = compare_menuex_item(menuex1->items, menuex2->items);
604 return different;
607 static int compare_rcdata(rcdata_t *rcdata1, rcdata_t *rcdata2) {
608 int different = 0;
609 if(!different &&
610 ((rcdata1->memopt != rcdata2->memopt) ||
611 (rcdata1->data->lvc.version != rcdata2->data->lvc.version) ||
612 (rcdata1->data->lvc.characts != rcdata2->data->lvc.characts)))
613 different = 1;
614 return different;
617 static int compare_stringtable(stringtable_t *stringtable1, stringtable_t *stringtable2) {
618 int different = 0;
619 int i;
620 while(!different && stringtable1 && stringtable2) {
621 if((stringtable1->memopt != stringtable2->memopt) ||
622 (stringtable1->lvc.version != stringtable2->lvc.version) ||
623 (stringtable1->lvc.characts != stringtable2->lvc.characts))
624 different = 1;
625 if(!different) {
626 if((stringtable1->nentries != stringtable2->nentries) ||
627 (stringtable1->idbase != stringtable2->idbase))
628 different = 1;
629 else
630 for(i = 0 ; i < stringtable1->nentries; i++)
631 if((stringtable1->entries[i].id != stringtable2->entries[i].id) ||
632 (stringtable1->entries[i].memopt != stringtable2->entries[i].memopt) ||
633 (stringtable1->entries[i].str && !stringtable2->entries[i].str) ||
634 (!stringtable1->entries[i].str && stringtable2->entries[i].str)) {
635 different = 1;
636 break;
639 stringtable1 = stringtable1->next;
640 stringtable2 = stringtable2->next;
642 return different;
645 static int compare_user(user_t *user1, user_t *user2) {
646 int different = 0;
647 char *nameid = NULL;
648 if(!different &&
649 ((user1->memopt != user2->memopt) ||
650 (user1->data->lvc.version != user2->data->lvc.version) ||
651 (user1->data->lvc.characts != user2->data->lvc.characts)))
652 different = 1;
653 nameid = strdup(get_nameid_str(user1->type));
654 if(!different && strcmp(nameid, get_nameid_str(user2->type)))
655 different = 1;
656 free(nameid);
657 return different;
660 static int compare_messagetable(messagetable_t *messagetable1, messagetable_t *messagetable2) {
661 int different = 0;
662 if(!different &&
663 ((messagetable1->memopt != messagetable2->memopt) ||
664 (messagetable1->data->lvc.version != messagetable2->data->lvc.version) ||
665 (messagetable1->data->lvc.characts != messagetable2->data->lvc.characts)))
666 different = 1;
667 return different;
670 static int compare_string(string_t *string1, string_t *string2) {
671 int different = 0;
672 if(!different &&
673 ((string1->size != string2->size) ||
674 (string1->type != string2->type)))
675 different = 1;
676 if(!different) {
677 if(string1->type == str_char)
678 different = memcmp(string1->str.cstr, string2->str.cstr, string1->size);
679 else if(string1->type == str_unicode)
680 different = memcmp(string1->str.wstr, string2->str.wstr, string1->size*sizeof(WCHAR));
681 else
682 different = 1;
684 return different;
687 static int compare_ver_block(ver_block_t *ver_block1, ver_block_t *ver_block2);
689 static int compare_ver_value(ver_value_t *ver_value1, ver_value_t *ver_value2) {
690 int different = 0;
691 int i = 0;
692 if(!different &&
693 (ver_value1->type == ver_value2->type)) {
694 switch(ver_value1->type) {
695 case val_str:
696 if(!different && ver_value1->key && ver_value2->key)
697 different = compare_string(ver_value1->key, ver_value2->key);
698 else if(!different &&
699 ((ver_value1->key && !ver_value2->key) ||
700 (!ver_value1->key && ver_value2->key)))
701 different = 1;
702 break;
703 case val_words:
704 if(!different && ver_value1->key && ver_value2->key)
705 different = compare_string(ver_value1->key, ver_value2->key);
706 else if(!different &&
707 ((ver_value1->key && !ver_value2->key) ||
708 (!ver_value1->key && ver_value2->key)))
709 different = 1;
710 if(!different && ver_value1->value.words && ver_value2->value.words) {
711 if(!different &&
712 (ver_value1->value.words->nwords != ver_value2->value.words->nwords))
713 different = 1;
714 if(!different)
715 for(i = 0; i < ver_value1->value.words->nwords; i++) {
716 if(ver_value1->value.words->words[i] != ver_value2->value.words->words[i]) {
717 different = 1;
718 break;
721 } else if(!different &&
722 ((ver_value1->value.words && !ver_value2->value.words) ||
723 (!ver_value1->value.words && ver_value2->value.words)))
724 different = 1;
725 break;
726 case val_block:
727 if(!different && ver_value1->value.block && ver_value2->value.block)
728 different = compare_ver_block(ver_value1->value.block, ver_value2->value.block);
729 else if(!different &&
730 ((ver_value1->value.block && !ver_value2->value.block) ||
731 (!ver_value1->value.block && ver_value2->value.block)))
732 different = 1;
733 break;
734 default:
735 different = 1;
737 } else
738 different = 1;
739 return different;
742 static int compare_ver_block(ver_block_t *ver_block1, ver_block_t *ver_block2) {
743 int different = 0;
744 ver_value_t *ver_value1 = NULL, *ver_value2 = NULL;
745 if(!different) {
746 ver_value1 = ver_block1->values;
747 ver_value2 = ver_block2->values;
748 while(!different && ver_value1 && ver_value2) {
749 different = compare_ver_value(ver_value1, ver_value2);
750 ver_value1 = ver_value1->next;
751 ver_value2 = ver_value2->next;
753 if(!different &&
754 ((ver_value1 && !ver_value2) ||
755 (!ver_value1 && ver_value2)))
756 different = 1;
758 return different;
761 static int compare_versioninfo(versioninfo_t *versioninfo1, versioninfo_t *versioninfo2) {
762 int different = 0;
763 ver_block_t *ver_block1 = NULL, *ver_block2 = NULL;
764 if(!different &&
765 ((versioninfo1->memopt != versioninfo2->memopt) ||
766 (versioninfo1->lvc.version != versioninfo2->lvc.version) ||
767 (versioninfo1->lvc.characts != versioninfo2->lvc.characts)))
768 different = 1;
769 if(!different && versioninfo1->gotit.fv && versioninfo2->gotit.fv) {
770 if((versioninfo1->filever_maj1 != versioninfo2->filever_maj1) ||
771 (versioninfo1->filever_maj2 != versioninfo2->filever_maj2) ||
772 (versioninfo1->filever_min1 != versioninfo2->filever_min1) ||
773 (versioninfo1->filever_min2 != versioninfo2->filever_min2))
774 different = 1;
775 } else if(!different &&
776 ((versioninfo1->gotit.fv && !versioninfo2->gotit.fv) ||
777 (!versioninfo1->gotit.fv && versioninfo2->gotit.fv)))
778 different = 1;
779 if(!different && versioninfo1->gotit.pv && versioninfo2->gotit.pv) {
780 if((versioninfo1->prodver_maj1 != versioninfo2->prodver_maj1) ||
781 (versioninfo1->prodver_maj2 != versioninfo2->prodver_maj2) ||
782 (versioninfo1->prodver_min1 != versioninfo2->prodver_min1) ||
783 (versioninfo1->prodver_min2 != versioninfo2->prodver_min2))
784 different = 1;
785 } else if(!different &&
786 ((versioninfo1->gotit.pv && !versioninfo2->gotit.pv) ||
787 (!versioninfo1->gotit.pv && versioninfo2->gotit.pv)))
788 different = 1;
789 if(!different && versioninfo1->gotit.fo && versioninfo2->gotit.fo) {
790 if(versioninfo1->fileos != versioninfo2->fileos)
791 different = 1;
792 } else if(!different &&
793 ((versioninfo1->gotit.fo && !versioninfo2->gotit.fo) ||
794 (!versioninfo1->gotit.fo && versioninfo2->gotit.fo)))
795 different = 1;
796 if(!different && versioninfo1->gotit.ff && versioninfo2->gotit.ff) {
797 if(versioninfo1->fileflags != versioninfo2->fileflags)
798 different = 1;
799 } else if(!different &&
800 ((versioninfo1->gotit.ff && !versioninfo2->gotit.ff) ||
801 (!versioninfo1->gotit.ff && versioninfo2->gotit.ff)))
802 different = 1;
803 if(!different && versioninfo1->gotit.ffm && versioninfo2->gotit.ffm) {
804 if(versioninfo1->fileflagsmask != versioninfo2->fileflagsmask)
805 different = 1;
806 } else if(!different &&
807 ((versioninfo1->gotit.ffm && !versioninfo2->gotit.ffm) ||
808 (!versioninfo1->gotit.ffm && versioninfo2->gotit.ffm)))
809 different = 1;
810 if(!different && versioninfo1->gotit.ft && versioninfo2->gotit.ft) {
811 if(versioninfo1->filetype != versioninfo2->filetype)
812 different = 1;
813 } else if(!different &&
814 ((versioninfo1->gotit.ft && !versioninfo2->gotit.ft) ||
815 (!versioninfo1->gotit.ft && versioninfo2->gotit.ft)))
816 different = 1;
817 if(!different && versioninfo1->gotit.fst && versioninfo2->gotit.fst) {
818 if(versioninfo1->filesubtype != versioninfo2->filesubtype)
819 different = 1;
820 } else if(!different &&
821 ((versioninfo1->gotit.fst && !versioninfo2->gotit.fst) ||
822 (!versioninfo1->gotit.fst && versioninfo2->gotit.fst)))
823 different = 1;
824 if(!different) {
825 ver_block1 = versioninfo1->blocks;
826 ver_block2 = versioninfo2->blocks;
827 while(!different && ver_block1 && ver_block2) {
828 different = compare_ver_block(ver_block1, ver_block2);
829 ver_block1 = ver_block1->next;
830 ver_block2 = ver_block2->next;
832 if(!different &&
833 ((ver_block1 && !ver_block2) ||
834 (ver_block1 && !ver_block2)))
835 different = 1;
837 return different;
840 static int compare_dlginit(dlginit_t *dlginit1, dlginit_t *dlginit2) {
841 int different = 0;
842 if(!different &&
843 ((dlginit1->memopt != dlginit2->memopt) ||
844 (dlginit1->data->lvc.version != dlginit2->data->lvc.version) ||
845 (dlginit1->data->lvc.characts != dlginit2->data->lvc.characts)))
846 different = 1;
847 return different;
850 static int compare_toolbar_item(toolbar_item_t *toolbar_item1, toolbar_item_t *toolbar_item2) {
851 int different = 0;
852 while(!different && toolbar_item1 && toolbar_item2) {
853 if((toolbar_item1->id && !toolbar_item2->id) ||
854 (!toolbar_item1->id && toolbar_item2->id))
855 different = 1;
856 toolbar_item1 = toolbar_item1->next;
857 toolbar_item2 = toolbar_item2->next;
859 if(!different &&
860 ((toolbar_item1 && !toolbar_item2) ||
861 (!toolbar_item1 && toolbar_item2)))
862 different = 1;
863 return different;
866 static int compare_toolbar(toolbar_t *toolbar1, toolbar_t *toolbar2) {
867 int different = 0;
868 if(!different &&
869 ((toolbar1->memopt != toolbar2->memopt) ||
870 (toolbar1->lvc.version != toolbar2->lvc.version) ||
871 (toolbar1->lvc.characts != toolbar2->lvc.characts)))
872 different = 1;
873 if(!different)
874 different = compare_toolbar_item(toolbar1->items, toolbar2->items);
875 return different;
878 static int compare_ani_curico(ani_curico_t *ani_curico1, ani_curico_t *ani_curico2) {
879 int different = 0;
880 if(!different &&
881 ((ani_curico1->memopt != ani_curico2->memopt) ||
882 (ani_curico1->data->lvc.version != ani_curico2->data->lvc.version) ||
883 (ani_curico1->data->lvc.characts != ani_curico2->data->lvc.characts)))
884 different = 1;
885 return different;
888 static int compare(resource_t *resource1, resource_t *resource2) {
889 switch(resource1->type) {
890 case res_acc:
891 return compare_accelerator(resource1->res.acc, resource2->res.acc);
892 case res_bmp:
893 return compare_bitmap(resource1->res.bmp, resource2->res.bmp);
894 case res_cur:
895 return compare_cursor(resource1->res.cur, resource2->res.cur);
896 case res_curg:
897 return compare_cursor_group(resource1->res.curg, resource2->res.curg);
898 case res_dlg:
899 return compare_dialog(resource1->res.dlg, resource2->res.dlg);
900 case res_dlgex:
901 return compare_dialogex(resource1->res.dlgex, resource2->res.dlgex);
902 case res_fnt:
903 return compare_font(resource1->res.fnt, resource2->res.fnt);
904 case res_fntdir:
905 return compare_fontdir(resource1->res.fnd, resource2->res.fnd);
906 case res_ico:
907 return compare_icon(resource1->res.ico, resource2->res.ico);
908 case res_icog:
909 return compare_icon_group(resource1->res.icog, resource2->res.icog);
910 case res_men:
911 return compare_menu(resource1->res.men, resource2->res.men);
912 case res_menex:
913 return compare_menuex(resource1->res.menex, resource2->res.menex);
914 case res_rdt:
915 return compare_rcdata(resource1->res.rdt, resource2->res.rdt);
916 case res_stt:
917 return compare_stringtable(resource1->res.stt, resource2->res.stt);
918 case res_usr:
919 return compare_user(resource1->res.usr, resource2->res.usr);
920 case res_msg:
921 return compare_messagetable(resource1->res.msg, resource2->res.msg);
922 case res_ver:
923 return compare_versioninfo(resource1->res.ver, resource2->res.ver);
924 case res_dlginit:
925 return compare_dlginit(resource1->res.dlgi, resource2->res.dlgi);
926 case res_toolbar:
927 return compare_toolbar(resource1->res.tbt, resource2->res.tbt);
928 case res_anicur:
929 case res_aniico:
930 return compare_ani_curico(resource1->res.ani, resource2->res.ani);
931 default:
932 /* Not supposed to reach here */
933 fprintf(stderr, "Not supposed to reach here (compare())\n");
934 abort();
935 return -1;
939 void verify_translations(resource_t *top) {
940 enum lang_type_e lang_type;
941 enum res_e res_type;
942 int **presence;
943 int i, j;
944 char *nameid;
945 char **problems;
946 int nb_problems, last_problem;
947 int complete, needs_work, partial;
948 resource_t *next = top;
950 for(res_type = res_0; res_type <= res_usr; res_type++) {
951 present_resources[res_type] = 0;
952 for(lang_type = lang_type_master; lang_type <= lang_type_normal; lang_type++) {
953 nb_resources[res_type][lang_type] = 0;
954 list_resources[res_type][lang_type] = NULL;
958 while(next) {
959 switch(next->type) {
960 case res_acc:
961 case res_bmp:
962 case res_cur:
963 case res_curg:
964 case res_dlg:
965 case res_dlgex:
966 case res_fnt:
967 case res_fntdir:
968 case res_ico:
969 case res_icog:
970 case res_men:
971 case res_menex:
972 case res_rdt:
973 case res_stt:
974 case res_usr:
975 case res_msg:
976 case res_ver:
977 case res_dlginit:
978 case res_toolbar:
979 case res_anicur:
980 case res_aniico:
981 add_resource(next);
982 break;
983 default:
984 fprintf(stderr, "Report this: unknown resource type parsed %08x\n", next->type);
986 next = next->next;
988 present_resources[res_acc] = 1;
989 res_names[res_acc] = strdup("accelerator");
990 present_resources[res_bmp] = 1;
991 res_names[res_bmp] = strdup("bitmap");
992 present_resources[res_cur] = 1;
993 res_names[res_cur] = strdup("cursor");
994 present_resources[res_curg] = 1;
995 res_names[res_curg] = strdup("cursor_group");
996 present_resources[res_dlg] = 1;
997 res_names[res_dlg] = strdup("dialog");
998 present_resources[res_dlgex] = 1;
999 res_names[res_dlgex] = strdup("dialogex");
1000 present_resources[res_fnt] = 1;
1001 res_names[res_fnt] = strdup("font");
1002 present_resources[res_fntdir] = 1;
1003 res_names[res_fntdir] = strdup("fontdir");
1004 present_resources[res_ico] = 1;
1005 res_names[res_ico] = strdup("icon");
1006 present_resources[res_icog] = 1;
1007 res_names[res_icog] = strdup("icon_group");
1008 present_resources[res_men] = 1;
1009 res_names[res_men] = strdup("menu");
1010 present_resources[res_menex] = 1;
1011 res_names[res_menex] = strdup("menuex");
1012 present_resources[res_rdt] = 1;
1013 res_names[res_rdt] = strdup("rcdata");
1014 present_resources[res_stt] = 1;
1015 res_names[res_stt] = strdup("stringtable");
1016 present_resources[res_usr] = 1;
1017 res_names[res_usr] = strdup("user");
1018 present_resources[res_msg] = 1;
1019 res_names[res_msg] = strdup("messagetable");
1020 present_resources[res_ver] = 1;
1021 res_names[res_ver] = strdup("versioninfo");
1022 present_resources[res_dlginit] = 1;
1023 res_names[res_dlginit] = strdup("dlginit");
1024 present_resources[res_toolbar] = 1;
1025 res_names[res_toolbar] = strdup("toolbar");
1026 present_resources[res_anicur] = 1;
1027 res_names[res_anicur] = strdup("ani_cursor");
1028 present_resources[res_aniico] = 1;
1029 res_names[res_aniico] = strdup("ani_icon");
1031 for(res_type = res_0; res_type <= res_usr; res_type++) {
1032 if(!present_resources[res_type]) {
1033 continue;
1035 if(nb_resources[res_type][lang_type_normal] > 0) {
1036 if(nb_resources[res_type][lang_type_master] && nb_resources[res_type][lang_type_neutral]) {
1037 fprintf(stderr, "Type %s:\n", res_names[res_type]);
1038 fprintf(stderr, "There are both a NEUTRAL and a MASTER version for %s, along with additional localized versions. The NEUTRAL versions will not be checked against other versions.\n", res_names[res_type]);
1039 } else if(nb_resources[res_type][lang_type_neutral]) {
1040 fprintf(stderr, "Type %s:\n", res_names[res_type]);
1041 fprintf(stderr, "There are no MASTER version, but there are some NEUTRAL versions for %s, so will use those instead of MASTER for comparison.\n", res_names[res_type]);
1042 list_resources[res_type][lang_type_master] = list_resources[res_type][lang_type_neutral];
1043 nb_resources[res_type][lang_type_master] = nb_resources[res_type][lang_type_neutral];
1044 } else if(!nb_resources[res_type][lang_type_master]) {
1045 fprintf(stderr, "Type %s:\n", res_names[res_type]);
1046 fprintf(stderr, "There are no NEUTRAL nor MASTER versions for %s, but there are some other localized versions. No comparison will be done at all.\n", res_names[res_type]);
1048 } else {
1049 if(nb_resources[res_type][lang_type_master] && nb_resources[res_type][lang_type_neutral]) {
1050 fprintf(stderr, "Type %s:\n", res_names[res_type]);
1051 fprintf(stderr, "There are both a NEUTRAL and a MASTER versions for %s, but no other localized version. No comparison will be done at all.\n", res_names[res_type]);
1052 } else if(nb_resources[res_type][lang_type_master]) {
1053 fprintf(stderr, "Type %s:\n", res_names[res_type]);
1054 fprintf(stderr, "There are only MASTER versions for %s. No comparison will be done at all.\n", res_names[res_type]);
1055 } else if(nb_resources[res_type][lang_type_neutral]) {
1056 /* fprintf(stderr, "There are only NEUTRAL versions for %s. No comparison will be done at all.\n", res_names[res_type]); */
1057 } else {
1058 /* fprintf(stderr, "There are no versions at all for %s. No comparison will be done at all.\n", res_names[res_type]); */
1062 presence = malloc(nb_resources[res_type][lang_type_master]*sizeof(int *));
1063 for(i = 0; i < nb_resources[res_type][lang_type_master]; i++) {
1064 presence[i] = calloc(NB_LANG, sizeof(int));
1065 presence[i][MASTER_LANGUAGE] = -1;
1068 for(i = 0; i < nb_resources[res_type][lang_type_normal]; i++) {
1069 for(j = 0; j < nb_resources[res_type][lang_type_master]; j++) {
1070 nameid = strdup(get_nameid_str(list_resources[res_type][lang_type_normal][i]->name));
1071 if(!strcmp(nameid, get_nameid_str(list_resources[res_type][lang_type_master][j]->name))) {
1072 if(compare(list_resources[res_type][lang_type_normal][i], list_resources[res_type][lang_type_master][j])) {
1073 presence[j][get_language_id(list_resources[res_type][lang_type_normal][i])] = 2;
1074 /* fprintf(stderr, "Differences in type %s, ID %s, for language %s\n", res_names[res_type], nameid, get_language_name(get_language_id(list_resources[res_type][lang_type_normal][i]))); */
1075 } else {
1076 presence[j][get_language_id(list_resources[res_type][lang_type_normal][i])] = 1;
1079 free(nameid);
1083 problems = malloc(sizeof(char *));
1084 problems[0] = strdup("");
1085 nb_problems = 0;
1086 last_problem = -1;
1087 for(i = 0; i < NB_LANG; i++) {
1088 complete = 1;
1089 needs_work = 0;
1090 partial = 0;
1091 for(j = 0; j < nb_resources[res_type][lang_type_master]; j++) {
1092 if(presence[j][i]) {
1093 partial = 1;
1094 if(presence[j][i] == 2) {
1095 needs_work = 1;
1096 problems = realloc(problems, (++nb_problems+1)*sizeof(char *));
1097 problems[nb_problems] = malloc(strlen(get_nameid_str(list_resources[res_type][lang_type_master][j]->name)) + 9);
1098 sprintf(problems[nb_problems], "DIFF %s %02x", get_nameid_str(list_resources[res_type][lang_type_master][j]->name), i);
1099 if(last_problem == i) {
1100 problems[nb_problems-1] = realloc(problems[nb_problems-1], strlen(problems[nb_problems-1]) + 3);
1101 strcat(problems[nb_problems-1], " \\");
1102 } else {
1103 last_problem = i;
1106 } else {
1107 complete = 0;
1108 problems = realloc(problems, (++nb_problems+1)*sizeof(char *));
1109 problems[nb_problems] = malloc(strlen(get_nameid_str(list_resources[res_type][lang_type_master][j]->name)) + 8);
1110 sprintf(problems[nb_problems], "ABS %s %02x", get_nameid_str(list_resources[res_type][lang_type_master][j]->name), i);
1111 if(last_problem == i) {
1112 problems[nb_problems-1] = realloc(problems[nb_problems-1], strlen(problems[nb_problems-1]) + 3);
1113 strcat(problems[nb_problems-1], " \\");
1114 } else {
1115 last_problem = i;
1119 if(complete && partial && !needs_work) {
1120 /* Support is complete, no need to do anything */
1121 /* fprintf(stderr, "Support for language %s is complete for %s.\n", get_language_name(i), res_names[res_type]); */
1122 printf(".");
1123 } else if(complete && partial && needs_work) {
1124 /* Support is incomplete (differing resources), needs work */
1125 /* fprintf(stderr, "Support for language %s is incomplete (differing resources) for %s.\n", get_language_name(i), res_names[res_type]); */
1126 printf("x");
1127 } else if(!complete && partial && !needs_work) {
1128 /* Support is incomplete (missing resources), needs work */
1129 /* fprintf(stderr, "Support for language %s is incomplete (missing resources) for %s.\n", get_language_name(i), res_names[res_type]); */
1130 printf("-");
1131 } else if(!complete && partial && needs_work) {
1132 /* Support is incomplete (missing and differing resources), needs work */
1133 /* fprintf(stderr, "Support for language %s is incomplete (missing and differing resources) for %s.\n", get_language_name(i), res_names[res_type]); */
1134 printf("+");
1135 } else if(!complete && !partial) {
1136 /* Support is totally absent, might be interesting to do */
1137 /* fprintf(stderr, "Support for language %s is absent for %s.\n", get_language_name(i), res_names[res_type]); */
1138 printf(" ");
1139 } else {
1140 /* Support is not relevant, no need to do anything */
1141 /* fprintf(stderr, "Support for language %s is not relevant for %s.\n", get_language_name(i), res_names[res_type]); */
1142 printf("n");
1145 printf("\n");
1146 for(i = 1; i <= nb_problems; i++) {
1147 printf("%s\n", problems[i]);
1148 free(problems[i]);
1150 free(problems[0]);
1151 free(problems);
1152 for(i = 0; i < nb_resources[res_type][lang_type_master]; i++)
1153 free(presence[i]);
1154 free(presence);