Translation support (wrc)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is part of my work on evaluating resource translations.

It contains the needed additions to wrc to compare (without needing to
create another parser) the various resource types.

For it to be truly useful, the second patch should be applied as well.

Changelog:
Add support for comparing resources to wrc for translations.

Vincent
Index: tools/wrc/Makefile.in
===================================================================
RCS file: /home/wine/wine/tools/wrc/Makefile.in,v
retrieving revision 1.28
diff -u -r1.28 Makefile.in
--- tools/wrc/Makefile.in	1 Sep 2003 23:59:41 -0000	1.28
+++ tools/wrc/Makefile.in	21 Oct 2003 02:50:58 -0000
@@ -15,6 +15,7 @@
 	genres.c \
 	newstruc.c \
 	readres.c \
+	translation.c \
 	utils.c \
 	wrc.c \
 	writeres.c
Index: tools/wrc/wrc.c
===================================================================
RCS file: /home/wine/wine/tools/wrc/wrc.c,v
retrieving revision 1.36
diff -u -r1.36 wrc.c
--- tools/wrc/wrc.c	18 Aug 2003 19:48:58 -0000	1.36
+++ tools/wrc/wrc.c	21 Oct 2003 02:50:58 -0000
@@ -39,6 +39,7 @@
 #include "utils.h"
 #include "readres.h"
 #include "dumpres.h"
+#include "translation.h"
 #include "genres.h"
 #include "newstruc.h"
 #include "parser.h"
@@ -97,6 +98,7 @@
 	"    * 0x08 Preprocessor messages\n"
 	"    * 0x10 Preprocessor lex messages\n"
 	"    * 0x20 Preprocessor yacc trace\n"
+	"    * 0x40 Verify translations\n"
 	"If no input filename is given and the output name is not overridden\n"
 	"with -o, then the output is written to \"wrc.tab.res\"\n"
 	;
@@ -123,6 +125,7 @@
  * debuglevel & DEBUGLEVEL_PPMSG	Preprocessor messages
  * debuglevel & DEBUGLEVEL_PPLEX	Preprocessor lex trace
  * debuglevel & DEBUGLEVEL_PPTRACE	Preprocessor yacc trace
+ * debuglevel & DEBUGLEVEL_TRANSLATION	Verify translations
  */
 int debuglevel = DEBUGLEVEL_NONE;
 
@@ -453,6 +456,12 @@
 
 	if(debuglevel & DEBUGLEVEL_DUMP)
 		dump_resources(resource_top);
+
+	if(debuglevel & DEBUGLEVEL_TRANSLATION)
+	{
+		verify_translations(resource_top);
+		exit(0);
+	}
 
 	/* Convert the internal lists to binary data */
 	resources2res(resource_top);
Index: tools/wrc/wrc.h
===================================================================
RCS file: /home/wine/wine/tools/wrc/wrc.h,v
retrieving revision 1.31
diff -u -r1.31 wrc.h
--- tools/wrc/wrc.h	5 Sep 2003 23:15:40 -0000	1.31
+++ tools/wrc/wrc.h	21 Oct 2003 02:50:58 -0000
@@ -45,6 +45,7 @@
 #define DEBUGLEVEL_PPMSG	0x0008
 #define DEBUGLEVEL_PPLEX	0x0010
 #define DEBUGLEVEL_PPTRACE	0x0020
+#define DEBUGLEVEL_TRANSLATION	0x0040
 
 extern int win32;
 extern int create_res;
--- /dev/null	2002-08-30 19:31:37.000000000 -0400
+++ tools/wrc/translation.c	2003-10-19 18:42:28.000000000 -0400
@@ -0,0 +1,894 @@
+/*
+ * Copyright 2003 Vincent Béron
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "translation.h"
+
+KEEP_RESOURCE(accelerator)
+KEEP_RESOURCE_RAW(bitmap)
+KEEP_RESOURCE(cursor)
+KEEP_RESOURCE(cursor_group)
+KEEP_RESOURCE(dialog)
+KEEP_RESOURCE(dialogex)
+KEEP_RESOURCE_RAW(font)
+KEEP_RESOURCE(icon)
+KEEP_RESOURCE(icon_group)
+KEEP_RESOURCE(menu)
+KEEP_RESOURCE(menuex)
+KEEP_RESOURCE_RAW(rcdata)
+KEEP_RESOURCE(stringtable)
+KEEP_RESOURCE_RAW(user)
+KEEP_RESOURCE_RAW(messagetable)
+KEEP_RESOURCE(versioninfo)
+KEEP_RESOURCE_RAW(dlginit)
+KEEP_RESOURCE(toolbar)
+KEEP_RESOURCE_RAW(ani_curico)
+
+static const char *get_language_name(int lid) {
+	PRETTYPRINTLANG(NEUTRAL)
+	PRETTYPRINTLANG(AFRIKAANS)
+	PRETTYPRINTLANG(ALBANIAN)
+	PRETTYPRINTLANG(ARABIC)
+	PRETTYPRINTLANG(ARMENIAN)
+	PRETTYPRINTLANG(ASSAMESE)
+	PRETTYPRINTLANG(AZERI)
+	PRETTYPRINTLANG(BASQUE)
+	PRETTYPRINTLANG(BELARUSIAN)
+	PRETTYPRINTLANG(BENGALI)
+	PRETTYPRINTLANG(BULGARIAN)
+	PRETTYPRINTLANG(CATALAN)
+	PRETTYPRINTLANG(CHINESE)
+	PRETTYPRINTLANG(CROATIAN)
+	PRETTYPRINTLANG(CZECH)
+	PRETTYPRINTLANG(DANISH)
+	PRETTYPRINTLANG(DIVEHI)
+	PRETTYPRINTLANG(DUTCH)
+	PRETTYPRINTLANG(ENGLISH)
+	PRETTYPRINTLANG(ESTONIAN)
+	PRETTYPRINTLANG(FAEROESE)
+	PRETTYPRINTLANG(FARSI)
+	PRETTYPRINTLANG(FINNISH)
+	PRETTYPRINTLANG(FRENCH)
+	PRETTYPRINTLANG(GALICIAN)
+	PRETTYPRINTLANG(GEORGIAN)
+	PRETTYPRINTLANG(GERMAN)
+	PRETTYPRINTLANG(GREEK)
+	PRETTYPRINTLANG(GUJARATI)
+	PRETTYPRINTLANG(HEBREW)
+	PRETTYPRINTLANG(HINDI)
+	PRETTYPRINTLANG(HUNGARIAN)
+	PRETTYPRINTLANG(ICELANDIC)
+	PRETTYPRINTLANG(INDONESIAN)
+	PRETTYPRINTLANG(ITALIAN)
+	PRETTYPRINTLANG(JAPANESE)
+	PRETTYPRINTLANG(KANNADA)
+	PRETTYPRINTLANG(KASHMIRI)
+	PRETTYPRINTLANG(KAZAK)
+	PRETTYPRINTLANG(KONKANI)
+	PRETTYPRINTLANG(KOREAN)
+	PRETTYPRINTLANG(KYRGYZ)
+	PRETTYPRINTLANG(LATVIAN)
+	PRETTYPRINTLANG(LITHUANIAN)
+	PRETTYPRINTLANG(MACEDONIAN)
+	PRETTYPRINTLANG(MALAY)
+	PRETTYPRINTLANG(MALAYALAM)
+	PRETTYPRINTLANG(MANIPURI)
+	PRETTYPRINTLANG(MARATHI)
+	PRETTYPRINTLANG(MONGOLIAN)
+	PRETTYPRINTLANG(NEPALI)
+	PRETTYPRINTLANG(NORWEGIAN)
+	PRETTYPRINTLANG(ORIYA)
+	PRETTYPRINTLANG(POLISH)
+	PRETTYPRINTLANG(PORTUGUESE)
+	PRETTYPRINTLANG(PUNJABI)
+	PRETTYPRINTLANG(ROMANIAN)
+	PRETTYPRINTLANG(RUSSIAN)
+	PRETTYPRINTLANG(SANSKRIT)
+	PRETTYPRINTLANG(SERBIAN)
+	PRETTYPRINTLANG(SINDHI)
+	PRETTYPRINTLANG(SLOVAK)
+	PRETTYPRINTLANG(SLOVENIAN)
+	PRETTYPRINTLANG(SPANISH)
+	PRETTYPRINTLANG(SWAHILI)
+	PRETTYPRINTLANG(SWEDISH)
+	PRETTYPRINTLANG(SYRIAC)
+	PRETTYPRINTLANG(TAMIL)
+	PRETTYPRINTLANG(TATAR)
+	PRETTYPRINTLANG(TELUGU)
+	PRETTYPRINTLANG(THAI)
+	PRETTYPRINTLANG(TURKISH)
+	PRETTYPRINTLANG(UKRAINIAN)
+	PRETTYPRINTLANG(URDU)
+	PRETTYPRINTLANG(UZBEK)
+	PRETTYPRINTLANG(VIETNAMESE)
+	PRETTYPRINTLANG(GAELIC)
+	PRETTYPRINTLANG(MALTESE)
+	PRETTYPRINTLANG(MAORI)
+	PRETTYPRINTLANG(RHAETO_ROMANCE)
+	PRETTYPRINTLANG(SAAMI)
+	PRETTYPRINTLANG(SORBIAN)
+	PRETTYPRINTLANG(SUTU)
+	PRETTYPRINTLANG(TSONGA)
+	PRETTYPRINTLANG(TSWANA)
+	PRETTYPRINTLANG(VENDA)
+	PRETTYPRINTLANG(XHOSA)
+	PRETTYPRINTLANG(ZULU)
+	PRETTYPRINTLANG(ESPERANTO)
+	PRETTYPRINTLANG(WALON)
+	PRETTYPRINTLANG(CORNISH)
+	PRETTYPRINTLANG(WELSH)
+	PRETTYPRINTLANG(BRETON)
+	return "Unkown language";
+}
+
+static int compare_accelerator(accelerator_t *accelerator1, accelerator_t *accelerator2) {
+	int different = 0;
+	event_t *ev1 = NULL, *ev2 = NULL;
+	if(!different &&
+	   ((accelerator1->memopt != accelerator2->memopt) ||
+	   (accelerator1->lvc.version != accelerator2->lvc.version) ||
+	   (accelerator1->lvc.characts != accelerator2->lvc.characts)))
+		different = 1;
+	ev1 = accelerator1->events;
+	ev2 = accelerator2->events;
+	while(!different && ev1 && ev2) {
+		if(!different &&
+		   ((ev1->id != ev2->id) ||
+		   (ev1->flags != ev2->flags)))
+			different = 1;
+		ev1 = ev1->next;
+		ev2 = ev2->next;
+	}
+	if(!different &&
+	   ((ev1 && !ev2) || (!ev1 && ev2)))
+		different = 1;
+	return different;
+}
+
+static int compare_bitmap(bitmap_t *bitmap1, bitmap_t *bitmap2) {
+	int different = 0;
+	if(!different &&
+	   ((bitmap1->memopt != bitmap2->memopt) ||
+	   (bitmap1->data->lvc.version != bitmap2->data->lvc.version) ||
+	   (bitmap1->data->lvc.characts != bitmap2->data->lvc.characts)))
+		different = 1;
+	return different;
+}
+
+static int compare_cursor(cursor_t *cursor1, cursor_t *cursor2) {
+	int different = 0;
+	if(!different &&
+	   ((cursor1->id != cursor2->id) ||
+	   (cursor1->width != cursor2->width) ||
+	   (cursor1->height != cursor2->height) ||
+	   (cursor1->xhot != cursor2->xhot) ||
+	   (cursor1->yhot != cursor2->yhot)))
+		different = 1;
+	if(!different &&
+	   ((cursor1->lvc.version != cursor2->lvc.version) ||
+	   (cursor1->lvc.characts != cursor2->lvc.characts)))
+		different = 1;
+	return different;
+}
+
+static int compare_cursor_group(cursor_group_t *cursor_group1, cursor_group_t *cursor_group2) {
+	int different = 0;
+	cursor_t *cursor1 = NULL, *cursor2 = NULL;
+	if(!different &&
+	   ((cursor_group1->memopt != cursor_group2->memopt) ||
+	   (cursor_group1->lvc.version != cursor_group2->lvc.version) ||
+	   (cursor_group1->lvc.characts != cursor_group2->lvc.characts)))
+		different = 1;
+	if(!different &&
+	   (cursor_group1->ncursor != cursor_group2->ncursor))
+		different = 1;
+	if(!different) {
+		cursor1 = cursor_group1->cursorlist;
+		cursor2 = cursor_group2->cursorlist;
+		while(!different && cursor1 && cursor2) {
+			different = compare_cursor(cursor1, cursor2);
+			cursor1 = cursor1->next;
+			cursor2 = cursor2->next;
+		}
+		if(!different &&
+		   ((cursor1 && !cursor2) ||
+		   (!cursor1 && cursor2)))
+			different = 1;
+	}
+	return different;
+}
+
+static int compare_control(control_t *control1, control_t *control2) {
+	int different = 0;
+	char *nameid = NULL;
+	if(!different &&
+		((control1 && !control2) ||
+		(!control1 && control2)))
+			different = 1;
+	if(different || !control1 || !control2)
+		return different;
+	nameid = strdup(get_nameid_str(control1->ctlclass));
+	if(!different && strcmp(nameid, get_nameid_str(control2->ctlclass)))
+		different = 1;
+	free(nameid);
+	if(!different && 
+	   (control1->id != control2->id))
+		different = 1;
+	if(!different && control1->gotstyle && control2->gotstyle) {
+		if((!control1->style || !control2->style) ||
+		   (control1->style->and_mask || control2->style->and_mask) ||
+		   (control1->style->or_mask != control2->style->or_mask))
+			different = 1;
+	} else if(!different &&
+		  ((control1->gotstyle && !control2->gotstyle) ||
+		  (!control1->gotstyle && control2->gotstyle)))
+			different = 1;
+	if(!different && control1->gotexstyle && control2->gotexstyle) {
+		if((!control1->exstyle || !control2->exstyle) ||
+		   (control1->exstyle->and_mask || control2->exstyle->and_mask) ||
+		   (control1->exstyle->or_mask != control2->exstyle->or_mask))
+			different = 1;
+	} else if(!different &&
+		  ((control1->gotexstyle && !control2->gotexstyle) ||
+		  (!control1->gotexstyle && control2->gotexstyle)))
+			different = 1;
+	if(!different && control1->gothelpid && control2->gothelpid) {
+		if(control1->helpid != control2->helpid)
+			different = 1;
+	} else if(!different &&
+		  ((control1->gothelpid && !control2->gothelpid) ||
+		  (!control1->gothelpid && control2->gothelpid)))
+			different = 1;
+	return different;
+}
+
+static int compare_dialog(dialog_t *dialog1, dialog_t *dialog2) {
+	int different = 0;
+	char *nameid = NULL;
+	if(!different &&
+	   ((dialog1->memopt != dialog2->memopt) ||
+	   (dialog1->lvc.version != dialog2->lvc.version) ||
+	   (dialog1->lvc.characts != dialog2->lvc.characts)))
+		different = 1;
+	if(!different && dialog1->gotstyle && dialog2->gotstyle) {
+		if((!dialog1->style || !dialog2->style) ||
+		   (dialog1->style->and_mask || dialog2->style->and_mask) ||
+		   (dialog1->style->or_mask != dialog2->style->or_mask))
+			different = 1;
+	} else if(!different &&
+		  ((dialog1->gotstyle && !dialog2->gotstyle) ||
+		  (!dialog1->gotstyle && dialog2->gotstyle)))
+			different = 1;
+	if(!different && dialog1->gotexstyle && dialog2->gotexstyle) {
+		if((!dialog1->exstyle || !dialog2->exstyle) ||
+		   (dialog1->exstyle->and_mask || dialog2->exstyle->and_mask) ||
+		   (dialog1->exstyle->or_mask != dialog2->exstyle->or_mask))
+			different = 1;
+	} else if(!different &&
+		  ((dialog1->gotexstyle && !dialog2->gotexstyle) ||
+		  (!dialog1->gotexstyle && dialog2->gotexstyle)))
+			different = 1;
+	nameid = strdup(get_nameid_str(dialog1->menu));
+	if(!different && strcmp(nameid, get_nameid_str(dialog2->menu)))
+		different = 1;
+	free(nameid);
+	nameid = strdup(get_nameid_str(dialog1->dlgclass));
+	if(!different && strcmp(nameid, get_nameid_str(dialog2->dlgclass)))
+		different = 1;
+	free(nameid);
+	if(!different)
+		different = compare_control(dialog1->controls, dialog2->controls);
+	return different;
+}
+
+static int compare_dialogex(dialogex_t *dialogex1, dialogex_t *dialogex2) {
+	int different = 0;
+	char *nameid = NULL;
+	if(!different &&
+	   ((dialogex1->memopt != dialogex2->memopt) ||
+	   (dialogex1->lvc.version != dialogex2->lvc.version) ||
+	   (dialogex1->lvc.characts != dialogex2->lvc.characts)))
+		different = 1;
+	if(!different && dialogex1->gotstyle && dialogex2->gotstyle) {
+		if((!dialogex1->style || !dialogex2->style) ||
+		   (dialogex1->style->and_mask || dialogex2->style->and_mask) ||
+		   (dialogex1->style->or_mask != dialogex2->style->or_mask))
+			different = 1;
+	} else if(!different &&
+		  ((dialogex1->gotstyle && !dialogex2->gotstyle) ||
+		  (!dialogex1->gotstyle && dialogex2->gotstyle)))
+			different = 1;
+	if(!different && dialogex1->gotexstyle && dialogex2->gotexstyle) {
+		if((!dialogex1->exstyle || !dialogex2->exstyle) ||
+		   (dialogex1->exstyle->and_mask || dialogex2->exstyle->and_mask) ||
+		   (dialogex1->exstyle->or_mask != dialogex2->exstyle->or_mask))
+			different = 1;
+	} else if(!different &&
+		  ((dialogex1->gotexstyle && !dialogex2->gotexstyle) ||
+		  (!dialogex1->gotexstyle && dialogex2->gotexstyle)))
+			different = 1;
+	if(!different && dialogex1->gothelpid && dialogex2->gothelpid) {
+		if(dialogex1->helpid != dialogex2->helpid)
+			different = 1;
+	} else if(!different &&
+		  ((dialogex1->gothelpid && !dialogex2->gothelpid) ||
+		  (!dialogex1->gothelpid && dialogex2->gothelpid)))
+			different = 1;
+	nameid = strdup(get_nameid_str(dialogex1->menu));
+	if(!different && strcmp(nameid, get_nameid_str(dialogex2->menu)))
+		different = 1;
+	free(nameid);
+	nameid = strdup(get_nameid_str(dialogex1->dlgclass));
+	if(!different && strcmp(nameid, get_nameid_str(dialogex2->dlgclass)))
+		different = 1;
+	free(nameid);
+	if(!different)
+		different = compare_control(dialogex1->controls, dialogex2->controls);
+	return different;
+}
+
+static int compare_font(font_t *font1, font_t *font2) {
+	int different = 0;
+	if(!different &&
+	   ((font1->memopt != font2->memopt) ||
+	   (font1->data->lvc.version != font2->data->lvc.version) ||
+	   (font1->data->lvc.characts != font2->data->lvc.characts)))
+		different = 1;
+	return different;
+}
+
+static int compare_icon(icon_t *icon1, icon_t *icon2) {
+	int different = 0;
+	if(!different &&
+	   ((icon1->id != icon2->id) ||
+	   (icon1->width != icon2->width) ||
+	   (icon1->height != icon2->height)))
+		different = 1;
+	if(!different &&
+	   ((icon1->lvc.version != icon2->lvc.version) ||
+	   (icon1->lvc.characts != icon2->lvc.characts)))
+		different = 1;
+	return different;
+}
+
+static int compare_icon_group(icon_group_t *icon_group1, icon_group_t *icon_group2) {
+	int different = 0;
+	icon_t *icon1 = NULL, *icon2 = NULL;
+	if(!different &&
+	   ((icon_group1->memopt != icon_group2->memopt) ||
+	   (icon_group1->lvc.version != icon_group2->lvc.version) ||
+	   (icon_group1->lvc.characts != icon_group2->lvc.characts)))
+		different = 1;
+	if(!different &&
+	   (icon_group1->nicon != icon_group2->nicon))
+		different = 1;
+	if(!different) {
+		icon1 = icon_group1->iconlist;
+		icon2 = icon_group2->iconlist;
+		while(!different && icon1 && icon2) {
+			different = compare_icon(icon1, icon2);
+			icon1 = icon1->next;
+			icon2 = icon2->next;
+		}
+		if(!different &&
+		   ((icon1 && !icon2) ||
+		   (!icon1 && icon2)))
+			different = 1;
+	}
+	return different;
+}
+
+static int compare_menu_item(menu_item_t *menu_item1, menu_item_t *menu_item2) {
+	int different = 0;
+	while(!different && menu_item1 && menu_item2) {
+		if(menu_item1->popup && menu_item2->popup)
+			different = compare_menu_item(menu_item1->popup, menu_item2->popup);
+		else if(!menu_item1->popup && !menu_item2->popup) {
+			if(menu_item1->name && menu_item2->name) {
+				if((menu_item1->id != menu_item2->id) ||
+				   (menu_item1->state != menu_item2->state))
+					different = 1;
+			} else if((menu_item1->name && !menu_item2->name) ||
+				  (!menu_item1->name && menu_item2->name))
+					different = 1;
+		} else
+			different = 1;
+		menu_item1 = menu_item1->next;
+		menu_item2 = menu_item2->next;
+	}
+	if(!different &&
+	   ((menu_item1 && !menu_item2) ||
+	   (!menu_item1 && menu_item2)))
+		different = 1;
+	return different;
+}
+
+static int compare_menu(menu_t *menu1, menu_t *menu2) {
+	int different = 0;
+	if(!different &&
+	   ((menu1->memopt != menu2->memopt) ||
+	   (menu1->lvc.version != menu2->lvc.version) ||
+	   (menu1->lvc.characts != menu2->lvc.characts)))
+		different = 1;
+	if(!different)
+		different = compare_menu_item(menu1->items, menu2->items);
+	return different;
+}
+
+static int compare_menuex_item(menuex_item_t *menuex_item1, menuex_item_t *menuex_item2) {
+	int different = 0;
+	while(!different && menuex_item1 && menuex_item2) {
+		if(menuex_item1->popup && menuex_item2->popup) {
+			if(!different && menuex_item1->gotid && menuex_item2->gotid) {
+				if(menuex_item1->id != menuex_item2->id)
+					different = 1;
+			} else if(!different &&
+				  ((menuex_item1->gotid && !menuex_item2->gotid) ||
+				  (!menuex_item2->gotid && menuex_item2->gotid)))
+					different = 1;
+			if(!different && menuex_item1->gottype && menuex_item2->gottype) {
+				if(menuex_item1->type != menuex_item2->type)
+					different = 1;
+			} else if(!different &&
+				  ((menuex_item1->gottype && !menuex_item2->gottype) ||
+				  (!menuex_item2->gottype && menuex_item2->gottype)))
+					different = 1;
+			if(!different && menuex_item1->gotstate && menuex_item2->gotstate) {
+				if(menuex_item1->state != menuex_item2->state)
+					different = 1;
+			} else if(!different &&
+				  ((menuex_item1->gotstate && !menuex_item2->gotstate) ||
+				  (!menuex_item2->gotstate && menuex_item2->gotstate)))
+					different = 1;
+			if(!different && menuex_item1->gothelpid && menuex_item2->gothelpid) {
+				if(menuex_item1->helpid != menuex_item2->helpid)
+					different = 1;
+			} else if(!different &&
+				  ((menuex_item1->gothelpid && !menuex_item2->gothelpid) ||
+				  (!menuex_item2->gothelpid && menuex_item2->gothelpid)))
+					different = 1;
+			if(!different)
+				different = compare_menuex_item(menuex_item1->popup, menuex_item2->popup);
+		} else if(!menuex_item1->popup && !menuex_item2->popup) {
+			if(menuex_item1->name && menuex_item2->name) {
+				if(!different && menuex_item1->gotid && menuex_item2->gotid) {
+					if(menuex_item1->id != menuex_item2->id)
+						different = 1;
+				} else if(!different &&
+					  ((menuex_item1->gotid && !menuex_item2->gotid) ||
+					  (!menuex_item2->gotid && menuex_item2->gotid)))
+						different = 1;
+				if(!different && menuex_item1->gottype && menuex_item2->gottype) {
+					if(menuex_item1->type != menuex_item2->type)
+						different = 1;
+				} else if(!different &&
+					  ((menuex_item1->gottype && !menuex_item2->gottype) ||
+					  (!menuex_item2->gottype && menuex_item2->gottype)))
+						different = 1;
+				if(!different && menuex_item1->gotstate && menuex_item2->gotstate) {
+					if(menuex_item1->state != menuex_item2->state)
+						different = 1;
+				} else if(!different &&
+					  ((menuex_item1->gotstate && !menuex_item2->gotstate) ||
+					  (!menuex_item2->gotstate && menuex_item2->gotstate)))
+						different = 1;
+				if(!different && menuex_item1->gothelpid && menuex_item2->gothelpid) {
+					if(menuex_item1->helpid != menuex_item2->helpid)
+						different = 1;
+				} else if(!different &&
+					  ((menuex_item1->gothelpid && !menuex_item2->gothelpid) ||
+					  (!menuex_item2->gothelpid && menuex_item2->gothelpid)))
+						different = 1;
+			} else if((menuex_item1->name && !menuex_item2->name) ||
+				  (!menuex_item1->name && menuex_item2->name))
+					different = 1;
+		} else
+			different = 1;
+		menuex_item1 = menuex_item1->next;
+		menuex_item2 = menuex_item2->next;
+	}
+	if(!different &&
+	   ((menuex_item1 && !menuex_item2) ||
+	   (!menuex_item1 && menuex_item2)))
+		different = 1;
+	return different;
+}
+
+static int compare_menuex(menuex_t *menuex1, menuex_t *menuex2) {
+	int different = 0;
+	if(!different &&
+	   ((menuex1->memopt != menuex2->memopt) ||
+	   (menuex1->lvc.version != menuex2->lvc.version) ||
+	   (menuex1->lvc.characts != menuex2->lvc.characts)))
+		different = 1;
+	if(!different)
+		different = compare_menuex_item(menuex1->items, menuex2->items);
+	return different;
+}
+
+static int compare_rcdata(rcdata_t *rcdata1, rcdata_t *rcdata2) {
+	int different = 0;
+	if(!different &&
+	   ((rcdata1->memopt != rcdata2->memopt) ||
+	   (rcdata1->data->lvc.version != rcdata2->data->lvc.version) ||
+	   (rcdata1->data->lvc.characts != rcdata2->data->lvc.characts)))
+		different = 1;
+	return different;
+}
+
+static int compare_stringtable(stringtable_t *stringtable1, stringtable_t *stringtable2) {
+	int different = 0;
+	int i;
+	while(!different && stringtable1 && stringtable2) {
+		if((stringtable1->memopt != stringtable2->memopt) ||
+		   (stringtable1->lvc.version != stringtable2->lvc.version) ||
+		   (stringtable1->lvc.characts != stringtable2->lvc.characts))
+			different = 1;
+		if(!different) {
+			if((stringtable1->nentries != stringtable2->nentries) ||
+			   (stringtable1->idbase != stringtable2->idbase))
+				different = 1;
+			else
+				for(i = 0 ; i < stringtable1->nentries; i++)
+					if((stringtable1->entries[i].id != stringtable2->entries[i].id) ||
+					   (stringtable1->entries[i].memopt != stringtable2->entries[i].memopt) ||
+					   (stringtable1->entries[i].str && !stringtable2->entries[i].str) ||
+					   (!stringtable1->entries[i].str && stringtable2->entries[i].str)) {
+						different = 1;
+						break;
+					}
+		}
+		stringtable1 = stringtable1->next;
+		stringtable2 = stringtable2->next;
+	}
+	return different;
+}
+
+static int compare_user(user_t *user1, user_t *user2) {
+	int different = 0;
+	char *nameid = NULL;
+	if(!different &&
+	   ((user1->memopt != user2->memopt) ||
+	   (user1->data->lvc.version != user2->data->lvc.version) ||
+	   (user1->data->lvc.characts != user2->data->lvc.characts)))
+		different = 1;
+	nameid = strdup(get_nameid_str(user1->type));
+	if(!different && strcmp(nameid, get_nameid_str(user2->type)))
+		different = 1;
+	free(nameid);
+	return different;
+}
+
+static int compare_messagetable(messagetable_t *messagetable1, messagetable_t *messagetable2) {
+	int different = 0;
+	if(!different &&
+	   ((messagetable1->memopt != messagetable2->memopt) ||
+	   (messagetable1->data->lvc.version != messagetable2->data->lvc.version) ||
+	   (messagetable1->data->lvc.characts != messagetable2->data->lvc.characts)))
+		different = 1;
+	return different;
+}
+
+static int compare_string(string_t *string1, string_t *string2) {
+	int different = 0;
+	if(!different &&
+	   ((string1->size != string2->size) ||
+	   (string1->type != string2->type)))
+		different = 1;
+	if(!different) {
+		if(string1->type == str_char)
+			different = memcmp(string1->str.cstr, string2->str.cstr, string1->size);
+		else if(string1->type == str_unicode)
+			different = memcmp(string1->str.wstr, string2->str.wstr, string1->size*sizeof(WCHAR));
+		else
+			different = 1;
+	}
+	return different;
+}
+
+static int compare_ver_block(ver_block_t *ver_block1, ver_block_t *ver_block2);
+
+static int compare_ver_value(ver_value_t *ver_value1, ver_value_t *ver_value2) {
+	int different = 0;
+	int i = 0;
+	if(!different &&
+	   (ver_value1->type == ver_value2->type)) {
+		switch(ver_value1->type) {
+			case val_str:
+				if(!different && ver_value1->key && ver_value2->key)
+					different = compare_string(ver_value1->key, ver_value2->key);
+				else if(!different &&
+					((ver_value1->key && !ver_value2->key) ||
+					(!ver_value1->key && ver_value2->key)))
+						different = 1;
+				break;
+			case val_words:
+				if(!different && ver_value1->key && ver_value2->key)
+					different = compare_string(ver_value1->key, ver_value2->key);
+				else if(!different &&
+					((ver_value1->key && !ver_value2->key) ||
+					(!ver_value1->key && ver_value2->key)))
+						different = 1;
+				if(!different && ver_value1->value.words && ver_value2->value.words) {
+					if(!different &&
+					   (ver_value1->value.words->nwords != ver_value2->value.words->nwords))
+						different = 1;
+					if(!different)
+						for(i = 0; i < ver_value1->value.words->nwords; i++) {
+							if(ver_value1->value.words->words[i] != ver_value2->value.words->words[i]) {
+								different = 1;
+								break;
+							}
+						}
+				} else if(!different &&
+					  ((ver_value1->value.words && !ver_value2->value.words) ||
+					  (!ver_value1->value.words && ver_value2->value.words)))
+						different = 1;
+				break;
+			case val_block:
+				if(!different && ver_value1->value.block && ver_value2->value.block)
+					different = compare_ver_block(ver_value1->value.block, ver_value2->value.block);
+				else if(!different &&
+					((ver_value1->value.block && !ver_value2->value.block) ||
+					(!ver_value1->value.block && ver_value2->value.block)))
+						different = 1;
+				break;
+			default:
+				different = 1;
+		}
+	} else
+		different = 1;
+	return different;
+}
+
+static int compare_ver_block(ver_block_t *ver_block1, ver_block_t *ver_block2) {
+	int different = 0;
+	ver_value_t *ver_value1 = NULL, *ver_value2 = NULL;
+	if(!different) {
+		ver_value1 = ver_block1->values;
+		ver_value2 = ver_block2->values;
+		while(!different && ver_value1 && ver_value2) {
+			different = compare_ver_value(ver_value1, ver_value2);
+			ver_value1 = ver_value1->next;
+			ver_value2 = ver_value2->next;
+		}
+		if(!different &&
+		   ((ver_value1 && !ver_value2) ||
+		   (!ver_value1 && ver_value2)))
+			different = 1;
+	}
+	return different;
+}
+
+static int compare_versioninfo(versioninfo_t *versioninfo1, versioninfo_t *versioninfo2) {
+	int different = 0;
+	ver_block_t *ver_block1 = NULL, *ver_block2 = NULL;
+	if(!different &&
+	   ((versioninfo1->memopt != versioninfo2->memopt) ||
+	   (versioninfo1->lvc.version != versioninfo2->lvc.version) ||
+	   (versioninfo1->lvc.characts != versioninfo2->lvc.characts)))
+		different = 1;
+	if(!different && versioninfo1->gotit.fv && versioninfo2->gotit.fv) {
+		if((versioninfo1->filever_maj1 != versioninfo2->filever_maj1) ||
+		   (versioninfo1->filever_maj2 != versioninfo2->filever_maj2) ||
+		   (versioninfo1->filever_min1 != versioninfo2->filever_min1) ||
+		   (versioninfo1->filever_min2 != versioninfo2->filever_min2))
+			different = 1;
+	} else if(!different &&
+		  ((versioninfo1->gotit.fv && !versioninfo2->gotit.fv) ||
+		  (!versioninfo1->gotit.fv && versioninfo2->gotit.fv)))
+			different = 1;
+	if(!different && versioninfo1->gotit.pv && versioninfo2->gotit.pv) {
+		if((versioninfo1->prodver_maj1 != versioninfo2->prodver_maj1) ||
+		   (versioninfo1->prodver_maj2 != versioninfo2->prodver_maj2) ||
+		   (versioninfo1->prodver_min1 != versioninfo2->prodver_min1) ||
+		   (versioninfo1->prodver_min2 != versioninfo2->prodver_min2))
+			different = 1;
+	} else if(!different &&
+		  ((versioninfo1->gotit.pv && !versioninfo2->gotit.pv) ||
+		  (!versioninfo1->gotit.pv && versioninfo2->gotit.pv)))
+			different = 1;
+	if(!different && versioninfo1->gotit.fo && versioninfo2->gotit.fo) {
+		if(versioninfo1->fileos != versioninfo2->fileos)
+			different = 1;
+	} else if(!different &&
+		  ((versioninfo1->gotit.fo && !versioninfo2->gotit.fo) ||
+		  (!versioninfo1->gotit.fo && versioninfo2->gotit.fo)))
+			different = 1;
+	if(!different && versioninfo1->gotit.ff && versioninfo2->gotit.ff) {
+		if(versioninfo1->fileflags != versioninfo2->fileflags)
+			different = 1;
+	} else if(!different &&
+		  ((versioninfo1->gotit.ff && !versioninfo2->gotit.ff) ||
+		  (!versioninfo1->gotit.ff && versioninfo2->gotit.ff)))
+			different = 1;
+	if(!different && versioninfo1->gotit.ffm && versioninfo2->gotit.ffm) {
+		if(versioninfo1->fileflagsmask != versioninfo2->fileflagsmask)
+			different = 1;
+	} else if(!different &&
+		  ((versioninfo1->gotit.ffm && !versioninfo2->gotit.ffm) ||
+		  (!versioninfo1->gotit.ffm && versioninfo2->gotit.ffm)))
+			different = 1;
+	if(!different && versioninfo1->gotit.ft && versioninfo2->gotit.ft) {
+		if(versioninfo1->filetype != versioninfo2->filetype)
+			different = 1;
+	} else if(!different &&
+		  ((versioninfo1->gotit.ft && !versioninfo2->gotit.ft) ||
+		  (!versioninfo1->gotit.ft && versioninfo2->gotit.ft)))
+			different = 1;
+	if(!different && versioninfo1->gotit.fst && versioninfo2->gotit.fst) {
+		if(versioninfo1->filesubtype != versioninfo2->filesubtype)
+			different = 1;
+	} else if(!different &&
+		  ((versioninfo1->gotit.fst && !versioninfo2->gotit.fst) ||
+		  (!versioninfo1->gotit.fst && versioninfo2->gotit.fst)))
+			different = 1;
+	if(!different) {
+		ver_block1 = versioninfo1->blocks;
+		ver_block2 = versioninfo2->blocks;
+		while(!different && ver_block1 && ver_block2) {
+			different = compare_ver_block(ver_block1, ver_block2);
+			ver_block1 = ver_block1->next;
+			ver_block2 = ver_block2->next;
+		}
+		if(!different &&
+		   ((ver_block1 && !ver_block2) ||
+		   (ver_block1 && !ver_block2)))
+			different = 1;
+	}
+	return different;
+}
+
+static int compare_dlginit(dlginit_t *dlginit1, dlginit_t *dlginit2) {
+	int different = 0;
+	if(!different &&
+	   ((dlginit1->memopt != dlginit2->memopt) ||
+	   (dlginit1->data->lvc.version != dlginit2->data->lvc.version) ||
+	   (dlginit1->data->lvc.characts != dlginit2->data->lvc.characts)))
+		different = 1;
+	return different;
+}
+
+static int compare_toolbar_item(toolbar_item_t *toolbar_item1, toolbar_item_t *toolbar_item2) {
+	int different = 0;
+	while(!different && toolbar_item1 && toolbar_item2) {
+		if((toolbar_item1->id && !toolbar_item2->id) ||
+		   (!toolbar_item1->id && toolbar_item2->id))
+			different = 1;
+		toolbar_item1 = toolbar_item1->next;
+		toolbar_item2 = toolbar_item2->next;
+	}
+	if(!different &&
+	   ((toolbar_item1 && !toolbar_item2) ||
+	   (!toolbar_item1 && toolbar_item2)))
+		different = 1;
+	return different;
+}
+
+static int compare_toolbar(toolbar_t *toolbar1, toolbar_t *toolbar2) {
+	int different = 0;
+	if(!different &&
+	   ((toolbar1->memopt != toolbar2->memopt) ||
+	   (toolbar1->lvc.version != toolbar2->lvc.version) ||
+	   (toolbar1->lvc.characts != toolbar2->lvc.characts)))
+		different = 1;
+	if(!different)
+		different = compare_toolbar_item(toolbar1->items, toolbar2->items);
+	return different;
+}
+
+static int compare_ani_curico(ani_curico_t *ani_curico1, ani_curico_t *ani_curico2) {
+	int different = 0;
+	if(!different &&
+	   ((ani_curico1->memopt != ani_curico2->memopt) ||
+	   (ani_curico1->data->lvc.version != ani_curico2->data->lvc.version) ||
+	   (ani_curico1->data->lvc.characts != ani_curico2->data->lvc.characts)))
+		different = 1;
+	return different;
+}
+
+void verify_translations(resource_t *top) {
+	DEFINE_VARIABLES_TRANSLATION
+	resource_t *next = top;
+	while(next) {
+		switch(next->type) {
+			case res_acc:
+				add_accelerator(next, next->res.acc);
+				break;
+			case res_bmp:
+				add_bitmap(next, next->res.bmp);
+				break;
+			case res_cur:
+				add_cursor(next, next->res.cur);
+				break;
+			case res_curg:
+				add_cursor_group(next, next->res.curg);
+				break;
+			case res_dlg:
+				add_dialog(next, next->res.dlg);
+				break;
+			case res_dlgex:
+				add_dialogex(next, next->res.dlgex);
+				break;
+			case res_fnt:
+				add_font(next, next->res.fnt);
+				break;
+			case res_ico:
+				add_icon(next, next->res.ico);
+				break;
+			case res_icog:
+				add_icon_group(next, next->res.icog);
+				break;
+			case res_men:
+				add_menu(next, next->res.men);
+				break;
+			case res_menex:
+				add_menuex(next, next->res.menex);
+				break;
+			case res_rdt:
+				add_rcdata(next, next->res.rdt);
+				break;
+			case res_stt:
+				add_stringtable(next, next->res.stt);
+				break;
+			case res_usr:
+				add_user(next, next->res.usr);
+				break;
+			case res_msg:
+				add_messagetable(next, next->res.msg);
+				break;
+			case res_ver:
+				add_versioninfo(next, next->res.ver);
+				break;
+			case res_dlginit:
+				add_dlginit(next, next->res.dlgi);
+				break;
+			case res_toolbar:
+				add_toolbar(next, next->res.tbt);
+				break;
+			case res_anicur:
+			case res_aniico:
+				add_ani_curico(next, next->res.ani);
+				break;
+			default:
+				fprintf(stderr, "Report this: unkown resource type parsed %08x\n", next->type);
+		}
+		next = next->next;
+	}
+	CHECK_TRANSLATION(accelerator)
+	CHECK_TRANSLATION_RAW(bitmap)
+	CHECK_TRANSLATION(cursor)
+	CHECK_TRANSLATION(cursor_group)
+	CHECK_TRANSLATION(dialog)
+	CHECK_TRANSLATION(dialogex)
+	CHECK_TRANSLATION_RAW(font)
+	CHECK_TRANSLATION(icon)
+	CHECK_TRANSLATION(icon_group)
+	CHECK_TRANSLATION(menu)
+	CHECK_TRANSLATION(menuex)
+	CHECK_TRANSLATION_RAW(rcdata)
+	CHECK_TRANSLATION(stringtable)
+	CHECK_TRANSLATION_RAW(user)
+	CHECK_TRANSLATION_RAW(messagetable)
+	CHECK_TRANSLATION(versioninfo)
+	CHECK_TRANSLATION_RAW(dlginit)
+	CHECK_TRANSLATION(toolbar)
+	CHECK_TRANSLATION_RAW(ani_curico)
+}
--- /dev/null	2002-08-30 19:31:37.000000000 -0400
+++ tools/wrc/translation.h	2003-10-20 22:38:45.000000000 -0400
@@ -0,0 +1,219 @@
+/*
+ * Verification of resources translations prototypes
+ *
+ * Copyright 2003 Vincent Béron
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WRC_TRANSLATION_H
+#define __WRC_TRANSLATION_H
+
+#include <string.h>
+
+#include "dumpres.h"
+
+#define MASTER_LANGUAGE LANG_ENGLISH
+
+#define KEEP_RESOURCE_COMMON(type, lang_id) \
+	int nb_list_##type = 0; \
+	int nb_master_##type = 0; \
+	int nb_neutral_##type = 0; \
+	resource_t **list_resource_##type = NULL; \
+	resource_t **master_resource_##type = NULL; \
+	resource_t **neutral_resource_##type = NULL; \
+	type##_t **list_##type = NULL; \
+	type##_t **master_##type = NULL; \
+	type##_t **neutral_##type = NULL; \
+	static void add_##type(resource_t *resource, type##_t *type) { \
+		if(type lang_id->lvc.language->id == MASTER_LANGUAGE) { \
+			ADD_RESOURCE(type, master) \
+		} else if(type lang_id->lvc.language->id == LANG_NEUTRAL) { \
+			ADD_RESOURCE(type, neutral) \
+		} else { \
+			ADD_RESOURCE(type, list) \
+		} \
+	}
+
+#define ADD_RESOURCE(type, list) { \
+	nb_##list##_##type++; \
+	list##_##type = realloc(list##_##type, nb_##list##_##type*sizeof(type##_t *)); \
+	list##_##type[nb_##list##_##type-1] = type; \
+	list##_resource_##type = realloc(list##_resource_##type, nb_##list##_##type*sizeof(resource_t *)); \
+	list##_resource_##type[nb_##list##_##type-1] = resource; \
+	}
+
+#define KEEP_RESOURCE(type) \
+	KEEP_RESOURCE_COMMON(type, )
+
+#define KEEP_RESOURCE_RAW(type) \
+	KEEP_RESOURCE_COMMON(type, ->data)
+
+#define DEFINE_VARIABLES_TRANSLATION \
+	int i, j; \
+	int **presence; \
+	int complete, partial, needs_work; \
+	char *nameid; \
+	char **problems; \
+	int nb_problems; \
+	int last_problem;
+
+#define ENSURE_MASTER_PRESENT(type) \
+	if(nb_list_##type > 0) { \
+		if(nb_master_##type && nb_neutral_##type) { \
+			fprintf(stderr, "There are both a NEUTRAL and a MASTER versions for %s, along with additional localized versions. The NEUTRAL versions will not be checked against other versions.\n", #type); \
+		} else if(nb_neutral_##type) { \
+			fprintf(stderr, "There are no MASTER version, but there are some NEUTRAL versions for %s, so will use those instead of MASTER.\n", #type); \
+			master_resource_##type = neutral_resource_##type; \
+			master_##type = neutral_##type; \
+			nb_master_##type = nb_neutral_##type; \
+		} else if(!nb_master_##type) { \
+			fprintf(stderr, "There are no NEUTRAL nor MASTER version for %s, but there are some other localized versions. No comparison will be done at all.\n", #type); \
+		} \
+	} else { \
+		if(nb_master_##type && nb_neutral_##type) { \
+			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", #type); \
+		} else if(nb_master_##type) { \
+			fprintf(stderr, "There are only MASTER versions for %s. No comparison will be done at all.\n", #type); \
+		} else if(nb_neutral_##type) { \
+			fprintf(stderr, "There are only NEUTRAL versions for %s. No comparison will be done at all.\n", #type); \
+		} else { \
+			/* fprintf(stderr, "There are no versions at all for %s. No comparison will be done at all.\n", #type); */ \
+		} \
+	}
+
+#define NB_LANG 0x94
+#define CHECK_DIFFERENCES(type, lang_id) \
+	presence = malloc(nb_master_##type*sizeof(int *)); \
+	problems = malloc(sizeof(char *)); \
+	problems[0] = strdup(""); \
+	nb_problems = 0; \
+	last_problem = -1; \
+	for(i = 0; i < nb_master_##type; i++) { \
+		presence[i] = calloc(NB_LANG, sizeof(int)); \
+		presence[i][MASTER_LANGUAGE] = -1; \
+	} \
+	for(i = 0; i < nb_list_##type; i++) { \
+		for(j = 0; j < nb_master_##type; j++) { \
+			nameid = strdup(get_nameid_str(list_resource_##type[i]->name)); \
+			if(!strcmp(nameid, get_nameid_str(master_resource_##type[j]->name))) { \
+				if(compare_##type(list_##type[i], master_##type[j])) { \
+					presence[j][list_##type[i]lang_id->lvc.language->id] = 2; \
+					/*problems = realloc(problems, (++nb_problems+1)*sizeof(char *));*/ \
+					/*problems[nb_problems] = malloc(strlen(nameid) + 9);*/ \
+					/*sprintf(problems[nb_problems], "DIFF %s %02x", nameid, list_##type[i]lang_id->lvc.language->id);*/ \
+					/*if(last_problem == list_##type[i]lang_id->lvc.language->id) {*/ \
+					/*	problems[nb_problems-1] = realloc(problems[nb_problems-1], strlen(problems[nb_problems-1]) + 3);*/ \
+					/*	strcat(problems[nb_problems-1], " \\");*/ \
+					/*} else {*/ \
+					/*	last_problem = list_##type[i]lang_id->lvc.language->id;*/ \
+					/*}*/ \
+					fprintf(stderr, "Differences in type %s, ID %s, for language %s\n", #type, nameid, get_language_name(list_##type[i]lang_id->lvc.language->id)); \
+				} else { \
+					presence[j][list_##type[i]lang_id->lvc.language->id] = 1; \
+				} \
+			} \
+			free(nameid); \
+		} \
+	} \
+	last_problem = -1; \
+	for(i = 0; i < NB_LANG; i++) { \
+		needs_work = 0; \
+		partial = 0; \
+		complete = 1; \
+		for(j = 0; j < nb_master_##type; j++) { \
+			if(presence[j][i]) { \
+				partial = 1; \
+				if(presence[j][i] == 2) { \
+					needs_work = 1; \
+					problems = realloc(problems, (++nb_problems+1)*sizeof(char *)); \
+					problems[nb_problems] = malloc(strlen(get_nameid_str(master_resource_##type[j]->name)) + 9); \
+					sprintf(problems[nb_problems], "DIFF %s %02x", get_nameid_str(master_resource_##type[j]->name), i); \
+					if(last_problem == i) { \
+						problems[nb_problems-1] = realloc(problems[nb_problems-1], strlen(problems[nb_problems-1]) + 3); \
+						strcat(problems[nb_problems-1], " \\"); \
+					} else { \
+						last_problem = i; \
+					} \
+				} \
+			} else { \
+				complete = 0; \
+				problems = realloc(problems, (++nb_problems+1)*sizeof(char *)); \
+				problems[nb_problems] = malloc(strlen(get_nameid_str(master_resource_##type[j]->name)) + 8); \
+				sprintf(problems[nb_problems], "ABS %s %02x", get_nameid_str(master_resource_##type[j]->name), i); \
+				if(last_problem == i) { \
+					problems[nb_problems-1] = realloc(problems[nb_problems-1], strlen(problems[nb_problems-1]) + 3); \
+					strcat(problems[nb_problems-1], " \\"); \
+				} else { \
+					last_problem = i; \
+				} \
+			} \
+		} \
+		if(complete && partial && !needs_work) { \
+			/* Support is complete, no need to do anything */ \
+			/* fprintf(stderr, "Support for language %s is complete for %s.\n", get_language_name(i), #type); */ \
+			printf("."); \
+		} else if(complete && partial && needs_work) { \
+			/* Support is incomplete (differing resources), needs work */ \
+			/* fprintf(stderr, "Support for language %s is incomplete (differing resources) for %s.\n", get_language_name(i), #type); */ \
+			printf("x"); \
+		} else if(!complete && partial && !needs_work) { \
+			/* Support is incomplete (missing resources), needs work */ \
+			/* fprintf(stderr, "Support for language %s is incomplete (missing resources) for %s.\n", get_language_name(i), #type); */ \
+			printf("-"); \
+		} else if(!complete && partial && needs_work) { \
+			/* Support is incomplete (missing and differing resources), needs work */ \
+			/* fprintf(stderr, "Support for language %s is incomplete (missing and differing resources) for %s.\n", get_language_name(i), #type); */ \
+			printf("+"); \
+		} else if(!complete && !partial) { \
+			/* Support is totally absent, might be interesting to do */ \
+			/* fprintf(stderr, "Support for language %s is absent for %s.\n", get_language_name(i), #type); */ \
+			printf(" "); \
+		} else { \
+			/* Support is not relevant, no need to do anything */ \
+			/* fprintf(stderr, "Support for language %s is not relevant for %s.\n", get_language_name(i), #type); */ \
+			printf("n"); \
+		} \
+	} \
+	printf("\n"); \
+	for(i = 1; i <= nb_problems; i++) { \
+		printf("%s\n", problems[i]); \
+		free(problems[i]); \
+	} \
+	free(problems[0]); \
+	free(problems); \
+	for(i = 0; i < nb_master_##type; i++) { \
+		free(presence[i]); \
+	} \
+	free(presence);
+
+#define CHECK_TRANSLATION(type) \
+	fprintf(stderr, "Type %s:\n", #type); \
+	ENSURE_MASTER_PRESENT(type) \
+	CHECK_DIFFERENCES(type, )
+
+#define CHECK_TRANSLATION_RAW(type) \
+	fprintf(stderr, "Type %s:\n", #type); \
+	ENSURE_MASTER_PRESENT(type) \
+	CHECK_DIFFERENCES(type, ->data)
+
+#define PRETTYPRINTLANG(langid) \
+	if(LANG_##langid == lid) { \
+		return #langid; \
+	}
+
+void verify_translations(resource_t *top);
+
+#endif

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux