1 /*
2  * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
3  *
4  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
5  */
6 #define _GNU_SOURCE
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <locale.h>
11 #include <stddef.h>
12 #include <wctype.h>
13 #include <limits.h>
14 
15 #ifndef _CTYPE_H
16 #define _CTYPE_H
17 #endif
18 #ifndef _WCTYPE_H
19 #define _WCTYPE_H
20 #endif
21 #include "include/bits/uClibc_ctype.h"
22 
23 /* TODO: maybe support -v like gen_wctype.c */
24 #define verbose_msg(msg...) if (verbose) fprintf(stderr, msg)
25 
26 /*  #define CTYPE_PACKED */
27 #define UPLOW_IDX_SHIFT		3
28 /* best if 2 unpacked or 3 packed */
29 #define CTYPE_IDX_SHIFT		3
30 /* 3 or 4 are very similar */
31 #define C2WC_IDX_SHIFT		3
32 
33 #define CTYPE_IDX_LEN		(128 >> (CTYPE_IDX_SHIFT))
34 #define UPLOW_IDX_LEN		(128 >> (UPLOW_IDX_SHIFT))
35 #define C2WC_IDX_LEN		(128 >> (C2WC_IDX_SHIFT))
36 
37 /*  #ifdef CTYPE_PACKED */
38 /*  #define CTYPE_ROW_LEN		(1 << ((CTYPE_IDX_SHIFT)-1)) */
39 /*  #else */
40 #define CTYPE_ROW_LEN		(1 << (CTYPE_IDX_SHIFT))
41 /*  #endif */
42 #define UPLOW_ROW_LEN		(1 << (UPLOW_IDX_SHIFT))
43 #define C2WC_ROW_LEN		(1 << (C2WC_IDX_SHIFT))
44 
45 
46 
47 #define MAX_WCHAR	(0x2600-1)
48 
49 static unsigned char ctype_tbl[256 * CTYPE_ROW_LEN];
50 static unsigned char uplow_tbl[256 * UPLOW_ROW_LEN];
51 #ifdef DO_WIDE_CHAR
52 static unsigned short c2wc_tbl[256 * C2WC_ROW_LEN];
53 #endif
54 static unsigned char tt[MAX_WCHAR+1];
55 static unsigned char ti[MAX_WCHAR+1];
56 static unsigned char xi[MAX_WCHAR+1];
57 
58 static int n_ctype_rows;
59 static int n_uplow_rows;
60 #ifdef DO_WIDE_CHAR
61 static int n_c2wc_rows;
62 #endif
63 static int tt_num;
64 static int ti_num;
65 
66 #define RANGE MAX_WCHAR
67 
68 #define TT_SHIFT 4
69 #define TI_SHIFT 4
70 
71 #define II_LEN		((MAX_WCHAR+1) >> (TT_SHIFT+TI_SHIFT))
72 
73 typedef struct {
74 	unsigned long c2w[256];
75 	unsigned char w2c[MAX_WCHAR];
76 	unsigned char ii[II_LEN];
77 	unsigned char ctype_idx[CTYPE_IDX_LEN];
78 	unsigned char uplow_idx[UPLOW_IDX_LEN];
79 	unsigned char c2wc_idx[C2WC_IDX_LEN];
80 } charset_data;
81 
main(int argc,char ** argv)82 int main(int argc, char **argv)
83 {
84 	FILE *fp;
85 	charset_data csd[30];
86 	unsigned long max_wchar;
87 	unsigned char *p;
88 	int numsets;
89 	int i;
90 	int j;
91 	char buf[80];
92 	unsigned char row[256];
93 #ifdef DO_WIDE_CHAR
94 	unsigned short wrow[256];
95 #endif
96 	char codeset_list[500];
97 	char codeset_index[30];
98 	int codeset_list_end = 0;
99 	int total_size = 0;
100 
101 	if (!setlocale(LC_CTYPE, "en_US.UTF-8")) {
102 		/* Silly foreigners disabling en_US locales */
103 		FILE *fp = popen("locale -a", "r");
104 		if (!fp)
105 			goto locale_failure;
106 
107 		while (!feof(fp)) {
108 			char buf[256];
109 			size_t len;
110 
111 			if (fgets(buf, sizeof(buf) - 10, fp) == NULL)
112 				goto locale_failure;
113 
114 			len = strlen(buf);
115 			if (len > 0 && buf[len - 1] == '\n')
116 				buf[--len] = '\0';
117 			if (len < 5 || strcasecmp(&buf[len-5], ".UTF8") != 0)
118 				strcat(buf, ".UTF8");
119 			if (setlocale(LC_CTYPE, buf))
120 				goto locale_success;
121 		}
122 
123  locale_failure:
124 		printf("could not find a UTF8 locale ... please enable en_US.UTF-8\n");
125 		return EXIT_FAILURE;
126  locale_success:
127 		pclose(fp);
128 	}
129 
130 #if 0
131 	if (argc == 1) {
132 		/* User requested 8-bit codesets, but didn't list any... */
133 		/* Allow to build, just so this feature can be left on in config. */
134 		printf("#ifdef __CTYPE_HAS_8_BIT_LOCALES\n");
135 		printf("#warning ignoring 8 bit codesets request"
136 				" as no codesets specified.\n");
137 		printf("#endif\n");
138 		printf("#undef __CTYPE_HAS_8_BIT_LOCALES\n\n");
139 
140 		printf("#define __LOCALE_DATA_NUM_CODESETS\t\t0\n");
141 		printf("#define __LOCALE_DATA_CODESET_LIST\t\t\"\"\n");
142 		return EXIT_SUCCESS;
143 	}
144 
145 /*  	printf("#define __CTYPE_HAS_8_BIT_LOCALES\t1\n\n"); */
146 	printf("#ifdef __CTYPE_HAS_8_BIT_LOCALES\n\n");
147 #endif
148 
149 	if (argc == 1) {
150 		printf("#undef __CTYPE_HAS_8_BIT_LOCALES\n\n");
151 
152 		printf("#define __LOCALE_DATA_NUM_CODESETS\t\t0\n");
153 		printf("#define __LOCALE_DATA_CODESET_LIST\t\t\"\"\n");
154 	} else {
155 		printf("#define __CTYPE_HAS_8_BIT_LOCALES\t\t1\n\n");
156 	}
157 
158 	printf("#define __LOCALE_DATA_Cctype_IDX_SHIFT\t%d\n", CTYPE_IDX_SHIFT);
159 	printf("#define __LOCALE_DATA_Cctype_IDX_LEN\t\t%d\n", CTYPE_IDX_LEN);
160 #ifdef CTYPE_PACKED
161 	printf("#define __LOCALE_DATA_Cctype_ROW_LEN\t\t%d\n", CTYPE_ROW_LEN >> 1);
162 	printf("#define __LOCALE_DATA_Cctype_PACKED\t\t1\n");
163 #else
164 	printf("#define __LOCALE_DATA_Cctype_ROW_LEN\t\t%d\n", CTYPE_ROW_LEN);
165 	printf("#undef __LOCALE_DATA_Cctype_PACKED\n");
166 #endif
167 
168 	printf("\n#define __LOCALE_DATA_Cuplow_IDX_SHIFT\t%d\n", UPLOW_IDX_SHIFT);
169 	printf("#define __LOCALE_DATA_Cuplow_IDX_LEN\t\t%d\n", UPLOW_IDX_LEN);
170 	printf("#define __LOCALE_DATA_Cuplow_ROW_LEN\t\t%d\n", UPLOW_ROW_LEN);
171 
172 #ifdef DO_WIDE_CHAR
173 	printf("\n#define __LOCALE_DATA_Cc2wc_IDX_LEN\t\t%d\n", C2WC_IDX_LEN);
174 	printf("#define __LOCALE_DATA_Cc2wc_IDX_SHIFT\t\t%d\n", C2WC_IDX_SHIFT);
175 	printf("#define __LOCALE_DATA_Cc2wc_ROW_LEN\t\t%d\n", C2WC_ROW_LEN);
176 #endif
177 
178 	printf("\ntypedef struct {\n");
179 	printf("\tunsigned char idx8ctype[%d];\n", CTYPE_IDX_LEN);
180 	printf("\tunsigned char idx8uplow[%d];\n", UPLOW_IDX_LEN);
181 #ifdef DO_WIDE_CHAR
182 	printf("\tunsigned char idx8c2wc[%d];\n", C2WC_IDX_LEN);
183 	printf("\tunsigned char idx8wc2c[%d];\n", II_LEN);
184 #endif
185 #ifndef __metag__
186 	printf("} __codeset_8_bit_t;\n\n");
187 #else
188 	printf("} __attribute__((__packed__)) __codeset_8_bit_t;\n\n");
189 #endif /* __metag__ */
190 
191 	printf("#ifdef WANT_DATA\n\n");
192 	printf("static const __codeset_8_bit_t codeset_8_bit[%d] = {\n", argc-1);
193 
194 	max_wchar = 0x7f;
195 	numsets = 0;
196 	codeset_index[0] = 0;
197 	while (--argc) {
198 		if (!(fp = fopen(*++argv,"r"))) {
199 			fprintf(stderr, "cannot open file \"%s\"\n", *argv);
200 			return EXIT_FAILURE;
201 		}
202 		fprintf(stderr, "processing %s... ", *argv);
203 
204 		{
205 			char *s0;
206 			char *s1;
207 			int n;
208 
209 			s0 = strrchr(*argv, '/');
210 			if (!s0) {
211 				s0 = *argv;
212 			} else {
213 				++s0;
214 			}
215 			s1 = strrchr(s0, '.');
216 			if (!s1) {
217 				n = strlen(s0);
218 			} else {
219 				n = s1 - s0;
220 			}
221 
222 /*  			if ((numsets == 0) && strncmp("ASCII", s0, n)) { */
223 /*  				printf("error - first codeset isn't ASCII!\n"); */
224 /*  				return EXIT_FAILURE; */
225 /*  			} */
226 
227 			if (numsets >= sizeof(codeset_index)) {
228 				fprintf(stderr, "error - too many codesets!\n");
229 				return EXIT_FAILURE;
230 			}
231 
232 			if (codeset_list_end + n + 1 + numsets + 1 + 1 >= 256) {
233 				fprintf(stderr, "error - codeset list to big!\n");
234 				return EXIT_FAILURE;
235 			}
236 
237 			codeset_index[numsets+1] = codeset_index[numsets] + n+1;
238 			strncpy(codeset_list + codeset_list_end, s0, n);
239 			codeset_list_end += (n+1);
240 			codeset_list[codeset_list_end - 1] = 0;
241 
242 			printf("\t{ /* %.*s */", n, s0);
243 		}
244 
245 		memset(&csd[numsets], 0, sizeof(charset_data));
246 		memset(xi, 0, sizeof(xi));
247 		{
248 			unsigned long c, wc;
249 			int lines;
250 			lines = 0;
251 			while (fgets(buf,sizeof(buf),fp)) {
252 				if ((2 != sscanf(buf, "{ %lx , %lx", &c, &wc))
253 					|| (c >= 256) || (wc > MAX_WCHAR)) {
254 					fprintf(stderr, "error: scanf failure! \"%s\"\n", buf);
255 					return EXIT_FAILURE;
256 				}
257 
258 				/* don't put in w2c... dynamicly build tt instead. */
259 
260 				if (c <= 0x7f) { /* check the 7bit entries but don't store */
261 					if (c != wc) {
262 						fprintf(stderr, "error: c != wc in %s\n", buf);
263 						return EXIT_FAILURE;
264 					}
265 					csd[numsets].c2w[c] = wc;
266 					csd[numsets].w2c[wc] = 0; /* ignore */
267 					if (wc > max_wchar) {
268 						max_wchar = wc;
269 					}
270 				} else {
271 					csd[numsets].c2w[c] = wc;
272 					csd[numsets].w2c[wc] = c;
273 					if (wc > max_wchar) {
274 						max_wchar = wc;
275 					}
276 				}
277 				++lines;
278 			}
279 			fprintf(stderr, "%d lines  ", lines);
280 
281 			for (i = 0 ; i <= MAX_WCHAR ; i += (1 << TT_SHIFT)) {
282 				p = &csd[numsets].w2c[i];
283 				for (j = 0 ; j < tt_num ; j++) {
284 					if (!memcmp(p, &tt[j << TT_SHIFT], (1 << TT_SHIFT))) {
285 						break;
286 					}
287 				}
288 				if (j == tt_num) { /* new entry */
289 					memcpy(&tt[j << TT_SHIFT], p, (1 << TT_SHIFT));
290 					++tt_num;
291 				}
292 				xi[i >> TT_SHIFT] = j;
293 			}
294 
295 			for (i = 0 ; i <= (MAX_WCHAR >> TT_SHIFT)  ; i += (1 << TI_SHIFT)) {
296 				p = &xi[i];
297 				for (j = 0 ; j < ti_num ; j++) {
298 					if (!memcmp(p, &ti[j << TI_SHIFT], (1 << TI_SHIFT))) {
299 						break;
300 					}
301 				}
302 				if (j == ti_num) { /* new entry */
303 					memcpy(&ti[j << TI_SHIFT], p, (1 << TI_SHIFT));
304 					++ti_num;
305 				}
306 				csd[numsets].ii[i >> TI_SHIFT] = j;
307 /*  				fprintf(stderr, "%d ", i >> TI_SHIFT); */
308 			}
309 
310 #if 1
311 			printf("\n\t\t/* idx8ctype data */\n\t\t{");
312 			for (i = 128 ; i < 256 ; i++) {
313 				wchar_t c;
314 				unsigned int d;
315 
316 /*  				if (!(i & 0x7)) { */
317 /*  					printf("\n"); */
318 /*  				} */
319 
320 				c = csd[numsets].c2w[i];
321 
322 				if (c == 0) {	/* non-existant char in codeset */
323 					d = __CTYPE_unclassified;
324 				} else if (iswdigit(c)) {
325 					d = __CTYPE_digit;
326 				} else if (iswalpha(c)) {
327 					d = __CTYPE_alpha_nonupper_nonlower;
328 					if (iswlower(c)) {
329 						d = __CTYPE_alpha_lower;
330 						if (iswupper(c)) {
331 							d = __CTYPE_alpha_upper_lower;
332 						}
333 					} else if (iswupper(c)) {
334 						d = __CTYPE_alpha_upper;
335 					}
336 				} else if (iswpunct(c)) {
337 					d = __CTYPE_punct;
338 				} else if (iswgraph(c)) {
339 					d = __CTYPE_graph;
340 				} else if (iswprint(c)) {
341 					d = __CTYPE_print_space_nonblank;
342 					if (iswblank(c)) {
343 						d = __CTYPE_print_space_blank;
344 					}
345 				} else if (iswspace(c) && !iswcntrl(c)) {
346 					d = __CTYPE_space_nonblank_noncntrl;
347 					if (iswblank(c)) {
348 						d = __CTYPE_space_blank_noncntrl;
349 					}
350 				} else if (iswcntrl(c)) {
351 					d = __CTYPE_cntrl_nonspace;
352 					if (iswspace(c)) {
353 						d = __CTYPE_cntrl_space_nonblank;
354 						if (iswblank(c)) {
355 							d = __CTYPE_cntrl_space_blank;
356 						}
357 					}
358 				} else {
359 					d = __CTYPE_unclassified;
360 				}
361 
362 #if 1
363 				row[i & (CTYPE_ROW_LEN-1)] = d;
364 				if ((i & (CTYPE_ROW_LEN-1)) == (CTYPE_ROW_LEN-1)) {
365 					p = ctype_tbl;
366 					for (j=0 ; j < n_ctype_rows ; j++) {
367 						if (!memcmp(p, row, CTYPE_ROW_LEN)) {
368 							break;
369 						}
370 						p += CTYPE_ROW_LEN;
371 					}
372 					if (j == n_ctype_rows) { /* new entry */
373 						if (++n_ctype_rows > 256) {
374 							fprintf(stderr, "error -- to many ctype rows!\n");
375 							return EXIT_FAILURE;
376 						}
377 						memcpy(p, row, CTYPE_ROW_LEN);
378 					}
379 					csd[numsets].ctype_idx[i >> CTYPE_IDX_SHIFT] = j;
380 					if (!((i >> CTYPE_IDX_SHIFT) & 0x7)
381 						&& (i != (127 + CTYPE_ROW_LEN))
382 						) {
383 						printf("\n\t\t ");
384 					}
385 					printf(" %#4x,", j);
386 				}
387 #else
388 				printf(" %#4x,", d);
389 #endif
390 			}
391 #endif
392 			printf(" }");
393 
394 #if 1
395 			printf(",\n\t\t/* idx8uplow data */\n\t\t{");
396 			for (i = 128 ; i < 256 ; i++) {
397 				wchar_t c, u, l;
398 /*  				if (!(i & 0x7)) { */
399 /*  					printf("\n"); */
400 /*  				} */
401 				c = csd[numsets].c2w[i];
402 				if ((c != 0) || 1) {
403 					u = towupper(c);
404 					l = towlower(c);
405 
406 					if (u >= 0x80) u = csd[numsets].w2c[u];
407 					if (l >= 0x80) l = csd[numsets].w2c[l];
408 
409 					if (u == 0) u = i; /* upper is missing, so ignore */
410 					if (l == 0) l = i; /* lower is missing, so ignore */
411 
412 #if 1
413 					/* store as unsigned char and let overflow handle it. */
414 /*  					if ((((u-i) < CHAR_MIN) || ((u-i) > CHAR_MAX)) */
415 /*  						|| (((i-l) < CHAR_MIN) || ((i-l) > CHAR_MAX)) */
416 /*  						) { */
417 /*  						fprintf(stderr, "error - uplow diff out of range! %d %ld %ld\n", */
418 /*  							   i, u, l); */
419 /*  						return EXIT_FAILURE; */
420 /*  					} */
421 
422 					row[i & (UPLOW_ROW_LEN-1)] = ((l==i) ? (u-i) : (i-l));
423 					if ((i & (UPLOW_ROW_LEN-1)) == (UPLOW_ROW_LEN-1)) {
424 						p = uplow_tbl;
425 						for (j=0 ; j < n_uplow_rows ; j++) {
426 							if (!memcmp(p, row, UPLOW_ROW_LEN)) {
427 								break;
428 							}
429 							p += UPLOW_ROW_LEN;
430 						}
431 						if (j == n_uplow_rows) { /* new entry */
432 							if (++n_uplow_rows > 256) {
433 								fprintf(stderr, "error -- to many uplow rows!\n");
434 								return EXIT_FAILURE;
435 							}
436 							memcpy(p, row, UPLOW_ROW_LEN);
437 						}
438 						csd[numsets].uplow_idx[i >> UPLOW_IDX_SHIFT] = j;
439 						if (!((i >> UPLOW_IDX_SHIFT) & 0x7)
440 							&& (i != (127 + UPLOW_ROW_LEN))
441 							) {
442 							printf("\n\t\t ");
443 						}
444 						printf(" %#4x,", j);
445 					}
446 
447 #elif 0
448 					if (!(i & 0x7) && i) {
449 						printf("\n");
450 					}
451 					printf(" %4ld,", (l==i) ? (u-i) : (i-l));
452 /*  					printf(" %4ld,", (l==i) ? u : l); */
453 #else
454 					if ((u != i) || (l != i)) {
455 #if 0
456 						printf(" %#08lx, %#08lx, %#08lx, %#08lx, %#08lx, %#08lx, \n",
457 								(unsigned long) i,
458 								(unsigned long) c,
459 								(unsigned long) l,
460 								(unsigned long) towlower(c),
461 								(unsigned long) u,
462 								(unsigned long) towupper(c));
463 
464 #else
465 						printf(" %#08lx, %8ld, %d, %8ld, %d, %#08lx\n",
466 								(unsigned long) i,
467 								(long) (l - i),
468 								iswupper(c),
469 								(long) (i - u),
470 								iswlower(c),
471 								(unsigned long) c);
472 #endif
473 					}
474 #endif
475 				}
476 			}
477 			printf(" }");
478 #endif
479 
480 #ifndef DO_WIDE_CHAR
481 			printf("\n");
482 #else  /* DO_WIDE_CHAR */
483 
484 #if 1
485 			printf(",\n\t\t/* idx8c2wc data */\n\t\t{");
486 			for (i = 128 ; i < 256 ; i++) {
487 #if 1
488 				wrow[i & (C2WC_ROW_LEN-1)] = csd[numsets].c2w[i];
489 				if ((i & (C2WC_ROW_LEN-1)) == (C2WC_ROW_LEN-1)) {
490 					p = (unsigned char *) c2wc_tbl;
491 					for (j=0 ; j < n_c2wc_rows ; j++) {
492 						if (!memcmp(p, (char *) wrow, 2*C2WC_ROW_LEN)) {
493 							break;
494 						}
495 						p += 2*C2WC_ROW_LEN;
496 					}
497 					if (j == n_c2wc_rows) { /* new entry */
498 						if (++n_c2wc_rows > 256) {
499 							fprintf(stderr, "error -- to many c2wc rows!\n");
500 							return EXIT_FAILURE;
501 						}
502 						memcpy(p, (char *) wrow, 2*C2WC_ROW_LEN);
503 					}
504 					csd[numsets].c2wc_idx[i >> C2WC_IDX_SHIFT] = j;
505 					if (!((i >> C2WC_IDX_SHIFT) & 0x7)
506 						&& (i != (127 + C2WC_ROW_LEN))
507 						) {
508 						printf("\n\t\t ");
509 					}
510 					printf(" %#4x,", j);
511 				}
512 #else
513 				if (!(i & 0x7) && i) {
514 					printf("\n");
515 				}
516 				printf(" %#6lx,", csd[numsets].c2w[i]);
517 #endif
518 			}
519 			printf(" },\n");
520 #endif
521 
522 #if 1
523 /*  			fprintf(stderr, "\nII_LEN = %d\n", II_LEN); */
524 			printf("\t\t/* idx8wc2c data */\n\t\t{");
525 			for (i = 0 ; i < II_LEN ; i++) {
526 				if (!(i & 0x7) && i) {
527 					printf("\n\t\t ");
528 				}
529 				printf(" %#4x,", csd[numsets].ii[i]);
530 			}
531 			printf(" }\n");
532 #endif
533 
534 #endif /* DO_WIDE_CHAR */
535 			printf("\t},\n");
536 
537 		}
538 		++numsets;
539 		fprintf(stderr, "done\n");
540 	}
541 	printf("};\n");
542 	printf("\n#endif /* WANT_DATA */\n");
543 
544 #ifdef DO_WIDE_CHAR
545 	printf("\n");
546 	printf("#define __LOCALE_DATA_Cwc2c_DOMAIN_MAX\t%#x\n", RANGE);
547 	printf("#define __LOCALE_DATA_Cwc2c_TI_SHIFT\t\t%d\n", TI_SHIFT);
548 	printf("#define __LOCALE_DATA_Cwc2c_TT_SHIFT\t\t%d\n", TT_SHIFT);
549 	printf("#define __LOCALE_DATA_Cwc2c_II_LEN\t\t%d\n", II_LEN);
550 	printf("#define __LOCALE_DATA_Cwc2c_TI_LEN\t\t%d\n", ti_num << TI_SHIFT);
551 	printf("#define __LOCALE_DATA_Cwc2c_TT_LEN\t\t%d\n", tt_num << TT_SHIFT);
552 	printf("\n");
553 
554 	printf("\n#define __LOCALE_DATA_Cwc2c_TBL_LEN\t\t%d\n",
555 			(ti_num << TI_SHIFT) + (tt_num << TT_SHIFT));
556 
557 	printf("#ifdef WANT_DATA\n\n");
558 	printf("static const unsigned char __LOCALE_DATA_Cwc2c_data[%d] = {\n",
559 			(ti_num << TI_SHIFT) + (tt_num << TT_SHIFT));
560 	printf("\t/* ti_table */\n\t");
561 	for (i=0 ; i < ti_num << TI_SHIFT ; i++) {
562 		if (!(i & 7) && i) {
563 			printf("\n\t");
564 		}
565 		printf(" %#4x,", ti[i]);
566 	}
567 	printf("\n");
568 	printf("\t/* tt_table */\n\t");
569 	for (i=0 ; i < tt_num << TT_SHIFT ; i++) {
570 		if (!(i & 7) && i) {
571 			printf("\n\t");
572 		}
573 		printf(" %#4x,", tt[i]);
574 	}
575 	printf("\n};\n");
576 
577 	printf("\n#endif /* WANT_DATA */\n");
578 #endif /* DO_WIDE_CHAR */
579 
580 	printf("\n#define __LOCALE_DATA_Cuplow_TBL_LEN\t\t%d\n",
581 			n_uplow_rows * UPLOW_ROW_LEN);
582 	printf("\n#ifdef WANT_DATA\n\n");
583 
584 	printf("\nstatic const unsigned char __LOCALE_DATA_Cuplow_data[%d] = {\n",
585 			n_uplow_rows * UPLOW_ROW_LEN);
586 	p = uplow_tbl;
587 	for (j=0 ; j < n_uplow_rows ; j++) {
588 		printf("\t");
589 		for (i=0 ; i < UPLOW_ROW_LEN ; i++) {
590 			printf(" %#4x,", (unsigned int)((unsigned char) p[i]));
591 		}
592 		printf("\n");
593 		p += UPLOW_ROW_LEN;
594 	}
595 	printf("};\n");
596 
597 	printf("\n#endif /* WANT_DATA */\n");
598 	printf("\n#define __LOCALE_DATA_Cctype_TBL_LEN\t\t%d\n",
599 #ifdef CTYPE_PACKED
600 			n_ctype_rows * CTYPE_ROW_LEN / 2
601 #else
602 			n_ctype_rows * CTYPE_ROW_LEN
603 #endif
604 			);
605 	printf("\n#ifdef WANT_DATA\n\n");
606 
607 
608 	printf("\nstatic const unsigned char __LOCALE_DATA_Cctype_data[%d] = {\n",
609 #ifdef CTYPE_PACKED
610 			n_ctype_rows * CTYPE_ROW_LEN / 2
611 #else
612 			n_ctype_rows * CTYPE_ROW_LEN
613 #endif
614 			);
615 	p = ctype_tbl;
616 	for (j=0 ; j < n_ctype_rows ; j++) {
617 		printf("\t");
618 		for (i=0 ; i < CTYPE_ROW_LEN ; i++) {
619 #ifdef CTYPE_PACKED
620 			printf(" %#4x,", (unsigned int)(p[i] + (p[i+1] << 4)));
621 			++i;
622 #else
623 			printf(" %#4x,", (unsigned int)p[i]);
624 #endif
625 		}
626 		printf("\n");
627 		p += CTYPE_ROW_LEN;
628 	}
629 	printf("};\n");
630 
631 	printf("\n#endif /* WANT_DATA */\n");
632 
633 #ifdef DO_WIDE_CHAR
634 
635 	printf("\n#define __LOCALE_DATA_Cc2wc_TBL_LEN\t\t%d\n",
636 			n_c2wc_rows * C2WC_ROW_LEN);
637 	printf("\n#ifdef WANT_DATA\n\n");
638 
639 	printf("\nstatic const unsigned short __LOCALE_DATA_Cc2wc_data[%d] = {\n",
640 			n_c2wc_rows * C2WC_ROW_LEN);
641 	p = (unsigned char *) c2wc_tbl;
642 	for (j=0 ; j < n_c2wc_rows ; j++) {
643 		printf("\t");
644 		for (i=0 ; i < C2WC_ROW_LEN ; i++) {
645 			printf(" %#6x,", (unsigned int)(((unsigned short *)p)[i]));
646 		}
647 		printf("\n");
648 		p += 2*C2WC_ROW_LEN;
649 	}
650 	printf("};\n");
651 	printf("\n#endif /* WANT_DATA */\n");
652 #endif /* DO_WIDE_CHAR */
653 	printf("\n\n");
654 
655 	printf("#define __LOCALE_DATA_NUM_CODESETS\t\t%d\n", numsets);
656 	printf("#define __LOCALE_DATA_CODESET_LIST \\\n\t\"");
657 	for (i=0 ; i < numsets ; i++) {
658 		printf("\\x%02x", numsets + 1 + (unsigned char) codeset_index[i]);
659 		if (((i & 7) == 7) && (i + 1 < numsets)) {
660 			printf("\" \\\n\t\"");
661 		}
662 	}
663 	printf("\" \\\n\t\"\\0\"");
664 	for (i=0 ; i < numsets ; i++) {
665 		printf(" \\\n\t\"%s\\0\"",
666 				codeset_list + ((unsigned char)codeset_index[i]));
667 	}
668 
669 	printf("\n\n");
670 	for (i=0 ; i < numsets ; i++) {
671 		char buf[30];
672 		char *z;
673 		strcpy(buf, codeset_list + ((unsigned char)codeset_index[i]));
674 		for (z=buf ; *z ; z++) {
675 			if (*z == '-') {
676 				*z = '_';
677 			}
678 		}
679 		printf("#define __CTYPE_HAS_CODESET_%s\n", buf);
680 	}
681 #ifdef DO_WIDE_CHAR
682 	printf("#define __CTYPE_HAS_CODESET_UTF_8\n");
683 #endif /* DO_WIDE_CHAR */
684 
685 #if 0
686 	printf("\n#endif /* __CTYPE_HAS_8_BIT_LOCALES */\n\n");
687 #endif
688 
689 	total_size = 0;
690 #ifdef DO_WIDE_CHAR
691 	fprintf(stderr, "tt_num = %d   ti_num = %d\n", tt_num, ti_num);
692 	fprintf(stderr, "max_wchar = %#lx\n", max_wchar);
693 
694 	fprintf(stderr, "size is %d * %d  +  %d * %d  + %d * %d  =  %d\n",
695 		   tt_num, 1 << TT_SHIFT, ti_num, 1 << TI_SHIFT,
696 		   ((MAX_WCHAR >> (TT_SHIFT + TI_SHIFT)) + 1), numsets,
697  		   j = tt_num * (1 << TT_SHIFT) + ti_num * (1 << TI_SHIFT)
698 		   + ((MAX_WCHAR >> (TT_SHIFT + TI_SHIFT)) + 1) * numsets);
699 	total_size += j;
700 #endif /* DO_WIDE_CHAR */
701 
702 #ifdef CTYPE_PACKED
703 	i = 2;
704 #else
705 	i = 1;
706 #endif
707 
708 	fprintf(stderr, "ctype - CTYPE_IDX_SHIFT = %d -- %d * %d + %d * %d = %d\n",
709 		   CTYPE_IDX_SHIFT, numsets, CTYPE_IDX_LEN, n_ctype_rows, CTYPE_ROW_LEN / i,
710 		   j = numsets * CTYPE_IDX_LEN +  n_ctype_rows * CTYPE_ROW_LEN / i);
711 	total_size += j;
712 
713 	fprintf(stderr, "uplow - UPLOW_IDX_SHIFT = %d -- %d * %d + %d * %d = %d\n",
714 		   UPLOW_IDX_SHIFT, numsets, UPLOW_IDX_LEN, n_uplow_rows, UPLOW_ROW_LEN,
715 		   j = numsets * UPLOW_IDX_LEN +  n_uplow_rows * UPLOW_ROW_LEN);
716 	total_size += j;
717 
718 #ifdef DO_WIDE_CHAR
719 
720 	fprintf(stderr, "c2wc - C2WC_IDX_SHIFT = %d -- %d * %d + 2 * %d * %d = %d\n",
721 		   C2WC_IDX_SHIFT, numsets, C2WC_IDX_LEN, n_c2wc_rows, C2WC_ROW_LEN,
722 		   j = numsets * C2WC_IDX_LEN +  2 * n_c2wc_rows * C2WC_ROW_LEN);
723 	total_size += j;
724 
725 #endif /* DO_WIDE_CHAR */
726 
727 	fprintf(stderr, "total size = %d\n", total_size);
728 
729 /*  	for (i=0 ; i < numsets ; i++) { */
730 /*  		printf("codeset_index[i] = %d  codeset_list[ci[i]] = \"%s\"\n", */
731 /*  			   (unsigned char) codeset_index[i], */
732 /*  			   codeset_list + ((unsigned char)codeset_index[i])); */
733 /*  	} */
734 
735 	return EXIT_SUCCESS;
736 }
737