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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define MASTER_LANGUAGE LANG_ENGLISH
33 static int present_resources
[res_usr
+1];
34 static char *res_names
[res_usr
+1];
35 static int nb_resources
[res_usr
+1][lang_type_normal
+1];
36 static resource_t
**list_resources
[res_usr
+1][lang_type_normal
+1];
38 static int get_language_id(resource_t
*resource
) {
39 switch(resource
->type
) {
41 return resource
->res
.acc
->lvc
.language
->id
;
43 return resource
->res
.bmp
->data
->lvc
.language
->id
;
45 return resource
->res
.cur
->lvc
.language
->id
;
47 return resource
->res
.curg
->lvc
.language
->id
;
49 return resource
->res
.dlg
->lvc
.language
->id
;
51 return resource
->res
.dlgex
->lvc
.language
->id
;
53 return resource
->res
.fnt
->data
->lvc
.language
->id
;
55 return resource
->res
.fnd
->data
->lvc
.language
->id
;
57 return resource
->res
.ico
->lvc
.language
->id
;
59 return resource
->res
.icog
->lvc
.language
->id
;
61 return resource
->res
.men
->lvc
.language
->id
;
63 return resource
->res
.menex
->lvc
.language
->id
;
65 return resource
->res
.rdt
->data
->lvc
.language
->id
;
67 return resource
->res
.stt
->lvc
.language
->id
;
69 return resource
->res
.usr
->data
->lvc
.language
->id
;
71 return resource
->res
.msg
->data
->lvc
.language
->id
;
73 return resource
->res
.ver
->lvc
.language
->id
;
75 return resource
->res
.dlgi
->data
->lvc
.language
->id
;
77 return resource
->res
.tbt
->lvc
.language
->id
;
80 return resource
->res
.ani
->data
->lvc
.language
->id
;
82 /* Not supposed to reach here */
83 fprintf(stderr
, "Not supposed to reach here (get_language_id())\n");
89 static void add_resource(resource_t
*resource
) {
90 enum lang_type_e lang_type
;
91 enum res_e res_type
= resource
->type
;
92 int lid
= get_language_id(resource
);
94 if(lid
== MASTER_LANGUAGE
) {
95 lang_type
= lang_type_master
;
96 } else if(lid
== LANG_NEUTRAL
) {
97 lang_type
= lang_type_neutral
;
99 lang_type
= lang_type_normal
;
101 nb_resources
[res_type
][lang_type
]++;
102 list_resources
[res_type
][lang_type
] = realloc(list_resources
[res_type
][lang_type
], nb_resources
[res_type
][lang_type
]*sizeof(resource_t
*));
103 list_resources
[res_type
][lang_type
][nb_resources
[res_type
][lang_type
]-1] = resource
;
108 #define PRETTYPRINTLANG(langid) \
109 if(LANG_##langid == lid) { \
113 static const char *get_language_name(int lid
) {
114 PRETTYPRINTLANG(NEUTRAL
)
115 PRETTYPRINTLANG(AFRIKAANS
)
116 PRETTYPRINTLANG(ALBANIAN
)
117 PRETTYPRINTLANG(ARABIC
)
118 PRETTYPRINTLANG(ARMENIAN
)
119 PRETTYPRINTLANG(ASSAMESE
)
120 PRETTYPRINTLANG(AZERI
)
121 PRETTYPRINTLANG(BASQUE
)
122 PRETTYPRINTLANG(BELARUSIAN
)
123 PRETTYPRINTLANG(BENGALI
)
124 PRETTYPRINTLANG(BULGARIAN
)
125 PRETTYPRINTLANG(CATALAN
)
126 PRETTYPRINTLANG(CHINESE
)
127 PRETTYPRINTLANG(CROATIAN
)
128 PRETTYPRINTLANG(CZECH
)
129 PRETTYPRINTLANG(DANISH
)
130 PRETTYPRINTLANG(DIVEHI
)
131 PRETTYPRINTLANG(DUTCH
)
132 PRETTYPRINTLANG(ENGLISH
)
133 PRETTYPRINTLANG(ESTONIAN
)
134 PRETTYPRINTLANG(FAEROESE
)
135 PRETTYPRINTLANG(FARSI
)
136 PRETTYPRINTLANG(FINNISH
)
137 PRETTYPRINTLANG(FRENCH
)
138 PRETTYPRINTLANG(GALICIAN
)
139 PRETTYPRINTLANG(GEORGIAN
)
140 PRETTYPRINTLANG(GERMAN
)
141 PRETTYPRINTLANG(GREEK
)
142 PRETTYPRINTLANG(GUJARATI
)
143 PRETTYPRINTLANG(HEBREW
)
144 PRETTYPRINTLANG(HINDI
)
145 PRETTYPRINTLANG(HUNGARIAN
)
146 PRETTYPRINTLANG(ICELANDIC
)
147 PRETTYPRINTLANG(INDONESIAN
)
148 PRETTYPRINTLANG(ITALIAN
)
149 PRETTYPRINTLANG(JAPANESE
)
150 PRETTYPRINTLANG(KANNADA
)
151 PRETTYPRINTLANG(KASHMIRI
)
152 PRETTYPRINTLANG(KAZAK
)
153 PRETTYPRINTLANG(KONKANI
)
154 PRETTYPRINTLANG(KOREAN
)
155 PRETTYPRINTLANG(KYRGYZ
)
156 PRETTYPRINTLANG(LATVIAN
)
157 PRETTYPRINTLANG(LITHUANIAN
)
158 PRETTYPRINTLANG(MACEDONIAN
)
159 PRETTYPRINTLANG(MALAY
)
160 PRETTYPRINTLANG(MALAYALAM
)
161 PRETTYPRINTLANG(MANIPURI
)
162 PRETTYPRINTLANG(MARATHI
)
163 PRETTYPRINTLANG(MONGOLIAN
)
164 PRETTYPRINTLANG(NEPALI
)
165 PRETTYPRINTLANG(NORWEGIAN
)
166 PRETTYPRINTLANG(ORIYA
)
167 PRETTYPRINTLANG(POLISH
)
168 PRETTYPRINTLANG(PORTUGUESE
)
169 PRETTYPRINTLANG(PUNJABI
)
170 PRETTYPRINTLANG(ROMANIAN
)
171 PRETTYPRINTLANG(RUSSIAN
)
172 PRETTYPRINTLANG(SANSKRIT
)
173 PRETTYPRINTLANG(SERBIAN
)
174 PRETTYPRINTLANG(SINDHI
)
175 PRETTYPRINTLANG(SLOVAK
)
176 PRETTYPRINTLANG(SLOVENIAN
)
177 PRETTYPRINTLANG(SPANISH
)
178 PRETTYPRINTLANG(SWAHILI
)
179 PRETTYPRINTLANG(SWEDISH
)
180 PRETTYPRINTLANG(SYRIAC
)
181 PRETTYPRINTLANG(TAMIL
)
182 PRETTYPRINTLANG(TATAR
)
183 PRETTYPRINTLANG(TELUGU
)
184 PRETTYPRINTLANG(THAI
)
185 PRETTYPRINTLANG(TURKISH
)
186 PRETTYPRINTLANG(UKRAINIAN
)
187 PRETTYPRINTLANG(URDU
)
188 PRETTYPRINTLANG(UZBEK
)
189 PRETTYPRINTLANG(VIETNAMESE
)
190 PRETTYPRINTLANG(GAELIC
)
191 PRETTYPRINTLANG(MALTESE
)
192 PRETTYPRINTLANG(MAORI
)
193 PRETTYPRINTLANG(RHAETO_ROMANCE
)
194 PRETTYPRINTLANG(SAAMI
)
195 PRETTYPRINTLANG(SORBIAN
)
196 PRETTYPRINTLANG(SUTU
)
197 PRETTYPRINTLANG(TSONGA
)
198 PRETTYPRINTLANG(TSWANA
)
199 PRETTYPRINTLANG(VENDA
)
200 PRETTYPRINTLANG(XHOSA
)
201 PRETTYPRINTLANG(ZULU
)
202 PRETTYPRINTLANG(ESPERANTO
)
203 PRETTYPRINTLANG(WALON
)
204 PRETTYPRINTLANG(CORNISH
)
205 PRETTYPRINTLANG(WELSH
)
206 PRETTYPRINTLANG(BRETON
)
207 return "Unkown language";
211 static int compare_accelerator(accelerator_t
*accelerator1
, accelerator_t
*accelerator2
) {
213 event_t
*ev1
= NULL
, *ev2
= NULL
;
215 ((accelerator1
->memopt
!= accelerator2
->memopt
) ||
216 (accelerator1
->lvc
.version
!= accelerator2
->lvc
.version
) ||
217 (accelerator1
->lvc
.characts
!= accelerator2
->lvc
.characts
)))
219 ev1
= accelerator1
->events
;
220 ev2
= accelerator2
->events
;
221 while(!different
&& ev1
&& ev2
) {
223 ((ev1
->id
!= ev2
->id
) ||
224 (ev1
->flags
!= ev2
->flags
)))
230 ((ev1
&& !ev2
) || (!ev1
&& ev2
)))
235 static int compare_bitmap(bitmap_t
*bitmap1
, bitmap_t
*bitmap2
) {
238 ((bitmap1
->memopt
!= bitmap2
->memopt
) ||
239 (bitmap1
->data
->lvc
.version
!= bitmap2
->data
->lvc
.version
) ||
240 (bitmap1
->data
->lvc
.characts
!= bitmap2
->data
->lvc
.characts
)))
245 static int compare_cursor(cursor_t
*cursor1
, cursor_t
*cursor2
) {
248 ((cursor1
->id
!= cursor2
->id
) ||
249 (cursor1
->width
!= cursor2
->width
) ||
250 (cursor1
->height
!= cursor2
->height
) ||
251 (cursor1
->xhot
!= cursor2
->xhot
) ||
252 (cursor1
->yhot
!= cursor2
->yhot
)))
255 ((cursor1
->lvc
.version
!= cursor2
->lvc
.version
) ||
256 (cursor1
->lvc
.characts
!= cursor2
->lvc
.characts
)))
261 static int compare_cursor_group(cursor_group_t
*cursor_group1
, cursor_group_t
*cursor_group2
) {
263 cursor_t
*cursor1
= NULL
, *cursor2
= NULL
;
265 ((cursor_group1
->memopt
!= cursor_group2
->memopt
) ||
266 (cursor_group1
->lvc
.version
!= cursor_group2
->lvc
.version
) ||
267 (cursor_group1
->lvc
.characts
!= cursor_group2
->lvc
.characts
)))
270 (cursor_group1
->ncursor
!= cursor_group2
->ncursor
))
273 cursor1
= cursor_group1
->cursorlist
;
274 cursor2
= cursor_group2
->cursorlist
;
275 while(!different
&& cursor1
&& cursor2
) {
276 different
= compare_cursor(cursor1
, cursor2
);
277 cursor1
= cursor1
->next
;
278 cursor2
= cursor2
->next
;
281 ((cursor1
&& !cursor2
) ||
282 (!cursor1
&& cursor2
)))
288 static int compare_control(control_t
*control1
, control_t
*control2
) {
292 ((control1
&& !control2
) ||
293 (!control1
&& control2
)))
295 if(different
|| !control1
|| !control2
)
297 nameid
= strdup(get_nameid_str(control1
->ctlclass
));
298 if(!different
&& strcmp(nameid
, get_nameid_str(control2
->ctlclass
)))
302 (control1
->id
!= control2
->id
))
304 if(!different
&& control1
->gotstyle
&& control2
->gotstyle
) {
305 if((!control1
->style
|| !control2
->style
) ||
306 (control1
->style
->and_mask
|| control2
->style
->and_mask
) ||
307 (control1
->style
->or_mask
!= control2
->style
->or_mask
))
309 } else if(!different
&&
310 ((control1
->gotstyle
&& !control2
->gotstyle
) ||
311 (!control1
->gotstyle
&& control2
->gotstyle
)))
313 if(!different
&& control1
->gotexstyle
&& control2
->gotexstyle
) {
314 if((!control1
->exstyle
|| !control2
->exstyle
) ||
315 (control1
->exstyle
->and_mask
|| control2
->exstyle
->and_mask
) ||
316 (control1
->exstyle
->or_mask
!= control2
->exstyle
->or_mask
))
318 } else if(!different
&&
319 ((control1
->gotexstyle
&& !control2
->gotexstyle
) ||
320 (!control1
->gotexstyle
&& control2
->gotexstyle
)))
322 if(!different
&& control1
->gothelpid
&& control2
->gothelpid
) {
323 if(control1
->helpid
!= control2
->helpid
)
325 } else if(!different
&&
326 ((control1
->gothelpid
&& !control2
->gothelpid
) ||
327 (!control1
->gothelpid
&& control2
->gothelpid
)))
332 static int compare_dialog(dialog_t
*dialog1
, dialog_t
*dialog2
) {
336 ((dialog1
->memopt
!= dialog2
->memopt
) ||
337 (dialog1
->lvc
.version
!= dialog2
->lvc
.version
) ||
338 (dialog1
->lvc
.characts
!= dialog2
->lvc
.characts
)))
340 if(!different
&& dialog1
->gotstyle
&& dialog2
->gotstyle
) {
341 if((!dialog1
->style
|| !dialog2
->style
) ||
342 (dialog1
->style
->and_mask
|| dialog2
->style
->and_mask
) ||
343 (dialog1
->style
->or_mask
!= dialog2
->style
->or_mask
))
345 } else if(!different
&&
346 ((dialog1
->gotstyle
&& !dialog2
->gotstyle
) ||
347 (!dialog1
->gotstyle
&& dialog2
->gotstyle
)))
349 if(!different
&& dialog1
->gotexstyle
&& dialog2
->gotexstyle
) {
350 if((!dialog1
->exstyle
|| !dialog2
->exstyle
) ||
351 (dialog1
->exstyle
->and_mask
|| dialog2
->exstyle
->and_mask
) ||
352 (dialog1
->exstyle
->or_mask
!= dialog2
->exstyle
->or_mask
))
354 } else if(!different
&&
355 ((dialog1
->gotexstyle
&& !dialog2
->gotexstyle
) ||
356 (!dialog1
->gotexstyle
&& dialog2
->gotexstyle
)))
358 nameid
= strdup(get_nameid_str(dialog1
->menu
));
359 if(!different
&& strcmp(nameid
, get_nameid_str(dialog2
->menu
)))
362 nameid
= strdup(get_nameid_str(dialog1
->dlgclass
));
363 if(!different
&& strcmp(nameid
, get_nameid_str(dialog2
->dlgclass
)))
367 different
= compare_control(dialog1
->controls
, dialog2
->controls
);
371 static int compare_dialogex(dialogex_t
*dialogex1
, dialogex_t
*dialogex2
) {
375 ((dialogex1
->memopt
!= dialogex2
->memopt
) ||
376 (dialogex1
->lvc
.version
!= dialogex2
->lvc
.version
) ||
377 (dialogex1
->lvc
.characts
!= dialogex2
->lvc
.characts
)))
379 if(!different
&& dialogex1
->gotstyle
&& dialogex2
->gotstyle
) {
380 if((!dialogex1
->style
|| !dialogex2
->style
) ||
381 (dialogex1
->style
->and_mask
|| dialogex2
->style
->and_mask
) ||
382 (dialogex1
->style
->or_mask
!= dialogex2
->style
->or_mask
))
384 } else if(!different
&&
385 ((dialogex1
->gotstyle
&& !dialogex2
->gotstyle
) ||
386 (!dialogex1
->gotstyle
&& dialogex2
->gotstyle
)))
388 if(!different
&& dialogex1
->gotexstyle
&& dialogex2
->gotexstyle
) {
389 if((!dialogex1
->exstyle
|| !dialogex2
->exstyle
) ||
390 (dialogex1
->exstyle
->and_mask
|| dialogex2
->exstyle
->and_mask
) ||
391 (dialogex1
->exstyle
->or_mask
!= dialogex2
->exstyle
->or_mask
))
393 } else if(!different
&&
394 ((dialogex1
->gotexstyle
&& !dialogex2
->gotexstyle
) ||
395 (!dialogex1
->gotexstyle
&& dialogex2
->gotexstyle
)))
397 if(!different
&& dialogex1
->gothelpid
&& dialogex2
->gothelpid
) {
398 if(dialogex1
->helpid
!= dialogex2
->helpid
)
400 } else if(!different
&&
401 ((dialogex1
->gothelpid
&& !dialogex2
->gothelpid
) ||
402 (!dialogex1
->gothelpid
&& dialogex2
->gothelpid
)))
404 nameid
= strdup(get_nameid_str(dialogex1
->menu
));
405 if(!different
&& strcmp(nameid
, get_nameid_str(dialogex2
->menu
)))
408 nameid
= strdup(get_nameid_str(dialogex1
->dlgclass
));
409 if(!different
&& strcmp(nameid
, get_nameid_str(dialogex2
->dlgclass
)))
413 different
= compare_control(dialogex1
->controls
, dialogex2
->controls
);
417 static int compare_font(font_t
*font1
, font_t
*font2
) {
420 ((font1
->memopt
!= font2
->memopt
) ||
421 (font1
->data
->lvc
.version
!= font2
->data
->lvc
.version
) ||
422 (font1
->data
->lvc
.characts
!= font2
->data
->lvc
.characts
)))
427 static int compare_fontdir(fontdir_t
*fontdir1
, fontdir_t
*fontdir2
) {
430 ((fontdir1
->memopt
!= fontdir2
->memopt
) ||
431 (fontdir1
->data
->lvc
.version
!= fontdir2
->data
->lvc
.version
) ||
432 (fontdir1
->data
->lvc
.characts
!= fontdir2
->data
->lvc
.characts
)))
437 static int compare_icon(icon_t
*icon1
, icon_t
*icon2
) {
440 ((icon1
->id
!= icon2
->id
) ||
441 (icon1
->width
!= icon2
->width
) ||
442 (icon1
->height
!= icon2
->height
)))
445 ((icon1
->lvc
.version
!= icon2
->lvc
.version
) ||
446 (icon1
->lvc
.characts
!= icon2
->lvc
.characts
)))
451 static int compare_icon_group(icon_group_t
*icon_group1
, icon_group_t
*icon_group2
) {
453 icon_t
*icon1
= NULL
, *icon2
= NULL
;
455 ((icon_group1
->memopt
!= icon_group2
->memopt
) ||
456 (icon_group1
->lvc
.version
!= icon_group2
->lvc
.version
) ||
457 (icon_group1
->lvc
.characts
!= icon_group2
->lvc
.characts
)))
460 (icon_group1
->nicon
!= icon_group2
->nicon
))
463 icon1
= icon_group1
->iconlist
;
464 icon2
= icon_group2
->iconlist
;
465 while(!different
&& icon1
&& icon2
) {
466 different
= compare_icon(icon1
, icon2
);
471 ((icon1
&& !icon2
) ||
478 static int compare_menu_item(menu_item_t
*menu_item1
, menu_item_t
*menu_item2
) {
480 while(!different
&& menu_item1
&& menu_item2
) {
481 if(menu_item1
->popup
&& menu_item2
->popup
)
482 different
= compare_menu_item(menu_item1
->popup
, menu_item2
->popup
);
483 else if(!menu_item1
->popup
&& !menu_item2
->popup
) {
484 if(menu_item1
->name
&& menu_item2
->name
) {
485 if((menu_item1
->id
!= menu_item2
->id
) ||
486 (menu_item1
->state
!= menu_item2
->state
))
488 } else if((menu_item1
->name
&& !menu_item2
->name
) ||
489 (!menu_item1
->name
&& menu_item2
->name
))
493 menu_item1
= menu_item1
->next
;
494 menu_item2
= menu_item2
->next
;
497 ((menu_item1
&& !menu_item2
) ||
498 (!menu_item1
&& menu_item2
)))
503 static int compare_menu(menu_t
*menu1
, menu_t
*menu2
) {
506 ((menu1
->memopt
!= menu2
->memopt
) ||
507 (menu1
->lvc
.version
!= menu2
->lvc
.version
) ||
508 (menu1
->lvc
.characts
!= menu2
->lvc
.characts
)))
511 different
= compare_menu_item(menu1
->items
, menu2
->items
);
515 static int compare_menuex_item(menuex_item_t
*menuex_item1
, menuex_item_t
*menuex_item2
) {
517 while(!different
&& menuex_item1
&& menuex_item2
) {
518 if(menuex_item1
->popup
&& menuex_item2
->popup
) {
519 if(!different
&& menuex_item1
->gotid
&& menuex_item2
->gotid
) {
520 if(menuex_item1
->id
!= menuex_item2
->id
)
522 } else if(!different
&&
523 ((menuex_item1
->gotid
&& !menuex_item2
->gotid
) ||
524 (!menuex_item2
->gotid
&& menuex_item2
->gotid
)))
526 if(!different
&& menuex_item1
->gottype
&& menuex_item2
->gottype
) {
527 if(menuex_item1
->type
!= menuex_item2
->type
)
529 } else if(!different
&&
530 ((menuex_item1
->gottype
&& !menuex_item2
->gottype
) ||
531 (!menuex_item2
->gottype
&& menuex_item2
->gottype
)))
533 if(!different
&& menuex_item1
->gotstate
&& menuex_item2
->gotstate
) {
534 if(menuex_item1
->state
!= menuex_item2
->state
)
536 } else if(!different
&&
537 ((menuex_item1
->gotstate
&& !menuex_item2
->gotstate
) ||
538 (!menuex_item2
->gotstate
&& menuex_item2
->gotstate
)))
540 if(!different
&& menuex_item1
->gothelpid
&& menuex_item2
->gothelpid
) {
541 if(menuex_item1
->helpid
!= menuex_item2
->helpid
)
543 } else if(!different
&&
544 ((menuex_item1
->gothelpid
&& !menuex_item2
->gothelpid
) ||
545 (!menuex_item2
->gothelpid
&& menuex_item2
->gothelpid
)))
548 different
= compare_menuex_item(menuex_item1
->popup
, menuex_item2
->popup
);
549 } else if(!menuex_item1
->popup
&& !menuex_item2
->popup
) {
550 if(menuex_item1
->name
&& menuex_item2
->name
) {
551 if(!different
&& menuex_item1
->gotid
&& menuex_item2
->gotid
) {
552 if(menuex_item1
->id
!= menuex_item2
->id
)
554 } else if(!different
&&
555 ((menuex_item1
->gotid
&& !menuex_item2
->gotid
) ||
556 (!menuex_item2
->gotid
&& menuex_item2
->gotid
)))
558 if(!different
&& menuex_item1
->gottype
&& menuex_item2
->gottype
) {
559 if(menuex_item1
->type
!= menuex_item2
->type
)
561 } else if(!different
&&
562 ((menuex_item1
->gottype
&& !menuex_item2
->gottype
) ||
563 (!menuex_item2
->gottype
&& menuex_item2
->gottype
)))
565 if(!different
&& menuex_item1
->gotstate
&& menuex_item2
->gotstate
) {
566 if(menuex_item1
->state
!= menuex_item2
->state
)
568 } else if(!different
&&
569 ((menuex_item1
->gotstate
&& !menuex_item2
->gotstate
) ||
570 (!menuex_item2
->gotstate
&& menuex_item2
->gotstate
)))
572 if(!different
&& menuex_item1
->gothelpid
&& menuex_item2
->gothelpid
) {
573 if(menuex_item1
->helpid
!= menuex_item2
->helpid
)
575 } else if(!different
&&
576 ((menuex_item1
->gothelpid
&& !menuex_item2
->gothelpid
) ||
577 (!menuex_item2
->gothelpid
&& menuex_item2
->gothelpid
)))
579 } else if((menuex_item1
->name
&& !menuex_item2
->name
) ||
580 (!menuex_item1
->name
&& menuex_item2
->name
))
584 menuex_item1
= menuex_item1
->next
;
585 menuex_item2
= menuex_item2
->next
;
588 ((menuex_item1
&& !menuex_item2
) ||
589 (!menuex_item1
&& menuex_item2
)))
594 static int compare_menuex(menuex_t
*menuex1
, menuex_t
*menuex2
) {
597 ((menuex1
->memopt
!= menuex2
->memopt
) ||
598 (menuex1
->lvc
.version
!= menuex2
->lvc
.version
) ||
599 (menuex1
->lvc
.characts
!= menuex2
->lvc
.characts
)))
602 different
= compare_menuex_item(menuex1
->items
, menuex2
->items
);
606 static int compare_rcdata(rcdata_t
*rcdata1
, rcdata_t
*rcdata2
) {
609 ((rcdata1
->memopt
!= rcdata2
->memopt
) ||
610 (rcdata1
->data
->lvc
.version
!= rcdata2
->data
->lvc
.version
) ||
611 (rcdata1
->data
->lvc
.characts
!= rcdata2
->data
->lvc
.characts
)))
616 static int compare_stringtable(stringtable_t
*stringtable1
, stringtable_t
*stringtable2
) {
619 while(!different
&& stringtable1
&& stringtable2
) {
620 if((stringtable1
->memopt
!= stringtable2
->memopt
) ||
621 (stringtable1
->lvc
.version
!= stringtable2
->lvc
.version
) ||
622 (stringtable1
->lvc
.characts
!= stringtable2
->lvc
.characts
))
625 if((stringtable1
->nentries
!= stringtable2
->nentries
) ||
626 (stringtable1
->idbase
!= stringtable2
->idbase
))
629 for(i
= 0 ; i
< stringtable1
->nentries
; i
++)
630 if((stringtable1
->entries
[i
].id
!= stringtable2
->entries
[i
].id
) ||
631 (stringtable1
->entries
[i
].memopt
!= stringtable2
->entries
[i
].memopt
) ||
632 (stringtable1
->entries
[i
].str
&& !stringtable2
->entries
[i
].str
) ||
633 (!stringtable1
->entries
[i
].str
&& stringtable2
->entries
[i
].str
)) {
638 stringtable1
= stringtable1
->next
;
639 stringtable2
= stringtable2
->next
;
644 static int compare_user(user_t
*user1
, user_t
*user2
) {
648 ((user1
->memopt
!= user2
->memopt
) ||
649 (user1
->data
->lvc
.version
!= user2
->data
->lvc
.version
) ||
650 (user1
->data
->lvc
.characts
!= user2
->data
->lvc
.characts
)))
652 nameid
= strdup(get_nameid_str(user1
->type
));
653 if(!different
&& strcmp(nameid
, get_nameid_str(user2
->type
)))
659 static int compare_messagetable(messagetable_t
*messagetable1
, messagetable_t
*messagetable2
) {
662 ((messagetable1
->memopt
!= messagetable2
->memopt
) ||
663 (messagetable1
->data
->lvc
.version
!= messagetable2
->data
->lvc
.version
) ||
664 (messagetable1
->data
->lvc
.characts
!= messagetable2
->data
->lvc
.characts
)))
669 static int compare_string(string_t
*string1
, string_t
*string2
) {
672 ((string1
->size
!= string2
->size
) ||
673 (string1
->type
!= string2
->type
)))
676 if(string1
->type
== str_char
)
677 different
= memcmp(string1
->str
.cstr
, string2
->str
.cstr
, string1
->size
);
678 else if(string1
->type
== str_unicode
)
679 different
= memcmp(string1
->str
.wstr
, string2
->str
.wstr
, string1
->size
*sizeof(WCHAR
));
686 static int compare_ver_block(ver_block_t
*ver_block1
, ver_block_t
*ver_block2
);
688 static int compare_ver_value(ver_value_t
*ver_value1
, ver_value_t
*ver_value2
) {
692 (ver_value1
->type
== ver_value2
->type
)) {
693 switch(ver_value1
->type
) {
695 if(!different
&& ver_value1
->key
&& ver_value2
->key
)
696 different
= compare_string(ver_value1
->key
, ver_value2
->key
);
697 else if(!different
&&
698 ((ver_value1
->key
&& !ver_value2
->key
) ||
699 (!ver_value1
->key
&& ver_value2
->key
)))
703 if(!different
&& ver_value1
->key
&& ver_value2
->key
)
704 different
= compare_string(ver_value1
->key
, ver_value2
->key
);
705 else if(!different
&&
706 ((ver_value1
->key
&& !ver_value2
->key
) ||
707 (!ver_value1
->key
&& ver_value2
->key
)))
709 if(!different
&& ver_value1
->value
.words
&& ver_value2
->value
.words
) {
711 (ver_value1
->value
.words
->nwords
!= ver_value2
->value
.words
->nwords
))
714 for(i
= 0; i
< ver_value1
->value
.words
->nwords
; i
++) {
715 if(ver_value1
->value
.words
->words
[i
] != ver_value2
->value
.words
->words
[i
]) {
720 } else if(!different
&&
721 ((ver_value1
->value
.words
&& !ver_value2
->value
.words
) ||
722 (!ver_value1
->value
.words
&& ver_value2
->value
.words
)))
726 if(!different
&& ver_value1
->value
.block
&& ver_value2
->value
.block
)
727 different
= compare_ver_block(ver_value1
->value
.block
, ver_value2
->value
.block
);
728 else if(!different
&&
729 ((ver_value1
->value
.block
&& !ver_value2
->value
.block
) ||
730 (!ver_value1
->value
.block
&& ver_value2
->value
.block
)))
741 static int compare_ver_block(ver_block_t
*ver_block1
, ver_block_t
*ver_block2
) {
743 ver_value_t
*ver_value1
= NULL
, *ver_value2
= NULL
;
745 ver_value1
= ver_block1
->values
;
746 ver_value2
= ver_block2
->values
;
747 while(!different
&& ver_value1
&& ver_value2
) {
748 different
= compare_ver_value(ver_value1
, ver_value2
);
749 ver_value1
= ver_value1
->next
;
750 ver_value2
= ver_value2
->next
;
753 ((ver_value1
&& !ver_value2
) ||
754 (!ver_value1
&& ver_value2
)))
760 static int compare_versioninfo(versioninfo_t
*versioninfo1
, versioninfo_t
*versioninfo2
) {
762 ver_block_t
*ver_block1
= NULL
, *ver_block2
= NULL
;
764 ((versioninfo1
->memopt
!= versioninfo2
->memopt
) ||
765 (versioninfo1
->lvc
.version
!= versioninfo2
->lvc
.version
) ||
766 (versioninfo1
->lvc
.characts
!= versioninfo2
->lvc
.characts
)))
768 if(!different
&& versioninfo1
->gotit
.fv
&& versioninfo2
->gotit
.fv
) {
769 if((versioninfo1
->filever_maj1
!= versioninfo2
->filever_maj1
) ||
770 (versioninfo1
->filever_maj2
!= versioninfo2
->filever_maj2
) ||
771 (versioninfo1
->filever_min1
!= versioninfo2
->filever_min1
) ||
772 (versioninfo1
->filever_min2
!= versioninfo2
->filever_min2
))
774 } else if(!different
&&
775 ((versioninfo1
->gotit
.fv
&& !versioninfo2
->gotit
.fv
) ||
776 (!versioninfo1
->gotit
.fv
&& versioninfo2
->gotit
.fv
)))
778 if(!different
&& versioninfo1
->gotit
.pv
&& versioninfo2
->gotit
.pv
) {
779 if((versioninfo1
->prodver_maj1
!= versioninfo2
->prodver_maj1
) ||
780 (versioninfo1
->prodver_maj2
!= versioninfo2
->prodver_maj2
) ||
781 (versioninfo1
->prodver_min1
!= versioninfo2
->prodver_min1
) ||
782 (versioninfo1
->prodver_min2
!= versioninfo2
->prodver_min2
))
784 } else if(!different
&&
785 ((versioninfo1
->gotit
.pv
&& !versioninfo2
->gotit
.pv
) ||
786 (!versioninfo1
->gotit
.pv
&& versioninfo2
->gotit
.pv
)))
788 if(!different
&& versioninfo1
->gotit
.fo
&& versioninfo2
->gotit
.fo
) {
789 if(versioninfo1
->fileos
!= versioninfo2
->fileos
)
791 } else if(!different
&&
792 ((versioninfo1
->gotit
.fo
&& !versioninfo2
->gotit
.fo
) ||
793 (!versioninfo1
->gotit
.fo
&& versioninfo2
->gotit
.fo
)))
795 if(!different
&& versioninfo1
->gotit
.ff
&& versioninfo2
->gotit
.ff
) {
796 if(versioninfo1
->fileflags
!= versioninfo2
->fileflags
)
798 } else if(!different
&&
799 ((versioninfo1
->gotit
.ff
&& !versioninfo2
->gotit
.ff
) ||
800 (!versioninfo1
->gotit
.ff
&& versioninfo2
->gotit
.ff
)))
802 if(!different
&& versioninfo1
->gotit
.ffm
&& versioninfo2
->gotit
.ffm
) {
803 if(versioninfo1
->fileflagsmask
!= versioninfo2
->fileflagsmask
)
805 } else if(!different
&&
806 ((versioninfo1
->gotit
.ffm
&& !versioninfo2
->gotit
.ffm
) ||
807 (!versioninfo1
->gotit
.ffm
&& versioninfo2
->gotit
.ffm
)))
809 if(!different
&& versioninfo1
->gotit
.ft
&& versioninfo2
->gotit
.ft
) {
810 if(versioninfo1
->filetype
!= versioninfo2
->filetype
)
812 } else if(!different
&&
813 ((versioninfo1
->gotit
.ft
&& !versioninfo2
->gotit
.ft
) ||
814 (!versioninfo1
->gotit
.ft
&& versioninfo2
->gotit
.ft
)))
816 if(!different
&& versioninfo1
->gotit
.fst
&& versioninfo2
->gotit
.fst
) {
817 if(versioninfo1
->filesubtype
!= versioninfo2
->filesubtype
)
819 } else if(!different
&&
820 ((versioninfo1
->gotit
.fst
&& !versioninfo2
->gotit
.fst
) ||
821 (!versioninfo1
->gotit
.fst
&& versioninfo2
->gotit
.fst
)))
824 ver_block1
= versioninfo1
->blocks
;
825 ver_block2
= versioninfo2
->blocks
;
826 while(!different
&& ver_block1
&& ver_block2
) {
827 different
= compare_ver_block(ver_block1
, ver_block2
);
828 ver_block1
= ver_block1
->next
;
829 ver_block2
= ver_block2
->next
;
832 ((ver_block1
&& !ver_block2
) ||
833 (ver_block1
&& !ver_block2
)))
839 static int compare_dlginit(dlginit_t
*dlginit1
, dlginit_t
*dlginit2
) {
842 ((dlginit1
->memopt
!= dlginit2
->memopt
) ||
843 (dlginit1
->data
->lvc
.version
!= dlginit2
->data
->lvc
.version
) ||
844 (dlginit1
->data
->lvc
.characts
!= dlginit2
->data
->lvc
.characts
)))
849 static int compare_toolbar_item(toolbar_item_t
*toolbar_item1
, toolbar_item_t
*toolbar_item2
) {
851 while(!different
&& toolbar_item1
&& toolbar_item2
) {
852 if((toolbar_item1
->id
&& !toolbar_item2
->id
) ||
853 (!toolbar_item1
->id
&& toolbar_item2
->id
))
855 toolbar_item1
= toolbar_item1
->next
;
856 toolbar_item2
= toolbar_item2
->next
;
859 ((toolbar_item1
&& !toolbar_item2
) ||
860 (!toolbar_item1
&& toolbar_item2
)))
865 static int compare_toolbar(toolbar_t
*toolbar1
, toolbar_t
*toolbar2
) {
868 ((toolbar1
->memopt
!= toolbar2
->memopt
) ||
869 (toolbar1
->lvc
.version
!= toolbar2
->lvc
.version
) ||
870 (toolbar1
->lvc
.characts
!= toolbar2
->lvc
.characts
)))
873 different
= compare_toolbar_item(toolbar1
->items
, toolbar2
->items
);
877 static int compare_ani_curico(ani_curico_t
*ani_curico1
, ani_curico_t
*ani_curico2
) {
880 ((ani_curico1
->memopt
!= ani_curico2
->memopt
) ||
881 (ani_curico1
->data
->lvc
.version
!= ani_curico2
->data
->lvc
.version
) ||
882 (ani_curico1
->data
->lvc
.characts
!= ani_curico2
->data
->lvc
.characts
)))
887 static int compare(resource_t
*resource1
, resource_t
*resource2
) {
888 switch(resource1
->type
) {
890 return compare_accelerator(resource1
->res
.acc
, resource2
->res
.acc
);
892 return compare_bitmap(resource1
->res
.bmp
, resource2
->res
.bmp
);
894 return compare_cursor(resource1
->res
.cur
, resource2
->res
.cur
);
896 return compare_cursor_group(resource1
->res
.curg
, resource2
->res
.curg
);
898 return compare_dialog(resource1
->res
.dlg
, resource2
->res
.dlg
);
900 return compare_dialogex(resource1
->res
.dlgex
, resource2
->res
.dlgex
);
902 return compare_font(resource1
->res
.fnt
, resource2
->res
.fnt
);
904 return compare_fontdir(resource1
->res
.fnd
, resource2
->res
.fnd
);
906 return compare_icon(resource1
->res
.ico
, resource2
->res
.ico
);
908 return compare_icon_group(resource1
->res
.icog
, resource2
->res
.icog
);
910 return compare_menu(resource1
->res
.men
, resource2
->res
.men
);
912 return compare_menuex(resource1
->res
.menex
, resource2
->res
.menex
);
914 return compare_rcdata(resource1
->res
.rdt
, resource2
->res
.rdt
);
916 return compare_stringtable(resource1
->res
.stt
, resource2
->res
.stt
);
918 return compare_user(resource1
->res
.usr
, resource2
->res
.usr
);
920 return compare_messagetable(resource1
->res
.msg
, resource2
->res
.msg
);
922 return compare_versioninfo(resource1
->res
.ver
, resource2
->res
.ver
);
924 return compare_dlginit(resource1
->res
.dlgi
, resource2
->res
.dlgi
);
926 return compare_toolbar(resource1
->res
.tbt
, resource2
->res
.tbt
);
929 return compare_ani_curico(resource1
->res
.ani
, resource2
->res
.ani
);
931 /* Not supposed to reach here */
932 fprintf(stderr
, "Not supposed to reach here (compare())\n");
938 void verify_translations(resource_t
*top
) {
939 enum lang_type_e lang_type
;
945 int nb_problems
, last_problem
;
946 int complete
, needs_work
, partial
;
947 resource_t
*next
= top
;
949 for(res_type
= res_0
; res_type
<= res_usr
; res_type
++) {
950 present_resources
[res_type
] = 0;
951 for(lang_type
= lang_type_master
; lang_type
<= lang_type_normal
; lang_type
++) {
952 nb_resources
[res_type
][lang_type
] = 0;
953 list_resources
[res_type
][lang_type
] = NULL
;
983 fprintf(stderr
, "Report this: unkown resource type parsed %08x\n", next
->type
);
987 present_resources
[res_acc
] = 1;
988 res_names
[res_acc
] = strdup("accelerator");
989 present_resources
[res_bmp
] = 1;
990 res_names
[res_bmp
] = strdup("bitmap");
991 present_resources
[res_cur
] = 1;
992 res_names
[res_cur
] = strdup("cursor");
993 present_resources
[res_curg
] = 1;
994 res_names
[res_curg
] = strdup("cursor_group");
995 present_resources
[res_dlg
] = 1;
996 res_names
[res_dlg
] = strdup("dialog");
997 present_resources
[res_dlgex
] = 1;
998 res_names
[res_dlgex
] = strdup("dialogex");
999 present_resources
[res_fnt
] = 1;
1000 res_names
[res_fnt
] = strdup("font");
1001 present_resources
[res_fntdir
] = 1;
1002 res_names
[res_fntdir
] = strdup("fontdir");
1003 present_resources
[res_ico
] = 1;
1004 res_names
[res_ico
] = strdup("icon");
1005 present_resources
[res_icog
] = 1;
1006 res_names
[res_icog
] = strdup("icon_group");
1007 present_resources
[res_men
] = 1;
1008 res_names
[res_men
] = strdup("menu");
1009 present_resources
[res_menex
] = 1;
1010 res_names
[res_menex
] = strdup("menuex");
1011 present_resources
[res_rdt
] = 1;
1012 res_names
[res_rdt
] = strdup("rcdata");
1013 present_resources
[res_stt
] = 1;
1014 res_names
[res_stt
] = strdup("stringtable");
1015 present_resources
[res_usr
] = 1;
1016 res_names
[res_usr
] = strdup("user");
1017 present_resources
[res_msg
] = 1;
1018 res_names
[res_msg
] = strdup("messagetable");
1019 present_resources
[res_ver
] = 1;
1020 res_names
[res_ver
] = strdup("versioninfo");
1021 present_resources
[res_dlginit
] = 1;
1022 res_names
[res_dlginit
] = strdup("dlginit");
1023 present_resources
[res_toolbar
] = 1;
1024 res_names
[res_toolbar
] = strdup("toolbar");
1025 present_resources
[res_anicur
] = 1;
1026 res_names
[res_anicur
] = strdup("ani_cursor");
1027 present_resources
[res_aniico
] = 1;
1028 res_names
[res_aniico
] = strdup("ani_icon");
1030 for(res_type
= res_0
; res_type
<= res_usr
; res_type
++) {
1031 if(!present_resources
[res_type
]) {
1034 if(nb_resources
[res_type
][lang_type_normal
] > 0) {
1035 if(nb_resources
[res_type
][lang_type_master
] && nb_resources
[res_type
][lang_type_neutral
]) {
1036 fprintf(stderr
, "Type %s:\n", res_names
[res_type
]);
1037 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
]);
1038 } else if(nb_resources
[res_type
][lang_type_neutral
]) {
1039 fprintf(stderr
, "Type %s:\n", res_names
[res_type
]);
1040 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
]);
1041 list_resources
[res_type
][lang_type_master
] = list_resources
[res_type
][lang_type_neutral
];
1042 nb_resources
[res_type
][lang_type_master
] = nb_resources
[res_type
][lang_type_neutral
];
1043 } else if(!nb_resources
[res_type
][lang_type_master
]) {
1044 fprintf(stderr
, "Type %s:\n", res_names
[res_type
]);
1045 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 if(nb_resources
[res_type
][lang_type_master
] && nb_resources
[res_type
][lang_type_neutral
]) {
1049 fprintf(stderr
, "Type %s:\n", res_names
[res_type
]);
1050 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
]);
1051 } else if(nb_resources
[res_type
][lang_type_master
]) {
1052 fprintf(stderr
, "Type %s:\n", res_names
[res_type
]);
1053 fprintf(stderr
, "There are only MASTER versions for %s. No comparison will be done at all.\n", res_names
[res_type
]);
1054 } else if(nb_resources
[res_type
][lang_type_neutral
]) {
1055 /* fprintf(stderr, "There are only NEUTRAL versions for %s. No comparison will be done at all.\n", res_names[res_type]); */
1057 /* fprintf(stderr, "There are no versions at all for %s. No comparison will be done at all.\n", res_names[res_type]); */
1061 presence
= malloc(nb_resources
[res_type
][lang_type_master
]*sizeof(int *));
1062 for(i
= 0; i
< nb_resources
[res_type
][lang_type_master
]; i
++) {
1063 presence
[i
] = calloc(NB_LANG
, sizeof(int));
1064 presence
[i
][MASTER_LANGUAGE
] = -1;
1067 for(i
= 0; i
< nb_resources
[res_type
][lang_type_normal
]; i
++) {
1068 for(j
= 0; j
< nb_resources
[res_type
][lang_type_master
]; j
++) {
1069 nameid
= strdup(get_nameid_str(list_resources
[res_type
][lang_type_normal
][i
]->name
));
1070 if(!strcmp(nameid
, get_nameid_str(list_resources
[res_type
][lang_type_master
][j
]->name
))) {
1071 if(compare(list_resources
[res_type
][lang_type_normal
][i
], list_resources
[res_type
][lang_type_master
][j
])) {
1072 presence
[j
][get_language_id(list_resources
[res_type
][lang_type_normal
][i
])] = 2;
1073 /* 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 presence
[j
][get_language_id(list_resources
[res_type
][lang_type_normal
][i
])] = 1;
1082 problems
= malloc(sizeof(char *));
1083 problems
[0] = strdup("");
1086 for(i
= 0; i
< NB_LANG
; i
++) {
1090 for(j
= 0; j
< nb_resources
[res_type
][lang_type_master
]; j
++) {
1091 if(presence
[j
][i
]) {
1093 if(presence
[j
][i
] == 2) {
1095 problems
= realloc(problems
, (++nb_problems
+1)*sizeof(char *));
1096 problems
[nb_problems
] = malloc(strlen(get_nameid_str(list_resources
[res_type
][lang_type_master
][j
]->name
)) + 9);
1097 sprintf(problems
[nb_problems
], "DIFF %s %02x", get_nameid_str(list_resources
[res_type
][lang_type_master
][j
]->name
), i
);
1098 if(last_problem
== i
) {
1099 problems
[nb_problems
-1] = realloc(problems
[nb_problems
-1], strlen(problems
[nb_problems
-1]) + 3);
1100 strcat(problems
[nb_problems
-1], " \\");
1107 problems
= realloc(problems
, (++nb_problems
+1)*sizeof(char *));
1108 problems
[nb_problems
] = malloc(strlen(get_nameid_str(list_resources
[res_type
][lang_type_master
][j
]->name
)) + 8);
1109 sprintf(problems
[nb_problems
], "ABS %s %02x", get_nameid_str(list_resources
[res_type
][lang_type_master
][j
]->name
), i
);
1110 if(last_problem
== i
) {
1111 problems
[nb_problems
-1] = realloc(problems
[nb_problems
-1], strlen(problems
[nb_problems
-1]) + 3);
1112 strcat(problems
[nb_problems
-1], " \\");
1118 if(complete
&& partial
&& !needs_work
) {
1119 /* Support is complete, no need to do anything */
1120 /* fprintf(stderr, "Support for language %s is complete for %s.\n", get_language_name(i), res_names[res_type]); */
1122 } else if(complete
&& partial
&& needs_work
) {
1123 /* Support is incomplete (differing resources), needs work */
1124 /* fprintf(stderr, "Support for language %s is incomplete (differing resources) for %s.\n", get_language_name(i), res_names[res_type]); */
1126 } else if(!complete
&& partial
&& !needs_work
) {
1127 /* Support is incomplete (missing resources), needs work */
1128 /* fprintf(stderr, "Support for language %s is incomplete (missing resources) for %s.\n", get_language_name(i), res_names[res_type]); */
1130 } else if(!complete
&& partial
&& needs_work
) {
1131 /* Support is incomplete (missing and differing resources), needs work */
1132 /* fprintf(stderr, "Support for language %s is incomplete (missing and differing resources) for %s.\n", get_language_name(i), res_names[res_type]); */
1134 } else if(!complete
&& !partial
) {
1135 /* Support is totally absent, might be interesting to do */
1136 /* fprintf(stderr, "Support for language %s is absent for %s.\n", get_language_name(i), res_names[res_type]); */
1139 /* Support is not relevant, no need to do anything */
1140 /* fprintf(stderr, "Support for language %s is not relevant for %s.\n", get_language_name(i), res_names[res_type]); */
1145 for(i
= 1; i
<= nb_problems
; i
++) {
1146 printf("%s\n", problems
[i
]);
1151 for(i
= 0; i
< nb_resources
[res_type
][lang_type_master
]; i
++)