10 static void openFile (const char *fname
) {
11 fi
= fopen(fname
, "r");
12 if (fi
== NULL
) { fprintf(stderr
, "FATAL: can't open input file: '%s'\n", fname
); exit(1); }
16 static char *trim (char *str
) {
19 if (str
== NULL
) return NULL
;
20 for (s
= str
; *s
&& isspace(*s
); ++s
) ;
21 if (s
> str
) memmove(str
, s
, strlen(s
)+1);
22 for (s
= str
+strlen(str
)-1; s
>= str
&& isspace(*s
); --s
) ;
28 static int hex2num (char *s
) {
34 res
= strtol(s
, &end
, 16);
35 if (end
[0] || res
< 0) return -1;
49 static char *stx
= NULL
;
51 static char *tok (void) {
53 for (; *stx
&& *stx
!= ';'; ++stx
) ;
59 // <0: eof; 0: bad record; >0: good record
60 static int readRecord (UCInfo
*ui
) {
61 static char str
[8192];
65 if (fgets(str
, sizeof(str
)-1, fi
) == NULL
) return -1;
67 if ((tk
= tok()) == NULL
) return 0;
68 if ((ui
->code
= hex2num(tk
)) < 0) return 0;
69 if (ui
->code
> 65535) return -1;
70 if ((ui
->name
= trim(tok())) == NULL
) return 0;
71 if ((ui
->class = trim(tok())) == NULL
) return 0;
73 for (f
= 9; f
> 0; --f
) if (tok() == NULL
) { printf("%d\n", f
); return 0; }
74 if ((u
= trim(tok())) == NULL
) return 0;
75 if ((l
= trim(tok())) == NULL
) return 0;
76 if (!u
[0]) ui
->upper
= ui
->code
; else ui
->upper
= hex2num(u
);
77 if (!l
[0]) ui
->lower
= ui
->code
; else ui
->lower
= hex2num(l
);
78 if (ui
->upper
< 0 || ui
->lower
< 0) return 0;
79 if (ui
->upper
> 65535 || ui
->lower
> 65535) abort();
89 int main (int argc
, char *argv
[]) {
91 int rc
, f
, totalmap
= 0;
94 if (argc
!= 3) { fprintf(stderr
, "usage: %s unitable.c unitable.txt\n", argv
[0]); exit(1); }
100 if (rc
== 0) continue;
101 if (ui
.code
< 128) continue;
102 if (strcmp(ui
.class, "Lu") != 0 && strcmp(ui
.class, "Ll") != 0) continue;
103 if (ui
.upper
== ui
.code
&& ui
.lower
== ui
.code
) continue;
105 for (f
= 0; f
< totalmap
; ++f
) {
106 if (map
[f
].code
== ui
.code
) { fprintf(stderr
, "FATAL: duplicate entries in the map!\n"); exit(1); }
107 if (map
[f
].code
> ui
.code
) { fprintf(stderr
, "FATAL: invalid entry order in the map!\n"); exit(1); }
110 map
[totalmap
].code
= ui
.code
;
111 map
[totalmap
].l
= ui
.lower
;
112 map
[totalmap
].u
= ui
.upper
;
114 if (totalmap
> 65535) { fprintf(stderr
, "FATAL: too many entries in the map!\n"); exit(1); }
118 fo
= fopen(argv
[1], "w");
119 if (fo
== NULL
) { fprintf(stderr
, "FATAL: can't create output file: '%s'\n", argv
[1]); exit(1); }
120 fprintf(fo
, "static const struct casemap unicode_case_mapping[%d] = {\n", totalmap
);
121 for (f
= 0; f
< totalmap
; ++f
) fprintf(fo
, "{0x%04x,0x%04x,0x%04x},\n", map
[f
].code
, map
[f
].l
, map
[f
].u
);
122 fprintf(fo
, "%s\n", "};");