Home | History | Annotate | Download | only in nls
      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  */
     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 
     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 
    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 
    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