1 | /* |
---|
2 | * Copyright 1995 by Paul Mattes. |
---|
3 | * Permission to use, copy, modify, and distribute this software and its |
---|
4 | * documentation for any purpose and without fee is hereby granted, |
---|
5 | * provided that the above copyright notice appear in all copies and that |
---|
6 | * both that copyright notice and this permission notice appear in |
---|
7 | * supporting documentation. |
---|
8 | */ |
---|
9 | |
---|
10 | /* |
---|
11 | * mkfb.c |
---|
12 | * Utility to create fallback definitions from a simple #ifdef'd .ad |
---|
13 | * file |
---|
14 | */ |
---|
15 | |
---|
16 | #include <stdio.h> |
---|
17 | #include <string.h> |
---|
18 | #include <ctype.h> |
---|
19 | |
---|
20 | #define BUFSZ 1024 /* input line buffer size */ |
---|
21 | #define ARRSZ 8192 /* output array size */ |
---|
22 | |
---|
23 | unsigned a_color[ARRSZ]; /* array of color indices */ |
---|
24 | unsigned n_color = 0; /* number of color definitions */ |
---|
25 | |
---|
26 | unsigned a_mono[ARRSZ]; /* array of mono indices */ |
---|
27 | unsigned n_mono = 0; /* number of mono definitions */ |
---|
28 | |
---|
29 | enum { BOTH, COLOR_ONLY, MONO_ONLY } mode = BOTH; |
---|
30 | |
---|
31 | char *me; |
---|
32 | |
---|
33 | void emit(); |
---|
34 | |
---|
35 | void |
---|
36 | usage() |
---|
37 | { |
---|
38 | fprintf(stderr, "usage: %s [infile]\n", me); |
---|
39 | exit(1); |
---|
40 | } |
---|
41 | |
---|
42 | main(argc, argv) |
---|
43 | int argc; |
---|
44 | char *argv[]; |
---|
45 | { |
---|
46 | char buf[BUFSZ]; |
---|
47 | int lno = 0; |
---|
48 | int cc = 0; |
---|
49 | int i; |
---|
50 | int continued = 0; |
---|
51 | char *filename = "standard input"; |
---|
52 | |
---|
53 | /* Parse arguments. */ |
---|
54 | if ((me = strrchr(argv[0], '/')) != (char *)NULL) |
---|
55 | me++; |
---|
56 | else |
---|
57 | me = argv[0]; |
---|
58 | switch (argc) { |
---|
59 | case 1: |
---|
60 | break; |
---|
61 | case 2: |
---|
62 | if (freopen(argv[1], "r", stdin) == (FILE *)NULL) { |
---|
63 | perror(argv[1]); |
---|
64 | exit(1); |
---|
65 | } |
---|
66 | filename = argv[1]; |
---|
67 | break; |
---|
68 | default: |
---|
69 | usage(); |
---|
70 | } |
---|
71 | |
---|
72 | /* Emit the initial boilerplate. */ |
---|
73 | printf("/* This file was created automatically from %s by mkfb. */\n\n", |
---|
74 | filename); |
---|
75 | printf("#if !defined(USE_APP_DEFAULTS) /*[*/\n\n"); |
---|
76 | printf("#include <stdio.h>\n"); |
---|
77 | printf("#include <X11/Intrinsic.h>\n\n"); |
---|
78 | printf("static unsigned char fsd[] = {\n"); |
---|
79 | |
---|
80 | /* Scan the file, emitting the fsd array and creating the indices. */ |
---|
81 | while (fgets(buf, BUFSZ, stdin) != (char *)NULL) { |
---|
82 | char *s = buf; |
---|
83 | int sl; |
---|
84 | char c; |
---|
85 | int white; |
---|
86 | |
---|
87 | lno++; |
---|
88 | |
---|
89 | /* Skip leading white space. */ |
---|
90 | while (isspace(*s)) |
---|
91 | s++; |
---|
92 | |
---|
93 | /* Remove trailing white space. */ |
---|
94 | while ((sl = strlen(s)) && isspace(s[sl-1])) |
---|
95 | s[sl-1] = '\0'; |
---|
96 | |
---|
97 | if (continued) |
---|
98 | goto emit_text; |
---|
99 | |
---|
100 | /* Skip comments and empty lines. */ |
---|
101 | if (!*s || *s == '!') |
---|
102 | continue; |
---|
103 | |
---|
104 | /* Check for simple if[n]defs. */ |
---|
105 | if (*s == '#') { |
---|
106 | if (!strcmp(s, "#ifdef COLOR")) { |
---|
107 | if (mode != BOTH) { |
---|
108 | fprintf(stderr, |
---|
109 | "%s, line %d: Nested #ifdef\n", |
---|
110 | filename, lno); |
---|
111 | exit(1); |
---|
112 | } |
---|
113 | mode = COLOR_ONLY; |
---|
114 | } else if (!strcmp(s, "#ifndef COLOR")) { |
---|
115 | if (mode != BOTH) { |
---|
116 | fprintf(stderr, |
---|
117 | "%s, line %d: Nested #ifndef\n", |
---|
118 | filename, lno); |
---|
119 | exit(1); |
---|
120 | } |
---|
121 | mode = MONO_ONLY; |
---|
122 | } else if (!strcmp(s, "#else")) { |
---|
123 | switch (mode) { |
---|
124 | case BOTH: |
---|
125 | fprintf(stderr, |
---|
126 | "%s, line %d: Missing #if[n]def\n", |
---|
127 | filename, lno); |
---|
128 | exit(1); |
---|
129 | break; |
---|
130 | case COLOR_ONLY: |
---|
131 | mode = MONO_ONLY; |
---|
132 | break; |
---|
133 | case MONO_ONLY: |
---|
134 | mode = COLOR_ONLY; |
---|
135 | break; |
---|
136 | } |
---|
137 | } else if (!strcmp(s, "#endif")) { |
---|
138 | if (mode == BOTH) { |
---|
139 | fprintf(stderr, |
---|
140 | "%s, line %d: Missing #if[n]def\n", |
---|
141 | filename, lno); |
---|
142 | exit(1); |
---|
143 | } |
---|
144 | mode = BOTH; |
---|
145 | } else { |
---|
146 | fprintf(stderr, |
---|
147 | "%s, line %d: Unrecognized # directive\n", |
---|
148 | filename, lno); |
---|
149 | exit(1); |
---|
150 | } |
---|
151 | continue; |
---|
152 | } |
---|
153 | |
---|
154 | /* Add array offsets. */ |
---|
155 | switch (mode) { |
---|
156 | case BOTH: |
---|
157 | if (n_color >= ARRSZ || n_mono >= ARRSZ) { |
---|
158 | fprintf(stderr, |
---|
159 | "%s, line %d: Buffer overflow\n", |
---|
160 | filename, lno); |
---|
161 | exit(1); |
---|
162 | } |
---|
163 | a_color[n_color++] = cc; |
---|
164 | a_mono[n_mono++] = cc; |
---|
165 | break; |
---|
166 | case COLOR_ONLY: |
---|
167 | if (n_color >= ARRSZ) { |
---|
168 | fprintf(stderr, |
---|
169 | "%s, line %d: Buffer overflow\n", |
---|
170 | filename, lno); |
---|
171 | exit(1); |
---|
172 | } |
---|
173 | a_color[n_color++] = cc; |
---|
174 | break; |
---|
175 | case MONO_ONLY: |
---|
176 | if (n_mono >= ARRSZ) { |
---|
177 | fprintf(stderr, |
---|
178 | "%s, line %d: Buffer overflow\n", |
---|
179 | filename, lno); |
---|
180 | exit(1); |
---|
181 | } |
---|
182 | a_mono[n_mono++] = cc; |
---|
183 | break; |
---|
184 | } |
---|
185 | |
---|
186 | /* Emit the text. */ |
---|
187 | emit_text: |
---|
188 | continued = 0; |
---|
189 | white = 0; |
---|
190 | while (c = *s++) { |
---|
191 | if (c == ' ' || c == '\t') |
---|
192 | white++; |
---|
193 | else if (white) { |
---|
194 | emit(' '); |
---|
195 | cc++; |
---|
196 | white = 0; |
---|
197 | } |
---|
198 | switch (c) { |
---|
199 | case ' ': |
---|
200 | case '\t': |
---|
201 | break; |
---|
202 | case '#': |
---|
203 | emit('\\'); |
---|
204 | emit('#'); |
---|
205 | cc += 2; |
---|
206 | break; |
---|
207 | case '\\': |
---|
208 | if (*s == '\0') { |
---|
209 | continued = 1; |
---|
210 | break; |
---|
211 | } |
---|
212 | /* else fall through */ |
---|
213 | default: |
---|
214 | emit(c); |
---|
215 | cc++; |
---|
216 | break; |
---|
217 | } |
---|
218 | } |
---|
219 | if (white) { |
---|
220 | emit(' '); |
---|
221 | cc++; |
---|
222 | white = 0; |
---|
223 | } |
---|
224 | if (!continued) { |
---|
225 | emit(0); |
---|
226 | cc++; |
---|
227 | } |
---|
228 | } |
---|
229 | printf("};\n\n"); |
---|
230 | |
---|
231 | /* Emit the fallback arrays themselves. */ |
---|
232 | printf("String color_fallbacks[%u] = {\n", n_color + 1); |
---|
233 | for (i = 0; i < n_color; i++) |
---|
234 | printf("\t(String)&fsd[%u],\n", a_color[i]); |
---|
235 | printf("\t(String)NULL\n};\n\n"); |
---|
236 | printf("String mono_fallbacks[%u] = {\n", n_mono + 1); |
---|
237 | for (i = 0; i < n_mono; i++) |
---|
238 | printf("\t(String)&fsd[%u],\n", a_mono[i]); |
---|
239 | printf("\t(String)NULL\n};\n\n"); |
---|
240 | |
---|
241 | /* Emit some test code. */ |
---|
242 | printf("%s", "#if defined(DEBUG) /*[*/\n\ |
---|
243 | main()\n\ |
---|
244 | {\n\ |
---|
245 | int i;\n\ |
---|
246 | \n\ |
---|
247 | for (i = 0; color_fallbacks[i]; i++)\n\ |
---|
248 | printf(\"color %d: %s\\n\", i, color_fallbacks[i]);\n\ |
---|
249 | for (i = 0; mono_fallbacks[i]; i++)\n\ |
---|
250 | printf(\"mono %d: %s\\n\", i, mono_fallbacks[i]);\n\ |
---|
251 | exit(0);\n\ |
---|
252 | }\n"); |
---|
253 | printf("#endif /*]*/\n\n"); |
---|
254 | printf("#endif /*]*/\n"); |
---|
255 | |
---|
256 | exit(0); |
---|
257 | } |
---|
258 | |
---|
259 | int n_out = 0; |
---|
260 | |
---|
261 | void |
---|
262 | emit(c) |
---|
263 | char c; |
---|
264 | { |
---|
265 | if (n_out >= 19) { |
---|
266 | printf("\n"); |
---|
267 | n_out = 0; |
---|
268 | } |
---|
269 | printf("%3d,", (unsigned char)c); |
---|
270 | n_out++; |
---|
271 | } |
---|