diff options
Diffstat (limited to 'troff/troff.d/fontmap.c')
| -rw-r--r-- | troff/troff.d/fontmap.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/troff/troff.d/fontmap.c b/troff/troff.d/fontmap.c new file mode 100644 index 0000000000000..afe8b44afdb89 --- /dev/null +++ b/troff/troff.d/fontmap.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2015, Carsten Kunze + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "fontmap.h" +#include "bst.h" + +extern char *progname; + +static void inibuf(char *, size_t); +static char *getword(int); +static int mapcmp(union bst_val, union bst_val); + +static char *filepath; +static char *bufp; +static char *bufe; + +struct bst map = { + NULL, + mapcmp +}; + +void +rdftmap(char *path) { + int fd; + struct stat sb; + char *buf; + ssize_t size; + char *key; + char *val; + if (map.root) return; + filepath = path; + if ((fd = open(path, O_RDONLY)) == -1) { + if (errno == ENOENT) return; + fprintf(stderr, "%s: Can't open font map file %s: ", + progname, path); + perror(NULL); + exit(1); + } + if (fstat(fd, &sb) == -1) { + fprintf(stderr, "%s: Can't get font map file %s status: ", + progname, path); + perror(NULL); + exit(1); + } + buf = malloc(sb.st_size); + if ((size = read(fd, buf, sb.st_size)) == -1) { + fprintf(stderr, "%s: Can't read font map file %s: ", + progname, path); + perror(NULL); + exit(1); + } + close(fd); + inibuf(buf, size); + while ((key = getword(0)) && (val = getword(1))) { + if (avl_add(&map, (union bst_val)(void *)key, + (union bst_val)(void *)val)) { + fprintf(stderr, "%s: Error while adding font " + "mapping %s -> %s\n", progname, key, val); + exit(1); + } + } + free(buf); +} + +char * +mapft(char *name) { + struct bst_node *n; + if (map.root && !bst_srch(&map, (union bst_val)(void *)name, &n)) + name = n->data.p; + return name; +} + +static void +inibuf(char *buf, size_t size) { + bufp = buf; + bufe = buf + size; +} + +/* + * type: + * 0 Accect \s*((#.*)?$|\S+) or EOF + * 1 Accept \s*\S+ + */ + +static char * +getword(int type) { + char *word = bufp; + char c; +nl: + while (word < bufe && ((c = *word) == ' ' || c == '\t')) word++; + if (word == bufe) goto eof; + if (c == '#' || c == '\n') { + if (type == 1) { + fprintf(stderr, "%s: Syntax error in font map file " + "%s\n", progname, filepath); + exit(1); + } + while (word < bufe && *word++ != '\n'); + if (word == bufe) goto eof; + goto nl; + } + bufp = word; + while (bufp < bufe && ((c = *bufp) != ' ' && c != '\t' && c != '\n' + && c != '#')) bufp++; + if (type == 0 && (c == '#' || c == '\n')) { + fprintf(stderr, "%s: Syntax error in font map file %s\n", + progname, filepath); + exit(1); + } + *bufp = 0; + word = strdup(word); + *bufp = c; + return word; +eof: + if (type == 1) { + fprintf(stderr, "%s: Unexpected end of font map file %s\n", + progname, filepath); + exit(1); + } + return NULL; +} + +static int +mapcmp(union bst_val a, union bst_val b) { + return strcmp(a.p, b.p); +} |
