Remove building with NOCRYPTO option
[minix3.git] / minix / commands / cawf / device.c
blob648a7472c04285886525ee99482311a634d82fd5
1 /*
2 * device.c -- cawf(1) output device support functions
3 */
5 /*
6 * Copyright (c) 1991 Purdue University Research Foundation,
7 * West Lafayette, Indiana 47907. All rights reserved.
9 * Written by Victor A. Abell <abe@mace.cc.purdue.edu>, Purdue
10 * University Computing Center. Not derived from licensed software;
11 * derived from awf(1) by Henry Spencer of the University of Toronto.
13 * Permission is granted to anyone to use this software for any
14 * purpose on any computer system, and to alter it and redistribute
15 * it freely, subject to the following restrictions:
17 * 1. The author is not responsible for any consequences of use of
18 * this software, even if they arise from flaws in it.
20 * 2. The origin of this software must not be misrepresented, either
21 * by explicit claim or by omission. Credits must appear in the
22 * documentation.
24 * 3. Altered versions must be plainly marked as such, and must not
25 * be misrepresented as being the original software. Credits must
26 * appear in the documentation.
28 * 4. This notice may not be removed or altered.
31 #include "cawf.h"
32 #include <ctype.h>
34 static unsigned char *Convstr(char *s, int *len);
35 static int Convfont(char *nm, char *s, char **fn, unsigned char **fi);
37 #ifndef UNIX
38 #define strcasecmp strcmpi
39 #endif
44 * Convstr(s, len) - convert a string
47 static unsigned char *Convstr(char *s, int *len) {
48 /* input string s
49 * length of result len
51 int c; /* character assembly */
52 unsigned char *cp; /* temporary character pointer */
53 char *em; /* error message */
54 int i; /* temporary index */
55 int l; /* length */
56 unsigned char *r; /* result string */
58 * Make space for the result.
60 if ((r = (unsigned char *)malloc(strlen((char *)s) + 1)) == NULL) {
61 (void) fprintf(stderr, "%s: out of string space at %s\n",
62 Pname, s);
63 return(NULL);
66 * Copy the input string to the result, processing '\\' escapes.
68 for (cp = r, l = 0; *s;) {
69 switch (*s) {
71 case '\\':
72 s++;
73 if (*s >= '0' && *s <= '7') {
75 * '\xxx' -- octal form
77 for (c = i = 0; i < 3; i++, s++) {
78 if (*s < '0' || *s > '7') {
79 em = "non-octal char";
80 bad_string:
81 (void) fprintf(stderr,
82 "%s: %s : %s\n",
83 Pname, em, (char *)r);
84 return(NULL);
86 c = (c << 3) + *s - '0';
88 if (c > 0377) {
89 em = "octal char > 0377";
90 goto bad_string;
92 *cp++ = c;
93 l++;
94 } else if (*s == 'x') {
96 * '\xyy' -- hexadecimal form
98 s++;
99 for (c = i = 0; i < 2; i++, s++) {
100 #if defined(__STDC__)
101 if ( ! isalpha(*s) && ! isdigit(*s))
102 #else
103 if ( ! isascii(*s) && ! isalpha(*s)
104 && ! isdigit(*s))
105 #endif
107 non_hex_char:
108 em = "non-hex char";
109 goto bad_string;
111 c = c << 4;
112 if (*s >= '0' && *s <= '9')
113 c += *s - '0';
114 else if ((*s >= 'a' && *s <= 'f')
115 || (*s >= 'A' && *s <= 'F'))
116 c += *s + 10 -
117 (isupper(*s) ? 'A' : 'a');
118 else
119 goto non_hex_char;
121 *cp++ = (unsigned char)c;
122 l++;
123 } else if (*s == 'E' || *s == 'e') {
125 * '\E' or '\e' -- ESCape
127 *cp++ = ESC;
128 l++;
129 s++;
130 } else if (*s == '\0') {
131 em = "no char after \\";
132 goto bad_string;
133 } else {
135 * escaped character (for some reason)
137 *cp++ = *s++;
138 l++;
140 break;
142 * Copy a "normal" character.
144 default:
145 *cp++ = *s++;
146 l++;
149 *cp = '\0';
150 *len = l;
151 return(r);
156 * Convfont(nm, s, fn, fi) - convert a font for a device
159 static int Convfont(char* nm, char *s, char **fn, unsigned char **fi) {
160 /* output device name nm
161 * font definition string s
162 * font name address fn
163 * initialization string address fi
165 char *cp; /* temporary character pointer */
166 int len; /* length */
168 * Get the font name, allocate space for it and allocate space for
169 * a font structure.
171 if ((cp = strchr(s, '=')) == NULL) {
172 (void) fprintf(stderr, "%s: bad %s font line format: %s\n",
173 Pname, nm, s);
174 return(0);
176 if ((*fn = (char *)malloc(cp - s + 1)) == NULL) {
177 (void) fprintf(stderr, "%s: no space for %s font name %s\n",
178 Pname, nm, s);
179 return(0);
181 (void) strncpy(*fn, s, cp - s);
182 (*fn)[cp - s] = '\0';
184 * Assmble the font initialization string.
186 if ((*fi = Convstr(cp + 1, &len)) == NULL)
187 return(0);
188 return(len);
193 * Defdev() - define the output device
196 int Defdev(void) {
197 unsigned char *fi = NULL; /* last font initialization string */
198 char *fn = NULL; /* font name */
199 int fd = 0; /* found-device flag */
200 FILE *fs; /* file stream */
201 int err = 0; /* errror count */
202 int i; /* temporary index */
203 int len; /* length */
204 char line[MAXLINE]; /* line buffer */
205 char *p; /* output device configuration file */
206 char *s; /* temporary string pointer */
208 * Check for the built-in devices, ANSI, NONE or NORMAL (default).
210 Fstr.b = Fstr.i = Fstr.it = Fstr.r = NULL;
211 Fstr.bl = Fstr.il = Fstr.itl = Fstr.rl = 0;
212 if (Device == NULL || strcasecmp(Device, "normal") == 0) {
213 Fontctl = 0;
214 check_font:
215 if (Devfont) {
216 (void) fprintf(stderr,
217 "%s: font %s for device %s illegal\n",
218 Pname, Devfont, Device ? Device : "NORMAL");
219 return(1);
221 return(0);
223 Fontctl = 1;
224 if (strcasecmp(Device, "ansi") == 0) {
225 Fstr.b = Newstr((unsigned char *)"x[1m");
226 Fstr.it = Newstr((unsigned char *)"x[4m");
227 Fstr.r = Newstr((unsigned char *)"x[0m");
228 Fstr.b[0] = Fstr.it[0] = Fstr.r[0] = ESC;
229 Fstr.bl = Fstr.itl = Fstr.rl = 4;
230 goto check_font;
232 if (strcasecmp(Device, "none") == 0)
233 goto check_font;
235 * If a device configuration file path is supplied, use it.
237 if (Devconf)
238 p = Devconf;
239 else {
242 * Use the CAWFLIB environment if it is defined.
244 if ((p = getenv("CAWFLIB")) == NULL)
245 p = CAWFLIB;
246 len = strlen(p) + 1 + strlen(DEVCONFIG) + 1;
247 if ((s = (char *)malloc(len)) == NULL) {
248 (void) fprintf(stderr, "%s: no space for %s name\n",
249 Pname, DEVCONFIG);
250 return(1);
252 (void) sprintf(s, "%s/%s", p, DEVCONFIG);
253 p = s;
256 * Open the configuration file.
258 #ifdef UNIX
259 if ((fs = fopen(p, "r")) == NULL)
260 #else
261 if ((fs = fopen(p, "rt")) == NULL)
262 #endif
264 (void) fprintf(stderr, "%s: can't open config file: %s\n",
265 Pname, p);
266 return(1);
268 *line = ' ';
270 * Look for a device definition line -- a line that begins with a name.
272 while ( ! feof(fs)) {
273 if (*line == '\t' || *line == '#' || *line == ' ') {
274 (void) fgets(line, MAXLINE, fs);
275 continue;
277 if ((s = strrchr(line, '\n')) != NULL)
278 *s = '\0';
279 else
280 line[MAXLINE-1] = '\0';
282 * Match device name.
284 if (strcmp(Device, line) != 0) {
285 (void) fgets(line, MAXLINE, fs);
286 continue;
288 fd = 1;
290 * Read the parameter lines for the device.
292 while (fgets(line, MAXLINE, fs) != NULL) {
293 if (*line == ' ') {
294 for (i = 1; line[i] == ' '; i++)
296 } else if (*line == '\t')
297 i = 1;
298 else
299 break;
300 #if defined(__STDC__)
301 if ( ! isalpha(line[i])
302 #else
303 if ( ! isascii(line[i]) || ! isalpha(line[i])
304 #endif
305 || line[i+1] != '=')
306 break;
307 if ((s = strrchr(line, '\n')) != NULL)
308 *s = '\0';
309 else
310 line[MAXLINE-1] = '\0';
311 switch (line[i]) {
313 * \tb=<bolding_string>
315 case 'b':
316 if (Fstr.b != NULL) {
317 (void) fprintf(stderr,
318 "%s: dup bold for %s in %s: %s\n",
319 Pname, Device, p, line);
320 (void) free(Fstr.b);
321 Fstr.b = NULL;
323 if ((Fstr.b = Convstr(&line[i+2], &Fstr.bl))
324 == NULL)
325 err++;
326 break;
328 * \ti=<italicization_string>
330 case 'i':
331 if (Fstr.it != NULL) {
332 (void) fprintf(stderr,
333 "%s: dup italic for %s in %s: %s\n",
334 Pname, Device, p, line);
335 (void) free(Fstr.it);
336 Fstr.it = NULL;
338 if ((Fstr.it = Convstr(&line[i+2], &Fstr.itl))
339 == NULL)
340 err++;
341 break;
343 * \tr=<return_to_Roman_string>
345 case 'r':
346 if (Fstr.r != NULL) {
347 (void) fprintf(stderr,
348 "%s: dup roman for %s in %s: %s\n",
349 Pname, Device, p, line);
350 (void) free(Fstr.r);
351 Fstr.r = NULL;
353 if ((Fstr.r = Convstr(&line[i+2], &Fstr.rl))
354 == NULL)
355 err++;
356 break;
358 * \tf=<font_name>=<font_initialization_string>
360 case 'f':
361 if ( ! Devfont || Fstr.i)
362 break;
363 if ((i = Convfont(Device, &line[i+2], &fn, &fi))
364 < 0)
365 err++;
366 else if (fn && strcmp(Devfont, fn) == 0) {
367 Fstr.i = fi;
368 Fstr.il = i;
369 fi = NULL;
371 if (fn) {
372 (void) free(fn);
373 fn = NULL;
375 if (fi) {
376 (void) free((char *)fi);
377 fi = NULL;
379 break;
381 * ????
383 default:
384 (void) fprintf(stderr,
385 "%s: unknown device %s line: %s\n",
386 Pname, Device, line);
387 err++;
390 break;
392 (void) fclose(fs);
393 if (err)
394 return(1);
396 * See if the device stanza was located and the font exists.
398 if ( ! fd) {
399 (void) fprintf(stderr, "%s: can't find device %s in %s\n",
400 Pname, Device, p);
401 return(1);
403 if (Devfont && ! Fstr.i) {
404 (void) fprintf(stderr,
405 "%s: font %s for device %s not found in %s\n",
406 Pname, Devfont, Device, p);
407 return(1);
409 return(0);