home *** CD-ROM | disk | FTP | other *** search
- /*
- * device.c -- cawf(1) output device support functions
- */
-
- /*
- * Copyright (c) 1991 Purdue University Research Foundation,
- * West Lafayette, Indiana 47907. All rights reserved.
- *
- * Written by Victor A. Abell <abe@mace.cc.purdue.edu>, Purdue
- * University Computing Center. Not derived from licensed software;
- * derived from awf(1) by Henry Spencer of the University of Toronto.
- *
- * Permission is granted to anyone to use this software for any
- * purpose on any computer system, and to alter it and redistribute
- * it freely, subject to the following restrictions:
- *
- * 1. The author is not responsible for any consequences of use of
- * this software, even if they arise from flaws in it.
- *
- * 2. The origin of this software must not be misrepresented, either
- * by explicit claim or by omission. Credits must appear in the
- * documentation.
- *
- * 3. Altered versions must be plainly marked as such, and must not
- * be misrepresented as being the original software. Credits must
- * appear in the documentation.
- *
- * 4. This notice may not be removed or altered.
- */
-
- #include "cawf.h"
- #include <ctype.h>
-
- _PROTOTYPE(static unsigned char *Convstr,(char *s, int *len));
- _PROTOTYPE(static int Convfont,(char *nm, char *s, char **fn,
- unsigned char **fi));
-
- #ifdef __EMX__
- #define strcasecmp stricmp
- #else /* not __EMX__ */
- # ifndef UNIX
- #define strcasecmp strcmpi
- # endif /* not UNIX */
- #endif /* __EMX__ */
-
-
-
- /*
- * Convstr(s, len) - convert a string
- */
-
- static unsigned char *
- Convstr(s, len)
- char *s; /* input string */
- int *len; /* length of result */
- {
- int c; /* character assembly */
- unsigned char *cp; /* temporary character pointer */
- char *em; /* error message */
- int i; /* temporary index */
- int l; /* length */
- unsigned char *r; /* result string */
- /*
- * Make space for the result.
- */
- if ((r = (unsigned char *)malloc(strlen((char *)s) + 1)) == NULL) {
- (void) fprintf(stderr, "%s: out of string space at %s\n",
- Pname, s);
- return(NULL);
- }
- /*
- * Copy the input string to the result, processing '\\' escapes.
- */
- for (cp = r, l = 0; *s;) {
- switch (*s) {
-
- case '\\':
- s++;
- if (*s >= '0' && *s <= '7') {
- /*
- * '\xxx' -- octal form
- */
- for (c = i = 0; i < 3; i++, s++) {
- if (*s < '0' || *s > '7') {
- em = "non-octal char";
- bad_string:
- (void) fprintf(stderr,
- "%s: %s : %s\n",
- Pname, em, (char *)r);
- return(NULL);
- }
- c = (c << 3) + *s - '0';
- }
- if (c > 0377) {
- em = "octal char > 0377";
- goto bad_string;
- }
- *cp++ = c;
- l++;
- } else if (*s == 'x') {
- /*
- * '\xyy' -- hexadecimal form
- */
- s++;
- for (c = i = 0; i < 2; i++, s++) {
- #if defined(__STDC__)
- if ( ! isalpha(*s) && ! isdigit(*s))
- #else
- if ( ! isascii(*s) && ! isalpha(*s)
- && ! isdigit(*s))
- #endif
- {
- non_hex_char:
- em = "non-hex char";
- goto bad_string;
- }
- c = c << 4;
- if (*s >= '0' && *s <= '9')
- c += *s - '0';
- else if ((*s >= 'a' && *s <= 'f')
- || (*s >= 'A' && *s <= 'F'))
- c += *s + 10 -
- (isupper(*s) ? 'A' : 'a');
- else
- goto non_hex_char;
- }
- *cp++ = (unsigned char)c;
- l++;
- } else if (*s == 'E' || *s == 'e') {
- /*
- * '\E' or '\e' -- ESCape
- */
- *cp++ = ESC;
- l++;
- s++;
- } else if (*s == '\0') {
- em = "no char after \\";
- goto bad_string;
- } else {
- /*
- * escaped character (for some reason)
- */
- *cp++ = *s++;
- l++;
- }
- break;
- /*
- * Copy a "normal" character.
- */
- default:
- *cp++ = *s++;
- l++;
- }
- }
- *cp = '\0';
- *len = l;
- return(r);
- }
-
-
- /*
- * Convfont(nm, s, fn, fi) - convert a font for a device
- */
-
- static int
- Convfont(nm, s, fn, fi)
- char *nm; /* output device name */
- char *s; /* font definition string */
- char **fn; /* font name address */
- unsigned char **fi; /* initialization string address */
- {
- char *cp; /* temporary character pointer */
- int len; /* length */
- /*
- * Get the font name, allocate space for it and allocate space for
- * a font structure.
- */
- if ((cp = strchr(s, '=')) == NULL) {
- (void) fprintf(stderr, "%s: bad %s font line format: %s\n",
- Pname, nm, s);
- return(0);
- }
- if ((*fn = (char *)malloc(cp - s + 1)) == NULL) {
- (void) fprintf(stderr, "%s: no space for %s font name %s\n",
- Pname, nm, s);
- return(0);
- }
- (void) strncpy(*fn, s, cp - s);
- (*fn)[cp - s] = '\0';
- /*
- * Assmble the font initialization string.
- */
- if ((*fi = Convstr(cp + 1, &len)) == NULL)
- return(0);
- return(len);
- }
-
-
- /*
- * Defdev() - define the output device
- */
-
- int
- Defdev()
- {
- unsigned char *fi = NULL; /* last font initialization string */
- char *fn = NULL; /* font name */
- int fd = 0; /* found-device flag */
- FILE *fs; /* file stream */
- int err = 0; /* errror count */
- int i; /* temporary index */
- int len; /* length */
- char line[MAXLINE]; /* line buffer */
- char *p; /* output device configuration file */
- char *s; /* temporary string pointer */
- /*
- * Check for the built-in devices, ANSI, NONE or NORMAL (default).
- */
- Fstr.b = Fstr.i = Fstr.it = Fstr.r = NULL;
- Fstr.bl = Fstr.il = Fstr.itl = Fstr.rl = 0;
- if (Device == NULL || strcasecmp(Device, "normal") == 0) {
- Fontctl = 0;
- check_font:
- if (Devfont) {
- (void) fprintf(stderr,
- "%s: font %s for device %s illegal\n",
- Pname, Devfont, Device ? Device : "NORMAL");
- return(1);
- }
- return(0);
- }
- Fontctl = 1;
- if (strcasecmp(Device, "ansi") == 0) {
- Fstr.b = Newstr((unsigned char *)"x[7m");
- Fstr.it = Newstr((unsigned char *)"x[4m");
- Fstr.r = Newstr((unsigned char *)"x[0m");
- Fstr.b[0] = Fstr.it[0] = Fstr.r[0] = ESC;
- Fstr.bl = Fstr.itl = Fstr.rl = 4;
- goto check_font;
- }
- if (strcasecmp(Device, "none") == 0)
- goto check_font;
- /*
- * If a device configuration file path is supplied, use it.
- */
- if (Devconf)
- p = Devconf;
- else {
-
- /*
- * Use the CAWFLIB environment if it is defined.
- */
- if ((p = getenv("CAWFLIB")) == NULL)
- p = CAWFLIB;
- len = strlen(p) + 1 + strlen(DEVCONFIG) + 1;
- if ((s = (char *)malloc(len)) == NULL) {
- (void) fprintf(stderr, "%s: no space for %s name\n",
- Pname, DEVCONFIG);
- return(1);
- }
- (void) sprintf(s, "%s/%s", p, DEVCONFIG);
- p = s;
- }
- /*
- * Open the configuration file.
- */
- #ifdef UNIX
- if ((fs = fopen(p, "r")) == NULL)
- #else
- if ((fs = fopen(p, "rt")) == NULL)
- #endif
- {
- (void) fprintf(stderr, "%s: can't open config file: %s\n",
- Pname, p);
- return(1);
- }
- *line = ' ';
- /*
- * Look for a device definition line -- a line that begins with a name.
- */
- while ( ! feof(fs)) {
- if (*line == '\t' || *line == '#' || *line == ' ') {
- (void) fgets(line, MAXLINE, fs);
- continue;
- }
- if ((s = strrchr(line, '\n')) != NULL)
- *s = '\0';
- else
- line[MAXLINE-1] = '\0';
- /*
- * Match device name.
- */
- if (strcmp(Device, line) != 0) {
- (void) fgets(line, MAXLINE, fs);
- continue;
- }
- fd = 1;
- /*
- * Read the parameter lines for the device.
- */
- while (fgets(line, MAXLINE, fs) != NULL) {
- if (*line == ' ') {
- for (i = 1; line[i] == ' '; i++)
- ;
- } else if (*line == '\t')
- i = 1;
- else
- break;
- #if defined(__STDC__)
- if ( ! isalpha(line[i])
- #else
- if ( ! isascii(line[i]) || ! isalpha(line[i])
- #endif
- || line[i+1] != '=')
- break;
- if ((s = strrchr(line, '\n')) != NULL)
- *s = '\0';
- else
- line[MAXLINE-1] = '\0';
- switch (line[i]) {
- /*
- * \tb=<bolding_string>
- */
- case 'b':
- if (Fstr.b != NULL) {
- (void) fprintf(stderr,
- "%s: dup bold for %s in %s: %s\n",
- Pname, Device, p, line);
- (void) free(Fstr.b);
- Fstr.b = NULL;
- }
- if ((Fstr.b = Convstr(&line[i+2], &Fstr.bl))
- == NULL)
- err++;
- break;
- /*
- * \ti=<italicization_string>
- */
- case 'i':
- if (Fstr.it != NULL) {
- (void) fprintf(stderr,
- "%s: dup italic for %s in %s: %s\n",
- Pname, Device, p, line);
- (void) free(Fstr.it);
- Fstr.it = NULL;
- }
- if ((Fstr.it = Convstr(&line[i+2], &Fstr.itl))
- == NULL)
- err++;
- break;
- /*
- * \tr=<return_to_Roman_string>
- */
- case 'r':
- if (Fstr.r != NULL) {
- (void) fprintf(stderr,
- "%s: dup roman for %s in %s: %s\n",
- Pname, Device, p, line);
- (void) free(Fstr.r);
- Fstr.r = NULL;
- }
- if ((Fstr.r = Convstr(&line[i+2], &Fstr.rl))
- == NULL)
- err++;
- break;
- /*
- * \tf=<font_name>=<font_initialization_string>
- */
- case 'f':
- if ( ! Devfont || Fstr.i)
- break;
- if ((i = Convfont(Device, &line[i+2], &fn, &fi))
- < 0)
- err++;
- else if (fn && strcmp(Devfont, fn) == 0) {
- Fstr.i = fi;
- Fstr.il = i;
- fi = NULL;
- }
- if (fn) {
- (void) free(fn);
- fn = NULL;
- }
- if (fi) {
- (void) free((char *)fi);
- fi = NULL;
- }
- break;
- /*
- * ????
- */
- default:
- (void) fprintf(stderr,
- "%s: unknown device %s line: %s\n",
- Pname, Device, line);
- err++;
- }
- }
- break;
- }
- (void) fclose(fs);
- if (err)
- return(1);
- /*
- * See if the device stanza was located and the font exists.
- */
- if ( ! fd) {
- (void) fprintf(stderr, "%s: can't find device %s in %s\n",
- Pname, Device, p);
- return(1);
- }
- if (Devfont && ! Fstr.i) {
- (void) fprintf(stderr,
- "%s: font %s for device %s not found in %s\n",
- Pname, Devfont, Device, p);
- return(1);
- }
- return(0);
- }
-