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