1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include <i18n.h>
6#include <langinfo.h>
7#include <libintl.h>
8
9/* return whether byte strings are equal or not.
10 * NULL strings are never equal
11 */
12static int my_streq(const char *va, const char *vb) {
13	const char *a = va;
14	const char *b = vb;
15	int i;
16	if ((NULL == a) || (NULL == b)) {
17		return 0;
18	}
19	for (i=0; a[i] != '\0' && b[i] != '\0'; i++) {
20		if (a[i] != b[i]) {
21			return 0;
22		}
23	}
24	return 1;
25}
26
27#if defined(CODESET_UTF_8)
28#define MY_CODESET "UTF-8"
29#elif defined(CODESET_LATIN1)
30#define MY_CODESET "iso-8859-1"
31#elif defined(CODESET_DEFAULT)
32#define MY_CODESET "default"
33#define bind_textdomain_codeset(domain,codeset) \
34	MY_CODESET
35#else
36#error Define one of the CODESET_* macros!
37#endif
38
39typedef struct {
40	char *locale;
41	char *orig;
42	char *latin1;
43	char *utf8;
44} TestCase;
45
46const TestCase testcases[] = {
47	{ "de_DE",
48	  N_("High saturation"),
49	  /* &auml; latin1   oct 333     hex e4    dec 228     */
50	  "Hohe S\344ttigung",
51	  /* &auml; utf-8    oct 303 244 hex c3 a4 dec 195 164 */
52	  "Hohe S\303\244ttigung" },
53	{ "fr_FR",
54	  N_("Not defined"),
55	  /* &eacute; latin1 oct 351     hex e9    dec 233     */
56	  "Non d\233fini",
57	  /* &eacute; utf-8  oct 303 251 hex c3    dec 195     */
58	  "Non d\303\251fini"
59	},
60	{ "es_ES",
61	  N_("High saturation"),
62	  /* &oacute; latin1 oct hex       dec 243 */
63	  "Alta saturaci\363n",
64	  /* &oacute; utf-8  oct hex c3 b3 dec */
65	  "Alta saturaci\303\263n"
66	},
67	{ NULL, NULL, NULL, NULL }
68};
69
70
71static int check(const int i)
72{
73	const char *oldtextdomain = textdomain(NULL);
74	const char *newtextdomain = textdomain(GETTEXT_PACKAGE);
75
76	const char *newcodeset = MY_CODESET;
77	const char *oldcodeset = bind_textdomain_codeset(GETTEXT_PACKAGE, NULL);
78	const char *realcodeset = bind_textdomain_codeset(GETTEXT_PACKAGE, MY_CODESET);
79
80	const char *orig   = testcases[i].orig;
81	const char *transl = gettext(testcases[i].orig);
82	const char *latin1 = testcases[i].latin1;
83	const char *utf8   = testcases[i].utf8;
84
85	printf(
86		"Old textdomain:  %s\n"
87		"New textdomain:  %s\n",
88		oldtextdomain,
89		newtextdomain
90		);
91
92	if (NULL != oldcodeset) {
93		printf(
94		       "Old codeset:     \"%s\" (locale default)\n",
95		       nl_langinfo(CODESET)
96		       );
97	} else {
98		printf(
99		       "Old codeset:     \"%s\"\n",
100		       oldcodeset
101		       );
102	}
103
104	printf(
105	       "Wanted codeset:  %s\n"
106	       "Real codeset:    %s\n",
107	       newcodeset,
108	       realcodeset
109	       );
110
111	printf(
112	       "Original:   %s\n"
113	       "Translated: %s\n"
114	       "iso-8859-1: %s\n"
115	       "utf-8:      %s\n",
116	       orig,
117	       transl,
118	       latin1,
119	       utf8
120	       );
121
122#if defined(CODESET_UTF_8)
123	return (my_streq(transl, utf8));
124#elif defined(CODESET_LATIN_1)
125	return (my_streq(transl, latin1));
126#else
127	/* make sure my_streq is used once */
128	return (my_streq(orig, orig));
129#endif
130}
131
132
133static int checks()
134{
135	int i;
136
137	const char *localeenv = getenv("LOCALEDIR");
138	const char *localedir = (localeenv!=NULL)?localeenv:LOCALEDIR;
139	const char *msgcatdir = bindtextdomain(GETTEXT_PACKAGE, localedir);
140
141	/* set locale to env settings */
142	const char *oldlocale = setlocale(LC_ALL, NULL);
143	const char *newlocale = setlocale(LC_ALL, "");
144
145	if (localeenv != NULL) {
146		printf("Msg catalog dir: %s (from environment variable LOCALEDIR\n",
147		       msgcatdir);
148	} else {
149		printf("Msg catalog dir: %s\n", msgcatdir);
150	}
151
152	if (newlocale == NULL) {
153		printf("Locale not available: \"%s\"\n", newlocale);
154		printf("Aborting without error.\n");
155		return 1;
156	}
157
158
159	printf(
160		"Old locale:      %s\n"
161		"New locale:      %s\n",
162		oldlocale,
163		newlocale
164		);
165
166	for (i=0; testcases[i].locale != NULL; i++) {
167		const int localelen = strlen(testcases[i].locale);
168		if (strncmp(newlocale, testcases[i].locale, localelen) == 0) {
169			return check(i);
170		}
171	}
172
173	printf("No test case found for locale: %s\n", newlocale);
174	return 1;
175}
176
177
178int main(int argc, char *argv[])
179{
180	if (argc > 1) {
181		if ((argc == 2) && (strcmp("--list", argv[1]) == 0)) {
182			int i;
183			for (i=0; testcases[i].locale != NULL; i++) {
184				printf("%s\n", testcases[i].locale);
185			}
186			return 0;
187		} else {
188			int i;
189			fprintf(stderr, "Illegal command line. Aborting.\n");
190			fprintf(stderr, "argc: %03d\n", argc);
191			for (i=0; i<argc; i++) {
192				fprintf(stderr, "%03d \"%s\"\n", i, argv[i]);
193			}
194			return 1;
195		}
196	} else {
197		int ret = checks();
198		printf("Test result: %s\n", (ret)?"success":"failure");
199		return (ret)?0:1;
200	}
201	return -1;
202}
203
204/*
205 * Local Variables:
206 * mode:c
207 * c-basic-offset: 8
208 * End:
209 */
210