• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
my_streq(const char * va,const char * vb)12 static 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 
39 typedef struct {
40 	char *locale;
41 	char *orig;
42 	char *latin1;
43 	char *utf8;
44 } TestCase;
45 
46 const 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 
check(const int i)71 static 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 
checks()133 static 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 
main(int argc,char * argv[])178 int 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