2 unicoverage - Show the coverage of Unicode Basic Multilingual
3 Plane scripts for a GNU Unifont hex glyph file
5 Synopsis: unicoverage [-ifont_file.hex] [-ocoverage_file.txt]
7 This program requires the file "coverage.dat" to be present
8 in the directory from which it is run.
10 Author: Paul Hardy, unifoundry <at> unifoundry.com, 6 January 2008
12 Copyright (C) 2008, 2013 Paul Hardy
16 This program is free software: you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation, either version 2 of the License, or
19 (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
37 int main(int argc, char *argv[]) {
39 unsigned i; /* loop variable */
40 unsigned slen; /* string length of coverage file line */
41 char inbuf[256]; /* input buffer */
42 unsigned thischar; /* the current character */
43 // unsigned char thischarbyte; /* unsigned char lowest byte of Unicode char */
45 char *infile="", *outfile=""; /* names of input and output files */
46 FILE *infp, *outfp; /* file pointers of input and output files */
47 FILE *coveragefp; /* file pointer to coverage.dat file */
48 int cstart, cend; /* current coverage start and end code points */
49 char coverstring[MAXBUF]; /* description of current coverage range */
50 int nglyphs; /* number of glyphs in this section */
51 int nextrange(); /* to get next range & name of Unicode glyphs */
53 if ((coveragefp = fopen("coverage.dat", "r")) == NULL) {
54 fprintf(stderr, "\nError: data file \"coverage.dat\" not found.\n\n");
59 for (i = 1; i < argc; i++) {
60 if (argv[i][0] == '-') { /* this is an option argument */
62 case 'i': /* name of input file */
65 case 'o': /* name of output file */
66 outfile = &argv[i][2];
68 default: /* if unrecognized option, print list and exit */
69 fprintf(stderr, "\nSyntax:\n\n");
70 fprintf(stderr, " %s -p<Unicode_Page> ", argv[0]);
71 fprintf(stderr, "-i<Input_File> -o<Output_File> -w\n\n");
72 fprintf(stderr, "\nExample:\n\n");
79 Make sure we can open any I/O files that were specified before
82 if (strlen(infile) > 0) {
83 if ((infp = fopen(infile, "r")) == NULL) {
84 fprintf(stderr, "Error: can't open %s for input.\n", infile);
91 if (strlen(outfile) > 0) {
92 if ((outfp = fopen(outfile, "w")) == NULL) {
93 fprintf(stderr, "Error: can't open %s for output.\n", outfile);
100 slen = nextrange(coveragefp, &cstart, &cend, coverstring);
105 fprintf(outfp, "Covered Range Script\n");
106 fprintf(outfp, "------- ----- ------\n\n");
108 Read in the glyphs in the file
110 while (slen != 0 && fgets(inbuf, MAXBUF-1, infp) != NULL) {
111 sscanf(inbuf, "%x", &thischar);
112 while (cend < thischar && slen != 0) {
113 /* print old range total */
114 fprintf(outfp, " %5.1f%% U+%04X..U+%04X %s\n",
115 100.0*nglyphs/(1+cend-cstart), cstart, cend, coverstring);
116 /* start new range total */
117 slen = nextrange(coveragefp, &cstart, &cend, coverstring);
119 Count Non-characters as existing for totals counts
122 if (cstart <= 0xFDD0 && cend >= 0xFDEF && nglyphs == 0)
124 else if (cstart <= 0xFFFE && cend >= 0xFFFF && nglyphs == 0)
128 If we read in a noncharacter, don't count it -- we already
129 counted it once above.
131 if (thischar < 0xFDD0 || (thischar > 0xFDEF && thischar < 0xFFFE))
133 // thischarbyte = (unsigned char)(thischar & 0xff);
135 /* print last range total */
136 fprintf(outfp, " %5.1f%% U+%04X..U+%04X %s\n",
137 100.0*nglyphs/(1+cend-cstart), cstart, cend, coverstring);
142 nextrange() - get next Unicode range
144 int nextrange(FILE *coveragefp,
145 int *cstart, int *cend,
149 static char inbuf[MAXBUF];
150 int retval; /* the return value */
152 if (fgets(inbuf, MAXBUF-1, coveragefp) != NULL) {
153 retval = strlen(inbuf);
154 if ((inbuf[0] >= '0' && inbuf[0] <= '9') ||
155 (inbuf[0] >= 'A' && inbuf[0] <= 'F') ||
156 (inbuf[0] >= 'a' && inbuf[0] <= 'f')) {
157 sscanf(inbuf, "%x-%x", cstart, cend);
159 while (inbuf[i] != ' ') i++; /* find first blank */
160 while (inbuf[i] == ' ') i++; /* find next non-blank */
161 strcpy(coverstring, &inbuf[i]);