Index: projects/doctools/contrib/heirloom-doctools/checknr/checknr.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/checknr/checknr.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/checknr/checknr.c (revision 307812) @@ -1,669 +1,637 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* from OpenSolaris "checknr.c 1.8 05/06/02 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany */ #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 #define USED __attribute__ ((used)) #elif defined __GNUC__ #define USED __attribute__ ((unused)) #else #define USED #endif static const char sccsid[] USED = "@(#)/usr/ucb/checknr.sl 1.3 (gritter) 11/6/05"; /* * checknr: check an nroff/troff input file for matching macro calls. * we also attempt to match size and font changes, but only the embedded * kind. These must end in \s0 and \fP resp. Maybe more sophistication * later but for now think of these restrictions as contributions to * structured typesetting. */ #include #include #include #include #include #include "global.h" static int maxstk; /* Stack size */ #define MAXBR 100 /* Max number of bracket pairs known */ #define MAXCMDS 500 /* Max number of commands known */ /* * The stack on which we remember what we've seen so far. */ static struct stkstr { int opno; /* number of opening bracket */ int pl; /* '+', '-', ' ' for \s, 1 for \f, 0 for .ft */ int parm; /* parm to size, font, etc */ int lno; /* line number the thing came in in */ } *stk; static int stktop; /* * The kinds of opening and closing brackets. */ static struct brstr { char *opbr; char *clbr; } br[MAXBR] = { /* A few bare bones troff commands */ #define SZ 0 { "sz", "sz" }, /* also \s */ #define FT 1 { "ft", "ft" }, /* also \f */ /* the -mm package */ { "AL", "LE" }, { "AS", "AE" }, { "BL", "LE" }, { "BS", "BE" }, { "DF", "DE" }, { "DL", "LE" }, { "DS", "DE" }, { "FS", "FE" }, { "ML", "LE" }, { "NS", "NE" }, { "RL", "LE" }, { "VL", "LE" }, /* the -ms package */ { "AB", "AE" }, { "BD", "DE" }, { "CD", "DE" }, { "DS", "DE" }, { "FS", "FE" }, { "ID", "DE" }, { "KF", "KE" }, { "KS", "KE" }, { "LD", "DE" }, { "LG", "NL" }, { "QS", "QE" }, { "RS", "RE" }, { "SM", "NL" }, { "XA", "XE" }, { "XS", "XE" }, /* The -me package */ { "(b", ")b" }, { "(c", ")c" }, { "(d", ")d" }, { "(f", ")f" }, { "(l", ")l" }, { "(q", ")q" }, { "(x", ")x" }, { "(z", ")z" }, /* Things needed by preprocessors */ { "EQ", "EN" }, { "TS", "TE" }, /* Refer */ { "[", "]" }, { NULL, NULL } }; /* * All commands known to nroff, plus macro packages. * Used so we can complain about unrecognized commands. */ static char *knowncmds[MAXCMDS] = { "$c", "$f", "$h", "$p", "$s", "(b", "(c", "(d", "(f", "(l", "(q", "(t", "(x", "(z", ")b", ")c", ")d", ")f", ")l", ")q", ")t", ")x", ")z", "++", "+c", "1C", "1c", "2C", "2c", "@(", "@)", "@C", "@D", "@F", "@I", "@M", "@c", "@e", "@f", "@h", "@m", "@n", "@o", "@p", "@r", "@t", "@z", "AB", "AE", "AF", "AI", "AL", "AM", "AS", "AT", "AU", "AX", "B", "B1", "B2", "BD", "BE", "BG", "BL", "BS", "BT", "BX", "C1", "C2", "CD", "CM", "CT", "D", "DA", "DE", "DF", "DL", "DS", "DT", "EC", "EF", "EG", "EH", "EM", "EN", "EQ", "EX", "FA", "FD", "FE", "FG", "FJ", "FK", "FL", "FN", "FO", "FQ", "FS", "FV", "FX", "H", "HC", "HD", "HM", "HO", "HU", "I", "ID", "IE", "IH", "IM", "IP", "IX", "IZ", "KD", "KE", "KF", "KQ", "KS", "LB", "LC", "LD", "LE", "LG", "LI", "LP", "MC", "ME", "MF", "MH", "ML", "MR", "MT", "ND", "NE", "NH", "NL", "NP", "NS", "OF", "OH", "OK", "OP", "P", "P1", "PF", "PH", "PP", "PT", "PX", "PY", "QE", "QP", "QS", "R", "RA", "RC", "RE", "RL", "RP", "RQ", "RS", "RT", "S", "S0", "S2", "S3", "SA", "SG", "SH", "SK", "SM", "SP", "SY", "T&", "TA", "TB", "TC", "TD", "TE", "TH", "TL", "TM", "TP", "TQ", "TR", "TS", "TX", "UL", "US", "UX", "VL", "WC", "WH", "XA", "XD", "XE", "XF", "XK", "XP", "XS", "[", "[-", "[0", "[1", "[2", "[3", "[4", "[5", "[<", "[>", "[]", "]", "]-", "]<", "]>", "][", "ab", "ac", "ad", "af", "am", "ar", "as", "b", "ba", "bc", "bd", "bi", "bl", "bp", "br", "bx", "c.", "c2", "cc", "ce", "cf", "ch", "chop", "cs", "ct", "cu", "da", "de", "di", "dl", "dn", "do", "ds", "dt", "dw", "dy", "ec", "ef", "eh", "el", "em", "eo", "ep", "ev", "evc", "ex", "fallback", "fc", "feature", "fi", "fl", "flig", "fo", "fp", "ft", "ftr", "fz", "fzoom", "hc", "he", "hidechar", "hl", "hp", "ht", "hw", "hx", "hy", "hylang", "i", "ie", "if", "ig", "in", "ip", "it", "ix", "kern", "kernafter", "kernbefore", "kernpair", "lc", "lg", "lhang", "lc_ctype", "li", "ll", "ln", "lo", "lp", "ls", "lt", "m1", "m2", "m3", "m4", "mc", "mk", "mo", "n1", "n2", "na", "ne", "nf", "nh", "nl", "nm", "nn", "np", "nr", "ns", "nx", "of", "oh", "os", "pa", "papersize", "pc", "pi", "pl", "pm", "pn", "po", "pp", "ps", "q", "r", "rb", "rd", "re", "recursionlimit", "return", "rhang", "rm", "rn", "ro", "rr", "rs", "rt", "sb", "sc", "sh", "shift", "sk", "so", "sp", "ss", "st", "sv", "sz", "ta", "tc", "th", "ti", "tl", "tm", "tp", "tr", "track", "u", "uf", "uh", "ul", "vs", "wh", "xflag", "xp", "yr", 0 }; static int lineno; /* current line number in input file */ static char *line; /* the current line */ static size_t linesize; /* allocated size of current line */ static char *cfilename; /* name of current file */ static int nfiles; /* number of files to process */ static int fflag; /* -f: ignore \f */ static int sflag; /* -s: ignore \s */ static int ncmds; /* size of knowncmds */ static int slot; /* slot in knowncmds found by binsrch */ static void growstk(void); static void usage(void); static void process(FILE *f); static void complain(int i); static void prop(int i); static void chkcmd(char *line, char *mac); static void nomatch(char *mac); static int eq(char *s1, char *s2); static void pe(int lineno); static void checkknown(char *mac); static void addcmd(char *line); static void addmac(char *mac); static int binsrch(char *mac); -static char *fgetline(char **line, size_t *linesize, size_t *llen, FILE *fp); static void growstk(void) { stktop++; if (stktop >= maxstk) { maxstk *= 2; stk = realloc(stk, sizeof *stk * maxstk); } } int main(int argc, char **argv) { FILE *f; int i; char *cp, *cq, c; stk = calloc(sizeof *stk, maxstk = 100); /* Figure out how many known commands there are */ while (knowncmds[ncmds]) ncmds++; while (argc > 1 && argv[1][0] == '-') { switch (argv[1][1]) { /* -a: add pairs of macros */ case 'a': /* look for empty macro slots */ for (i = 0; br[i].opbr; i++) ; cp = &argv[1][3]; while (*cp) { size_t s; if (i >= MAXBR - 3) { printf("Only %d known pairs allowed\n", MAXBR/2); exit(1); } for (cq = cp; *cq && *cq != '.'; cq++); if (*cq != '.') usage(); *cq = 0; s = cq - cp + 1; br[i].opbr = malloc(s); n_strcpy(br[i].opbr, cp, s); *cq = '.'; cp = &cq[1]; for (cq = cp; *cq && *cq != '.'; cq++); c = *cq; *cq = 0; s = cq - cp + 1; br[i].clbr = malloc(s); n_strcpy(br[i].clbr, cp, s); *cq = c; cp = c ? &cq[1] : cq; /* knows pairs are also known cmds */ addmac(br[i].opbr); addmac(br[i].clbr); i++; } break; /* -c: add known commands */ case 'c': cp = &argv[1][3]; while (*cp) { for (cq = cp; *cq && *cq != '.'; cq++); c = *cq; *cq = 0; addmac(cp); *cq = c; cp = c ? &cq[1] : cq; } break; /* -f: ignore font changes */ case 'f': fflag = 1; break; /* -s: ignore size changes */ case 's': sflag = 1; break; default: usage(); } argc--; argv++; } nfiles = argc - 1; if (nfiles > 0) { for (i = 1; i < argc; i++) { cfilename = argv[i]; f = fopen(cfilename, "r"); if (f == NULL) { perror(cfilename); exit(1); } else { process(f); fclose(f); } } } else { cfilename = "stdin"; process(stdin); } return (0); } static void usage(void) { printf("Usage: checknr -s -f -a.xx.yy.xx.yy... -c.xx.xx.xx...\n"); exit(1); } static void process(FILE *f) { int i, n; char mac[512]; /* The current macro or nroff command */ int pl; stktop = -1; - for (lineno = 1; fgetline(&line, &linesize, NULL, f); lineno++) { + for (lineno = 1; getline(&line, &linesize, f) > 0; lineno++) { if (line[0] == '.') { /* * find and isolate the macro/command name. */ strncpy(mac, line+1, sizeof mac-1)[sizeof mac-1] = 0; if (isspace(mac[0]&0377)) { pe(lineno); printf("Empty command\n"); } else { for (i = 1; mac[i]; i++) if (isspace(mac[i]&0377)) { mac[i] = 0; break; } } /* * Is it a known command? */ checkknown(mac); /* * Should we add it? */ if (eq(mac, "de")) addcmd(line); chkcmd(line, mac); } /* * At this point we process the line looking * for \s and \f. */ for (i = 0; line[i]; i++) if (line[i] == '\\' && (i == 0 || line[i-1] != '\\')) { if (!sflag && line[++i] == 's') { pl = line[++i]&0377; if (isdigit(pl)) { n = pl - '0'; pl = ' '; } else n = 0; while (isdigit(line[++i]&0377)) n = 10 * n + line[i] - '0'; i--; if (n == 0) { if (stk[stktop].opno == SZ) { stktop--; } else { pe(lineno); printf( "unmatched \\s0\n"); } } else { growstk(); stk[stktop].opno = SZ; stk[stktop].pl = pl; stk[stktop].parm = n; stk[stktop].lno = lineno; } } else if (!fflag && line[i] == 'f') { n = line[++i]; if (n == 'P') { if (stk[stktop].opno == FT) { stktop--; } else { pe(lineno); printf( "unmatched \\fP\n"); } } else { growstk(); stk[stktop].opno = FT; stk[stktop].pl = 1; stk[stktop].parm = n; stk[stktop].lno = lineno; } } } } /* * We've hit the end and look at all this stuff that hasn't been * matched yet! Complain, complain. */ for (i = stktop; i >= 0; i--) { complain(i); } } static void complain(int i) { pe(stk[i].lno); printf("Unmatched "); prop(i); printf("\n"); } static void prop(int i) { if (stk[i].pl == 0) printf(".%s", br[stk[i].opno].opbr); else switch (stk[i].opno) { case SZ: printf("\\s%c%d", stk[i].pl, stk[i].parm); break; case FT: printf("\\f%c", stk[i].parm); break; default: printf("Bug: stk[%d].opno = %d = .%s, .%s", i, stk[i].opno, br[stk[i].opno].opbr, br[stk[i].opno].clbr); } } /* ARGSUSED */ static void chkcmd(char *line, char *mac) { int i; /* * Check to see if it matches top of stack. */ if (stktop >= 0 && eq(mac, br[stk[stktop].opno].clbr)) stktop--; /* OK. Pop & forget */ else { /* No. Maybe it's an opener */ for (i = 0; br[i].opbr; i++) { if (eq(mac, br[i].opbr)) { /* Found. Push it. */ growstk(); stk[stktop].opno = i; stk[stktop].pl = 0; stk[stktop].parm = 0; stk[stktop].lno = lineno; break; } /* * Maybe it's an unmatched closer. * NOTE: this depends on the fact * that none of the closers can be * openers too. */ if (eq(mac, br[i].clbr)) { nomatch(mac); break; } } } } static void nomatch(char *mac) { int i, j; /* * Look for a match further down on stack * If we find one, it suggests that the stuff in * between is supposed to match itself. */ for (j = stktop; j >= 0; j--) if (eq(mac, br[stk[j].opno].clbr)) { /* Found. Make a good diagnostic. */ if (j == stktop-2) { /* * Check for special case \fx..\fR and don't * complain. */ if (stk[j+1].opno == FT && stk[j+1].parm != 'R' && stk[j+2].opno == FT && stk[j+2].parm == 'R') { stktop = j -1; return; } /* * We have two unmatched frobs. Chances are * they were intended to match, so we mention * them together. */ pe(stk[j+1].lno); prop(j+1); printf(" does not match %d: ", stk[j+2].lno); prop(j+2); printf("\n"); } else for (i = j+1; i <= stktop; i++) { complain(i); } stktop = j-1; return; } /* Didn't find one. Throw this away. */ pe(lineno); printf("Unmatched .%s\n", mac); } /* eq: are two strings equal? */ static int eq(char *s1, char *s2) { return (strcmp(s1, s2) == 0); } /* print the first part of an error message, given the line number */ static void pe(int lineno) { if (nfiles > 1) printf("%s: ", cfilename); printf("%d: ", lineno); } static void checkknown(char *mac) { if (eq(mac, ".")) return; if (binsrch(mac) >= 0) return; if (mac[0] == '\\' && mac[1] == '"') /* comments */ return; pe(lineno); printf("Unknown command: .%s\n", mac); } /* * We have a .de xx line in "line". Add xx to the list of known commands. */ static void addcmd(char *line) { char *mac; /* grab the macro being defined */ mac = line+4; while (isspace(*mac&0377)) mac++; if (*mac == 0) { pe(lineno); printf("illegal define: %s\n", line); return; } mac[2] = 0; if (isspace(mac[1]&0377) || mac[1] == '\\') mac[1] = 0; addmac(mac); } /* * Add mac to the list. We should really have some kind of tree * structure here but this is a quick-and-dirty job and I just don't * have time to mess with it. (I wonder if this will come back to haunt * me someday?) Anyway, I claim that .de is fairly rare in user * nroff programs, and the loop below is pretty fast. */ static void addmac(char *mac) { char **src, **dest, **loc; size_t s; if (binsrch(mac) >= 0) { /* it's OK to redefine something */ #ifdef DEBUG printf("binsrch(%s) -> already in table\n", mac); #endif return; } /* binsrch sets slot as a side effect */ #ifdef DEBUG printf("binsrch(%s) -> %d\n", mac, slot); #endif if (ncmds >= MAXCMDS) { printf("Only %d known commands allowed\n", MAXCMDS); exit(1); } loc = &knowncmds[slot]; src = &knowncmds[ncmds-1]; dest = src+1; while (dest > loc) *dest-- = *src--; s = strlen(mac) + 1; *loc = malloc(s); n_strcpy(*loc, mac, s); ncmds++; #ifdef DEBUG printf("after: %s %s %s %s %s, %d cmds\n", knowncmds[slot-2], knowncmds[slot-1], knowncmds[slot], knowncmds[slot+1], knowncmds[slot+2], ncmds); #endif } /* * Do a binary search in knowncmds for mac. * If found, return the index. If not, return -1. */ static int binsrch(char *mac) { char *p; /* pointer to current cmd in list */ int d; /* difference if any */ int mid; /* mid point in binary search */ int top, bot; /* boundaries of bin search, inclusive */ top = ncmds-1; bot = 0; while (top >= bot) { mid = (top+bot)/2; p = knowncmds[mid]; d = p[0] - mac[0]; if (d == 0) d = strcmp(&p[1], &mac[1]); if (d == 0) return (mid); if (d < 0) bot = mid + 1; else top = mid - 1; } slot = bot; /* place it would have gone */ return (-1); -} - -#define LSIZE 256 - -static char * -fgetline(char **line, size_t *linesize, size_t *llen, FILE *fp) -{ - int c; - size_t n = 0; - - if (*line == NULL || *linesize < LSIZE + n + 1) - *line = realloc(*line, *linesize = LSIZE + n + 1); - for (;;) { - if (n >= *linesize - LSIZE / 2) - *line = realloc(*line, *linesize += LSIZE); - c = getc(fp); - if (c != EOF) { - (*line)[n++] = c; - (*line)[n] = '\0'; - if (c == '\n') - break; - } else { - if (n > 0) - break; - else - return NULL; - } - } - if (llen) - *llen = n; - return *line; } Index: projects/doctools/contrib/heirloom-doctools/compat.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/compat.c (nonexistent) +++ projects/doctools/contrib/heirloom-doctools/compat.c (revision 307812) @@ -0,0 +1,47 @@ +/* Carsten Kunze, 2016 */ + +#include + +#ifndef HAVE_STRLCPY +size_t +strlcpy(char *dst, const char *src, size_t dstsize) { + size_t srcsize; + /* Not conform to strlcpy, but avoids to access illegal memory in case + * of unterminated strings */ + for (srcsize = 0; srcsize < dstsize; srcsize++) + if (!src[srcsize]) + break; + if (dstsize > srcsize) + dstsize = srcsize; + else if (dstsize) + dstsize--; + if (dstsize) + /* assumes non-overlapping buffers */ + memcpy(dst, src, dstsize); + dst[dstsize] = 0; + return srcsize; +} +#endif + +#ifndef HAVE_STRLCAT +size_t +strlcat(char *dst, const char *src, size_t dstsize) { + size_t ld, ls; + for (ld = 0; ld < dstsize - 1; ld++) + if (!dst[ld]) + break; + dst += ld; + dstsize -= ld; + for (ls = 0; ls < dstsize; ls++) + if (!src[ls]) + break; + if (dstsize > ls) + dstsize = ls; + else if (dstsize) + dstsize--; + if (dstsize) + memcpy(dst, src, dstsize); + dst[dstsize] = 0; + return ld + ls; +} +#endif Property changes on: projects/doctools/contrib/heirloom-doctools/compat.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: projects/doctools/contrib/heirloom-doctools/eqn/checkeq.d/checkeq.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/checkeq.d/checkeq.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/eqn/checkeq.d/checkeq.c (revision 307812) @@ -1,148 +1,128 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* from OpenSolaris "checkeq.c 1.6 05/06/02 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany */ #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 #define USED __attribute__ ((used)) #elif defined __GNUC__ #define USED __attribute__ ((unused)) #else #define USED #endif static const char sccsid[] USED = "@(#)/usr/ucb/checkeq.sl 4.1 (gritter) 9/15/05"; #include #include static void check(FILE *); -static char *fgetline(char **, size_t *, FILE *); static FILE *fin; static int delim = '$'; int main(int argc, char **argv) { if (argc <= 1) check(stdin); else while (--argc > 0) { if ((fin = fopen(*++argv, "r")) == NULL) { perror(*argv); exit(1); } printf("%s:\n", *argv); check(fin); fclose(fin); } return (0); } static void check(FILE *f) { int start, line, eq, ndel, totdel; char *in = NULL, *p; size_t insize = 0; start = eq = line = ndel = totdel = 0; - while (fgetline(&in, &insize, f) != NULL) { + while (getline(&in, &insize, f) > 0) { line++; ndel = 0; for (p = in; *p; p++) if (*p == delim) ndel++; if (*in == '.' && *(in+1) == 'E' && *(in+2) == 'Q') { if (eq++) printf(" Spurious EQ, line %d\n", line); if (totdel) printf(" EQ in %c%c, line %d\n", delim, delim, line); } else if (*in == '.' && *(in+1) == 'E' && *(in+2) == 'N') { if (eq == 0) printf(" Spurious EN, line %d\n", line); else eq = 0; if (totdel > 0) printf(" EN in %c%c, line %d\n", delim, delim, line); start = 0; } else if (eq && *in == 'd' && *(in+1) == 'e' && *(in+2) == 'l' && *(in+3) == 'i' && *(in+4) == 'm') { for (p = in+5; *p; p++) if (*p != ' ') { if (*p == 'o' && *(p+1) == 'f') delim = 0; else delim = *p; break; } if (delim == 0) printf(" Delim off, line %d\n", line); else printf(" New delims %c%c, line %d\n", delim, delim, line); } if (ndel > 0 && eq > 0) printf(" %c%c in EQ, line %d\n", delim, delim, line); if (ndel == 0) continue; totdel += ndel; if (totdel%2) { if (start == 0) start = line; else { printf(" %d line %c%c, lines %d-%d\n", line-start+1, delim, delim, start, line); start = line; } } else { if (start > 0) { printf(" %d line %c%c, lines %d-%d\n", line-start+1, delim, delim, start, line); start = 0; } totdel = 0; } } if (totdel) printf(" Unfinished %c%c\n", delim, delim); if (eq) printf(" Unfinished EQ\n"); -} - -static char * -fgetline(char **lp, size_t *zp, FILE *fp) -{ - size_t n = 0; - int c; - - while ((c = getc(fp)) != EOF) { - if (n >= *zp) - *lp = realloc(*lp, *zp += 600); - (*lp)[n++] = c; - if (c == '\n') - break; - } - if (n >= *zp) - *lp = realloc(*lp, *zp += 600); - (*lp)[n] = 0; - return c != EOF ? *lp : NULL; } Index: projects/doctools/contrib/heirloom-doctools/eqn/diacrit.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/diacrit.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/eqn/diacrit.c (revision 307812) @@ -1,128 +1,128 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "diacrit.c 1.6 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)diacrit.c 1.7 (gritter) 1/13/08 */ #include "e.h" #include "y.tab.h" void diacrit(int p1, int type) { int c, t; #ifndef NEQN float effps; #endif /* NEQN */ c = oalloc(); t = oalloc(); #ifdef NEQN nrwid(p1, ps, p1); - printf(".nr 10 %gu\n", max(eht[p1]-ebase[p1]-VERT(2),0)); + printf(".nr 10 %gu\n", (float)max(eht[p1]-ebase[p1]-VERT(2),0)); #else /* NEQN */ effps = EFFPS(ps); nrwid(p1, effps, p1); printf(".nr 10 %gp\n", VERT(max(eht[p1]-ebase[p1]-EM(1,ps),0))); /* vertical shift if high */ printf(".if \\n(ct>1 .nr 10 \\n(10+\\s%s.25m\\s0\n", tsize(effps)); if (type != HAT && type != TILDE) { printf(".nr %d \\s%s.1m\\s0\n", t, tsize(effps)); /* horiz shift if high */ printf(".if \\n(ct>1 .nr %d \\s%s.15m\\s0\n", t, tsize(effps)); } else printf(".nr %d 0\n", t); #endif /* NEQN */ switch(type) { case VEC: /* vec */ #ifndef NEQN printf(".ds %d \\v'-.4m'\\s%s\\(->\\s0\\v'.4m'\n", c, tsize(max(effps-3, 6))); break; #endif /* NEQN */ case DYAD: /* dyad */ #ifdef NEQN printf(".ds %d \\v'-12p'_\\v'12p'\n", c); #else /* !NEQN */ printf(".ds %d \\v'-.4m'\\s%s\\z\\(<-\\(->\\s0\\v'.4m'\n", c, tsize(max(effps-3, 6))); #endif /* !NEQN */ break; case HAT: printf(".ds %d ^\n", c); break; case TILDE: printf(".ds %d ~\n", c); break; case DOT: #ifndef NEQN printf(".ds %d \\s%s\\v'-.67m'.\\v'.67m'\\s0\n", c, tsize(effps)); #else /* NEQN */ printf(".ds %d \\v'-12p'.\\v'12p'\n", c); #endif /* NEQN */ break; case DOTDOT: #ifndef NEQN printf(".ds %d \\s%s\\v'-.67m'..\\v'.67m\\s0'\n", c, tsize(effps)); #else /* NEQN */ printf(".ds %d \\v'-12p'..\\v'12p'\n", c); #endif /* NEQN */ break; case BAR: #ifndef NEQN printf(".ds %d \\s%s\\v'.28m'\\h'.05m'\\l'\\n(%du-.1m\\(rn'\\h'.05m'\\v'-.28m'\\s0\n", c, tsize(effps), p1); #else /* NEQN */ printf(".ds %d \\v'-12p'\\l'\\n(%du'\\v'12p'\n", c, p1); #endif /* NEQN */ break; case UNDER: #ifndef NEQN printf(".ds %d \\l'\\n(%du\\(ul'\n", c, p1); printf(".nr %d 0\n", t); printf(".nr 10 0-%gp\n", ebase[p1]); #else /* NEQN */ printf(".ds %d \\l'\\n(%du'\n", c, p1); #endif /* NEQN */ break; } nrwid(c, ps, c); #ifndef NEQN if (!ital(lfont[p1])) printf(".nr %d 0\n", t); printf(".as %d \\h'-\\n(%du-\\n(%du/2u+\\n(%du'\\v'0-\\n(10u'\\*(%d", p1, p1, c, t, c); printf("\\v'\\n(10u'\\h'-\\n(%du+\\n(%du/2u-\\n(%du'\n", c, p1, t); /* BUG - should go to right end of widest */ #else /* NEQN */ printf(".as %d \\h'-\\n(%du-\\n(%du/2u'\\v'0-\\n(10u'\\*(%d", p1, p1, c, c); printf("\\v'\\n(10u'\\h'-\\n(%du+\\n(%du/2u'\n", c, p1); #endif /* NEQN */ #ifndef NEQN if (type != UNDER) eht[p1] += VERT(EM(0.15, ps)); /* 0.15m */ if(dbg)printf(".\tdiacrit: %c over S%d, lf=%c, rf=%c, h=%g,b=%g\n", type, p1, lfont[p1], rfont[p1], eht[p1], ebase[p1]); #else /* NEQN */ if (type != UNDER) eht[p1] += VERT(1); if (dbg) printf(".\tdiacrit: %c over S%d, h=%d, b=%d\n", type, p1, eht[p1], ebase[p1]); #endif /* NEQN */ ofree(c); ofree(t); } Index: projects/doctools/contrib/heirloom-doctools/eqn/e.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/e.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/eqn/e.h (revision 307812) @@ -1,188 +1,182 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from "e.h 1.5 05/06/02 SMI" "ucbeqn:e.h 1.1" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)e.h 1.13 (gritter) 1/13/08 */ /* * Changes Copyright (c) 2014 Carsten Kunze (carsten.kunze at arcor.de) */ #include #include #include "global.h" -#if defined (__GLIBC__) && defined (_IO_getc_unlocked) -#undef getc -#define getc(f) _IO_getc_unlocked(f) -#endif - #define FATAL 1 #define ROM '1' #ifndef NEQN #define ITAL '2' #define BLD '3' #else /* NEQN */ #define ITAL '1' #define BLD '1' #endif /* NEQN */ #define rom(c) (((c) & 0177) == ROM) #define ital(c) (((c) & 0177) == ITAL) #define bld(c) (((c) & 0177) == BLD) #define OP 0200 #define op(c) ((c) & OP) #ifndef NEQN #define VERT(n) (n) #define POINT 72 #define EM(m, ps) ((((float)(m)*(ps) * resolution) / POINT)) #else /* NEQN */ #define VERT(n) (20 * (n)) #endif /* NEQN */ #define EFFPS(p) ((p) >= 6 ? (p) : 6) extern int dbg; extern int ct; extern int lp[]; extern int used[]; /* available registers */ extern float ps; /* dflt init pt size */ #define resolution 72 /* was: resolution of ditroff */ extern float deltaps; /* default change in ps */ extern float gsize; /* global size */ extern int gfont; /* global font */ extern int ft; /* dflt font */ extern FILE *curfile; /* current input file */ extern int ifile; /* input file number */ extern int linect; /* line number in current file */ extern int eqline; /* line where eqn started */ extern int svargc; extern char **svargv; #ifndef NEQN extern float eht[100]; extern float ebase[100]; #else /* NEQN */ extern int eht[100]; extern int ebase[100]; #endif /* NEQN */ extern int lfont[100]; extern int rfont[100]; extern int eqnreg, eqnht; extern int lefteq, righteq; extern int lastchar; /* last character read by lex */ extern int markline; /* 1 if this EQ/EN contains mark or lineup */ extern char *progname; typedef struct s_tbl { const char *name; const char *defn; struct s_tbl *next; } tbl; extern char *spaceval; /* use in place of normal \x (for pic) */ extern tbl *keytbl[]; /* key words */ extern tbl *restbl[]; /* reserved words */ extern tbl *deftbl[]; /* user-defined names */ /* diacrit.c */ void diacrit(int, int); /* e.c */ int yyparse(void); /* eqnbox.c */ void eqnbox(int, int, int); /* font.c */ void setfont(char); void font(int, int); void fatbox(int); void globfont(void); /* fromto.c */ void fromto(int, int, int); /* funny.c */ void funny(int); /* glob.c */ /* integral.c */ void integral(int, int, int); void setintegral(void); /* io.c */ int main(int, char **); void eqnexit(int); int eqn(int, char **); #define getline(s, n) eqngetline(s, n) int getline(char **, size_t *); void do_inline(void); void putout(int); -float max(float, float); int oalloc(void); void ofree(int); void setps(float); void nrwid(int, float, int); void setfile(int, char **); void yyerror(char *); void init(void); void error(int, const char *, ...); /* lex.c */ int gtc(void); int openinfile(void); -void pbstr(register char *); +void pbstr(register const char *); int yylex(void); int getstr(char *, register int); int cstr(char *, int, int); void define(int); void space(void); char *strsave(char *); void include(void); void delim(void); /* lookup.c */ tbl *lookup(tbl **, const char *, const char *); void init_tbl(void); /* mark.c */ void mark(int); void lineup(int); /* matrix.c */ void column(int, int); void matrix(int); /* move.c */ void move(int, int, int); /* over.c */ void boverb(int, int); /* paren.c */ void paren(int, int, int); void brack(int, const char *, const char *, const char *); /* pile.c */ void lpile(int, int, int); /* shift.c */ void bshiftb(int, int, int); void shift(int); void shift2(int, int, int); /* size.c */ void setsize(char *); void size(float, int); void globsize(void); char *tsize(float); /* sqrt.c */ #define sqrt(n) eqnsqrt(n) void sqrt(int); /* text.c */ void text(int, char *); int trans(int, char *); void shim(int); void roman(int); void name4(int, int); Index: projects/doctools/contrib/heirloom-doctools/eqn/io.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/io.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/eqn/io.c (revision 307812) @@ -1,323 +1,318 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983-1988, 2001 by Sun Microsystems, Inc. * All rights reserved. */ /* from OpenSolaris "io.c 1.10 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)io.c 1.13 (gritter) 1/13/08 */ # include "e.h" #include #include #include static char *in; /* input buffer */ static size_t insize; /* input buffer size */ static int noeqn; int main(int argc,char **argv) { progname = basename(argv[0]); eqnexit(eqn(argc, argv)); /*NOTREACHED*/ return 0; } void eqnexit(int n) { #ifdef gcos if (n) fprintf(stderr, "run terminated due to eqn error\n"); exit(0); #endif exit(n); } int eqn(int argc,char **argv) { int i, type; setfile(argc,argv); init_tbl(); /* install keywords in tables */ while ((type=getline(&in, &insize)) != EOF) { eqline = linect; if (type == lefteq) do_inline(); else if (*in == '.') { char *p; printf("%s",in); for (p = in + 1; *p == ' ' || *p == '\t'; p++); if (!*p || *p != 'E' || p[1] != 'Q') continue; for (i=11; i<100; used[i++]=0); printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n"); printf(".if \\n(.X .nrf 99 \\n(.s\n"); markline = 0; init(); yyparse(); if (eqnreg>0) { printf(".nr %d \\w'\\*(%d'\n", eqnreg, eqnreg); /* printf(".if \\n(%d>\\n(.l .tm too-long eqn, file %s, between lines %d-%d\n", */ /* eqnreg, svargv[ifile], eqline, linect); */ printf(".nr MK %d\n", markline); /* for -ms macros */ printf(".if %d>\\n(.v .ne %du\n", eqnht, eqnht); printf(".rn %d 10\n", eqnreg); if(!noeqn)printf("\\*(10\n"); } printf(".ps \\n(99\n.ft \\n(98\n"); printf(".EN"); if (lastchar == EOF) { putchar('\n'); break; } if (putchar(lastchar) != '\n') while (putchar(gtc()) != '\n'); } else printf("%s",in); } return(0); } int getline(char **sp, size_t *np) { register int c, esc = 0, par = 0, brack = 0; size_t n = 0; char *xp; for (;;) { c = gtc(); if (n+1 >= *np) { xp = realloc(*sp, *np += 128); if (xp == NULL) { error( !FATAL, "input line too long: %.20s\n", in); xp[--n] = '\0'; break; } *sp = xp; } (*sp)[n++] = c; if (c=='\\') esc++; else { if (c=='\n' || c==EOF || (c==lefteq && !esc && !par && !brack)) break; if (par) par--; if (brack && c == ']') brack = 0; if (esc) { switch (c) { case '*': case 'f': case 'g': case 'k': case 'n': case 'P': case 'V': case 'Y': break; case '(': par += 2; break; case '[': brack++; break; default: esc = 0; } } } } if (c==lefteq && !esc) n--; (*sp)[n++] = '\0'; return(c); } void do_inline(void) { int ds; printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n"); printf(".if \\n(.X .nrf 99 \\n(.s\n"); ds = oalloc(); printf(".rm %d \n", ds); do{ if (*in) printf(".as %d \"%s\n", ds, in); init(); yyparse(); if (eqnreg > 0) { printf(".as %d \\*(%d\n", ds, eqnreg); ofree(eqnreg); } printf(".ps \\n(99\n.ft \\n(98\n"); } while (getline(&in, &insize) == lefteq); if (*in) printf(".as %d \"%s", ds, in); printf(".ps \\n(99\n.ft \\n(98\n"); printf("\\*(%d\n", ds); ofree(ds); } void putout(int p1) { #ifndef NEQN float before, after; if(dbg)printf(".\tanswer <- S%d, h=%g,b=%g\n",p1, eht[p1], ebase[p1]); #else /* NEQN */ int before, after; if(dbg)printf(".\tanswer <- S%d, h=%d,b=%d\n",p1, eht[p1], ebase[p1]); #endif /* NEQN */ eqnht = eht[p1]; printf(".ds %d ", p1); /* suppposed to leave room for a subscript or superscript */ #ifndef NEQN before = eht[p1] - ebase[p1] - VERT(EM(1.2, ps)); #else /* NEQN */ before = eht[p1] - ebase[p1] - VERT(3); /* 3 = 1.5 lines */ #endif /* NEQN */ if (spaceval != NULL) printf("\\x'0-%s'", spaceval); else if (before > 0) #ifndef NEQN printf("\\x'0-%gp'", before); #else /* NEQN */ printf("\\x'0-%du'", before); #endif /* NEQN */ printf("\\f%c\\s%s\\*(%d%s\n", gfont, tsize(gsize), p1, ital(rfont[p1]) ? "\\|" : ""); printf(".ie \\n(.X=0 .as %d \\s\\n(99\n", p1); printf(".el .as %d \\s[\\n(99]\n", p1); printf(".as %d \\f\\n(98", p1); #ifndef NEQN after = ebase[p1] - VERT(EM(0.2, ps)); #else /* NEQN */ after = ebase[p1] - VERT(1); #endif /* NEQN */ if (spaceval == NULL && after > 0) #ifndef NEQN printf("\\x'%gp'", after); #else /* NEQN */ printf("\\x'%du'", after); #endif /* NEQN */ putchar('\n'); eqnreg = p1; if (spaceval != NULL) { free(spaceval); spaceval = NULL; } } -float -max(float i,float j) { - return (i>j ? i : j); -} - int oalloc(void) { int i; for (i=11; i<100; i++) if (used[i]++ == 0) return(i); error( FATAL, "no eqn strings left", i); return(0); } void ofree(int n) { used[n] = 0; } void setps(float p) { printf(".ps %g\n", EFFPS(p)); } void nrwid(int n1, float p, int n2) { printf(".nr %d \\w'\\s%s\\*(%d'\n", n1, tsize(EFFPS(p)), n2); } void setfile(int argc, char **argv) { static char *nullstr = "-"; svargc = --argc; svargv = argv; while (svargc > 0 && svargv[1][0] == '-') { switch (svargv[1][1]) { case 'd': lefteq=svargv[1][2]; righteq=svargv[1][3]; break; case 's': gsize = atof(&svargv[1][2]); break; case 'p': deltaps = atof(&svargv[1][2]); break; case 'f': gfont = svargv[1][2]; break; case 'e': noeqn++; break; case 'r': /*resolution = atoi(&svargv[1][2]);*/ break; case 0: goto endargs; default: dbg = 1; } svargc--; svargv++; } endargs: ifile = 1; linect = 1; if (svargc <= 0) { curfile = stdin; svargv[1] = nullstr; } else openinfile(); /* opens up the first input file */ } void yyerror(char *unused) {;} void init(void) { ct = 0; ps = gsize; ft = gfont; setps(ps); printf(".ft %c\n", ft); } void error(int fatal, const char *s1, ...) { va_list ap; if (fatal>0) printf("%s fatal error: ", progname); va_start(ap, s1); vfprintf(stdout, s1, ap); va_end(ap); printf("\nfile %s, between lines %d and %d\n", svargv[ifile], eqline, linect); fprintf(stderr, "%s: ", progname); if (fatal>0) fprintf(stderr, "fatal error: "); va_start(ap, s1); vfprintf(stderr, s1, ap); va_end(ap); fprintf(stderr, "\nfile %s, between lines %d and %d\n", svargv[ifile], eqline, linect); if (fatal > 0) eqnexit(1); } Index: projects/doctools/contrib/heirloom-doctools/eqn/lex.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/lex.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/eqn/lex.c (revision 307812) @@ -1,307 +1,307 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "lex.c 1.6 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)lex.c 1.7 (gritter) 11/21/07 */ /* * Changes Copyright (c) 2014 Carsten Kunze (carsten.kunze at arcor.de) */ #include "e.h" #include #include #include #include "y.tab.h" extern YYSTYPE yyval; #define SSIZE 400 static char token[SSIZE]; static int sp; #define putbak(c) *ip++ = c; #define PUSHBACK 300 /* maximum pushback characters */ static char ibuf[PUSHBACK+SSIZE]; /* pushback buffer for definitions, etc. */ static char *ip = ibuf; int gtc(void) { loop: if (ip > ibuf) return(*--ip); /* already present */ lastchar = getc(curfile); if (lastchar=='\n') linect++; if (lastchar != EOF) return(lastchar); if (++ifile > svargc) { return(EOF); } fclose(curfile); linect = 1; if (openinfile() == 0) goto loop; return(EOF); } /* * open file indexed by ifile in svargv, return non zero if fail */ int openinfile(void) { if (strcmp(svargv[ifile], "-") == 0){ curfile = stdin; return(0); } else if ((curfile=fopen(svargv[ifile], "r")) != NULL){ return(0); } error(FATAL, "can't open file %s", svargv[ifile]); return(1); } void -pbstr(register char *str) +pbstr(register const char *str) { - register char *p; + register const char *p; p = str; while (*p++); --p; if (ip >= &ibuf[PUSHBACK]) error( FATAL, "pushback overflow"); while (p > str) putbak(*--p); } int yylex(void) { register int c; tbl *tp; beg: while ((c=gtc())==' ' || c=='\n') ; yylval.token = c; switch(c) { case EOF: return(EOF); case '~': return(SPACE); case '^': return(THIN); case '\t': return(TAB); case '{': return('{'); case '}': return('}'); case '"': for (sp=0; (c=gtc())!='"' && c != '\n'; ) { if (c == '\\') if ((c = gtc()) != '"') token[sp++] = '\\'; token[sp++] = c; if (sp>=SSIZE) error(FATAL, "quoted string %.20s... too long", token); } token[sp]='\0'; yylval.str = &token[0]; if (c == '\n') error(!FATAL, "missing \" in %.20s", token); return(QTEXT); } if (c==righteq) return(EOF); putbak(c); if (getstr(token, SSIZE)) return EOF; if (dbg)printf(".\tlex token = |%s|\n", token); if ((tp = lookup(deftbl, token, NULL)) != NULL) { putbak(' '); pbstr(tp->defn); putbak(' '); if (dbg) printf(".\tfound %s|=%s|\n", token, tp->defn); } else if ((tp = lookup(keytbl, token, NULL)) == NULL) { if(dbg)printf(".\t%s is not a keyword\n", token); return(CONTIG); } else if ((intptr_t)tp->defn == DEFINE || (intptr_t)tp->defn == NDEFINE || (intptr_t)tp->defn == TDEFINE) define((intptr_t)tp->defn); else if (tp->defn == (char *) DELIM) delim(); else if (tp->defn == (char *) GSIZE) globsize(); else if (tp->defn == (char *) GFONT) globfont(); else if (tp->defn == (char *) INCLUDE) include(); else if (tp->defn == (char *) SPACE) space(); else { return((intptr_t) tp->defn); } goto beg; } /* returns: 1 if ".{WS}+EN" found, 0 else */ int getstr(char *s, register int n) { register int c; register char *p; enum { INI = 0, OTH, SP, C1, C2, PB } st = INI; p = s; while ((c = gtc()) == ' ' || c == '\n') ; if (c == EOF) { *s = 0; return 0; } while (((c != ' ' && c != '\t') || st == SP) && c != '\n' && c != '{' && c != '}' && c != '"' && c != '~' && c != '^' && c != righteq) { if (c == '\\') if ((c = gtc()) != '"') *p++ = '\\'; switch (st) { case INI: st = c == '.' ? SP : OTH; break; case SP: if (c == 'E') st = C1; else if (c != ' ' && c != '\t') st = PB; break; case C1: st = c == 'N' ? C2 : PB; break; case C2: st = PB; break; default: ; } *p++ = c; if (st == PB) goto TF; else { if (--n <= 0) error(FATAL, "token %.20s... too long", s); c = gtc(); } } if (c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq) putbak(c); TF: if (st == SP || st == C1 || st == PB) { while (--p != s) putbak(*p); p++; } *p = '\0'; yylval.str = s; return st == C2; } int cstr(char *s, int quote, int maxs) { int del, c, i; s[0] = 0; while((del=gtc()) == ' ' || del == '\t'); if (quote) for (i=0; (c=gtc()) != del && c != EOF;) { s[i++] = c; if (i >= maxs) return(1); /* disaster */ } else { if (del == '\n') return (1); s[0] = del; for (i=1; (c=gtc())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) { s[i++]=c; if (i >= maxs) return(1); /* disaster */ } } s[i] = '\0'; if (c == EOF) error(FATAL, "Unexpected end of input at %.20s", s); return(0); } void define(int type) { char *p1, *p2; extern tbl *deftbl[]; getstr(token, SSIZE); /* get name */ if (type != DEFINE) { cstr(token, 1, SSIZE); /* skip the definition too */ return; } p1 = strsave(token); if (cstr(token, 1, SSIZE)) error(FATAL, "Unterminated definition at %.20s", token); p2 = strsave(token); lookup(deftbl, p1, p2); if (dbg)printf(".\tname %s defined as %s\n", p1, p2); } char *spaceval = NULL; void space(void) /* collect line of form "space amt" to replace \x in output */ { getstr(token, SSIZE); spaceval = strsave(token); if (dbg) printf(".\tsetting space to %s\n", token); } char * strsave(char *s) { register char *q; size_t l; l = strlen(s)+1; q = malloc(l); if (q == NULL) error(FATAL, "out of space in strsave on %s", s); n_strcpy(q, s, l); return(q); } void include(void) { error(!FATAL, "Include not yet implemented"); } void delim(void) { yyval.token = eqnreg = 0; if (cstr(token, 0, SSIZE)) error(FATAL, "Bizarre delimiters at %.20s", token); lefteq = token[0]; righteq = token[1]; if (lefteq == 'o' && righteq == 'f') lefteq = righteq = '\0'; } Index: projects/doctools/contrib/heirloom-doctools/grap/coord.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/grap/coord.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/grap/coord.c (revision 307812) @@ -1,83 +1,84 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/grap/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)coord.c 1.3 (gritter) 10/18/05 */ #include #include #include +#include "global.h" #include "grap.h" #include "y.tab.h" char *dflt_coord = "gg"; char *curr_coord = "gg"; int ncoord = 0; /* number of explicit coord's given */ Point xcoord; Point ycoord; int xcflag = 0; /* 1 if xcoord set */ int ycflag = 0; int logcoord = 0; void coord_x(Point pt) /* remember x coord */ { xcoord = pt; xcflag = 1; margin = 0; /* no extra space around picture if explicit coords */ } void coord_y(Point pt) { ycoord = pt; ycflag = 1; margin = 0; /* no extra space if explicit coords */ } void coordlog(int n) /* remember log scaling */ { logcoord = n; } void coord(Obj *p) /* set coord range */ { static char buf[10]; ncoord++; if (ncoord > 1 && strcmp(p->name, dflt_coord) == 0) { /* resetting default coordinate by implication */ snprintf(buf, sizeof(buf), "gg%d", ncoord); dflt_coord = buf; p = lookup(dflt_coord, 1); } if (xcflag) { p->coord |= XFLAG; p->pt.x = min(xcoord.x,xcoord.y); /* "xcoord" is xmin, xmax */ p->pt1.x = max(xcoord.x,xcoord.y); if ((logcoord&XFLAG) && p->pt.x <= 0.0) FATAL("can't have log of x coord %g,%g", p->pt.x, p->pt1.x); xcflag = 0; } if (ycflag) { p->coord |= YFLAG; p->pt.y = min(ycoord.x,ycoord.y); /* "ycoord" is ymin, ymax */ p->pt1.y = max(ycoord.x,ycoord.y); if ((logcoord&YFLAG) && p->pt.y <= 0.0) FATAL("can't have log of y coord %g,%g", p->pt.y, p->pt1.y); ycflag = 0; } p->log = logcoord; logcoord = 0; auto_x = 0; } void resetcoord(Obj *p) /* reset current coordinate */ { curr_coord = p->name; } Index: projects/doctools/contrib/heirloom-doctools/grap/grap.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/grap/grap.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/grap/grap.h (revision 307812) @@ -1,257 +1,254 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/grap/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)grap.h 1.5 (gritter) 12/5/05 */ extern void FATAL(const char *, ...); extern void WARNING(const char *, ...); #include "global.h" #define dprintf if(dbg)printf #define String 01 #define Macro 02 #define File 04 #define Char 010 #define Thru 020 #define Free 040 #define MARGIN 0.07 /* default margin around data */ #define SLOP 1.001 /* slop for limits of for loops */ #define FRAMEWID 3 /* default width for boxes and ellipses */ #define FRAMEHT 2 /* default height and line length */ #define TICKLEN 0.1 #define MAXNUM 200 #define XFLAG 01 #define YFLAG 02 #define INTICK 01 #define OUTICK 02 #define BOT 01 #define TOP 02 #define RIGHT 04 #define LEFT 010 #define RJUST 01 #define LJUST 02 #define ABOVE 04 #define BELOW 010 typedef struct infile { FILE *fin; char *fname; int lineno; } Infile; typedef struct { /* input source */ int type; /* Macro, String, File */ char *sp; /* if String or Macro */ } Src; extern Src src[], *srcp; /* input source stack */ #define MAXARGS 100 typedef struct { /* argument stack */ char *argstk[MAXARGS]; /* pointers to args */ char *argval; /* points to space containing args */ } Arg; extern Infile infile[10]; extern Infile *curfile; typedef struct { struct obj *obj; double x, y; } Point; typedef struct attr { /* e.g., DASH 1.1 or "..." rjust size *.5 */ int type; double fval; char *sval; int just; /* justification, for STRING type */ int op; /* optional operator, ditto */ struct attr *next; } Attr; typedef struct obj { /* a name and its properties */ char *name; char *val; /* body of define, etc. */ double fval; /* if a numeric variable */ Point pt; /* usually for max and min */ Point pt1; int type; /* NAME, DEFNAME, ... */ int first; /* 1 after 1st item seen */ int coord; /* 1 if coord system specified for this name */ int log; /* x, y, or z (= x+y) */ Attr *attr; /* DASH, etc., for now */ struct obj *next; } Obj; #define YYSTYPE YYSTYPE typedef union { /* the yacc stack type */ int i; char *p; double f; Point pt; Obj *op; Attr *ap; } YYSTYPE; extern YYSTYPE yylval; extern int dbg; extern int ntext; extern double num[MAXNUM]; extern int nnum; extern int ntick, tside; extern char *tostring(char *); extern char *grow(char *, char *, int, int); extern int lineno; extern int synerr; extern int codegen; extern char tempfile[]; extern FILE *tfd; extern int Sflag; extern Point ptmin, ptmax; extern char *dflt_coord; extern char *curr_coord; extern int ncoord; extern int auto_x; extern double margin; extern int autoticks; extern int pointsize, ps_set; #define logit(x) (x) = log10(x) #define Log10(x) errcheck(log10(x), "log") #define Exp(x) errcheck(exp(x), "exp") #define Sqrt(x) errcheck(sqrt(x), "sqrt") -#define min(x,y) (((x) <= (y)) ? (x) : (y)) -#define max(x,y) (((x) >= (y)) ? (x) : (y)) - extern void yyerror(char *); extern void coord_x(Point); extern void coord_y(Point); extern void coordlog(int); extern void coord(Obj *); extern void resetcoord(Obj *); extern void savenum(int, double); extern void setjust(int); extern void setsize(int, double); extern void range(Point); extern void halfrange(Obj *, int, double); extern Obj *lookup(char *, int); extern double getvar(Obj *); extern double setvar(Obj *, double); extern Point makepoint(Obj *, double, double); extern Attr *makefattr(int, double); extern Attr *makesattr(char *); extern Attr *makeattr(int, double, char *, int, int); extern Attr *addattr(Attr *, Attr *); extern void freeattr(Attr *); extern char *slprint(Attr *); extern char *juststr(int); extern char *sprntf(char *, Attr *); extern void forloop(Obj *, double, double, int, double, char *); extern void nextfor(void); extern void endfor(void); extern char *ifstat(double, char *, char *); extern void frame(void); extern void frameht(double); extern void framewid(double); extern void frameside(int, Attr *); extern void pushsrc(int, char *); extern void popsrc(void); extern void definition(char *); extern char *delimstr(char *); extern int baldelim(int, char *); extern void dodef(Obj *); extern int getarg(char *); #ifdef FLEX_SCANNER extern int xxinput(void); extern int xxunput(int); #else /* !FLEX_SCANNER */ #define input xxinput #define unput xxunput extern int input(void); extern int unput(int); #endif /* !FLEX_SCANNER */ extern int nextchar(void); extern void do_thru(void); extern void pbstr(char *); extern double errcheck(double, char *); extern void yyerror(char *); extern void eprint(void); extern int yywrap(void); extern void copyfile(char *); extern void copydef(Obj *); extern Obj *copythru(char *); extern char *addnewline(char *); extern void copyuntil(char *); extern void copy(void); extern void shell_init(void); extern void shell_text(char *); extern void shell_exec(void); extern void labelwid(double); extern void labelmove(int, double); extern void label(int, Attr *); extern void lab_adjust(void); extern char *sizeit(Attr *); extern void line(int, Point, Point, Attr *); extern void circle(double, Point); extern char *xyname(Point); extern void pic(char *); extern void numlist(void); extern void plot(Attr *, Point); extern void plotnum(double, char *, Point); extern void drawdesc(int, Obj *, Attr *, char *); extern void next(Obj *, Point, Attr *); extern void print(void); extern void endstat(void); extern void graph(char *); extern void setup(void); extern void do_first(void); extern void reset(void); extern void opentemp(void); extern void savetick(double, char *); extern void dflt_tick(double); extern void tickside(int); extern void tickoff(int); extern void gridtickoff(void); extern void setlist(void); extern void tickdir(int, double, int); extern void ticks(void); extern double modfloor(double, double); extern double modceil(double, double); extern void do_autoticks(Obj *); extern void logtick(double, double, double); extern Obj *setauto(void); extern void autoside(Obj *, int); extern void autolog(Obj *, int); extern void iterator(double, double, int, double, char *); extern void ticklist(Obj *, int); extern void print_ticks(int, int, Obj *, char *, char *); extern void maketick(int, char *, int, int, double, char *, char *, char *); extern void griddesc(Attr *); extern void gridlist(Obj *); extern char *desc_str(Attr *); extern int sidelog(int, int); extern Obj *objlist; Index: projects/doctools/contrib/heirloom-doctools/grap/input.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/grap/input.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/grap/input.c (revision 307812) @@ -1,628 +1,593 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/grap/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)input.c 1.7 (gritter) 12/25/06 */ #include #include #include #include #include #include "grap.h" #include "y.tab.h" -#if defined (__GLIBC__) && defined (_IO_getc_unlocked) -#undef getc -#define getc(f) _IO_getc_unlocked(f) -#endif - Infile infile[10]; Infile *curfile = infile; #define MAXSRC 50 Src src[MAXSRC]; /* input source stack */ Src *srcp = src; void pushsrc(int type, char *ptr) /* new input source */ { if (++srcp >= src + MAXSRC) FATAL("inputs nested too deep"); srcp->type = type; srcp->sp = ptr; if (dbg) { printf("\n%3d ", (int)(srcp - src)); switch (srcp->type) { case File: printf("push file %s\n", ((Infile *)ptr)->fname); break; case Macro: printf("push macro <%s>\n", ptr); break; case Char: printf("push char <%c>\n", *ptr); break; case Thru: printf("push thru\n"); break; case String: printf("push string <%s>\n", ptr); break; case Free: printf("push free <%s>\n", ptr); break; default: FATAL("pushed bad type %d", srcp->type); } } } void popsrc(void) /* restore an old one */ { if (srcp <= src) FATAL("too many inputs popped"); if (dbg) { printf("%3d ", (int)(srcp - src)); switch (srcp->type) { case File: printf("pop file\n"); break; case Macro: printf("pop macro\n"); break; case Char: printf("pop char <%c>\n", *srcp->sp); break; case Thru: printf("pop thru\n"); break; case String: printf("pop string\n"); break; case Free: printf("pop free\n"); break; default: FATAL("pop weird input %d", srcp->type); } } srcp--; } void definition(char *s) /* collect definition for s and install */ /* definitions picked up lexically */ { char *p; Obj *stp; p = delimstr("definition"); stp = lookup(s, 0); if (stp != NULL) { /* it's there before */ if (stp->type != DEFNAME) { WARNING("%s used as variable and definition", s); return; } free(stp->val); } else { stp = lookup(s, 1); stp->type = DEFNAME; } stp->val = p; dprintf("installing %s as `%s'\n", s, p); } char *delimstr(char *s) /* get body of X ... X */ /* message if too big */ { int c, delim, rdelim, n, deep; static char *buf = NULL; static int nbuf = 0; char *p; if (buf == NULL) buf = grow(buf, "buf", nbuf += 1000, sizeof(buf[0])); while ((delim = input()) == ' ' || delim == '\t' || delim == '\n') ; rdelim = baldelim(delim, "{}"); /* could be "(){}[]`'" */ deep = 1; for (p = buf; ; ) { c = input(); if (c == rdelim) if (--deep == 0) break; if (c == delim) deep++; if (p >= buf + nbuf) { n = p - buf; buf = grow(buf, "buf", nbuf += 1000, sizeof(buf[0])); p = buf + n; } if (c == EOF) FATAL("end of file in %s %c %.20s... %c", s, delim, buf, delim); *p++ = c; } *p = '\0'; dprintf("delimstr %s %c <%s> %c\n", s, delim, buf, delim); return tostring(buf); } int baldelim(int c, char *s) /* replace c by balancing entry in s */ { for ( ; *s; s += 2) if (*s == c) return s[1]; return c; } Arg args[10]; /* argument frames */ Arg *argfp = args; /* frame pointer */ int argcnt; /* number of arguments seen so far */ void dodef(Obj *stp) /* collect args and switch input to defn */ { int i, len; char *p; Arg *ap; ap = argfp+1; if (ap >= args+10) FATAL("arguments too deep"); argcnt = 0; if (input() != '(') FATAL("disaster in dodef"); if (ap->argval == 0) ap->argval = malloc(1000); for (p = ap->argval; (len = getarg(p)) != -1; p += len) { ap->argstk[argcnt++] = p; if (input() == ')') break; } for (i = argcnt; i < MAXARGS; i++) ap->argstk[i] = ""; if (dbg) for (i = 0; i < argcnt; i++) printf("arg %d.%d = <%s>\n", (int)(ap-args), i+1, ap->argstk[i]); argfp = ap; pushsrc(Macro, stp->val); } int getarg(char *p) /* pick up single argument, store in p, return length */ { int n, c, npar; n = npar = 0; for ( ;; ) { c = input(); if (c == EOF) FATAL("end of file in getarg!"); if (npar == 0 && (c == ',' || c == ')')) break; if (c == '"') /* copy quoted stuff intact */ do { *p++ = c; n++; } while ((c = input()) != '"' && c != EOF); else if (c == '(') npar++; else if (c == ')') npar--; n++; *p++ = c; } *p = 0; unput(c); return(n + 1); } #define PBSIZE 2000 char pbuf[PBSIZE]; /* pushback buffer */ char *pb = pbuf-1; /* next pushed back character */ char ebuf[200]; /* collect input here for error reporting */ char *ep = ebuf; int begin = 0; extern int thru; extern Obj *thrudef; extern char *untilstr; int input(void) { register int c; if (thru && begin) { do_thru(); begin = 0; } c = nextchar(); dprintf(" <%c>", c); if (ep >= ebuf + sizeof ebuf) ep = ebuf; return (*ep++ = c) & 0377; } int nextchar(void) { register int c = 0; loop: switch (srcp->type) { case Free: /* free string */ free(srcp->sp); popsrc(); goto loop; case Thru: /* end of pushed back line */ begin = 1; popsrc(); c = '\n'; break; case Char: if (pb >= pbuf) { c = *pb--; popsrc(); break; } else { /* can't happen? */ popsrc(); goto loop; } case String: c = *srcp->sp++; if (c == '\0') { popsrc(); goto loop; } else { if (*srcp->sp == '\0') /* empty, so pop */ popsrc(); break; } case Macro: c = *srcp->sp++; if (c == '\0') { if (--argfp < args) FATAL("argfp underflow"); popsrc(); goto loop; } else if (c == '$' && isdigit((int)*srcp->sp)) { /* $3 */ int n = 0; while (isdigit((int)*srcp->sp)) n = 10 * n + *srcp->sp++ - '0'; if (n > 0 && n <= MAXARGS) pushsrc(String, argfp->argstk[n-1]); goto loop; } break; case File: c = getc(curfile->fin); if (c == EOF) { if (curfile == infile) FATAL("end of file inside .G1/.G2"); if (curfile->fin != stdin) { fclose(curfile->fin); free(curfile->fname); /* assumes allocated */ } curfile--; printf(".lf %d %s\n", curfile->lineno, curfile->fname); popsrc(); thru = 0; /* chicken out */ thrudef = 0; if (untilstr) { free(untilstr); untilstr = 0; } goto loop; } if (c == '\n') curfile->lineno++; break; } return c; } void do_thru(void) /* read one line, make into a macro expansion */ { int c, i; char *p; Arg *ap; ap = argfp+1; if (ap >= args+10) FATAL("arguments too deep"); if (ap->argval == NULL) ap->argval = malloc(1000); p = ap->argval; argcnt = 0; c = nextchar(); if (thru == 0) { /* end of file was seen, so thru is done */ unput(c); return; } for ( ; c != '\n' && c != EOF; ) { if (c == ' ' || c == '\t') { c = nextchar(); continue; } if (argcnt >= MAXARGS) FATAL("too many fields on input line"); ap->argstk[argcnt++] = p; if (c == '"') { do { *p++ = c; if ((c = nextchar()) == '\\') { *p++ = c; *p++ = nextchar(); c = nextchar(); } } while (c != '"' && c != '\n' && c != EOF); *p++ = '"'; if (c == '"') c = nextchar(); } else { do { *p++ = c; } while ((c = nextchar())!=' ' && c!='\t' && c!='\n' && c!=',' && c!=EOF); if (c == ',') c = nextchar(); } *p++ = '\0'; } if (c == EOF) FATAL("unexpected end of file in do_thru"); if (argcnt == 0) { /* ignore blank line */ pushsrc(Thru, (char *) 0); return; } for (i = argcnt; i < MAXARGS; i++) ap->argstk[i] = ""; if (dbg) for (i = 0; i < argcnt; i++) printf("arg %d.%d = <%s>\n", (int)(ap-args), i+1, ap->argstk[i]); if (strcmp(ap->argstk[0], ".G2") == 0) { thru = 0; thrudef = 0; pushsrc(String, "\n.G2\n"); return; } if (untilstr && strcmp(ap->argstk[0], untilstr) == 0) { thru = 0; thrudef = 0; free(untilstr); untilstr = 0; return; } pushsrc(Thru, (char *) 0); dprintf("do_thru pushing back <%s>\n", thrudef->val); argfp = ap; pushsrc(Macro, thrudef->val); } int unput(int c) { if (++pb >= pbuf + sizeof pbuf) FATAL("pushback overflow"); if (--ep < ebuf) ep = ebuf + sizeof(ebuf) - 1; *pb = c; pushsrc(Char, pb); return c; } void pbstr(char *s) { pushsrc(String, s); } double errcheck(double x, char *s) { if (errno == EDOM) { errno = 0; WARNING("%s argument out of domain", s); } else if (errno == ERANGE) { errno = 0; WARNING("%s result out of range", s); } return x; } char errbuf[200]; void yyerror(char *s) { extern char *cmdname; int ern = errno; /* cause some libraries clobber it */ if (synerr) return; fflush(stdout); fprintf(stderr, "%s: %s", cmdname, s); if (ern > 0) { errno = ern; perror("???"); } fprintf(stderr, " near %s:%d\n", curfile->fname, curfile->lineno+1); eprint(); synerr = 1; errno = 0; } void eprint(void) /* try to print context around error */ { char *p, *q; p = ep - 1; if (p > ebuf && *p == '\n') p--; for ( ; p >= ebuf && *p != '\n'; p--) ; while (*p == '\n') p++; fprintf(stderr, " context is\n\t"); for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--) ; for (; p < q; p++) if (isprint((int)*p)) putc(*p, stderr); fprintf(stderr, " >>> "); for (; p < q; p++) if (isprint((int)*p)) putc(*p, stderr); fprintf(stderr, " <<< "); while (pb >= pbuf) putc(*pb--, stderr); fgets(ebuf, sizeof ebuf, curfile->fin); fprintf(stderr, "%s", ebuf); pbstr("\n.G2\n"); /* safety first */ ep = ebuf; } int yywrap(void) {return 1;} char *newfile = 0; /* filename for file copy */ char *untilstr = 0; /* string that terminates a thru */ int thru = 0; /* 1 if copying thru macro */ Obj *thrudef = 0; /* macro being used */ void copyfile(char *s) /* remember file to start reading from */ { newfile = s; } void copydef(Obj *p) /* remember macro Obj */ { thrudef = p; } Obj *copythru(char *s) /* collect the macro name or body for thru */ { Obj *p; char *q; p = lookup(s, 0); if (p != NULL) { if (p->type == DEFNAME) { p->val = addnewline(p->val); return p; } else FATAL("%s used as define and name", s); } /* have to collect the definition */ pbstr(s); /* first char is the delimiter */ q = delimstr("thru body"); p = lookup("nameless", 1); if (p != NULL) if (p->val) free(p->val); p->type = DEFNAME; p->val = q; p->val = addnewline(p->val); dprintf("installing nameless as `%s'\n", p->val); return p; } char *addnewline(char *p) /* add newline to end of p */ { int n; n = strlen(p); if (p[n-1] != '\n') { p = realloc(p, n+2); p[n] = '\n'; p[n+1] = '\0'; } return p; } void copyuntil(char *s) /* string that terminates a thru */ { untilstr = s; } void copy(void) /* begin input from file, etc. */ { FILE *fin; if (newfile) { if ((fin = fopen(newfile, "r")) == NULL) FATAL("can't open file %s", newfile); curfile++; curfile->fin = fin; curfile->fname = tostring(newfile); curfile->lineno = 0; printf(".lf 1 %s\n", curfile->fname); pushsrc(File, curfile->fname); newfile = 0; } if (thrudef) { thru = 1; begin = 1; /* wrong place */ } } char shellbuf[1000], *shellp; void shell_init(void) /* set up to interpret a shell command */ { fprintf(tfd, "# shell cmd...\n"); shellp = shellbuf; } void shell_text(char *s) /* add string to command being collected */ { /* fprintf(tfd, "#add <%s> to <%s>\n", s, shellbuf); */ while (*s) { if (shellp+5 >= &shellbuf[sizeof shellbuf]) FATAL("shell command too long"); if (*s == '\'') { /* protect interior quotes */ *shellp++ = '\''; *shellp++ = '\\'; *shellp++ = '\''; } *shellp++ = *s++; } } void shell_exec(void) /* do it */ { /* fprintf(tfd, "# run <%s>\n", shellbuf); */ *shellp = '\0'; if (Sflag) WARNING("-S inhibited execution of shell command"); else system(shellbuf); -} - -#define LSIZE 128 - -char *fgetline(char **line, size_t *linesize, size_t *llen, FILE *fp) -{ - int c; - size_t n = 0; - - if (*line == NULL || *linesize < LSIZE + n + 1) - *line = realloc(*line, *linesize = LSIZE + n + 1); - for (;;) { - if (n >= *linesize - LSIZE / 2) - *line = realloc(*line, *linesize += LSIZE); - c = getc(fp); - if (c != EOF) { - (*line)[n++] = c; - (*line)[n] = '\0'; - if (c == '\n') - break; - } else { - if (n > 0) - break; - else - return NULL; - } - } - if (llen) - *llen = n; - return *line; } Index: projects/doctools/contrib/heirloom-doctools/grap/main.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/grap/main.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/grap/main.c (revision 307812) @@ -1,187 +1,186 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/grap/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)main.c 1.5 (gritter) 12/5/05 */ #include #include #include #include #include #include #include "grap.h" #include "y.tab.h" int dbg = 0; #define GRAPDEFINES LIBDIR "/grap.defines" char *lib_defines = GRAPDEFINES; int lib = 1; /* 1 to include lib_defines */ FILE *tfd = NULL; char tempfile[] = "/var/tmp/grapXXXXXX"; int Sflag; int synerr = 0; int codegen = 0; /* 1=>output for this picture; 0=>no output */ char *cmdname; Obj *objlist = NULL; /* all names stored here */ #define BIG 1e30 Point ptmin = { NULL, -BIG, -BIG }; Point ptmax = { NULL, BIG, BIG }; extern const char version[]; extern int yyparse(void); extern void setdefaults(void); extern void getdata(void); int main(int argc, char *argv[]) { extern void onintr(int), fpecatch(int); if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, onintr); signal(SIGFPE, fpecatch); cmdname = argv[0]; close(mkstemp(tempfile)); while (argc > 1 && *argv[1] == '-') { switch (argv[1][1]) { case 'd': dbg = 1; tfd = stdout; n_strcpy(tempfile, "grap.temp", sizeof(tempfile)); unlink(tempfile); fprintf(stderr, "%s\n", version); break; case 'l': /* turn off /usr/lib inclusion */ lib = 0; break; case 'S': Sflag = 1; break; case 'U': Sflag = 0; break; } argc--; argv++; } setdefaults(); curfile = infile; if (argc <= 1) { curfile->fin = stdin; curfile->fname = tostring("-"); pushsrc(File, curfile->fname); getdata(); } else while (argc-- > 1) { if ((curfile->fin = fopen(*++argv, "r")) == NULL) { fprintf(stderr, "grap: can't open %s\n", *argv); onintr(0); } curfile->fname = tostring(*argv); pushsrc(File, curfile->fname); getdata(); fclose(curfile->fin); free(curfile->fname); } if (!dbg) unlink(tempfile); exit(0); } /*ARGSUSED*/ void onintr(int n) { if (!dbg) unlink(tempfile); exit(1); } void fpecatch(int n) { WARNING("floating point exception"); onintr(n); } char *grow(char *ptr, char *name, int num, int size) /* make array bigger */ { char *p; if (ptr == NULL) p = malloc(num * size); else p = realloc(ptr, num * size); if (p == NULL) FATAL("can't grow %s to %d", name, num * size); return p; } static struct { char *name; double val; } defaults[] ={ { "frameht" , FRAMEHT }, { "framewid", FRAMEWID }, { "ticklen" , TICKLEN }, { "slop" , SLOP }, { NULL , 0 } }; void setdefaults(void) /* set default sizes for variables */ { int i; Obj *p; for (i = 0; defaults[i].name != NULL; i++) { p = lookup(defaults[i].name, 1); setvar(p, defaults[i].val); } } void getdata(void) /* read input */ { register FILE *fin; char *buf = NULL, *buf1 = NULL; size_t size = 0; int ln; - char *fgetline(char **, size_t *, size_t *, FILE *); fin = curfile->fin; curfile->lineno = 0; printf(".lf 1 %s\n", curfile->fname); - while (fgetline(&buf, &size, NULL, fin) != NULL) { + while (getline(&buf, &size, fin) > 0) { curfile->lineno++; if (*buf == '.' && *(buf+1) == 'G' && *(buf+2) == '1') { setup(); fprintf(stdout, ".PS%s", &buf[3]); /* maps .G1 [w] to .PS w */ printf("scale = 1\n"); /* defends against cip users */ printf(".lf %d\n", curfile->lineno+1); yyparse(); fprintf(stdout, ".PE\n"); printf(".lf %d\n", curfile->lineno+1); fflush(stdout); } else if (buf[0] == '.' && buf[1] == 'l' && buf[2] == 'f') { buf1 = realloc(buf1, size); if (sscanf(buf+3, "%d %s", &ln, buf1) == 2) { free(curfile->fname); printf(".lf %d %s\n", curfile->lineno = ln, curfile->fname = tostring(buf1)); } else printf(".lf %d\n", curfile->lineno = ln); } else fputs(buf, stdout); } free(buf); free(buf1); } Index: projects/doctools/contrib/heirloom-doctools/grap/misc.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/grap/misc.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/grap/misc.c (revision 307812) @@ -1,308 +1,305 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/grap/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)misc.c 1.3 (gritter) 10/18/05 */ #include #include #include #include #include "grap.h" #include "y.tab.h" int nnum = 0; /* number of saved numbers */ double num[MAXNUM]; int just; /* current justification mode (RJUST, etc.) */ int sizeop; /* current optional operator for size change */ double sizexpr; /* current size change expression */ void savenum(int n, double f) /* save f in num[n] */ { num[n] = f; nnum = n+1; if (nnum >= MAXNUM) WARNING("too many numbers"); } void setjust(int j) { just |= j; } void setsize(int op, double expr) { sizeop = op; sizexpr = expr; } char *tostring(char *s) { - register char *p; - size_t l; + char *p; - l = strlen(s)+1; - p = malloc(l); + p = strdup(s); if (p == NULL) FATAL("out of space in tostring on %s", s); - n_strcpy(p, s, l); return(p); } void range(Point pt) /* update the range for point pt */ { Obj *p = pt.obj; if (!(p->coord & XFLAG)) { if (pt.x > p->pt1.x) p->pt1.x = pt.x; if (pt.x < p->pt.x) p->pt.x = pt.x; } if (!(p->coord & YFLAG)) { if (pt.y > p->pt1.y) p->pt1.y = pt.y; if (pt.y < p->pt.y) p->pt.y = pt.y; } } void halfrange(Obj *p, int side, double val) /* record max and min for one direction */ { if (!(p->coord&XFLAG) && (side == LEFT || side == RIGHT)) { if (val < p->pt.y) p->pt.y = val; if (val > p->pt1.y) p->pt1.y = val; } else if (!(p->coord&YFLAG) && (side == TOP || side == BOT)) { if (val < p->pt.x) p->pt.x = val; if (val > p->pt1.x) p->pt1.x = val; } } Obj *lookup(char *s, int inst) /* find s in objlist, install if inst */ { Obj *p; int found = 0; for (p = objlist; p; p = p->next){ if (strcmp(s, p->name) == 0) { found = 1; break; } } if (p == NULL && inst != 0) { p = (Obj *) calloc(1, sizeof(Obj)); if (p == NULL) FATAL("out of space in lookup"); p->name = tostring(s); p->type = NAME; p->pt = ptmax; p->pt1 = ptmin; p->fval = 0.0; p->next = objlist; objlist = p; } dprintf("lookup(%s,%d) = %d\n", s, inst, found); return p; } double getvar(Obj *p) /* return value of variable */ { return p->fval; } double setvar(Obj *p, double f) /* set value of variable to f */ { if (strcmp(p->name, "pointsize") == 0) { /* kludge */ pointsize = f; ps_set = 1; } p->type = VARNAME; return p->fval = f; } Point makepoint(Obj *s, double x, double y) /* make a Point */ { Point p; dprintf("makepoint: %s, %g,%g\n", s->name, x, y); p.obj = s; p.x = x; p.y = y; return p; } Attr *makefattr(int type, double fval) /* set double in attribute */ { return makeattr(type, fval, (char *) 0, 0, 0); } Attr *makesattr(char *s) /* make an Attr cell containing s */ { Attr *ap = makeattr(STRING, sizexpr, s, just, sizeop); just = sizeop = 0; sizexpr = 0.0; return ap; } Attr *makeattr(int type, double fval, char *sval, int just, int op) { Attr *a; a = (Attr *) malloc(sizeof(Attr)); if (a == NULL) FATAL("out of space in makeattr"); a->type = type; a->fval = fval; a->sval = sval; a->just = just; a->op = op; a->next = NULL; return a; } Attr *addattr(Attr *a1, Attr *ap) /* add attr ap to end of list a1 */ { Attr *p; if (a1 == 0) return ap; if (ap == 0) return a1; for (p = a1; p->next; p = p->next) ; p->next = ap; return a1; } void freeattr(Attr *ap) /* free an attribute list */ { Attr *p; while (ap) { p = ap->next; /* save next */ if (ap->sval) free(ap->sval); free((char *) ap); ap = p; } } char *slprint(Attr *stringlist) /* print strings from stringlist */ { int ntext, n, last_op, last_just; double last_fval; static char buf[1000]; Attr *ap; buf[0] = '\0'; last_op = last_just = 0; last_fval = 0.0; for (ntext = 0, ap = stringlist; ap != NULL; ap = ap->next) ntext++; snprintf(buf, sizeof(buf), "box invis wid 0 ht %d*textht", ntext); n = strlen(buf); for (ap = stringlist; ap != NULL; ap = ap->next) { if (ap->op == 0) { /* propagate last value */ ap->op = last_op; ap->fval = last_fval; } else { last_op = ap->op; last_fval = ap->fval; } snprintf(buf+n, sizeof(buf) - n, " \"%s\"", ps_set || ap->op ? sizeit(ap) : ap->sval); if (ap->just) last_just = ap->just; if (last_just) n_strcat(buf+n, juststr(last_just), sizeof(buf) - n); n = strlen(buf); } return buf; /* watch it: static */ } char *juststr(int j) /* convert RJUST, etc., into string */ { static char buf[50]; buf[0] = '\0'; if (j & RJUST) n_strcat(buf, " rjust", sizeof(buf)); if (j & LJUST) n_strcat(buf, " ljust", sizeof(buf)); if (j & ABOVE) n_strcat(buf, " above", sizeof(buf)); if (j & BELOW) n_strcat(buf, " below", sizeof(buf)); return buf; /* watch it: static */ } char *sprntf(char *s, Attr *ap) /* sprintf(s, attrlist ap) */ { char buf[500]; int n; Attr *p; for (n = 0, p = ap; p; p = p->next) n++; switch (n) { case 0: return s; case 1: snprintf(buf, sizeof(buf), s, ap->fval); break; case 2: snprintf(buf, sizeof(buf), s, ap->fval, ap->next->fval); break; case 3: snprintf(buf, sizeof(buf), s, ap->fval, ap->next->fval, ap->next->next->fval); break; case 5: WARNING("too many expressions in sprintf"); case 4: snprintf(buf, sizeof(buf), s, ap->fval, ap->next->fval, ap->next->next->fval, ap->next->next->next->fval); break; } free(s); return tostring(buf); } static void verror(const char *fmt, va_list ap) { char errbuf[4096]; vsnprintf(errbuf, sizeof errbuf, fmt, ap); yyerror(errbuf); } void FATAL(const char *fmt, ...) { va_list ap; va_start(ap, fmt); verror(fmt, ap); va_end(ap); exit(1); } void WARNING(const char *fmt, ...) { va_list ap; va_start(ap, fmt); verror(fmt, ap); va_end(ap); } Index: projects/doctools/contrib/heirloom-doctools/include/global.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/include/global.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/include/global.h (revision 307812) @@ -1,17 +1,37 @@ #ifdef HAVE_STRLCPY # define n_strcpy(dst, src, dstsize) strlcpy(dst, src, dstsize) #else # define n_strcpy(dst, src, dstsize) strcpy(dst, src) #endif #ifdef HAVE_STRLCAT # define n_strcat(dst, src, dstsize) strlcat(dst, src, dstsize) #else # define n_strcat(dst, src, dstsize) strcat(dst, src) #endif #ifdef HAVE_WCSLCPY # define n_wcscpy(dst, src, size ) wcslcpy(dst, src, size ) #else # define n_wcscpy(dst, src, size ) wcscpy(dst, src) #endif + +#define min(x,y) ((x) < (y) ? (x) : (y)) +#define max(x,y) ((x) > (y) ? (x) : (y)) +#define prefix(str, pfx) (strncmp(pfx, str, strlen(pfx)) == 0) + +#undef __unused +#define __unused __attribute__((unused)) + +#ifdef __GLIBC__ +#ifdef _IO_getc_unlocked +#undef getc +#define getc(f) _IO_getc_unlocked(f) +#endif +#ifdef _IO_putc_unlocked +#undef putc +#undef putchar +#define putc(c, f) _IO_putc_unlocked(c, f) +#define putchar(c) _IO_putc_unlocked(c, stdout) +#endif +#endif Index: projects/doctools/contrib/heirloom-doctools/mpm/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/mpm/Makefile.mk (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/mpm/Makefile.mk (revision 307812) @@ -1,30 +1,30 @@ OBJ = misc.o page.o queue.o range.o slug.o version.o -FLAGS = $(EUC) $(DEFINES) +FLAGS = $(EUC) $(DEFINES) -I../include .c.o: $(CC) $(CFLAGS) $(WARN) $(FLAGS) $(CPPFLAGS) -c $< .cc.o: $(CXX) $(CFLAGS) $(WARN) $(FLAGS) $(CPPFLAGS) -c $< all: pm pm: $(OBJ) $(CXX) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -lm -o pm install: all test -d $(ROOT)$(LIBDIR) || mkdir -p $(ROOT)$(LIBDIR) $(INSTALL) -c pm $(ROOT)$(LIBDIR)/pm $(STRIP) $(ROOT)$(LIBDIR)/pm clean: rm -f $(OBJ) pm core log *~ mrproper: clean misc.o: misc.cc misc.h page.o: page.cc misc.h slug.h range.h page.h queue.o: queue.cc misc.h slug.h range.h page.h range.o: range.cc misc.h slug.h range.h slug.o: slug.cc misc.h slug.h Index: projects/doctools/contrib/heirloom-doctools/mpm/misc.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/mpm/misc.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/mpm/misc.h (revision 307812) @@ -1,51 +1,34 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 source code published at the 9fans list by Rob Pike, * * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)misc.h 1.3 (gritter) 10/30/05 */ #include #include #include #include #include +#include "global.h" -#ifdef __GLIBC__ -#ifdef _IO_getc_unlocked -#undef getc -#define getc(f) _IO_getc_unlocked(f) -#endif -#ifdef _IO_putc_unlocked -#undef putc -#undef putchar -#define putc(c, f) _IO_putc_unlocked(c, f) -#define putchar(c) _IO_putc_unlocked(c, stdout) -#endif -#endif /* __GLIBC__ */ - extern char *progname; extern int linenum; extern int wantwarn; extern void FATAL(const char *, ...); extern void WARNING(const char *, ...); #define eq(s,t) (strcmp(s,t) == 0) - -inline int max(int x, int y) { return x > y ? x : y; } -inline int min(int x, int y) { return x > y ? y : x; } -// already defined in stdlib.h: -//inline int abs(int x) { return (x >= 0) ? x : -x; } extern int dbg; extern int pn, userpn; // actual and user-defined page numbers extern int pagetop, pagebot; // printing margins extern int physbot; // physical bottom of the page Index: projects/doctools/contrib/heirloom-doctools/pic/for.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/pic/for.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/pic/for.c (revision 307812) @@ -1,107 +1,107 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/pic/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)for.c 1.3 (gritter) 10/18/05 */ #include #include #include "pic.h" #include "y.tab.h" #define SLOP 1.001 typedef struct { char *var; /* index variable */ double to; /* limit */ double by; int op; /* operator */ char *str; /* string to push back */ } For; static For forstk[10]; /* stack of for loops */ static For *forp = forstk; /* pointer to current top */ -void setfval(char *, double); +void setfval(const char *, double); void nextfor(void); void forloop(char *var, double from, double to, int op, double by, char *str) /* set up a for loop */ { dprintf("# for %s from %g to %g by %c %g \n", var, from, to, op, by); if (++forp >= forstk+10) FATAL("for loop nested too deep"); forp->var = var; forp->to = to; forp->op = op; forp->by = by; forp->str = str; setfval(var, from); nextfor(); unput('\n'); } void nextfor(void) /* do one iteration of a for loop */ { /* BUG: this should depend on op and direction */ if (getfval(forp->var) > SLOP * forp->to) { /* loop is done */ free(forp->str); if (--forp < forstk) FATAL("forstk popped too far"); } else { /* another iteration */ pushsrc(String, "\nEndfor\n"); pushsrc(String, forp->str); } } void endfor(void) /* end one iteration of for loop */ { struct symtab *p = lookup(forp->var); switch (forp->op) { case '+': case ' ': p->s_val.f += forp->by; break; case '-': p->s_val.f -= forp->by; break; case '*': p->s_val.f *= forp->by; break; case '/': p->s_val.f /= forp->by; break; } nextfor(); } char *ifstat(double expr, char *thenpart, char *elsepart) { dprintf("if %g then <%s> else <%s>\n", expr, thenpart, elsepart? elsepart : ""); if (expr) { unput('\n'); pushsrc(Free, thenpart); pushsrc(String, thenpart); unput('\n'); if (elsepart) free(elsepart); return thenpart; /* to be freed later */ } else { free(thenpart); if (elsepart) { unput('\n'); pushsrc(Free, elsepart); pushsrc(String, elsepart); unput('\n'); } return elsepart; } } Index: projects/doctools/contrib/heirloom-doctools/pic/input.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/pic/input.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/pic/input.c (revision 307812) @@ -1,641 +1,606 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/pic/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)input.c 1.8 (gritter) 12/25/06 */ #include #include #include #include #include #include "pic.h" #include "y.tab.h" -#if defined (__GLIBC__) && defined (_IO_getc_unlocked) -#undef getc -#define getc(f) _IO_getc_unlocked(f) -#endif - Infile infile[10]; Infile *curfile = infile; #define MAXSRC 50 Src src[MAXSRC]; /* input source stack */ Src *srcp = src; void do_thru(void); int nextchar(void); int getarg(char *); int baldelim(int, const char *); static void popsrc(void); static char *addnewline(char *); void pushsrc(int type, const char *ptr) /* new input source */ { if (++srcp >= src + MAXSRC) FATAL("inputs nested too deep"); srcp->type = type; srcp->sp = ptr; if (dbg > 1) { printf("\n%3d ", (int)(srcp - src)); switch (srcp->type) { case File: printf("push file %s\n", ptr ? ((Infile *)ptr)->fname : "(null)"); break; case Macro: printf("push macro <%s>\n", ptr); break; case Char: printf("push char <%c>\n", *ptr); break; case Thru: printf("push thru\n"); break; case String: printf("push string <%s>\n", ptr); break; case Free: printf("push free <%s>\n", ptr); break; default: FATAL("pushed bad type %d", srcp->type); } } } static void popsrc(void) /* restore an old one */ { if (srcp <= src) FATAL("too many inputs popped"); if (dbg > 1) { printf("%3d ", (int)(srcp - src)); switch (srcp->type) { case File: printf("pop file\n"); break; case Macro: printf("pop macro\n"); break; case Char: printf("pop char <%c>\n", *srcp->sp); break; case Thru: printf("pop thru\n"); break; case String: printf("pop string\n"); break; case Free: printf("pop free\n"); break; default: FATAL("pop weird input %d", srcp->type); } } srcp--; } void definition(const char *s) /* collect definition for s and install */ /* definitions picked up lexically */ { char *p; struct symtab *stp; p = delimstr("definition"); stp = lookup(s); if (stp != NULL) { /* it's there before */ if (stp->s_type != DEFNAME) { WARNING("%s used as variable and definition", s); return; } free(stp->s_val.p); stp->s_val.p = p; } else { YYSTYPE u; u.p = p; makevar(tostring(s), DEFNAME, u); } dprintf("installing %s as `%s'\n", s, p); } char *delimstr(const char *s) /* get body of X ... X */ /* message if too big */ { int c, delim, rdelim, n, deep; static char *buf = NULL; static int nbuf = 0; char *p; if (buf == NULL) buf = grow(buf, "buf", nbuf += 1000, sizeof(buf[0])); while ((delim = input()) == ' ' || delim == '\t' || delim == '\n') ; rdelim = baldelim(delim, "{}"); /* could be "(){}[]`'" */ deep = 1; for (p = buf; ; ) { c = input(); if (c == rdelim) if (--deep == 0) break; if (c == delim) deep++; if (p >= buf + nbuf) { n = p - buf; buf = grow(buf, "buf", nbuf += 1000, sizeof(buf[0])); p = buf + n; } if (c == EOF) FATAL("end of file in %s %c %.20s... %c", s, delim, buf, delim); *p++ = c; } *p = '\0'; dprintf("delimstr %s %c <%s> %c\n", s, delim, buf, delim); return tostring(buf); } int baldelim(int c, const char *s) /* replace c by balancing entry in s */ { for ( ; *s; s += 2) if (*s == c) return s[1]; return c; } void undefine(char *s) /* undefine macro */ { while (*s != ' ' && *s != '\t') /* skip "undef..." */ s++; while (*s == ' ' || *s == '\t') s++; freedef(s); } static Arg args[10]; /* argument frames */ static Arg *argfp = args; /* frame pointer */ static int argcnt; /* number of arguments seen so far */ void dodef(struct symtab *stp) /* collect args and switch input to defn */ { int i, len; char *p; Arg *ap; ap = argfp+1; if (ap >= args+10) FATAL("arguments too deep"); argcnt = 0; if (input() != '(') FATAL("disaster in dodef"); if (ap->argval == 0) ap->argval = malloc(1000); for (p = ap->argval; (len = getarg(p)) != -1; p += len) { ap->argstk[argcnt++] = p; if (input() == ')') break; } for (i = argcnt; i < MAXARGS; i++) ap->argstk[i] = ""; if (dbg) for (i = 0; i < argcnt; i++) printf("arg %d.%d = <%s>\n", (int)(ap-args), i+1, ap->argstk[i]); argfp = ap; pushsrc(Macro, stp->s_val.p); } int getarg(char *p) /* pick up single argument, store in p, return length */ { int n, c, npar; n = npar = 0; for ( ;; ) { c = input(); if (c == EOF) FATAL("end of file in getarg"); if (npar == 0 && (c == ',' || c == ')')) break; if (c == '"') /* copy quoted stuff intact */ do { *p++ = c; n++; } while ((c = input()) != '"' && c != EOF); else if (c == '(') npar++; else if (c == ')') npar--; n++; *p++ = c; } *p = 0; unput(c); return(n + 1); } #define PBSIZE 2000 static char pbuf[PBSIZE]; /* pushback buffer */ static char *pb = pbuf-1; /* next pushed back character */ static char ebuf[200]; /* collect input here for error reporting */ static char *ep = ebuf; static int begin = 0; extern int thru; extern struct symtab *thrudef; extern char *untilstr; int input(void) { register int c; if (thru && begin) { do_thru(); begin = 0; } c = nextchar(); if (dbg > 1) printf(" <%c>", c); if (ep >= ebuf + sizeof ebuf) ep = ebuf; return (*ep++ = c) & 0377; } int nextchar(void) { register int c = 0; loop: switch (srcp->type) { case Free: /* free string */ free(srcp->sp); popsrc(); goto loop; case Thru: /* end of pushed back line */ begin = 1; popsrc(); c = '\n'; break; case Char: if (pb >= pbuf) { c = *pb--; popsrc(); break; } else { /* can't happen? */ popsrc(); goto loop; } case String: c = *srcp->sp++; if (c == '\0') { popsrc(); goto loop; } else { if (*srcp->sp == '\0') /* empty, so pop */ popsrc(); break; } case Macro: c = *srcp->sp++; if (c == '\0') { if (--argfp < args) FATAL("argfp underflow"); popsrc(); goto loop; } else if (c == '$' && isdigit((int)*srcp->sp)) { int n = 0; while (isdigit((int)*srcp->sp)) n = 10 * n + *srcp->sp++ - '0'; if (n > 0 && n <= MAXARGS) pushsrc(String, argfp->argstk[n-1]); goto loop; } break; case File: c = getc(curfile->fin); if (c == EOF) { if (curfile == infile) FATAL("end of file inside .PS/.PE"); if (curfile->fin != stdin) { fclose(curfile->fin); free(curfile->fname); /* assumes allocated */ } curfile--; printlf(curfile->lineno, curfile->fname); popsrc(); thru = 0; /* chicken out */ thrudef = 0; if (untilstr) { free(untilstr); untilstr = 0; } goto loop; } if (c == '\n') curfile->lineno++; break; } return c; } void do_thru(void) /* read one line, make into a macro expansion */ { int c, i; char *p; Arg *ap; ap = argfp+1; if (ap >= args+10) FATAL("arguments too deep"); if (ap->argval == NULL) ap->argval = malloc(1000); p = ap->argval; argcnt = 0; c = nextchar(); if (thru == 0) { /* end of file was seen, so thru is done */ unput(c); return; } for ( ; c != '\n' && c != EOF; ) { if (c == ' ' || c == '\t') { c = nextchar(); continue; } ap->argstk[argcnt++] = p; if (c == '"') { do { *p++ = c; if ((c = nextchar()) == '\\') { *p++ = c; *p++ = nextchar(); c = nextchar(); } } while (c != '"' && c != '\n' && c != EOF); *p++ = '"'; if (c == '"') c = nextchar(); } else { do { *p++ = c; } while ((c = nextchar())!=' ' && c!='\t' && c!='\n' && c!=',' && c!=EOF); if (c == ',') c = nextchar(); } *p++ = '\0'; } if (c == EOF) FATAL("unexpected end of file in do_thru"); if (argcnt == 0) { /* ignore blank line */ pushsrc(Thru, (char *) 0); return; } for (i = argcnt; i < MAXARGS; i++) ap->argstk[i] = ""; if (dbg) for (i = 0; i < argcnt; i++) printf("arg %d.%d = <%s>\n", (int)(ap-args), i+1, ap->argstk[i]); if (strcmp(ap->argstk[0], ".PE") == 0) { thru = 0; thrudef = 0; pushsrc(String, "\n.PE\n"); return; } if (untilstr && strcmp(ap->argstk[0], untilstr) == 0) { thru = 0; thrudef = 0; free(untilstr); untilstr = 0; return; } pushsrc(Thru, (char *) 0); dprintf("do_thru pushing back <%s>\n", thrudef->s_val.p); argfp = ap; pushsrc(Macro, thrudef->s_val.p); } int unput(int c) { if (++pb >= pbuf + sizeof pbuf) FATAL("pushback overflow"); if (--ep < ebuf) ep = ebuf + sizeof(ebuf) - 1; *pb = c; pushsrc(Char, pb); return c; } void pbstr(const char *s) { pushsrc(String, s); } double errcheck(double x, char *s) { if (errno == EDOM) { errno = 0; WARNING("%s argument out of domain", s); } else if (errno == ERANGE) { errno = 0; WARNING("%s result out of range", s); } return x; } void eprint(void); void yyerror(char *s) { int ern = errno; /* cause some libraries clobber it */ if (synerr) return; fflush(stdout); fprintf(stderr, "%s: %s", cmdname, s); if (ern > 0) { errno = ern; perror("???"); } fprintf(stderr, " near %s:%d\n", curfile->fname, curfile->lineno+1); eprint(); synerr = 1; errno = 0; } void eprint(void) /* try to print context around error */ { char *p, *q; p = ep - 1; if (p > ebuf && *p == '\n') p--; for ( ; p >= ebuf && *p != '\n'; p--) ; while (*p == '\n') p++; fprintf(stderr, " context is\n\t"); for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--) ; while (p < q) putc(*p++, stderr); fprintf(stderr, " >>> "); while (p < ep) putc(*p++, stderr); fprintf(stderr, " <<< "); while (pb >= pbuf) putc(*pb--, stderr); fgets(ebuf, sizeof ebuf, curfile->fin); fprintf(stderr, "%s", ebuf); pbstr("\n.PE\n"); /* safety first */ ep = ebuf; } void yywrap(void) {} static char *newfile = 0; /* filename for file copy */ char *untilstr = 0; /* string that terminates a thru */ int thru = 0; /* 1 if copying thru macro */ struct symtab *thrudef = 0; /* macro being used */ void copyfile(char *s) /* remember file to start reading from */ { newfile = s; } void copydef(struct symtab *p) /* remember macro symtab ptr */ { thrudef = p; } struct symtab *copythru(const char *s) /* collect the macro name or body for thru */ { struct symtab *p; char *q, *addnewline(char *); p = lookup(s); if (p != NULL) { if (p->s_type == DEFNAME) { p->s_val.p = addnewline(p->s_val.p); return p; } else FATAL("%s used as define and name", s); } /* have to collect the definition */ pbstr(s); /* first char is the delimiter */ q = delimstr("thru body"); s = "nameless"; p = lookup(s); if (p != NULL) { if (p->s_val.p) free(p->s_val.p); p->s_val.p = q; } else { YYSTYPE u; u.p = q; p = makevar(tostring(s), DEFNAME, u); } p->s_val.p = addnewline(p->s_val.p); dprintf("installing %s as `%s'\n", s, p->s_val.p); return p; } static char *addnewline(char *p) /* add newline to end of p */ { int n; n = strlen(p); if (p[n-1] != '\n') { p = realloc(p, n+2); p[n] = '\n'; p[n+1] = '\0'; } return p; } void copyuntil(char *s) /* string that terminates a thru */ { untilstr = s; } void copy(void) /* begin input from file, etc. */ { FILE *fin; if (newfile) { if ((fin = fopen(newfile, "r")) == NULL) FATAL("can't open file %s", newfile); curfile++; curfile->fin = fin; curfile->fname = newfile; curfile->lineno = 0; printlf(1, curfile->fname); pushsrc(File, curfile->fname); newfile = 0; } if (thrudef) { thru = 1; begin = 1; /* wrong place */ } } static char shellbuf[1000], *shellp; void shell_init(void) /* set up to interpret a shell command */ { shellp = shellbuf; } void shell_text(char *s) /* add string to command being collected */ { while ((*shellp++ = *s++)) { if (shellp >= &shellbuf[sizeof shellbuf]) FATAL("shell command too long"); } shellp--; } void shell_exec(void) /* do it */ { *shellp = '\0'; if (Sflag) WARNING("-S inhibited execution of shell command"); else system(shellbuf); -} - -#define LSIZE 128 - -char *fgetline(char **line, size_t *linesize, size_t *llen, FILE *fp) -{ - int c; - size_t n = 0; - - if (*line == NULL || *linesize < LSIZE + n + 1) - *line = realloc(*line, *linesize = LSIZE + n + 1); - for (;;) { - if (n >= *linesize - LSIZE / 2) - *line = realloc(*line, *linesize += LSIZE); - c = getc(fp); - if (c != EOF) { - (*line)[n++] = c; - (*line)[n] = '\0'; - if (c == '\n') - break; - } else { - if (n > 0) - break; - else - return NULL; - } - } - if (llen) - *llen = n; - return *line; } Index: projects/doctools/contrib/heirloom-doctools/pic/main.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/pic/main.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/pic/main.c (revision 307812) @@ -1,310 +1,309 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/pic/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)main.c 1.6 (gritter) 12/5/05 */ #include #include #include #include #include "pic.h" #include "y.tab.h" extern const char version[]; obj **objlist = 0; /* store the elements here */ int nobjlist = 0; /* size of objlist array */ int nobj = 0; Attr *attr; /* attributes stored here as collected */ int nattrlist = 0; int nattr = 0; /* number of entries in attr_list */ Text *text = 0; /* text strings stored here as collected */ int ntextlist = 0; /* size of text[] array */ int ntext = 0; int ntext1 = 0; /* record ntext here on entry to each figure */ double curx = 0; double cury = 0; int hvmode = R_DIR; /* R => join left to right, D => top to bottom, etc. */ int codegen = 0; /* 1=>output for this picture; 0=>no output */ char *PEstring; /* "PS" or "PE" picked up by lexer */ double deltx = 6; /* max x value in output, for scaling */ double delty = 6; /* max y value in output, for scaling */ int dbg = 0; int lineno = 0; int synerr = 0; static int anyerr = 0; /* becomes 1 if synerr ever 1 */ char *cmdname; int Sflag; double xmin = 30000; /* min values found in actual data */ double ymin = 30000; double xmax = -30000; /* max */ double ymax = -30000; void fpecatch(int); void getdata(void), setdefaults(void); int getpid(void); int main(int argc, char *argv[]) { char buf[20]; signal(SIGFPE, fpecatch); cmdname = argv[0]; while (argc > 1 && *argv[1] == '-') { switch (argv[1][1]) { case 'd': dbg = atoi(&argv[1][2]); if (dbg == 0) dbg = 1; fprintf(stderr, "%s\n", version); break; case 'V': fprintf(stderr, "%s\n", version); return 0; case 'S': Sflag = 1; break; case 'U': Sflag = 0; break; } argc--; argv++; } setdefaults(); objlist = (obj **) grow((char *)objlist, "objlist", nobjlist += 1000, sizeof(obj *)); text = (Text *) grow((char *)text, "text", ntextlist += 1000, sizeof(Text)); attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr)); snprintf(buf, sizeof(buf), "/%d/", getpid()); pushsrc(String, buf); definition("pid"); curfile = infile; pushsrc(File, curfile->fname); if (argc <= 1) { curfile->fin = stdin; curfile->fname = tostring("-"); getdata(); } else while (argc-- > 1) { if ((curfile->fin = fopen(*++argv, "r")) == NULL) { fprintf(stderr, "%s: can't open %s\n", cmdname, *argv); exit(1); } curfile->fname = tostring(*argv); getdata(); fclose(curfile->fin); free(curfile->fname); } return anyerr; } void fpecatch(int n) { FATAL("floating point exception %d", n); } char *grow(char *ptr, const char *name, int num, int size) /* make array bigger */ { char *p; if (ptr == NULL) p = malloc(num * size); else p = realloc(ptr, num * size); if (p == NULL) FATAL("can't grow %s to %d", name, num * size); return p; } static struct { const char *name; double val; short scalable; /* 1 => adjust when "scale" changes */ } defaults[] ={ { "scale" , SCALE , 1 }, { "lineht" , HT , 1 }, { "linewid" , HT , 1 }, { "moveht" , HT , 1 }, { "movewid" , HT , 1 }, { "dashwid" , HT10 , 1 }, { "boxht" , HT , 1 }, { "boxwid" , WID , 1 }, { "circlerad" , HT2 , 1 }, { "arcrad" , HT2 , 1 }, { "ellipseht" , HT , 1 }, { "ellipsewid", WID , 1 }, { "arrowht" , HT5 , 1 }, { "arrowwid" , HT10 , 1 }, { "arrowhead" , 2 , 0 }, /* arrowhead style */ { "textht" , 0.0 , 1 }, /* 6 lines/inch is also a useful value */ { "textwid" , 0.0 , 1 }, { "maxpsht" , MAXHT , 0 }, { "maxpswid" , MAXWID, 0 }, { "fillval" , 0.7 , 0 }, /* gray value for filling boxes */ { NULL , 0 , 0 } }; void setdefaults(void) /* set default sizes for variables like boxht */ { int i; YYSTYPE v; for (i = 0; defaults[i].name != NULL; i++) { v.f = defaults[i].val; makevar(tostring(defaults[i].name), VARNAME, v); } } void resetvar(void) /* reset variables listed */ { int i, j; if (nattr == 0) { /* none listed, so do all */ setdefaults(); return; } for (i = 0; i < nattr; i++) { for (j = 0; defaults[j].name != NULL; j++) if (strcmp(defaults[j].name, attr[i].a_val.p) == 0) { setfval(defaults[j].name, defaults[j].val); free(attr[i].a_val.p); break; } } } void checkscale(char *s) /* if s is "scale", adjust default variables */ { int i; double scale; if (strcmp(s, "scale") == 0) { scale = getfval("scale"); for (i = 1; defaults[i].name != NULL; i++) if (defaults[i].scalable) setfval(defaults[i].name, defaults[i].val * scale); } } void getdata(void) { char *p, *buf = NULL, *buf1 = NULL; size_t size = 0; int ln; void reset(void), openpl(char *), closepl(char *); int yyparse(void); - char *fgetline(char **, size_t *, size_t *, FILE *); curfile->lineno = 0; printlf(1, curfile->fname); - while (fgetline(&buf, &size, NULL, curfile->fin) != NULL) { + while (getline(&buf, &size, curfile->fin) > 0) { curfile->lineno++; if (buf[0] == '.' && buf[1] == 'l' && buf[2] == 'f') { buf1 = realloc(buf1, size); if (sscanf(buf+3, "%d %s", &ln, buf1) == 2) { free(curfile->fname); printlf(curfile->lineno = ln, curfile->fname = tostring(buf1)); } else printlf(curfile->lineno = ln, NULL); } else if (*buf == '.') { for (p = buf + 1; *p == ' ' || *p == '\t'; p++); if (!*p || *p != 'P' || p[1] != 'S') { fputs(buf, stdout); continue; } for (p = &buf[3]; *p == ' '; p++) ; if (*p++ == '<') { Infile svfile; svfile = *curfile; buf1 = realloc(buf1, size); sscanf(p, "%s", buf1); if ((curfile->fin=fopen(buf1, "r")) == NULL) FATAL("can't open %s", buf1); curfile->fname = tostring(buf1); getdata(); fclose(curfile->fin); free(curfile->fname); *curfile = svfile; printlf(curfile->lineno, curfile->fname); continue; } reset(); yyparse(); anyerr += synerr; deltx = (xmax - xmin) / getfval("scale"); delty = (ymax - ymin) / getfval("scale"); if (buf[3] == ' ') { /* next things are wid & ht */ if (sscanf(&buf[4],"%lf %lf", &deltx, &delty) < 2) delty = deltx * (ymax-ymin) / (xmax-xmin); /* else { * double xfac, yfac; */ /* xfac = deltx / (xmax-xmin); * yfac = delty / (ymax-ymin); * if (xfac <= yfac) * delty = xfac * (ymax-ymin); * else * deltx = yfac * (xmax-xmin); *} */ } dprintf("deltx = %g, delty = %g\n", deltx, delty); if (codegen && !synerr) { openpl(&buf[3]); /* puts out .PS, with ht & wid stuck in */ printlf(curfile->lineno+1, NULL); print(); /* assumes \n at end */ closepl(PEstring); /* does the .PE/F */ free(PEstring); } printlf(curfile->lineno+1, NULL); fflush(stdout); } else fputs(buf, stdout); } free(buf); free(buf1); } void reset(void) { obj *op; int i; extern int nstack; for (i = 0; i < nobj; i++) { op = objlist[i]; if (op->o_type == BLOCK) freesymtab(op->o_symtab); free((char *)objlist[i]); } nobj = 0; nattr = 0; for (i = 0; i < ntext; i++) if (text[i].t_val) free(text[i].t_val); ntext = ntext1 = 0; codegen = synerr = 0; nstack = 0; curx = cury = 0; PEstring = 0; hvmode = R_DIR; xmin = ymin = 30000; xmax = ymax = -30000; } Index: projects/doctools/contrib/heirloom-doctools/pic/misc.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/pic/misc.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/pic/misc.c (revision 307812) @@ -1,479 +1,476 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/pic/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)misc.c 1.3 (gritter) 10/18/05 */ #include #include #include #include #include #include "pic.h" #include "y.tab.h" int whatpos(obj *p, int corner, double *px, double *py); void makeattr(int type, int sub, YYSTYPE val); YYSTYPE getblk(obj *, char *); int setdir(int n) /* set direction (hvmode) from LEFT, RIGHT, etc. */ { switch (n) { case UP: hvmode = U_DIR; break; case DOWN: hvmode = D_DIR; break; case LEFT: hvmode = L_DIR; break; case RIGHT: hvmode = R_DIR; break; } return(hvmode); } int curdir(void) /* convert current dir (hvmode) to RIGHT, LEFT, etc. */ { switch (hvmode) { case R_DIR: return RIGHT; case L_DIR: return LEFT; case U_DIR: return UP; case D_DIR: return DOWN; } FATAL("can't happen curdir"); return 0; } double getcomp(obj *p, int t) /* return component of a position */ { switch (t) { case DOTX: return p->o_x; case DOTY: return p->o_y; case DOTWID: switch (p->o_type) { case BOX: case BLOCK: case TEXT: return p->o_val[0]; case CIRCLE: case ELLIPSE: return 2 * p->o_val[0]; case LINE: case ARROW: return p->o_val[0] - p->o_x; case PLACE: return 0; } case DOTHT: switch (p->o_type) { case BOX: case BLOCK: case TEXT: return p->o_val[1]; case CIRCLE: case ELLIPSE: return 2 * p->o_val[1]; case LINE: case ARROW: return p->o_val[1] - p->o_y; case PLACE: return 0; } case DOTRAD: switch (p->o_type) { case CIRCLE: case ELLIPSE: return p->o_val[0]; } } WARNING("you asked for a weird dimension or position"); return 0; } static double exprlist[100]; static int nexpr = 0; void exprsave(double f) { exprlist[nexpr++] = f; } char *sprintgen(char *fmt) { char buf[1000]; snprintf(buf, sizeof(buf), fmt, exprlist[0], exprlist[1], exprlist[2], exprlist[3], exprlist[4]); nexpr = 0; free(fmt); return tostring(buf); } void makefattr(int type, int sub, double f) /* double attr */ { YYSTYPE val; val.f = f; makeattr(type, sub, val); } void makeoattr(int type, obj *o) /* obj* attr */ { YYSTYPE val; val.o = o; makeattr(type, 0, val); } void makeiattr(int type, int i) /* int attr */ { YYSTYPE val; val.i = i; makeattr(type, 0, val); } void maketattr(int sub, char *p) /* text attribute: takes two */ { YYSTYPE val; val.p = p; makeattr(TEXTATTR, sub, val); } void addtattr(int sub) /* add text attrib to existing item */ { attr[nattr-1].a_sub |= sub; } void makevattr(char *p) /* varname attribute */ { YYSTYPE val; val.p = p; makeattr(VARNAME, 0, val); } void makeattr(int type, int sub, YYSTYPE val) /* add attribute type and val */ { if (type == 0 && val.i == 0) { /* clear table for next stat */ nattr = 0; return; } if (nattr >= nattrlist) attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr)); dprintf("attr %d: %d %d %d\n", nattr, type, sub, val.i); attr[nattr].a_type = type; attr[nattr].a_sub = sub; attr[nattr].a_val = val; nattr++; } void printexpr(double f) /* print expression for debugging */ { printf("%g\n", f); } void printpos(obj *p) /* print position for debugging */ { printf("%g, %g\n", p->o_x, p->o_y); } char *tostring(const char *s) { - register char *p; - size_t l; + char *p; - l = strlen(s)+1; - p = malloc(l); + p = strdup(s); if (p == NULL) FATAL("out of space in tostring on %s", s); - n_strcpy(p, s, l); return(p); } obj *makepos(double x, double y) /* make a position cell */ { obj *p; p = makenode(PLACE, 0); p->o_x = x; p->o_y = y; return(p); } obj *makebetween(double f, obj *p1, obj *p2) /* make position between p1 and p2 */ { obj *p; dprintf("fraction = %.2f\n", f); p = makenode(PLACE, 0); p->o_x = p1->o_x + f * (p2->o_x - p1->o_x); p->o_y = p1->o_y + f * (p2->o_y - p1->o_y); return(p); } obj *getpos(obj *p, int corner) /* find position of point */ { double x, y; whatpos(p, corner, &x, &y); return makepos(x, y); } int whatpos(obj *p, int corner, double *px, double *py) /* what is the position (no side effect) */ { double x, y, x1 = 0, y1 = 0; dprintf("whatpos %lo %d %d\n", (long)p, p->o_type, corner); x = p->o_x; y = p->o_y; if (p->o_type != PLACE && p->o_type != MOVE) { x1 = p->o_val[0]; y1 = p->o_val[1]; } switch (p->o_type) { case PLACE: break; case BOX: case BLOCK: case TEXT: switch (corner) { case NORTH: y += y1 / 2; break; case SOUTH: y -= y1 / 2; break; case EAST: x += x1 / 2; break; case WEST: x -= x1 / 2; break; case NE: x += x1 / 2; y += y1 / 2; break; case SW: x -= x1 / 2; y -= y1 / 2; break; case SE: x += x1 / 2; y -= y1 / 2; break; case NW: x -= x1 / 2; y += y1 / 2; break; case START: if (p->o_type == BLOCK) return whatpos(objlist[(int)p->o_val[2]], START, px, py); case END: if (p->o_type == BLOCK) return whatpos(objlist[(int)p->o_val[3]], END, px, py); } break; case ARC: switch (corner) { case START: if (p->o_attr & CW_ARC) { x = p->o_val[2]; y = p->o_val[3]; } else { x = x1; y = y1; } break; case END: if (p->o_attr & CW_ARC) { x = x1; y = y1; } else { x = p->o_val[2]; y = p->o_val[3]; } break; } if (corner == START || corner == END) break; x1 = y1 = sqrt((x1-x)*(x1-x) + (y1-y)*(y1-y)); /* Fall Through! */ case CIRCLE: case ELLIPSE: switch (corner) { case NORTH: y += y1; break; case SOUTH: y -= y1; break; case EAST: x += x1; break; case WEST: x -= x1; break; case NE: x += 0.707 * x1; y += 0.707 * y1; break; case SE: x += 0.707 * x1; y -= 0.707 * y1; break; case NW: x -= 0.707 * x1; y += 0.707 * y1; break; case SW: x -= 0.707 * x1; y -= 0.707 * y1; break; } break; case LINE: case SPLINE: case ARROW: switch (corner) { case START: break; /* already in place */ case END: x = x1; y = y1; break; default: /* change! */ case CENTER: x = (x+x1)/2; y = (y+y1)/2; break; case NORTH: if (y1 > y) { x = x1; y = y1; } break; case SOUTH: if (y1 < y) { x = x1; y = y1; } break; case EAST: if (x1 > x) { x = x1; y = y1; } break; case WEST: if (x1 < x) { x = x1; y = y1; } break; } break; case MOVE: /* really ought to be same as line... */ break; } dprintf("whatpos returns %g %g\n", x, y); *px = x; *py = y; return 1; } obj *gethere(void) /* make a place for curx,cury */ { dprintf("gethere %g %g\n", curx, cury); return(makepos(curx, cury)); } obj *getlast(int n, int t) /* find n-th previous occurrence of type t */ { int i, k; obj *p; k = n; for (i = nobj-1; i >= 0; i--) { p = objlist[i]; if (p->o_type == BLOCKEND) { i = p->o_val[4]; continue; } if (p->o_type != t) continue; if (--k > 0) continue; /* not there yet */ dprintf("got a last of x,y= %g,%g\n", p->o_x, p->o_y); return(p); } FATAL("there is no %dth last", n); return(NULL); } obj *getfirst(int n, int t) /* find n-th occurrence of type t */ { int i, k; obj *p; k = n; for (i = 0; i < nobj; i++) { p = objlist[i]; if (p->o_type == BLOCK && t != BLOCK) { /* skip whole block */ i = p->o_val[5] + 1; continue; } if (p->o_type != t) continue; if (--k > 0) continue; /* not there yet */ dprintf("got a first of x,y= %g,%g\n", p->o_x, p->o_y); return(p); } FATAL("there is no %dth ", n); return(NULL); } double getblkvar(obj *p, char *s) /* find variable s2 in block p */ { YYSTYPE y; y = getblk(p, s); return y.f; } obj *getblock(obj *p, char *s) /* find variable s in block p */ { YYSTYPE y; y = getblk(p, s); return y.o; } YYSTYPE getblk(obj *p, char *s) /* find union type for s in p */ { static YYSTYPE bug; struct symtab *stp; if (p->o_type != BLOCK) { WARNING(".%s is not in that block", s); return(bug); } for (stp = p->o_symtab; stp != NULL; stp = stp->s_next) if (strcmp(s, stp->s_name) == 0) { dprintf("getblk %s found x,y= %g,%g\n", s, (stp->s_val.o)->o_x, (stp->s_val.o)->o_y); return(stp->s_val); } WARNING("there is no .%s in that []", s); return(bug); } obj *fixpos(obj *p, double x, double y) { dprintf("fixpos returns %g %g\n", p->o_x + x, p->o_y + y); return makepos(p->o_x + x, p->o_y + y); } obj *addpos(obj *p, obj *q) { dprintf("addpos returns %g %g\n", p->o_x+q->o_x, p->o_y+q->o_y); return makepos(p->o_x+q->o_x, p->o_y+q->o_y); } obj *subpos(obj *p, obj *q) { dprintf("subpos returns %g %g\n", p->o_x-q->o_x, p->o_y-q->o_y); return makepos(p->o_x-q->o_x, p->o_y-q->o_y); } obj *makenode(int type, int n) { obj *p; p = (obj *) calloc(1, sizeof(obj) + (n-1)*sizeof(ofloat)); if (p == NULL) FATAL("out of space in makenode"); p->o_type = type; p->o_count = n; p->o_nobj = nobj; p->o_mode = hvmode; p->o_x = curx; p->o_y = cury; p->o_nt1 = ntext1; p->o_nt2 = ntext; ntext1 = ntext; /* ready for next caller */ if (nobj >= nobjlist) objlist = (obj **) grow((char *) objlist, "objlist", nobjlist *= 2, sizeof(obj *)); objlist[nobj++] = p; return(p); } void extreme(double x, double y) /* record max and min x and y values */ { if (x > xmax) xmax = x; if (y > ymax) ymax = y; if (x < xmin) xmin = x; if (y < ymin) ymin = y; } static void verror(const char *fmt, va_list ap) { char errbuf[4096]; vsnprintf(errbuf, sizeof errbuf, fmt, ap); yyerror(errbuf); } void FATAL(const char *fmt, ...) { va_list ap; va_start(ap, fmt); verror(fmt, ap); va_end(ap); exit(1); } void WARNING(const char *fmt, ...) { va_list ap; va_start(ap, fmt); verror(fmt, ap); va_end(ap); } Index: projects/doctools/contrib/heirloom-doctools/pic/pic.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/pic/pic.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/pic/pic.h (revision 307812) @@ -1,269 +1,268 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/pic/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)pic.h 1.6 (gritter) 12/5/05 */ #include "global.h" #ifndef PI #define PI 3.1415926535897932384626433832795028841971693993751 #endif #define MAXWID 8.5 /* default limits max picture to 8.5 x 11; */ #define MAXHT 11 /* change to taste without peril */ #define dprintf if(dbg)printf extern void yyerror(char *); extern void FATAL(const char *, ...); extern void WARNING(const char *, ...); #define DEFAULT 0 #define HEAD1 1 #define HEAD2 2 #define HEAD12 (HEAD1+HEAD2) #define INVIS 4 #define CW_ARC 8 /* clockwise arc */ #define DOTBIT 16 /* line styles */ #define DASHBIT 32 #define FILLBIT 64 /* gray-fill on boxes, etc. */ #define NOEDGEBIT 128 /* no edge on filled object */ #define CENTER 01 /* text attributes */ #define LJUST 02 #define RJUST 04 #define ABOVE 010 #define BELOW 020 #define SPREAD 040 #define SCALE 1.0 /* default scale: units/inch */ #define WID 0.75 /* default width for boxes and ellipses */ #define WID2 0.375 #define HT 0.5 /* default height and line length */ #define HT2 (HT/2) #define HT5 (HT/5) #define HT10 (HT/10) /* these have to be like so, so that we can write */ /* things like R & V, etc. */ #define H 0 #define V 1 #define R_DIR 0 #define U_DIR 1 #define L_DIR 2 #define D_DIR 3 #define ishor(n) (((n) & V) == 0) #define isvert(n) (((n) & V) != 0) #define isright(n) ((n) == R_DIR) #define isleft(n) ((n) == L_DIR) #define isdown(n) ((n) == D_DIR) #define isup(n) ((n) == U_DIR) typedef float ofloat; /* for o_val[] in obj; could be double */ typedef struct obj { /* stores various things in variable length */ int o_type; int o_count; /* number of things */ int o_nobj; /* index in objlist */ int o_mode; /* hor or vert */ float o_x; /* coord of "center" */ float o_y; int o_nt1; /* 1st index in text[] for this object */ int o_nt2; /* 2nd; difference is #text strings */ int o_attr; /* HEAD, CW, INVIS, etc., go here */ int o_size; /* linesize */ int o_nhead; /* arrowhead style */ struct symtab *o_symtab; /* symtab for [...] */ float o_ddval; /* value of dot/dash expression */ float o_fillval; /* gray scale value */ ofloat o_val[1]; /* actually this will be > 1 in general */ /* type is not always FLOAT!!!! */ } obj; typedef union { /* the yacc stack type */ int i; char *p; obj *o; double f; struct symtab *st; } YYSTYPE; #define YYSTYPE YYSTYPE extern YYSTYPE yylval; struct symtab { char *s_name; int s_type; YYSTYPE s_val; struct symtab *s_next; }; typedef struct { /* attribute of an object */ int a_type; int a_sub; YYSTYPE a_val; } Attr; typedef struct { int t_type; /* CENTER, LJUST, etc. */ char t_op; /* optional sign for size changes */ char t_size; /* size, abs or rel */ char *t_val; } Text; #define String 01 #define Macro 02 #define File 04 #define Char 010 #define Thru 020 #define Free 040 typedef struct { /* input source */ int type; /* Macro, String, File */ char *sp; /* if String or Macro */ } Src; extern Src src[], *srcp; /* input source stack */ typedef struct { FILE *fin; char *fname; int lineno; } Infile; extern Infile infile[], *curfile; #define MAXARGS 20 typedef struct { /* argument stack */ char *argstk[MAXARGS]; /* pointers to args */ char *argval; /* points to space containing args */ } Arg; extern int dbg; extern obj **objlist; extern int nobj, nobjlist; extern Attr *attr; extern int nattr, nattrlist; extern Text *text; extern int ntextlist; extern int ntext; extern int ntext1; extern double curx, cury; extern int hvmode; extern int codegen; extern char *PEstring; extern int Sflag; extern char *cmdname; char *tostring(const char *); char *grow(char *, const char *, int, int); double getfval(const char *), getcomp(obj *, int), getblkvar(obj *, char *); YYSTYPE getvar(const char *); struct symtab *lookup(const char *), *makevar(char *, int, YYSTYPE); char *ifstat(double, char *, char *), *delimstr(const char *), *sprintgen(char *); void forloop(char *var, double from, double to, int op, double by, char *_str); int setdir(int), curdir(void); void pbstr(const char *); void endfor(void); void dodef(struct symtab *stp); void freedef(char *); void undefine(char *s); void print(void); void resetvar(void); void checkscale(char *); void pushsrc(int, const char *); void copy(void); void copyuntil(char *); void copyfile(char *); void copydef(struct symtab *); void definition(const char *); void freesymtab(struct symtab *); -void setfval(char *s, double f); +void setfval(const char *s, double f); struct symtab *copythru(const char *); #ifdef FLEX_SCANNER int xxinput(void); int xxunput(int); #else /* !FLEX_SCANNER */ #define input xxinput #define unput xxunput int input(void); int unput(int); #endif /* !FLEX_SCANNER */ void extreme(double, double); void shell_exec(void); void shell_init(void); void shell_text(char *); extern double deltx, delty; extern int lineno; extern int synerr; extern double xmin, ymin, xmax, ymax; obj *leftthing(int), *boxgen(void), *circgen(int), *arcgen(int); obj *linegen(int), *splinegen(void), *movegen(void); obj *textgen(void), *plotgen(void); obj *troffgen(char *), *rightthing(obj *, int), *blockgen(obj *, obj *); obj *makenode(int, int), *makepos(double, double); obj *fixpos(obj *, double, double); obj *addpos(obj *, obj *), *subpos(obj *, obj *); obj *makebetween(double, obj *, obj *); obj *getpos(obj *, int), *gethere(void), *getfirst(int, int); obj *getlast(int, int), *getblock(obj *, char *); void savetext(int, char *); void makeiattr(int, int); void makevattr(char *); void makefattr(int type, int sub, double f); void maketattr(int, char *); void makeoattr(int, obj *); void makeattr(int type, int sub, YYSTYPE val); void printexpr(double); void printpos(obj *); void exprsave(double); void addtattr(int); void printlf(int, char *); void openpl(char *); void closepl(char *); void hvflush(void); void flyback(void); void troff(char *); void label(char *, int, int); void line(double, double, double, double); void fillstart(double); void fillend(int, int); void box(double, double, double, double); void circle(double, double, double); void spline(double, double, double, ofloat *, int, double); void ellipse(double, double, double, double); void arc(double, double, double, double, double, double); void dot(void); void arrow(double, double, double, double, double, double, double, int); -char *fgetline(char **, size_t *, size_t *, FILE *); struct pushstack { double p_x; double p_y; int p_hvmode; double p_xmin; double p_ymin; double p_xmax; double p_ymax; struct symtab *p_symtab; }; extern struct pushstack stack[]; extern int nstack; extern int cw; extern double errcheck(double, char *); #define Log10(x) errcheck(log10(x), "log") #define Exp(x) errcheck(exp(x), "exp") #define Sqrt(x) errcheck(sqrt(x), "sqrt") Index: projects/doctools/contrib/heirloom-doctools/pic/pltroff.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/pic/pltroff.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/pic/pltroff.c (revision 307812) @@ -1,380 +1,369 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/pic/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)pltroff.c 1.3 (gritter) 2/8/06 */ #include #include #include #include "pic.h" -#ifndef __unused -#define __unused __attribute__((unused)) -#endif extern int dbg; -#define abs(n) (n >= 0 ? n : -(n)) -#define max(x,y) ((x)>(y) ? (x) : (y)) - static const char *textshift = "\\v'.2m'"; /* move text this far down */ /* scaling stuff defined by s command as X0,Y0 to X1,Y1 */ /* output dimensions set by -l,-w options to 0,0 to hmax, vmax */ /* default output is 6x6 inches */ static double xscale; static double yscale; static double hpos = 0; /* current horizontal position in output coordinate system */ static double vpos = 0; /* current vertical position; 0 is top of page */ static double htrue = 0; /* where we really are */ static double vtrue = 0; static double X0, Y0; /* left bottom of input */ static double X1, Y1; /* right top of input */ extern double deltx; extern double delty; extern double xmin, ymin, xmax, ymax; double xconv(double), yconv(double), xsc(double), ysc(double); void space(double, double, double, double); void hgoto(double), vgoto(double), hmot(double), vmot(double); void move(double, double), movehv(double, double); void cont(double, double); void openpl(char *s) /* initialize device; s is residue of .PS invocation line */ { double maxw, maxh, ratio = 1; double odeltx = deltx, odelty = delty; hpos = vpos = 0; maxw = getfval("maxpswid"); maxh = getfval("maxpsht"); if (deltx > maxw) { /* shrink horizontal */ ratio = maxw / deltx; deltx *= ratio; delty *= ratio; } if (delty > maxh) { /* shrink vertical */ ratio = maxh / delty; deltx *= ratio; delty *= ratio; } if (ratio != 1) { fprintf(stderr, "pic: %g X %g picture shrunk to", odeltx, odelty); fprintf(stderr, " %g X %g\n", deltx, delty); } space(xmin, ymin, xmax, ymax); printf(".\\\" %g %g %g %g\n", xmin, ymin, xmax, ymax); printf(".\\\" %.3fi %.3fi %.3fi %.3fi\n", xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax)); printf(".nr 00 \\n(.u\n"); printf(".nf\n"); printf(".PS %.3fi %.3fi %s", yconv(ymin), xconv(xmax), s); /* assumes \n comes as part of s */ } void space(double x0, double y0, double x1, double y1) /* set limits of page */ { X0 = x0; Y0 = y0; X1 = x1; Y1 = y1; xscale = deltx == 0.0 ? 1.0 : deltx / (X1-X0); yscale = delty == 0.0 ? 1.0 : delty / (Y1-Y0); } double xconv(double x) /* convert x from external to internal form */ { return (x-X0) * xscale; } double xsc(double x) /* convert x from external to internal form, scaling only */ { return (x) * xscale; } double yconv(double y) /* convert y from external to internal form */ { return (Y1-y) * yscale; } double ysc(double y) /* convert y from external to internal form, scaling only */ { return (y) * yscale; } void closepl(char *PEline) /* clean up after finished */ { printf(".if n .do\n"); movehv(0.0, 0.0); /* get back to where we started */ if (strchr(PEline, 'F') == NULL) { printf(".sp 1+%.3fi\n", yconv(ymin)); } printf("%s\n", PEline); printf(".if \\n(00 .fi\n"); } void move(double x, double y) /* go to position x, y in external coords */ { hgoto(xconv(x)); vgoto(yconv(y)); } void movehv(double h, double v) /* go to internal position h, v */ { hgoto(h); vgoto(v); } void hmot(double n) /* generate n units of horizontal motion */ { hpos += n; } void vmot(double n) /* generate n units of vertical motion */ { vpos += n; } void hgoto(double n) { hpos = n; } void vgoto(double n) { vpos = n; } -double fabs(double x) -{ - return x < 0 ? -x : x; -} - void hvflush(void) /* get to proper point for output */ { if (fabs(hpos-htrue) >= 0.0005) { printf("\\h'%.3fi'", hpos - htrue); htrue = hpos; } if (fabs(vpos-vtrue) >= 0.0005) { printf("\\v'%.3fi'", vpos - vtrue); vtrue = vpos; } } void flyback(void) /* return to upper left corner (entry point) */ { printf(".sp -1\n"); htrue = vtrue = 0; } void printlf(int n, char *f) { if (f) printf(".lf %d %s\n", n, f); else printf(".lf %d\n", n); } void troff(char *s) /* output troff right here */ { printf("%s\n", s); } void label(char *s, int t, int nh) /* text s of type t nh half-lines up */ { int q; char *p; if (!s) return; hvflush(); dprintf("label: %s %o %d\n", s, t, nh); printf("%s", textshift); /* shift down and left */ if (t & ABOVE) nh++; else if (t & BELOW) nh--; if (nh) printf("\\v'%du*\\n(.vu/2u'", -nh); /* just in case the text contains a quote: */ q = 0; for (p = s; *p; p++) if (*p == '\'') { q = 1; break; } t &= ~(ABOVE|BELOW); if (t & LJUST) { printf("%s", s); } else if (t & RJUST) { if (q) printf("\\h\\(ts-\\w\\(ts%s\\(tsu\\(ts%s", s, s); else printf("\\h'-\\w'%s'u'%s", s, s); } else { /* CENTER */ if (q) printf("\\h\\(ts-\\w\\(ts%s\\(tsu/2u\\(ts%s", s, s); else printf("\\h'-\\w'%s'u/2u'%s", s, s); } printf("\n"); flyback(); } void line(double x0, double y0, double x1, double y1) /* draw line from x0,y0 to x1,y1 */ { move(x0, y0); cont(x1, y1); } void arrow(double x0, double y0, double x1, double y1, double w, double h, double ang, int nhead) /* draw arrow (without shaft) */ { double alpha, rot, drot, hyp; double dx, dy; int i; rot = atan2(w / 2, h); hyp = sqrt(w/2 * w/2 + h * h); alpha = atan2(y1-y0, x1-x0) + ang; if (nhead < 2) nhead = 2; dprintf("rot=%g, hyp=%g, alpha=%g\n", rot, hyp, alpha); printf(".if t \\{\\\n"); for (i = nhead-1; i >= 0; i--) { drot = 2 * rot / (double) (nhead-1) * (double) i; dx = hyp * cos(alpha + PI - rot + drot); dy = hyp * sin(alpha + PI - rot + drot); dprintf("dx,dy = %g,%g\n", dx, dy); line(x1+dx, y1+dy, x1, y1); } printf(".\\}\n"); } static double lastgray = 0; void fillstart(double v) /* this works only for postscript, obviously. */ { /* uses drechsler's dpost conventions... */ hvflush(); printf("\\X'BeginObject %g setgray'\n", v); lastgray = v; flyback(); } void fillend(int vis, int fill __unused) { hvflush(); printf("\\X'EndObject gsave eofill grestore %g setgray %s'\n", !vis ? lastgray : 0.0, vis ? "stroke" : ""); /* for dashed: [50] 0 setdash just before stroke. */ lastgray = 0; flyback(); } void box(double x0, double y0, double x1, double y1) { move(x0, y0); cont(x0, y1); cont(x1, y1); cont(x1, y0); cont(x0, y0); } void cont(double x, double y) /* continue line from here to x,y */ { double h1, v1; double dh, dv; int rh = 0; h1 = xconv(x); v1 = yconv(y); dh = h1 - hpos; dv = v1 - vpos; if (dh > 0 && !dv) { rh = 1; move(x, y); dh = -dh; } hvflush(); printf("\\D'l%.3fi %.3fi'\n", dh, dv); if (rh) move(x, y); flyback(); /* expensive */ hpos = h1; vpos = v1; } void circle(double x, double y, double r) { move(x-r, y); hvflush(); printf("\\D'c%.3fi'\n", xsc(2 * r)); flyback(); } void spline(double x, double y, double n, ofloat *p, int dashed __unused, double ddval __unused) { int i; double dx, dy; double xerr, yerr; move(x, y); hvflush(); xerr = yerr = 0.0; printf("\\D'~"); for (i = 0; i < 2 * n; i += 2) { dx = xsc(xerr += p[i]); xerr -= dx/xscale; dy = ysc(yerr += p[i+1]); yerr -= dy/yscale; printf(" %.3fi %.3fi", dx, -dy); /* WATCH SIGN */ } printf("'\n"); flyback(); } void ellipse(double x, double y, double r1, double r2) { double ir1, ir2; move(x-r1, y); hvflush(); ir1 = xsc(r1); ir2 = ysc(r2); - printf("\\D'e%.3fi %.3fi'\n", 2 * ir1, 2 * abs(ir2)); + printf("\\D'e%.3fi %.3fi'\n", 2 * ir1, 2 * fabs(ir2)); flyback(); } void arc(double x, double y, double x0, double y0, double x1, double y1) /* draw arc with center x,y */ { move(x0, y0); hvflush(); printf("\\D'a%.3fi %.3fi %.3fi %.3fi'\n", xsc(x-x0), -ysc(y-y0), xsc(x1-x), -ysc(y1-y)); /* WATCH SIGNS */ flyback(); } void dot(void) { hvflush(); /* what character to draw here depends on what's available. */ /* on the 202, l. is good but small. */ /* in general, use a smaller, shifted period and hope */ printf("\\&\\f1\\h'-.1m'\\v'.03m'\\s-3.\\s+3\\fP\n"); flyback(); } Index: projects/doctools/contrib/heirloom-doctools/pic/symtab.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/pic/symtab.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/pic/symtab.c (revision 307812) @@ -1,116 +1,116 @@ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/pic/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)symtab.c 1.3 (gritter) 10/18/05 */ #include #include #include #include #include "pic.h" #include "y.tab.h" YYSTYPE getvar(const char *s) /* return value of variable s (usually pointer) */ { struct symtab *p; static YYSTYPE bug; p = lookup(s); if (p == NULL) { if (islower((int)s[0])) WARNING("no such variable as %s", s); else WARNING("no such place as %s", s); return(bug); } return(p->s_val); } double getfval(const char *s) /* return float value of variable s */ { YYSTYPE y; y = getvar(s); return y.f; } -void setfval(char *s, double f) /* set variable s to f */ +void setfval(const char *s, double f) /* set variable s to f */ { struct symtab *p; if ((p = lookup(s)) != NULL) p->s_val.f = f; } struct symtab *makevar(char *s, int t, YYSTYPE v) /* make variable named s in table */ /* assumes s is static or from tostring */ { struct symtab *p; for (p = stack[nstack].p_symtab; p != NULL; p = p->s_next) if (strcmp(s, p->s_name) == 0) break; if (p == NULL) { /* it's a new one */ p = (struct symtab *) malloc(sizeof(struct symtab)); if (p == NULL) FATAL("out of symtab space with %s", s); p->s_next = stack[nstack].p_symtab; stack[nstack].p_symtab = p; /* stick it at front */ } p->s_name = s; p->s_type = t; p->s_val = v; return(p); } struct symtab *lookup(const char *s) /* find s in symtab */ { int i; struct symtab *p; for (i = nstack; i >= 0; i--) /* look in each active symtab */ for (p = stack[i].p_symtab; p != NULL; p = p->s_next) if (strcmp(s, p->s_name) == 0) return(p); return(NULL); } void freesymtab(struct symtab *p) /* free space used by symtab at p */ { struct symtab *q; for ( ; p != NULL; p = q) { q = p->s_next; free(p->s_name); /* assumes done with tostring */ free((char *)p); } } void freedef(char *s) /* free definition for string s */ { struct symtab *p, *q, *op; for (p = op = q = stack[nstack].p_symtab; p != NULL; p = p->s_next) { if (strcmp(s, p->s_name) == 0) { /* got it */ if (p->s_type != DEFNAME) break; if (p == op) /* 1st elem */ stack[nstack].p_symtab = p->s_next; else q->s_next = p->s_next; free(p->s_name); free(p->s_val.p); free((char *)p); return; } q = p; } /* WARNING("%s is not defined at this point", s); */ } Index: projects/doctools/contrib/heirloom-doctools/picpack/getopt.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/picpack/getopt.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/picpack/getopt.c (nonexistent) @@ -1,222 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany - * - * Sccsid @(#)getopt.c 1.10 (gritter) 12/16/07 - */ -/* from OpenSolaris "getopt.c 1.23 05/06/08 SMI" */ - -/* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ - - -/* - * See getopt(3C) and SUS/XPG getopt() for function definition and - * requirements. - * - * This actual implementation is a bit looser than the specification - * as it allows any character other than ':' to be used as an option - * character - The specification only guarantees the alnum characters - * ([a-z][A-Z][0-9]). - */ - -#include -#include -#include - -extern ssize_t write(int, const void *, size_t); - -char *optarg = NULL; -int optind = 1; -int opterr = 1; -int optopt = 0; - -#define ERR(s, c) err(s, c, optstring, argv[0]) -static void -err(const char *s, int c, const char *optstring, const char *argv0) -{ - char errbuf[256], *ep = errbuf; - const char *cp; - - if (opterr && optstring[0] != ':') { - for (cp = argv0; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - for (cp = ": "; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - for (cp = s; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - for (cp = " -- "; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - if (ep<&errbuf[sizeof errbuf]) - *ep++ = c; - if (ep<&errbuf[sizeof errbuf]) - *ep++ = '\n'; - write(2, errbuf, ep - errbuf); - } -} - -/* - * getopt_sp is required to keep state between successive calls to getopt() - * while extracting aggregated options (ie: -abcd). Hence, getopt() is not - * thread safe or reentrant, but it really doesn't matter. - * - * So, why isn't this "static" you ask? Because the historical Bourne - * shell has actually latched on to this little piece of private data. - */ -int getopt_sp = 1; - -/* - * Determine if the specified character (c) is present in the string - * (optstring) as a regular, single character option. If the option is found, - * return a pointer into optstring pointing at the option character, - * otherwise return null. The character ':' is not allowed. - */ -static char * -parse(const char *optstring, const char c) -{ - char *cp = (char *)optstring; - - if (c == ':') - return (NULL); - do { - if (*cp == c) - return (cp); - } while (*cp++ != '\0'); - return (NULL); -} - -/* - * External function entry point. - */ -int -getopt(int argc, char *const *argv, const char *optstring) -{ - char c; - char *cp; - - /* - * Has the end of the options been encountered? The following - * implements the SUS requirements: - * - * If, when getopt() is called: - * argv[optind] is a null pointer - * *argv[optind] is not the character '-' - * argv[optind] points to the string "-" - * getopt() returns -1 without changing optind. If - * argv[optind] points to the string "--" - * getopt() returns -1 after incrementing optind. - */ - if (getopt_sp == 1) { - if (optind >= argc || argv[optind][0] != '-' || - argv[optind] == NULL || argv[optind][1] == '\0') - return (EOF); - else if (strcmp(argv[optind], "--") == 0) { - optind++; - return (EOF); - } - } - - /* - * Getting this far indicates that an option has been encountered. - * Note that the syntax of optstring applies special meanings to - * the characters ':' and '(', so they are not permissible as - * option letters. A special meaning is also applied to the ')' - * character, but its meaning can be determined from context. - * Note that the specification only requires that the alnum - * characters be accepted. - */ - optopt = c = (unsigned char)argv[optind][getopt_sp]; - optarg = NULL; - if ((cp = parse(optstring, c)) == NULL) { - /* LINTED: variable format specifier */ - ERR("illegal option", c); - if (argv[optind][++getopt_sp] == '\0') { - optind++; - getopt_sp = 1; - } - return ('?'); - } - optopt = c = *cp; - - /* - * A valid option has been identified. If it should have an - * option-argument, process that now. SUS defines the setting - * of optarg as follows: - * - * 1. If the option was the last character in the string pointed to - * by an element of argv, then optarg contains the next element - * of argv, and optind is incremented by 2. If the resulting - * value of optind is not less than argc, this indicates a - * missing option-argument, and getopt() returns an error - * indication. - * - * 2. Otherwise, optarg points to the string following the option - * character in that element of argv, and optind is incremented - * by 1. - * - * The second clause allows -abcd (where b requires an option-argument) - * to be interpreted as "-a -b cd". - */ - if (*(cp + 1) == ':') { - /* The option takes an argument */ - if (argv[optind][getopt_sp+1] != '\0') { - optarg = &argv[optind++][getopt_sp+1]; - } else if (++optind >= argc) { - /* LINTED: variable format specifier */ - ERR("option requires an argument", c); - getopt_sp = 1; - optarg = NULL; - return (optstring[0] == ':' ? ':' : '?'); - } else - optarg = argv[optind++]; - getopt_sp = 1; - } else { - /* The option does NOT take an argument */ - if (argv[optind][++getopt_sp] == '\0') { - getopt_sp = 1; - optind++; - } - optarg = NULL; - } - return (c); -} /* getopt() */ - -#ifdef __APPLE__ -/* - * Starting with Mac OS 10.5 Leopard, turns getopt() - * into getopt$UNIX2003() by default. Consequently, this function - * is called instead of the one defined above. However, optind is - * still taken from this file, so in effect, options are not - * properly handled. Defining an own getopt$UNIX2003() function - * works around this issue. - */ -int -getopt$UNIX2003(int argc, char *const argv[], const char *optstring) -{ - return getopt(argc, argv, optstring); -} -#endif /* __APPLE__ */ Property changes on: projects/doctools/contrib/heirloom-doctools/picpack/getopt.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: projects/doctools/contrib/heirloom-doctools/picpack/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/picpack/Makefile.mk (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/picpack/Makefile.mk (revision 307812) @@ -1,21 +1,21 @@ -OBJ = picpack.o getopt.o +OBJ = picpack.o FLAGS = -I../troff/troff.d/dpost.d .c.o: $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< all: picpack picpack: $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o picpack install: $(INSTALL) -c picpack $(ROOT)$(BINDIR)/picpack $(STRIP) $(ROOT)$(BINDIR)/picpack $(INSTALL) -c -m 644 picpack.1 $(ROOT)$(MANDIR)/man1/picpack.1 clean: rm -f $(OBJ) picpack core log *~ mrproper: clean Index: projects/doctools/contrib/heirloom-doctools/picpack/picpack.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/picpack/picpack.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/picpack/picpack.c (revision 307812) @@ -1,658 +1,608 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 2001 by Sun Microsystems, Inc. * All rights reserved. */ /* from OpenSolaris "picpack.c 1.6 05/06/08 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany */ #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 #define USED __attribute__ ((used)) #elif defined __GNUC__ #define USED __attribute__ ((unused)) #else #define USED #endif static const char sccsid[] USED = "@(#)picpack.sl 5.1 (gritter) 10/25/05"; /* * * picpack - picture packing pre-processor * * A trivial troff pre-processor that copies files to stdout, expanding picture * requests into an in-line format that's passed transparently through troff and * handled by dpost. The program is an attempt to address requirements, expressed * by several organizations, of being able to store a document as a single file * (usually troff input) that can then be sent through dpost and ultimately to * a PostScript printer. * * The program looks for strings listed in the keys[] array at the start of each * line. When a picture request (as listed in keys[]) is found the second string * on the line is taken to be a picture file pathname that's added (in transparent * mode) to the output file. In addition each in-line picture file is preceeded by * device control command (again passed through in transparent mode) that looks * like, * * x X InlinePicture filename bytes * * where bytes is the size of the picture file (which begins on the next line) * and filename is the pathname of the picture file. dpost uses both arguments to * manage in-line pictures (in a big temp file). To handle pictures in diversions * picpack reads each input file twice. The first pass looks for picture inclusion * requests and copies each picture file transparently to the output file, while * second pass just copies the input file to the output file. Things could still * break, but the two pass method should handle most jobs. * * The recognized in-line picture requests are saved in keys[] and by default only * expand .BP and .PI macro calls. The -k option changes the recognized strings, * and may be needed if you've built your own picture inclusion macros on top of * .BP or .PI or decided to list each picture file at the start of your input file * using a dummy macro. For example you could require every in-line picture be * named by a dummy macro (say .iP), then the command line, * * picpack -k.iP file > file.pack * * hits on lines that begin with .iP (rather than .BP or .PI), and the only files * pulled in would be ones named as the second argument to the new .iP macro. The * -k option accepts a space or comma separated list of up to 10 different key * strings. picpack imposes no contraints on key strings, other than not allowing * spaces or commas. A key string can begin with \" and in that case it would be * troff comment. * * Although the program will help some users, there are obvious disadvantages. * Perhaps the most important is that troff output files (with in-line pictures * included) don't fit the device independent language accepted by important post * processors like proof, and that means you won't be able to reliably preview a * packed file on your 5620 or whatever. Another potential problem is that picture * files can be large. Packing everything together in a single file at an early * stage has a better chance of exceeding your system's ulimit. * */ #include #include #include #include #include #include #include #include "gen.h" /* general purpose definitions */ #include "ext.h" /* external variable definitions */ #define TEMPDIR "/var/tmp" #include "glob.c" static const char *keys[11] = {".BP", ".PI", NULL}; static int quiet = FALSE; static FILE *fp_in; /* input */ static FILE *fp_out; /* and output files */ static void newkeys(char *); static FILE *copystdin(void); static void copyfile(int, int); static void picpack(void); static void do_inline(char *); static int gotpicfile(char *); static void addpicfile(char *); -char *fgetline(char **line, size_t *linesize, size_t *llen, FILE *fp); - /*****************************************************************************/ int main(int agc, char **agv) { /* * * A picture packing pre-processor that copies input files to stdout, expanding * picture requests (as listed in keys[]) to an in-line format that can be passed * through troff (using transparent mode) and handled later by dpost. * */ fp_in = stdin; fp_out = stdout; argc = agc; /* global so everyone can use them */ argv = agv; prog_name = argv[0]; /* just for error messages */ options(); /* command line options */ arguments(); /* translate all the input files */ done(); /* clean things up */ return x_stat; /* everything probably went OK */ } /* End of main */ /*****************************************************************************/ void options(void) { int ch; /* name returned by getopt() */ /* * * Handles the command line options. * */ while ( (ch = getopt(argc, argv, "k:qDI")) != EOF ) { switch ( ch ) { case 'k': /* new expansion key strings */ newkeys(optarg); break; case 'q': /* disables "missing picture" messages */ quiet = TRUE; break; case 'D': /* debug flag */ debug = ON; break; case 'I': /* ignore FATAL errors */ ignore = ON; break; case '?': /* don't know the option */ error(FATAL, ""); break; default: error(FATAL, "missing case for option %c", ch); break; } /* End switch */ } /* End while */ argc -= optind; /* get ready for non-options args */ argv += optind; } /* End of options */ /*****************************************************************************/ static void newkeys( char *list /* comma or space separated key strings */ ) { char *p; /* next key string from *list */ int i; /* goes in keys[i] */ int n; /* last key string slot in keys[] */ /* * * Separates *list into space or comma separated strings and adds each one to the * keys[] array. The strings in keys[] are used to locate the picture inclusion * requests that are translated to the in-line format. The keys array must end * with a NULL pointer and by default only expands .BP and .PI macro calls. * */ n = (sizeof(keys) / sizeof(char *)) - 1; for ( i = 0, p = strtok(list, " ,"); p != NULL; i++, p = strtok(NULL, " ,") ) if ( i >= n ) error(FATAL, "too many key strings"); else keys[i] = p; keys[i] = NULL; } /* End of newkeys */ /*****************************************************************************/ void arguments(void) { /* * * Makes sure all the non-option command line arguments are processed. If we get * here and there aren't any arguments left, or if '-' is one of the input files * we process stdin, after copying it to a temporary file. * */ if ( argc < 1 ) { fp_in = copystdin(); picpack(); } else while ( argc > 0 ) { if ( strcmp(*argv, "-") == 0 ) fp_in = copystdin(); else if ( (fp_in = fopen(*argv, "r")) == NULL ) error(FATAL, "can't open %s", *argv); picpack(); fclose(fp_in); argc--; argv++; } /* End while */ } /* End of arguments */ /*****************************************************************************/ static FILE * copystdin(void) { char tfile[] = TEMPDIR "/postXXXXXX"; /* temporary file name */ int fd_out; /* and its file descriptor */ FILE *fp; /* return value - will be new input file */ /* * * Copies stdin to a temp file, unlinks the file, and returns the file pointer for * the new temporary file to the caller. Needed because we read each input file * twice in an attempt to handle pictures in diversions. * */ if ( (fd_out = mkstemp(tfile)) == -1 ) error(FATAL, "can't create %s", tfile); copyfile(fileno(stdin), fd_out); close(fd_out); if ( (fp = fopen(tfile, "r")) == NULL ) error(FATAL, "can't open %s", tfile); unlink(tfile); return(fp); } /* End of copystdin */ /*****************************************************************************/ static void copyfile( int fd_in, /* input */ int fd_out /* and output files */ ) { char buf[512]; /* internal buffer for reads and writes */ int count; /* number of bytes put in buf[] */ /* * * Copies file fd_in to fd_out. Handles the second pass for each input file and * also used to copy stdin to a temporary file. * */ while ( (count = read(fd_in, buf, sizeof(buf))) > 0 ) if ( write(fd_out, buf, count) != count ) error(FATAL, "write error"); } /* End of copyfile */ /*****************************************************************************/ void done(void) { /* * * Finished with all the input files so unlink the temporary file that we used * to record the in-line picture file pathnames. * */ if ( temp_file != NULL ) unlink(temp_file); } /* End of done */ /*****************************************************************************/ static void picpack(void) { char *line = NULL; /* next input line */ size_t linesize = 0; char name[100]; /* picture file names - from BP or PI */ int i; /* for looking through keys[] */ /* * * Handles the two passes over the next input file. First pass compares the start * of each line in *fp_in with the key strings saved in the keys[] array. If a * match is found do_inline() is called to copy the picture file (the file named * as the second string in line[]) to stdout, provided the file hasn't previously * been copied. The second pass goes back to the start of fp_in and copies it all * to the output file. * */ - while ( fgetline(&line, &linesize, NULL, fp_in) != NULL ) { + while ( getline(&line, &linesize, fp_in) > 0 ) { for ( i = 0; keys[i] != NULL; i++ ) if ( strncmp(line, keys[i], strlen(keys[i])) == 0 ) { if ( sscanf(line, "%*s %s", name) == 1 ) { strtok(name, "("); if ( gotpicfile(name) == FALSE ) do_inline(name); } /* End if */ } /* End if */ } /* End while */ fflush(fp_out); /* second pass - copy fp_in to fp_out */ fseek(fp_in, 0L, 0); copyfile(fileno(fp_in), fileno(fp_out)); free(line); } /* End of picpack */ /*****************************************************************************/ static void do_inline( char *name /* name of the in-line picture file */ ) { long size; /* and its size in bytes - from fstat */ FILE *fp; /* for reading file *name */ int ch; /* next character from picture file */ int lastch = '\n'; /* so we know when to put out \! */ struct stat sbuf; /* for the picture file size */ /* * * Copies the picture file *name to the output file in an in-line format that can * be passed through troff and recovered later by dpost. Transparent mode is used * so each line starts with \! and all \ characters must be escaped. The in-line * picture sequence begins with an "x X InlinePicture" device control command that * names the picture file and gives its size (in bytes). * */ if ( (fp = fopen(name, "r")) != NULL ) { fstat(fileno(fp), &sbuf); if ( (size = sbuf.st_size) > 0 ) { fprintf(fp_out, "\\!x X InlinePicture %s %ld\n", name, size); while ( (ch = getc(fp)) != EOF ) { if ( lastch == '\n' ) fprintf(fp_out, "\\!"); if ( ch == '\\' ) putc('\\', fp_out); putc(lastch = ch, fp_out); } /* End while */ if ( lastch != '\n' ) putc('\n', fp_out); } /* End if */ fclose(fp); addpicfile(name); } else if ( quiet == FALSE ) error(NON_FATAL, "can't read picture file %s", name); } /* End of do_inline */ /*****************************************************************************/ static int gotpicfile(char *name) { char buf[100]; FILE *fp_pic; /* * * Checks the list of previously added picture files in *temp_file and returns * FALSE if it's a new file and TRUE otherwise. Probably should open the temp * file once for update and leave it open, rather than opening and closing it * every time. * */ if ( temp_file != NULL ) if ( (fp_pic = fopen(temp_file, "r")) != NULL ) { while ( fscanf(fp_pic, "%s", buf) != EOF ) if ( strcmp(buf, name) == 0 ) { fclose(fp_pic); return(TRUE); } /* End if */ fclose(fp_pic); } /* End if */ return(FALSE); } /* End of gotpicfile */ /*****************************************************************************/ static void addpicfile(char *name) { FILE *fp_pic; static char template[] = TEMPDIR "/picpacXXXXXX"; /* * * Adds string *name to the list of in-line picture files that's maintained in * *temp_file. Should undoubtedly open the file once for update and use fseek() * to move around in the file! * */ if ( temp_file == NULL ) if ( close(mkstemp(temp_file = template)) < 0 ) return; if ( (fp_pic = fopen(temp_file, "a")) != NULL ) { fprintf(fp_pic, "%s\n", name); fclose(fp_pic); } /* End if */ } /* End of addpicfile */ - -/*****************************************************************************/ - -static void * -srealloc(void *p, size_t size) -{ - if ((p = realloc(p, size)) == NULL) { - write(2, "Can't malloc\n", 13); - _exit(0177); - } - return p; -} - -#define LSIZE 128 /* initial line size */ - -#if defined (__GLIBC__) && defined (_IO_getc_unlocked) -#undef getc -#define getc(f) _IO_getc_unlocked(f) -#endif - -char * -fgetline(char **line, size_t *linesize, size_t *llen, FILE *fp) -{ - int c; - size_t n = 0; - - if (*line == NULL || *linesize < LSIZE + n + 1) - *line = srealloc(*line, *linesize = LSIZE + n + 1); - for (;;) { - if (n >= *linesize - LSIZE / 2) - *line = srealloc(*line, *linesize += LSIZE); - c = getc(fp); - if (c != EOF) { - (*line)[n++] = c; - (*line)[n] = '\0'; - if (c == '\n') - break; - } else { - if (n > 0) - break; - else - return NULL; - } - } - if (llen) - *llen = n; - return *line; -} /* from OpenSolaris "misc.c 1.6 05/06/08 SMI" */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright 2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany */ void error(int kind, const char *mesg, ...) { /* * * Called when we've run into some kind of program error. *mesg is printed using * the control string arguments a?. We'll quit if we're not ignoring errors and * kind is FATAL. * */ if ( mesg != NULL && *mesg != '\0' ) { va_list ap; fprintf(stderr, "%s: ", prog_name); va_start(ap, mesg); vfprintf(stderr, mesg, ap); va_end(ap); if ( lineno > 0 ) fprintf(stderr, " (line %ld)", lineno); if ( position > 0 ) fprintf(stderr, " (near byte %ld)", position); putc('\n', stderr); } /* End if */ if ( kind == FATAL && ignore == OFF ) { if ( temp_file != NULL ) unlink(temp_file); exit(x_stat | 01); } /* End if */ } /* End of error */ Index: projects/doctools/contrib/heirloom-doctools/ptx/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/ptx/Makefile.mk (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/ptx/Makefile.mk (revision 307812) @@ -1,23 +1,23 @@ OBJ = ptx.o -FLAGS = -DLIBDIR='"$(LIBDIR)"' $(EUC) +FLAGS = -DLIBDIR='"$(LIBDIR)"' $(EUC) -I../include .c.o: $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< all: ptx ptx: $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o ptx install: $(INSTALL) -c ptx $(ROOT)$(BINDIR)/ptx $(STRIP) $(ROOT)$(BINDIR)/ptx $(INSTALL) -c -m 644 ptx.1 $(ROOT)$(MANDIR)/man1/ptx.1 test -d $(ROOT)$(LIBDIR) || mkdir -p $(ROOT)$(LIBDIR) $(INSTALL) -c -m 644 eign $(ROOT)$(LIBDIR)/eign clean: rm -f $(OBJ) ptx core log *~ mrproper: clean Index: projects/doctools/contrib/heirloom-doctools/ptx/ptx.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/ptx/ptx.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/ptx/ptx.c (revision 307812) @@ -1,713 +1,704 @@ /* from Unix 7th Edition /usr/src/cmd/ptx.c */ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, November 2005. */ /* * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * Redistributions of source code and documentation must retain the * above copyright notice, this list of conditions and the following * disclaimer. * 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. * All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed or owned by Caldera * International, Inc. * Neither the name of Caldera International, Inc. nor the names of * other contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA * INTERNATIONAL, INC. 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 CALDERA INTERNATIONAL, INC. 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. */ #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 #define USED __attribute__ ((used)) #elif defined __GNUC__ #define USED __attribute__ ((unused)) #else #define USED #endif static const char sccsid[] USED = "@(#)/usr/ucb/ptx.sl 1.5 (gritter) 11/6/05"; /* permuted title index ptx [-t] [-i ignore] [-o only] [-w num] [-f] [input] [output] Ptx reads the input file and permutes on words in it. It excludes all words in the ignore file. Alternately it includes words in the only file. if neither is given it excludes the words in /usr/lib/eign. The width of the output line can be changed to num characters. If omitted 72 is default unless troff than 100. the -f flag tells the program to fold the output the -t flag says the output is for troff and the output is then wider.  make: cc ptx.c -lS */ #include #include #ifdef EUC #include #include #endif #include #include #include #include #include #include #include #include #include +#include "global.h" + #define DEFLTX LIBDIR "/eign" #define TILDE 0177 #define SORT "sort" #define N 30 #define MAX N*BUFSIZ #define MAXT 2048 #define MASK 03777 #define SET 1 #define isabreak(c) (btable[c]) - -#ifdef __GLIBC__ -#ifdef _IO_getc_unlocked -#undef getc -#define getc(f) _IO_getc_unlocked(f) -#endif -#ifdef _IO_putc_unlocked -#undef putc -#define putc(c, f) _IO_putc_unlocked(c, f) -#endif -#endif #define getline xxgetline static int status; #ifdef EUC #define NCHARS 0x110000 #else /* !EUC */ #define NCHARS 256 #define iswupper isupper #define towlower tolower #define iswspace isspace #define wchar_t unsigned char #endif /* !EUC */ static const wchar_t *hasht[MAXT]; static wchar_t *line; static wchar_t btable[NCHARS]; static int ignore; static int only; static int llen = 72; static int gap = 3; static int gutter = 3; static int mlen; static int wlen; static int rflag; static int halflen; static wchar_t *strtbufp, *endbufp; static const char *empty = ""; static char *infile; static FILE *inptr /*= stdin*/; static char *outfile; static FILE *outptr /*= stdout*/; static char *sortfile; /* output of sort program */ static char nofold[] = {'-', 'd', 't', TILDE, 0}; static char fold[] = {'-', 'd', 'f', 't', TILDE, 0}; static char *sortopt = nofold; static FILE *sortptr; static char *bfile; /*contains user supplied break chars */ static FILE *bptr; static void msg(const char *, const char *); static void diag(const char *, const char *); static wchar_t *getline(void); static void cmpline(const wchar_t *); static int cmpword(const wchar_t *, const wchar_t *, const wchar_t *); static void putline(const wchar_t *, const wchar_t *); static void getsort(void); static const wchar_t *rtrim(const wchar_t *, const wchar_t *, int); static const wchar_t *ltrim(const wchar_t *, const wchar_t *, int); static void putout(const wchar_t *, const wchar_t *); static void onintr(int); static int hash(const wchar_t *, const wchar_t *); static int storeh(int, const wchar_t *); #ifdef EUC static wint_t peekc = WEOF; static wint_t GETC(FILE *fp) { char mb[MB_LEN_MAX+1]; wchar_t wc; int c, i, n; mbstate_t state; if (peekc != WEOF) { wc = peekc; peekc = WEOF; return wc; } bad: if ((c = getc(fp)) == EOF) return WEOF; if (c & 0200) { i = 0; for (;;) { mb[i++] = c; mb[i] = 0; memset(&state, 0, sizeof state); if ((n = mbrtowc(&wc, mb, i, &state)) == (size_t)-1) goto bad; if (n == (size_t)-2) { if ((c = getc(fp)) == EOF) return WEOF; continue; } if (wc >= NCHARS) goto bad; return wc; } } return c; } static void UNGETC(int c, FILE *fp) { peekc = c; } static int PUTC(int c, FILE *fp) { char mb[MB_LEN_MAX]; int i, n; if ((n = wctomb(mb, c)) > 0) { for (i = 0; i < n; i++) putc(mb[i]&0377, fp); return c; } else if (n == 0) { putc(0, fp); return 0; } else return EOF; } #define L "l" #else /* !EUC */ #define GETC(f) getc(f) #define UNGETC(c, f) ungetc(c, f) #define PUTC(c, f) putc(c, f) #define L #endif /* !EUC */ int main(int argc,char **argv) { char template[] = "/tmp/ptxsXXXXXX"; register int c; register wchar_t *bufp; int pid; wchar_t *pend; const char *xfile; FILE *xptr; setlocale(LC_CTYPE, ""); inptr = stdin; outptr = stdout; if(signal(SIGHUP,onintr)==SIG_IGN) signal(SIGHUP,SIG_IGN); if(signal(SIGINT,onintr)==SIG_IGN) signal(SIGINT,SIG_IGN); signal(SIGPIPE,onintr); signal(SIGTERM,onintr); /* argument decoding */ xfile = DEFLTX; argv++; while(argc>1 && **argv == '-') { switch (*++*argv){ case 'r': rflag++; break; case 'f': sortopt = fold; break; case 'w': if(argc >= 2) { argc--; wlen++; llen = atoi(*++argv); if(llen == 0) diag("Wrong width:",*argv); break; } case 't': if(wlen == 0) llen = 100; break; case 'g': if(argc >=2) { argc--; gap = gutter = atoi(*++argv); } break; case 'i': if(only) diag("Only file already given.",empty); if (argc>=2){ argc--; ignore++; xfile = *++argv; } break; case 'o': if(ignore) diag("Ignore file already given",empty); if (argc>=2){ only++; argc--; xfile = *++argv; } break; case 'b': if(argc>=2) { argc--; bfile = *++argv; } break; default: msg("Illegal argument:",*argv); } argc--; argv++; } if(argc>3) diag("Too many filenames",empty); else if(argc==3){ infile = *argv++; outfile = *argv; if((outptr = fopen(outfile,"w")) == NULL) diag("Cannot open output file:",outfile); } else if(argc==2) { infile = *argv; outfile = 0; } /* Default breaks of blank, tab and newline */ btable[' '] = SET; btable['\t'] = SET; btable['\n'] = SET; if(bfile) { if((bptr = fopen(bfile,"r")) == NULL) diag("Cannot open break char file",bfile); while((c = GETC(bptr)) != EOF) btable[c] = SET; } /* Allocate space for a buffer. If only or ignore file present read it into buffer. Else read in default ignore file and put resulting words in buffer. */ if((strtbufp = calloc(N,BUFSIZ)) == NULL) diag("Out of memory space",empty); bufp = strtbufp; endbufp = strtbufp+MAX; if((xptr = fopen(xfile,"r")) == NULL) diag("Cannot open file",xfile); while(bufp < endbufp && (c = GETC(xptr)) != EOF) { if(isabreak(c)) { if(storeh(hash(strtbufp,bufp),strtbufp)) diag("Too many words",xfile); *bufp++ = '\0'; strtbufp = bufp; } else { *bufp++ = (iswupper(c)?towlower(c):c); } } if (bufp >= endbufp) diag("Too many words in file",xfile); endbufp = --bufp; /* open output file for sorting */ close(mkstemp(template)); sortfile = template; if((sortptr = fopen(sortfile, "w")) == NULL) diag("Cannot open output for sorting:",sortfile); /* get a line of data and compare each word for inclusion or exclusion in the sort phase */ if (infile!=0 && (inptr = fopen(infile,"r")) == NULL) diag("Cannot open data: ",infile); while((pend=getline())) cmpline(pend); fclose(sortptr); switch (pid = fork()){ case -1: /* cannot fork */ diag("Cannot fork",empty); case 0: /* child */ execlp(SORT, SORT, sortopt, "+0", "-1", "+1", sortfile, "-o", sortfile, NULL); default: /* parent */ while(wait(&status) != pid); } getsort(); onintr(0); /*NOTREACHED*/ return 0; } static void msg(const char *s,const char *arg) { fprintf(stderr,"%s %s\n",s,arg); return; } static void diag(const char *s,const char *arg) { msg(s,arg); exit(1); } static wchar_t * getline(void) { register int c; register int i = 0; if (line == NULL) line = calloc(1, mlen = 1); /* Throw away leading white space */ while(iswspace(c=GETC(inptr))) ; if(c==EOF) return(0); UNGETC(c,inptr); while(( c=GETC(inptr)) != EOF) { switch (c) { case '\n': while(iswspace(line[--i])); line[++i] = '\n'; return(&line[i]); case '\t': c = ' '; /*FALLTHRU*/ break; default: if (i+1 >= mlen) line = realloc(line, mlen += 200); line[i++] = c; } } return(0); } static void cmpline(const wchar_t *pend) { const wchar_t *pstrt, *pchar, *cp; const wchar_t **hp; int flag; pchar = line; if(rflag) while(pcharhalflen-1) p3b = p3a+halflen-1; p2a = ltrim(ref,p2b=linep,halflen-1); if(p2b-p2a>halflen-1) p2a = p2b-halflen-1; p1b = rtrim(p1a=p3b+(iswspace(p3b[0])!=0),tilde, w=halflen-(p2b-p2a)-gap); if(p1b-p1a>w) p1b = p1a; p4a = ltrim(ref,p4b=p2a-(iswspace(p2a[-1])!=0), w=halflen-(p3b-p3a)-gap); if(p4b-p4a>w) p4a = p4b; fprintf(outptr,".xx \""); putout(p1a,p1b); /* tilde-1 to account for extra space before TILDE */ if(p1b!=(tilde-1) && p1a!=p1b) fprintf(outptr,"/"); fprintf(outptr,"\" \""); if(p4a==p4b && p2a!=ref && p2a!=p2b) fprintf(outptr,"/"); putout(p2a,p2b); fprintf(outptr,"\" \""); putout(p3a,p3b); /* ++p3b to account for extra blank after TILDE */ /* ++p3b to account for extra space before TILDE */ if(p1a==p1b && ++p3b!=tilde) fprintf(outptr,"/"); fprintf(outptr,"\" \""); if(p1a==p1b && p4a!=ref && p4a!=p4b) fprintf(outptr,"/"); putout(p4a,p4b); if(rflag) fprintf(outptr,"\" %" L "s\n",tilde); else fprintf(outptr,"\"\n"); linep = line; break; case '"': /* put double " for " */ *linep++ = c; default: *linep++ = c; } } } static const wchar_t * rtrim(const wchar_t *a,const wchar_t *c,int d) { const wchar_t *b,*x; b = c; for(x=a+1; x<=c&&x-a<=d; x++) if((x==c||iswspace(x[0]))&&!isspace(x[-1])) b = x; if(b=c&&b-x<=d; x--) if(!iswspace(x[0])&&(x==c||isspace(x[-1]))) a = x; if(a>c&&!iswspace(a[-1])) a--; return(a); } static void putout(const wchar_t *strt,const wchar_t *end) { const wchar_t *cp; cp = strt; for(cp=strt; cp>2)) & MASK; return(k); } static int storeh(int num,const wchar_t *strtp) { int i; for(i=num; i$@ sed 's:@REFDIR@:$(REFDIR):g' indxbib.sh >>$@ roffbib: roffbib.sh rm -f $@ echo '#!$(SHELL)' >$@ sed 's:@BINDIR@:$(BINDIR):g' roffbib.sh >>$@ papers/runinv: papers/runinv.sh rm -f $@ echo '#!$(SHELL)' >$@ sed 's:@REFDIR@:$(REFDIR):g' papers/runinv.sh >>$@ install: all for i in refer addbib lookbib sortbib; \ do \ $(INSTALL) -c $$i $(ROOT)$(BINDIR)/$$i || exit; \ $(STRIP) $(ROOT)$(BINDIR)/$$i || exit; \ done $(INSTALL) -c roffbib $(ROOT)$(BINDIR)/roffbib $(INSTALL) -c indxbib $(ROOT)$(BINDIR)/indxbib test -d $(ROOT)$(REFDIR) || mkdir -p $(ROOT)$(REFDIR) for i in hunt inv mkey; \ do \ $(INSTALL) -c $$i $(ROOT)$(REFDIR)/$$i || exit; \ $(STRIP) $(ROOT)$(REFDIR)/$$i || exit; \ done test -d $(ROOT)$(REFDIR)/papers || mkdir -p $(ROOT)$(REFDIR)/papers $(INSTALL) -c -m 644 \ papers/Rbstjissue $(ROOT)$(REFDIR)/papers/Rbstjissue $(INSTALL) -c -m 644 papers/Rv7man $(ROOT)$(REFDIR)/papers/Rv7man $(INSTALL) -c papers/runinv $(ROOT)$(REFDIR)/papers/runinv - cd $(ROOT)$(REFDIR)/papers && PATH=$(ROOT)$(REFDIR):$$PATH ./runinv + for i in a b c; do \ + $(INSTALL) -m 644 papers/Ind.i$$i $(ROOT)$(REFDIR)/papers/; \ + done for i in addbib.1 lookbib.1 refer.1 roffbib.1 sortbib.1; \ do \ $(INSTALL) -c -m 644 $$i $(ROOT)$(MANDIR)/man1/$$i || exit; \ done rm -f $(ROOT)$(MANDIR)/man1/indxbib.1 ln -s lookbib.1 $(ROOT)$(MANDIR)/man1/indxbib.1 clean: rm -f $(ROBJ) refer $(AOBJ) addbib $(LOBJ) lookbib \ $(SOBJ) sortbib roffbib indxbib $(MOBJ) mkey \ - $(IOBJ) inv $(HOBJ) hunt papers/runinv core log *~ + $(IOBJ) inv $(HOBJ) hunt papers/runinv core log *~ \ + papers/Ind.i? mrproper: clean addbib.o: addbib.c deliv2.o: deliv2.c refer..c glue1.o: glue1.c refer..c glue2.o: glue2.c refer..c glue3.o: glue3.c refer..c glue4.o: glue4.c refer..c glue5.o: glue5.c refer..c hunt1.o: hunt1.c refer..c hunt2.o: hunt2.c refer..c hunt3.o: hunt3.c refer..c hunt5.o: hunt5.c hunt6.o: hunt6.c refer..c hunt7.o: hunt7.c refer..c hunt8.o: hunt8.c refer..c hunt9.o: hunt9.c inv1.o: inv1.c refer..c inv2.o: inv2.c refer..c inv3.o: inv3.c inv5.o: inv5.c refer..c inv6.o: inv6.c refer..c lookbib.o: lookbib.c mkey1.o: mkey1.c refer..c mkey2.o: mkey2.c refer..c mkey3.o: mkey3.c refer..c refer0.o: refer0.c refer..c refer1.o: refer1.c refer..c refer2.o: refer2.c refer..c refer3.o: refer3.c refer..c refer4.o: refer4.c refer..c refer5.o: refer5.c refer..c refer6.o: refer6.c refer..c refer7.o: refer7.c refer..c refer8.o: refer8.c refer..c shell.o: shell.c sortbib.o: sortbib.c tick.o: tick.c version.o: version.c Index: projects/doctools/contrib/heirloom-doctools/refer/deliv2.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/refer/deliv2.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/refer/deliv2.c (revision 307812) @@ -1,84 +1,74 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "deliv2.c 1.4 05/06/02 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)deliv2.c 1.3 (gritter) 10/22/05 */ #include #include #include #include #include "refer..c" int hash (const char *s) { int c, n; for(n=0; (c= *s); s++) n += (c*n+ (c << (unsigned)n%4)); return(n>0 ? n : -n); } void err (const char *s, ...) { va_list ap; fprintf(stderr, "Error: "); va_start(ap, s); vfprintf(stderr, s, ap); va_end(ap); putc('\n', stderr); exit(1); } -int -prefix(const char *t, const char *s) -{ - int c; - - while ((c= *t++) == *s++) - if (c==0) return(1); - return(c==0 ? 1: 0); -} - const char * mindex(const char *s, int c) { register const char *p; for( p=s; *p; p++) if (*p ==c) return(p); return(0); } void * zalloc(int m,int n) { void * # if D1 fprintf(stderr, "calling calloc for %d*%d bytes\n",m,n); # endif t = calloc(m,n); # if D1 fprintf(stderr, "calloc returned %p\n", t); # endif return(t); } Index: projects/doctools/contrib/heirloom-doctools/refer/refer..c =================================================================== --- projects/doctools/contrib/heirloom-doctools/refer/refer..c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/refer/refer..c (revision 307812) @@ -1,196 +1,191 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "refer..c 1.3 05/06/02 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)refer..c 1.5 (gritter) 12/25/06 */ #include #include #include #include "global.h" #ifndef EUC #undef getw #define getw(f) getc(f) #undef putw #define putw(c, f) putc(c, f) #endif /* !EUC */ #define FLAG 003 #define AFLAG 007 #define NRFTXT 10000 #define NRFTBL 500 #define NTFILE 20 #define QLEN 512 #define ANSLEN 4000 #define TAGLEN 400 #define NSERCH 20 #define MXSIG 200 /* max bytes in aggregate signal */ -#ifndef __unused -#define __unused __attribute__((unused)) -#endif - extern FILE *in; extern int endpush, sort, labels, keywant, bare; extern int biblio, science, postpunct; extern const char *smallcaps; extern char *comname; extern const char *keystr; extern const char *convert; extern int authrev; extern int nmlen, dtlen; extern char *rdata[], **search; extern int refnum; extern char *reftable[]; extern char *rtp, reftext[]; extern int sep; extern char tfile[]; extern char gfile[]; extern char ofile[]; extern char hidenam[]; extern const char *Ifile; extern int Iline; extern FILE *fo, *ftemp; extern char *fgnames[]; extern char **fgnamp; extern int keepold; extern int lmaster; extern int reached; extern int colevel; extern int prfreqs; extern int typeindex; extern long indexdate; extern int *hfreq; extern int hfrflg; extern int iflong; extern FILE *fd; extern char usedir[]; extern char *sinput, *soutput, *tagout; /* deliv2.c */ int hash(const char *); void err(const char *, ...); -int prefix(const char *, const char *); const char *mindex(const char *, int); void *zalloc(int, int); /* glue1.c */ void huntmain(int, char **); char *todir(char *); int setfrom(int); /* glue2.c */ void savedir(void); void restodir(void); /* glue3.c */ int corout(char *, char *, const char *, char *, int); int callhunt(char *, char *, char *, int); int dodeliv(char *, char *, char *, int); /* glue4.c */ int grepcall(char *, char *, char *); void clfgrep(void); /* glue5.c */ int fgrep(int, char **); /* hunt1.c */ char *todir(char *); int setfrom(int); /* hunt2.c */ int doquery(long *, int, FILE *, int, char **, unsigned *); long getl(FILE *); void putl(long, FILE *); int hcomp(int, int); int hexch(int, int); /* hunt3.c */ int getq(char **); /* hunt5.c */ void result(unsigned *, int, FILE *); long gdate(FILE *); /* hunt6.c */ int baddrop(unsigned *, int, FILE *, int, char **, char *, int); int auxil(char *, char *); /* hunt7.c */ int findline(char *, char **, int, long); /* hunt8.c */ void runbib(const char *); int makefgrep(char *); int ckexist(const char *, const char *); FILE *iopen(const char *, const char *); /* hunt9.c */ void remote(const char *, const char *); /* inv2.c */ int newkeys(FILE *, FILE *, FILE *, int, FILE *, int *); char *trimnl(char *); /* inv3.c */ int getargs(char *, char **); /* inv5.c */ int recopy(FILE *, FILE *, FILE *, int); /* inv6.c */ void whash(FILE *, FILE *, FILE *, int, int, long *, int *); void putl(long, FILE *); long getl(FILE *); /* mkey2.c */ void dofile(FILE *, const char *); int outkey(char *, int, int); long grec(char *, FILE *); char *trimnl(char *); /* mkey3.c */ int common(char *); void cominit(void); int c_look(char *, int); /* refer2.c */ void doref(char *); int newline(const char *); void choices(char *); int control(int); /* refer4.c */ void output(const char *); void append(char *); void flout(void); char *trimnl(char *); /* refer5.c */ void putsig(int, char **, int, char *, char *, int); char *fpar(int, char **, char *, size_t, int, int, int); -void putkey(int, char **, int, char *); +void putkey(int, char **, int, const char *); void tokeytab(const char *, int); int keylet(char *, int); void mycpy(char *, const char *); void mycpy2(char *, const char *, int); void initadd(char *, const char *, const char *); char *artskp(char *); /* refer6.c */ void putref(int, char **); int tabs(char **, char *); const char *class(int, char **); int hastype(int, char **, int); char *caps(char *, char *); char *revauth(char *, char *); int last(const char *); /* refer7.c */ int chkdup(const char *); void dumpold(void); void recopy1(char *); void condense(int *, int, char *); int wswap(const void *, const void *); /* refer8.c */ char *input(char *, size_t); char *lookat(void); void addch(char *, int); /* shell.c */ void shell(int, int (*)(int, int), int (*)(int, int)); /* tick.c */ void tick(void); void tock(void); Index: projects/doctools/contrib/heirloom-doctools/refer/refer1.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/refer/refer1.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/refer/refer1.c (revision 307812) @@ -1,194 +1,195 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "refer1.c 1.5 05/06/02 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)refer1.c 1.3 (gritter) 10/22/05 */ #include #include #include #include +#include #include "refer..c" static void signals(void); static void intr(int); static void cleanup(void); int main(int argc,char **argv) /* process command-line arguments */ { char line[BUFSIZ], *s; int nodeflt = 0; in = stdin; fo = stdout; ftemp = stdout; signals(); while (argc > 1 && argv[1][0] == '-') { switch(argv[1][1]) { case 'e': endpush++; break; case 's': sort++; endpush = 1; if (argv[1][2]) keystr = argv[1]+2; break; case 'l': labels++; s = argv[1]+2; nmlen = atoi(s); while (*s) if (*s++ == ',') break; dtlen = atoi(s); break; case 'k': keywant = (argv[1][2] ? argv[1][2] : 'L'); labels++; break; case 'n': nodeflt = 1; break; case 'p': argc--; argv++; *search++ = argv[1]; if (search-rdata > NSERCH) err("too many -p options (%d)", NSERCH); break; case 'a': authrev = atoi(argv[1]+2); if (authrev<=0) authrev = 1000; break; case 'b': bare = (argv[1][2] == '1') ? 1 : 2; break; case 'c': smallcaps = argv[1]+2; break; case 'f': refnum = atoi(argv[1]+2) - 1; break; case 'B': biblio++; bare = 2; if (argv[1][2]) convert = argv[1]+2; break; case 'S': science++; labels = 1; break; case 'P': postpunct++; break; } argc--; argv++; } if (getenv("REFER") != NULL) *search++ = getenv("REFER"); else if (nodeflt == 0) *search++ = REFDIR "/papers/Ind"; if (sort && !labels) { snprintf(ofile, NTFILE, "/tmp/rj%db", (int)getpid()); ftemp = fopen(ofile, "w"); if (ftemp == NULL) { fprintf(stderr, "Can't open scratch file\n"); exit(1); } } if (endpush) { snprintf(tfile, NTFILE, "/tmp/rj%da", (int)getpid()); fo = fopen(tfile, "w"); if (fo == NULL) { fo = ftemp; fprintf(stderr, "Can't open scratch file"); } sep = 002; /* separate records without confusing sort..*/ } else fo = ftemp; do { if (argc > 1) { fclose(in); Iline = 0; in = fopen(Ifile = argv[1], "r"); argc--; argv++; if (in == NULL) { err("Can't read %s", Ifile); continue; } } while (input(line, sizeof(line))) { Iline++; if (biblio && *line == '\n') doref(line); else if (biblio && Iline == 1 && *line == '%') doref(line); - else if (!prefix(".[", line)) + else if (!prefix(line, ".[")) output(line); else doref(line); } } while (argc > 1); if (endpush && fo != NULL) dumpold(); output(""); if (sort && !labels) recopy1(ofile); clfgrep(); cleanup(); return 0; } static void signals(void) { if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, intr); signal(SIGHUP, intr); signal(SIGPIPE, intr); signal(SIGTERM, intr); } static void intr(int unused __unused) { signal(SIGINT, SIG_IGN); cleanup(); exit(1); } static void cleanup(void) { if (tfile[0]) unlink(tfile); if (gfile[0]) unlink(gfile); if (ofile[0]) unlink(ofile); if (hidenam[0]) unlink(hidenam); } Index: projects/doctools/contrib/heirloom-doctools/refer/refer2.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/refer/refer2.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/refer/refer2.c (revision 307812) @@ -1,215 +1,215 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "refer2.c 1.4 05/06/02 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)refer2.c 1.4 (gritter) 9/7/08 */ #include "refer..c" #include #include #include #include #define NFLD 30 #define TLEN PATH_MAX extern FILE *in; char one[ANSLEN]; int onelen = ANSLEN; static char dr [100] = ""; void doref(char *line1) { char buff[QLEN], dbuff[3*QLEN]; char answer[ANSLEN], temp[TLEN], line[BUFSIZ]; char *p, **sr, *flds[NFLD], *r; int nf, nr, query = 0, alph, digs; again: buff[0] = dbuff[0] = 0; if (biblio && Iline == 1 && line1[0] == '%') n_strcat(dbuff, line1, sizeof(dbuff)); while (input(line, sizeof(line))) { /* get query */ Iline++; - if (prefix(".]", line)) + if (prefix(line, ".]")) break; if (biblio && line[0] == '\n') break; if (biblio && line[0] == '%' && line[1] == *convert) break; if (control(line[0])) query = 1; n_strcat(query ? dbuff : buff, line, query ? sizeof(dbuff) : sizeof(buff)); if (strlen(buff) > QLEN) err("query too long (%d)", strlen(buff)); if (strlen(dbuff) > 3 * QLEN) err("record at line %d too long", Iline-1); } if (biblio && line[0] == '\n' && feof(in)) return; if (strcmp(buff, "$LIST$\n")==0) { assert (dbuff[0] == 0); dumpold(); return; } answer[0] = 0; for (p = buff; *p; p++) { if (isupper((int)*p)) *p |= 040; } alph = digs = 0; for (p = buff; *p; p++) { if (isalpha((int)*p)) alph++; else if (isdigit((int)*p)) digs++; else { *p = 0; if ((alph+digs < 3) || common(p-alph)) { r = p-alph; while (r < p) *r++ = ' '; } if (alph == 0 && digs > 0) { r = p-digs; if (digs != 4 || atoi(r)/100 != 19) { while (r < p) *r++ = ' '; } } *p = ' '; alph = digs = 0; } } one[0] = 0; if (buff[0]) { /* do not search if no query */ for (sr = rdata; sr < search; sr++) { temp[0] = 0; corout(buff, temp, "hunt", *sr, TLEN); assert(strlen(temp) < TLEN); if (strlen(temp)+strlen(answer) > BUFSIZ) err("Accumulated answers too large",0); n_strcat(answer, temp, sizeof(answer)); if (strlen(answer)>BUFSIZ) err("answer too long (%d)", strlen(answer)); if (newline(answer) > 0) break; } } assert(strlen(one) < ANSLEN); assert(strlen(answer) < ANSLEN); if (buff[0]) switch (newline(answer)) { case 0: fprintf(stderr, "No such paper: %s\n", buff); return; default: fprintf(stderr, "Too many hits: %s\n", trimnl(buff)); choices(answer); p = buff; while (*p != '\n') p++; *++p = 0; case 1: if (endpush) if ((nr = chkdup(answer))) { if (bare < 2) { nf = tabs(flds, one); nf += tabs(flds+nf, dbuff); assert(nf < NFLD); putsig(nf,flds,nr,line1,line,0); } return; } if (one[0] == 0) corout(answer, one, "deliv", dr, QLEN); break; } assert(strlen(buff) < QLEN); assert(strlen(one) < ANSLEN); nf = tabs(flds, one); nf += tabs(flds+nf, dbuff); assert(nf < NFLD); refnum++; if (sort) putkey(nf, flds, refnum, keystr); if (bare < 2) putsig(nf, flds, refnum, line1, line, 1); else flout(); putref(nf, flds); if (biblio && line[0] == '\n') goto again; if (biblio && line[0] == '%' && line[1] == *convert) fprintf(fo, "%s%c%s", convert+1, sep, line+3); } int newline(const char *s) { int k = 0, c; while ((c = *s++)) if (c == '\n') k++; return(k); } void choices(char *buff) { char ob[BUFSIZ], *p, *r, *q, *t; int nl; for (r = p = buff; *p; p++) { if (*p == '\n') { *p++ = 0; corout(r, ob, "deliv", dr, BUFSIZ); nl = 1; for (q = ob; *q; q++) { if (nl && (q[0]=='.'||q[0]=='%') && q[1]=='T') { q += 3; for (t = q; *t && *t != '\n'; t++) ; *t = 0; fprintf(stderr, "%.70s\n", q); q = 0; break; } nl = *q == '\n'; } if (q) fprintf(stderr, "??? at %s\n",r); r=p; } } } int control(int c) { if (c == '.') return(1); if (c == '%') return(1); return(0); } Index: projects/doctools/contrib/heirloom-doctools/refer/refer5.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/refer/refer5.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/refer/refer5.c (revision 307812) @@ -1,360 +1,360 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "refer5.c 1.5 05/06/02 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)refer5.c 1.3 (gritter) 10/22/05 */ #include #include #include #include "refer..c" #define SAME 0 #define NFLAB 3000 /* number of bytes to record all labels */ #define NLABC 1000 /* max number of labels */ static char sig[MXSIG]; static char bflab[NFLAB]; static char *labtab[NLABC]; static char *lbp = bflab; static char labc[NLABC]; static char stbuff[50]; static int prevsig; void putsig (int nf, char **flds, int nref, char *nstline, char *endline, int toindex) /* choose signal style */ { char t[100], t1[MXSIG], t2[100], format[10], *sd, *stline; int addon = 0, another = 0; static FILE *fhide = 0; if (labels) { if (nf == 0) /* old */ snprintf(t, sizeof(t), "%s%c", labtab[nref], labc[nref]); else { *t = 0; if (keywant) fpar(nf, flds, t, sizeof(t), keywant, 1, 0); if (science && t[0] == 0) { if (fpar(nf, flds, t, sizeof(t), 'A', 1, 0) != 0) { if (fpar(nf, flds, t2, sizeof(t2), 'D', 1, 0) != 0) { n_strcat(t, ", ", sizeof(t)); n_strcat(t, t2, sizeof(t)); } } } else if (t[0] == 0) { if (nmlen > 0) { snprintf(format, sizeof(format), "%%.%ds%%s", nmlen); } else { snprintf(format, sizeof(format), "%%s%%s"); } /* format is %s%s for default labels */ /* or %.3s%s eg if wanted */ if (fpar(nf, flds, t2, sizeof(t2), 'D', 1, 0)) { sd = t2; if (dtlen > 0) { int n = strlen(sd) - dtlen; if (n > 0) sd += n; } } else { sd = ""; } t1[0] = 0; fpar(nf, flds, t1, sizeof(t1), 'A', 1, 0); snprintf(t, sizeof(t), format, t1, sd); } if (keywant) { addon = 0; for (sd = t; *sd; sd++) ; if (*--sd == '-') { addon = 1; *sd = 0; } } if ((!keywant || addon) && !science) { addch(t, keylet(t, nref)); } else { tokeytab (t,nref); } } } else { if (sort) snprintf(t, sizeof(t), "%c%d%c", FLAG, nref, FLAG); else snprintf(t, sizeof(t), "%d", nref); } - another = (sd = lookat()) ? prefix(".[", sd) : 0; + another = (sd = lookat()) ? prefix(sd, ".[") : 0; if (another && (strcmp(".[\n", sd) != SAME)) fprintf(stderr, "File %s line %d: punctuation ignored from: %s", Ifile, Iline, sd); if ((strlen(sig) + strlen(t)) > MXSIG) err("sig overflow (%d)", MXSIG); n_strcat(sig, t, sizeof(sig)); #if EBUG fprintf(stderr, "sig is now %s leng %d\n",sig,strlen(sig)); #endif trimnl(nstline); trimnl(endline); stline = stbuff; if (prevsig == 0) { n_strcpy (stline, nstline, sizeof(stbuff)); prevsig=1; } if (stline[2] || endline[2]) { stline += 2; endline += 2; } else { stline = "\\*([."; endline = "\\*(.]"; } if (science) { stline = " ("; endline = ")"; } if (bare == 0) { if (!another) { snprintf(t1, sizeof(t1), "%s%s%s\n", stline, sig, endline); if (strlen(t1) > MXSIG) err("t1 overflow (%d)", MXSIG); append(t1); flout(); sig[0] = 0; prevsig = 0; if (fo == fhide) { int ch; fclose(fhide); fhide = fopen(hidenam, "r"); fo = ftemp; while ((ch = getc(fhide)) != EOF) putc(ch, fo); fclose(fhide); unlink(hidenam); } } else { if (labels) { n_strcat(sig, ",\\|", sizeof(sig)); } else { /* * Seperate reference numbers with AFLAG * for later sorting and condensing. */ t1[0] = AFLAG; t1[1] = '\0'; n_strcat(sig, t1, sizeof(sig)); } if (fo == ftemp) { /* hide if need be */ snprintf(hidenam, NTFILE, "/tmp/rj%dc", (int)getpid()); #if EBUG fprintf(stderr, "hiding in %s\n", hidenam); #endif fhide = fopen(hidenam, "w"); if (fhide == NULL) err("Can't get scratch file %s", hidenam); fo = fhide; } } } if (bare < 2) if (nf > 0 && toindex) fprintf(fo,".ds [F %s%c",t,sep); if (bare > 0) flout(); #if EBUG fprintf(stderr, "sig is now %s\n",sig); #endif } char * fpar (int nf, char **flds, char *out, size_t outsiz __unused, int c, int seq, int prepend) { char *p, *s; int i, fnd = 0; for(i = 0; i < nf; i++) if (flds[i][1] == c && ++fnd >= seq) { /* for titles use first word otherwise last */ if (c == 'T' || c == 'J') { p = flds[i]+3; - if (prefix("A ", p)) + if (prefix(p, "A ")) p += 2; - if (prefix("An ", p)) + if (prefix(p, "An ")) p += 3; - if (prefix("The ", p)) + if (prefix(p, "The ")) p += 4; mycpy2(out, p, 20); return(out); } /* if its not 'L' then use just the last word */ s = p = flds[i]+2; if (c != 'L') { for(; *p; p++); while (p > s && *p != ' ') p--; } /* special wart for authors */ if (c == 'A' && (p[-1] == ',' || p[1] =='(')) { p--; while (p > s && *p != ' ') p--; mycpy(out, p+1); } else n_strcpy(out, p+1, outsiz); if (c == 'A' && prepend) initadd(out, flds[i]+2, p); return(out); } return(0); } void -putkey(int nf, char **flds, int nref, char *_keystr) +putkey(int nf, char **flds, int nref, const char *_keystr) { char t1[50], *sf; int ctype, i, count; fprintf(fo, ".\\\""); if (nf <= 0) fprintf(fo, "%s%c%c", labtab[nref], labc[nref], sep); else { while ((ctype = *_keystr++)) { count = atoi(_keystr); if (*_keystr=='+') count=999; if (count <= 0) count = 1; for(i = 1; i <= count; i++) { sf = fpar(nf, flds, t1, sizeof(t1), ctype, i, 1); if (sf == 0) break; sf = artskp(sf); fprintf(fo, "%s%c", sf, '-'); } } fprintf(fo, "%c%d%c%c", FLAG, nref, FLAG, sep); } } void tokeytab (const char *t, int nref) { n_strcpy(labtab[nref]=lbp, t, sizeof(bflab) - (lbp - bflab)); while (*lbp++) ; } int keylet(char *t, int nref) { int i; int x = 'a' - 1; for(i = 1; i < nref; i++) { if (strcmp(labtab[i], t) == 0) x = labc[i]; } tokeytab (t, nref); if (lbp-bflab > NFLAB) err("bflab overflow (%d)", NFLAB); if (nref > NLABC) err("nref in labc overflow (%d)", NLABC); #if EBUG fprintf(stderr, "lbp up to %d of %d\n", lbp-bflab, NFLAB); #endif return(labc[nref] = x+1); } void mycpy(char *s, const char *t) { while (*t && *t != ',' && *t != ' ') *s++ = *t++; *s = 0; } void mycpy2(char *s, const char *t, int n) { int c; while (n-- && (c= *t++) > 0) { if (c == ' ') c = '-'; *s++ = c; } *s = 0; } void initadd(char *to, const char *from, const char *stop) { int c, nalph = 1; while (*to) to++; while (from < stop) { c = *from++; if (!isalpha(c)) { if (nalph) *to++ = '.'; nalph = 0; continue; } if (nalph++ == 0) *to++ = c; } *to = 0; } static char *articles[] = { "the ", "an ", "a ", 0 }; char * artskp(char *s) /* skips over initial "a ", "an ", "the " in s */ { char **p, *r1, *r2; for (p = articles; *p; p++) { r2 = s; for (r1 = *p; ((*r1 ^ *r2) & ~040 ) == 0; r1++) r2++; if (*r1 == 0 && *r2 != 0) return(r2); } return(s); } Index: projects/doctools/contrib/heirloom-doctools/tbl/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/tbl/Makefile.mk (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/tbl/Makefile.mk (revision 307812) @@ -1,45 +1,45 @@ OBJ = t0.o t1.o t2.o t3.o t4.o t5.o t6.o t7.o t8.o t9.o tb.o tc.o te.o \ tf.o tg.o ti.o tm.o ts.o tt.o tu.o tv.o version.o -FLAGS = -DMACDIR='"$(MACDIR)"' +FLAGS = -DMACDIR='"$(MACDIR)"' -I../include .c.o: $(CC) $(CFLAGS) $(WARN) $(FLAGS) $(CPPFLAGS) -c $< all: tbl tbl: $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o tbl install: $(INSTALL) -c tbl $(ROOT)$(BINDIR)/tbl $(STRIP) $(ROOT)$(BINDIR)/tbl $(INSTALL) -c -m 644 tbl.1 $(ROOT)$(MANDIR)/man1/tbl.1 clean: rm -f $(OBJ) tbl core log *~ mrproper: clean t..o: t..c t0.o: t0.c t..c t1.o: t1.c t..c t2.o: t2.c t..c t3.o: t3.c t..c t4.o: t4.c t..c t5.o: t5.c t..c t6.o: t6.c t..c t7.o: t7.c t..c t8.o: t8.c t..c t9.o: t9.c t..c tb.o: tb.c t..c tc.o: tc.c t..c te.o: te.c t..c tf.o: tf.c t..c tg.o: tg.c t..c ti.o: ti.c t..c tm.o: tm.c t..c ts.o: ts.c tt.o: tt.c t..c tu.o: tu.c t..c tv.o: tv.c t..c Index: projects/doctools/contrib/heirloom-doctools/tbl/t..c =================================================================== --- projects/doctools/contrib/heirloom-doctools/tbl/t..c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/tbl/t..c (revision 307812) @@ -1,224 +1,214 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "t..c 1.4 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)t..c 1.19 (gritter) 9/11/06 */ /* t..c : external declarations */ # include # include # include +# include "global.h" -# if defined (__GLIBC__) && defined (_IO_getc_unlocked) -# undef getc -# define getc(f) _IO_getc_unlocked(f) -# endif - # define MAXCHS 2000 # define MAXSTR 1024 # define MAXRPT 100 # define CLLEN 100 # define SHORTLINE 4 # define BIGBUF 8192 extern int MAXLIN; extern int MAXCOL; extern int MAXHEAD; extern int nlin, ncol, iline, nclin, nslin; extern int **style; extern int **ctop; extern char ***font; extern char ***csize; extern char ***vsize; extern char **cll; extern int *xcol; extern int *stynum; extern int F1, F2; extern int **lefline; extern int *fullbot; extern char **instead; extern int expflg; extern int xcolflg; extern int ctrflg; extern int evenflg; extern int *evenup; extern int boxflg; extern int dboxflg; extern int decimalpoint; extern int linsize; extern int tab; extern int pr1403; extern int graphics; extern int Graphics; extern int linsize, delim1, delim2; extern int allflg; extern int textflg; extern int left1flg; extern int rightl; struct colstr {char *col, *rcol;}; extern struct colstr **table; extern char *cspace, *cstore, *cbase; extern char *exstore, *exlim; extern int *sep; extern int *used, *lused, *rused; extern int *linestop; extern char *leftover; extern char *last; extern const char *ifile; extern int *topat; extern intptr_t texname; extern int texct; extern int texct2; extern char texstr[]; extern int linstart; extern int nokeep; extern const char *progname; extern int utf8; extern int tlp; extern int nflm; extern FILE *tabin, *tabout; # define CRIGHT 80 # define CLEFT 40 # define CMID 60 # define S1 31 # define S2 32 # define TMP 38 # define SF 35 # define SL 34 # define LSIZE 33 # define SIND 37 # define SVS 36 /* this refers to the relative position of lines */ # define LEFT 1 # define RIGHT 2 # define THRU 3 # define TOP 1 # define BOT 2 /* t1.c */ int tbl(int, char *[]); void setinp(int, char **); int swapin(void); /* t2.c */ void tableput(void); /* t3.c */ int getcomm(void); void backrest(char *); /* t4.c */ int getspec(void); int readspec(void); /* t5.c */ int gettbl(void); int nodata(int); int oneh(int); int permute(void); int vspand(int, int, int); int vspen(char *); /* t6.c */ void maktab(void); void wide(char *, char *, char *); int filler(char *); /* t7.c */ int runout(void); void runtabs(int, int); int ifline(char *); void need(void); void deftail(void); /* t8.c */ void putline(int, int); void puttext(char *, char *, char *); void funnies(int, int); void putfont(const char *); void putsize(const char *); /* t9.c */ int yetmore(void); int domore(char *); /* tb.c */ void checkuse(void); int real(char *); char *chspace(void); void updspace(char *, char *, int); struct colstr *alocv(int); void release(void); /* tc.c */ int choochar(void); int point(int); /* te.c */ int error(const char *); char *errmsg(int); char *gets1(char **, char **, size_t *); void un1getc(int); int get1char(void); /* tf.c */ void savefill(void); void rstofill(void); void endoff(void); void ifdivert(void); void saveline(void); void restline(void); void cleanfc(void); void warnon(void); void warnoff(void); void svgraph(void); /* tg.c */ char *get_text(char *, int, int, char *, char *); void untext(void); char *nreg(char *, size_t, const char *, int); /* ti.c */ int interv(int, int); int interh(int, int); int up1(int); /* tm.c */ char *maknew(char *); int ineqn(char *, char *); /* ts.c */ -int match(const char *, const char *); -int prefix(const char *, const char *); int cprefix(const char *, const char *); int letter(int); -int numb(char *); -int digit(int); -int max(int, int); void tcopy(char *, char *); /* tt.c */ int ctype(int, int); -int min(int, int); int fspan(int, int); int lspan(int, int); int ctspan(int, int); void tohcol(int); int allh(int); int thish(int, int); /* tu.c */ void makeline(int, int, int); void fullwide(int, int); void drawline(int, int, int, int, int, int); void getstop(void); int left(int, int, int *); int lefdata(int, int); int next(int); int prev(int); /* tv.c */ void drawvert(int, int, int, int); int midbar(int, int); int midbcol(int, int); int barent(char *); Index: projects/doctools/contrib/heirloom-doctools/tbl/t1.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/tbl/t1.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/tbl/t1.c (revision 307812) @@ -1,194 +1,190 @@ /* Co/pyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "t1.c 1.9 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)t1.c 1.12 (gritter) 9/8/06 */ /* t1.c: main control and input switching */ # # include "t..c" #include #include #include #include #include # ifdef gcos /* required by GCOS because file is passed to "tbl" by troff preprocessor */ # define _f1 _f extern FILE *_f[]; # endif # ifndef gcos # define MACROS "/usr/doctools/tmac/tmac.s" # define MACROSS MACDIR "/s" # define PYMACS "/usr/doctools/tmac/tmac.m" # define PYMACSS MACDIR "/m" # define MEMACSS MACDIR "/e" # endif # ifdef gcos # define MACROS "cc/troff/smac" # define PYMACS "cc/troff/mmac" # endif # define ever (;;) -#ifndef __unused -#define __unused __attribute__((unused)) -#endif - # ifndef gcos static void badsig(int); # endif int main(int argc, char *argv[]) { progname = basename(argv[0]); # ifndef gcos signal(SIGPIPE, badsig); # endif # ifdef gcos if(!intss()) tabout = fopen("qq", "w"); /* default media code is type 5 */ # endif exit(tbl(argc,argv)); } int tbl(int argc, char *argv[]) { char *line = NULL; size_t linesize = 0; /* required by GCOS because "stdout" is set by troff preprocessor */ tabin=stdin; tabout=stdout; setinp(argc,argv); while (gets1(&line, &line, &linesize)) { fprintf(tabout, "%s\n",line); if (cprefix("TS", line)) tableput(); } fclose(tabin); free(line); return(0); } static int sargc; static char **sargv; void setinp(int argc, char **argv) { sargc = argc; sargv = argv; sargc--; sargv++; if (sargc>0) swapin(); if (pr1403 || utf8 || tlp) nflm = 1; } int swapin(void) { char *optarg; while (sargc>0 && **sargv=='-') /* Mem fault if no test on sargc */ { if (sargc<=0) return(0); - if (match("-me", *sargv)) + if (strcmp("-me", *sargv) == 0) { *sargv = MEMACSS; break; } - if (match("-ms", *sargv)) + if (strcmp("-ms", *sargv) == 0) { *sargv = MACROSS; break; } - if (match("-mm", *sargv)) + if (strcmp("-mm", *sargv) == 0) { *sargv = PYMACSS; break; } if ((*sargv)[1] == 'T') { optarg = *sargv + 2; if (!*optarg) { sargc--; sargv++; if (!sargc || **sargv == '-') { fprintf(stderr, "%s: Argument expected" " after option -T\n", progname); exit(1); } optarg = *sargv; } if (*optarg == 'X' && !optarg[1]) { pr1403=1; } else if (!strcmp(optarg, "lp")) { tlp = 1; utf8 = 0; Graphics = 0; } else if (!strcmp(optarg, "locale")) { Graphics = 0; if (strstr(setlocale(LC_ALL, ""), "UTF-8")) { utf8 = 1; tlp = 0; } else { tlp = 1; } } } - else if (match("-g", *sargv)) + else if (strcmp("-g", *sargv) == 0) { Graphics=1; utf8 = 0; tlp = 0; } else { (void) fprintf(stderr, "%s: Invalid option " "(%s).\n", progname, *sargv); (void) fprintf(stderr, "Usage: %s [ -me ] " "[ -mm ] [ -ms ] [ filename ... ]\n", progname); exit(1); } sargc--; sargv++; } if (sargc<=0) return(0); # ifndef gcos /* file closing is done by GCOS troff preprocessor */ if (tabin!=stdin) fclose(tabin); # endif tabin = fopen(ifile= *sargv, "r"); iline=1; # ifndef gcos /* file names are all put into f. by the GCOS troff preprocessor */ fprintf(tabout, ".ds f. %s\n",ifile); # endif fprintf(tabout, ".lf 1 %s\n", ifile); if (tabin==NULL) return error("Can't open file"); sargc--; sargv++; return(1); } # ifndef gcos void badsig(int unused __unused) { signal(SIGPIPE, SIG_IGN); exit(0); } # endif Index: projects/doctools/contrib/heirloom-doctools/tbl/t3.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/tbl/t3.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/tbl/t3.c (revision 307812) @@ -1,132 +1,134 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "t3.c 1.5 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)t3.c 1.12 (gritter) 9/11/06 */ /* t3.c: interpret commands affecting whole table */ # include "t..c" # include # include +# include "global.h" + static struct optstr {const char *optnam; int *optadd;} options [] = { { "expand", &expflg }, { "EXPAND", &expflg }, { "center", &ctrflg }, { "CENTER", &ctrflg }, { "box", &boxflg }, { "BOX", &boxflg }, { "allbox", &allflg }, { "ALLBOX", &allflg }, { "doublebox", &dboxflg }, { "DOUBLEBOX", &dboxflg }, { "frame", &boxflg }, { "FRAME", &boxflg }, { "doubleframe", &dboxflg }, { "DOUBLEFRAME", &dboxflg }, { "tab", &tab }, { "TAB", &tab }, { "linesize", &linsize }, { "LINESIZE", &linsize }, { "decimalpoint", &decimalpoint }, { "DECIMALPOINT", &decimalpoint }, { "delim", &delim1 }, { "DELIM", &delim1 }, { "graphics", &graphics }, { "GRAPICS", &graphics }, { "nokeep", &nokeep }, { "NOKEEP", &nokeep }, { "left", NULL }, { NULL, NULL } }; int getcomm(void) { char *line = NULL, *cp, nb[25], *t; size_t linesize = 0; struct optstr *lp; int c, ci, found; for(lp= options; lp->optadd; lp++) *(lp->optadd) = 0; texname = texstr[texct=0]; texct2 = -1; tab = '\t'; decimalpoint = '.'; if (pr1403) graphics = 0; else graphics = Graphics; printf(".nr %d \\n(.s\n", LSIZE); gets1(&line, &line, &linesize); /* see if this is a command line */ if (strchr(line,';') == NULL) { backrest(line); free(line); return 0; } for(cp=line; (c = *cp) != ';'; cp++) { if (!letter(c)) continue; found=0; for(lp= options; lp->optnam; lp++) { - if (prefix(lp->optnam, cp)) { + if (prefix(cp, lp->optnam)) { cp += strlen(lp->optnam); if (letter(*cp)) return error("Misspelled global option"); while (*cp==' ')cp++; t=nb; if ( *cp == '(') while ((ci= *++cp) != ')') *t++ = ci; else cp--; *t++ = 0; *t=0; if (!lp->optadd) goto found; *(lp->optadd) = 1; if (lp->optadd == &tab || lp->optadd == &decimalpoint) { if (nb[0]) *(lp->optadd) = nb[0]; } if (lp->optadd == &linsize) printf(".nr %d %s\n", LSIZE, nb); if (lp->optadd == &delim1) { delim1 = nb[0]; delim2 = nb[1]; } found: found=1; break; } } if (!found) return error("Illegal option"); } cp++; backrest(cp); free(line); return 0; } void backrest(char *cp) { char *s; for(s=cp; *s; s++); un1getc('\n'); while (s>cp) un1getc(*--s); } Index: projects/doctools/contrib/heirloom-doctools/tbl/t4.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/tbl/t4.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/tbl/t4.c (revision 307812) @@ -1,473 +1,476 @@ /* * Copyright 1983-2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* from OpenSolaris "t4.c 1.10 05/06/02 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * Portions Copyright (c) 2015 Carsten Kunze * * Sccsid @(#)t4.c 1.7 (gritter) 9/8/06 */ /* t4.c: read table specification */ # include "t..c" # include # include +# include +# include "global.h" + static int oncol; static int morecols(int); static int moreheads(int); static void initspec(int); static void inithead(int, int); int getspec(void) { int i; moreheads(0); morecols(0); initspec(0); nclin=ncol=0; oncol =0; left1flg=rightl=0; if (readspec()) return -1; fprintf(tabout, ".rm"); for(i=0; i0) {ncol++; rightl++;}; if(sawchar) nclin++; if (nclin>=MAXHEAD && !moreheads(nclin)) return error("too many lines in specification"); icol=0; if (ncol==0 || nclin==0) return error("no specification"); if (c== '.') { while ((c=get1char()) && c != '\n') if (c != ' ' && c != '\t') return error( "dot not last character on format line"); /* fix up sep - default is 3 except at edge */ for(icol=0; icol=MAXCOL && !morecols(icol)) return error("too many columns in table"); sawchar=1; continue; case 'b': case 'i': c += 'A'-'a'; /* FALLTHRU */ case 'B': case 'I': if (sawchar == 0) continue; if (icol==0) continue; snp=font[nclin][icol-1]; snp[0]= (c=='I' ? '2' : '3'); snp[1]=0; continue; case 't': case 'T': if (sawchar == 0) { continue; } if (icol>0) ctop[nclin][icol-1] = 1; continue; case 'd': case 'D': if (sawchar == 0) continue; if (icol>0) ctop[nclin][icol-1] = -1; continue; case 'f': case 'F': if (sawchar == 0) continue; if (icol==0) continue; snp=font[nclin][icol-1]; snp[0]=snp[1]=stopc=0; for(i=0; i= '0' && c<= '9') break; } if (stopc) if (get1char()!=stopc) return error("Nonterminated font name"); continue; case 'P': case 'p': if (sawchar == 0) continue; if (icol<=0) continue; temp = snp = csize[nclin][icol-1]; while ((c = get1char())) { if (c== ' ' || c== tab || c=='\n') break; if (c=='-' || c == '+') if (snp>temp) break; else *snp++=c; else - if (digit(c)) + if (isdigit(c)) *snp++ = c; else break; if (snp-temp>20) return error("point size too large"); } *snp = 0; if (atoi(temp)>36) return error("point size unreasonable"); un1getc (c); continue; case 'V': case 'v': if (sawchar == 0) continue; if (icol<=0) continue; temp = snp = vsize[nclin][icol-1]; while ((c = get1char())) { if (c== ' ' || c== tab || c=='\n') break; if (c=='-' || c == '+') if (snp>temp) break; else *snp++=c; else - if (digit(c)) + if (isdigit(c)) *snp++ = c; else break; if (snp-temp>20) return error( "vertical spacing value too large"); } *snp=0; un1getc(c); continue; case 'w': case 'W': if (sawchar == 0) { /* * This should be an error case. * However, for the backward-compatibility, * treat as if 'c' was specified. */ style[nclin][icol] = 'c'; icol++; if (icol >= MAXCOL && !morecols(icol)) { return error("too many columns in table"); } sawchar = 1; } snp = cll [icol-1]; /* Dale Smith didn't like this check * possible to have two text blocks * of different widths now .... if (*snp) { fprintf(tabout, "Ignored second width specification"); continue; } * end commented out code ... */ stopc=0; while ((c = get1char())) { if (snp==cll[icol-1] && c==' ') continue; if (snp==cll[icol-1] && c=='(') { stopc = ')'; continue; } if ( !stopc && (c>'9' || c< '0')) break; if (stopc && c== stopc) break; if (snp-cll[icol-1]>CLLEN) return error ("column width too long"); *snp++ =c; } *snp=0; if (!stopc) un1getc(c); continue; case 'x': case 'X': if (!sawchar || icol < 1) break; xcol[icol-1] = 1; xcolflg++; expflg = 0; break; case 'e': case 'E': if (sawchar == 0) continue; if (icol<1) continue; evenup[icol-1]=1; evenflg=1; continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': sn[0] = c; snp=sn+1; - while (digit(*snp++ = c = get1char())) + while (isdigit(*snp++ = c = get1char())) ; un1getc(c); - sep[icol-1] = max(sep[icol-1], numb(sn)); + sep[icol-1] = max(sep[icol-1], strtol(sn, NULL, 10)); continue; case '|': lefline[nclin][icol]++; if (icol==0) left1flg=1; continue; } } return error("EOF reading table specification"); } static int morecols(int n) { int i, j, inc = 10, maxcol; void *vp; if (n < MAXCOL) return(1); while ((maxcol = MAXCOL + inc) < n) inc *= 2; for (i=0; i # include # include "t..c" # include +# include static int morelines(int); int gettbl(void) { int icol, ch; char *ocbase; size_t linesize = MAXSTR; morelines(0); if (!(cbase = cstore = cspace = chspace())) return -1; textflg=0; for (nlin=nslin=0; ocbase=cbase, gets1(&cbase, &cstore, &linesize); nlin++) { cspace += cbase - ocbase; stynum[nlin]=nslin; if (cprefix("TE", cstore)) { leftover=0; break; } if (cprefix("TC", cstore) || cprefix("T&", cstore)) { if (readspec()) return -1; nslin++; } if (nlin>=MAXLIN && !morelines(nlin)) { leftover=cstore; break; } table[nlin] = NULL; fullbot[nlin]=0; if (cstore[0] == '.' && !isdigit((unsigned char)cstore[1])) { instead[nlin] = cstore; while (*cstore++); continue; } else instead[nlin] = 0; if (nodata(nlin)) { if ((ch = oneh(nlin))) fullbot[nlin]= ch; nlin++; nslin++; instead[nlin]=(char *)0; fullbot[nlin]=0; } if ((table[nlin] = alocv((ncol+2)*sizeof(table[0][0]))) == (struct colstr *)-1) return -1; if (cstore[1]==0) switch(cstore[0]) { case '_': fullbot[nlin]= '-'; continue; case '=': fullbot[nlin]= '='; continue; } stynum[nlin] = nslin; nslin = min(nslin+1, nclin-1); for (icol = 0; icol MAXCHS) if (!(cbase = cstore = cspace = chspace())) return -1; } last = cstore; if (permute()) return -1; if (textflg) untext(); return 0; } int nodata(int il) { int c; for (c=0; c=nlin)return(0); if (instead[ir]) return(0); if (ifform==0 && ctype(ir,ij)=='^') return(1); if (table[ir]==0) return(0); if (table[ir][ij].rcol!=0) return(0); if (fullbot[ir]) return(0); return(vspen(table[ir][ij].col)); } -int + +int vspen(char *s) { if (s==0) return(0); if (!point((intptr_t)s)) return(0); - return(match(s, SPAN)); + return(strcmp(s, SPAN) == 0); } + static int morelines(int n) { int inc = 200, maxlin; void *vp; if (n>MAXLIN) return(1); while ((maxlin = MAXLIN + inc) < n) inc *= 2; if ((vp = realloc(table, maxlin * sizeof *table)) == NULL) return(0); table = vp; if ((vp = realloc(stynum, (maxlin + 1) * sizeof *stynum)) == NULL) return(0); stynum = vp; if ((vp = realloc(fullbot, maxlin * sizeof *fullbot)) == NULL) return(0); fullbot = vp; memset(&fullbot[MAXLIN], 0, inc * sizeof *fullbot); if ((vp = realloc(instead, maxlin * sizeof *instead)) == NULL) return(0); instead = vp; memset(&instead[MAXLIN], 0, inc * sizeof *instead); if ((vp = realloc(linestop, maxlin * sizeof *linestop)) == NULL) return(0); linestop = vp; MAXLIN = maxlin; return(1); } Index: projects/doctools/contrib/heirloom-doctools/tbl/tg.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/tbl/tg.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/tbl/tg.c (revision 307812) @@ -1,127 +1,128 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "tg.c 1.6 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)tg.c 1.10 (gritter) 10/2/07 */ /* tg.c: process included text blocks */ # include "t..c" # include # include +# include /* get_text was originally gettext and was renamed */ char * get_text(char *sp, int ilin, int icol, char *fn, char *sz) { /* get a section of text */ char *line = NULL; size_t linesize = 0; char *oname; const char *vs; if (texname==0) texct2 = texname = 300; if (texct2>0 && point(texct2)) { error("Too many text block diversions"); return (char *)-1; } if (textflg==0) { fprintf(tabout, ".nr %d \\n(.lu\n", SL); /* remember old line length */ textflg=1; } fprintf(tabout, ".eo\n"); fprintf(tabout, ".am %02d 00\n", icol+80); fprintf(tabout, ".br\n"); if (texct2 < 0) fprintf(tabout, ".di %c+\n", (int)texname); else fprintf(tabout, ".do di %d+\n", texct2); rstofill(); if (fn && *fn) fprintf(tabout, ".nr %d \\n(.f\n.ft %s\n", S1, fn); fprintf(tabout, ".ft \\n(.f\n"); /* protect font */ vs = vsize[stynum[ilin]][icol]; if ((sz && *sz) || (vs && *vs)) { fprintf(tabout, ".nr %d \\n(.v\n", S2); if (vs==0 || *vs==0) vs= "\\n(.s+2"; if (sz && *sz) fprintf(tabout, ".ps %s\n",sz); fprintf(tabout, ".vs %s\n",vs); fprintf(tabout, ".if \\n(%du>\\n(.vu .sp \\n(%du-\\n(.vu\n", S2,S2); } if (cll[icol][0]) fprintf(tabout, ".ll %sn\n", cll[icol]); else fprintf(tabout, ".ll \\n(%du*%du/%du\n",SL,ctspan(ilin,icol),ncol+1); fprintf(tabout,".if \\n(.l<\\n(%d .ll \\n(%du\n", icol+CRIGHT, icol+CRIGHT); if (ctype(ilin,icol)=='a') fprintf(tabout, ".ll -2n\n"); fprintf(tabout, ".in 0\n"); while (gets1(&line, &line, &linesize)) { if (line[0]=='T' && line[1]=='}' && line[2]== tab) break; - if (match("T}", line)) break; + if (strcmp("T}", line) == 0) break; fprintf(tabout, "%s\n", line); } if (fn && *fn) fprintf(tabout, ".ft \\n(%d\n", S1); if (sz && *sz) fprintf(tabout, ".br\n.ps\n.vs\n"); fprintf(tabout, ".br\n"); fprintf(tabout, ".di\n"); if (texct2 < 0) { fprintf(tabout, ".nr %c| \\n(dn\n", (int)texname); fprintf(tabout, ".nr %c- \\n(dl\n", (int)texname); } else { fprintf(tabout, ".do nr %d| \\n(dn\n", texct2); fprintf(tabout, ".do nr %d- \\n(dl\n", texct2); } fprintf(tabout, ".00\n"); fprintf(tabout, ".ec \\\n"); /* copy remainder of line */ if (line[2]) tcopy (sp, line+3); else *sp=0; oname = (char *)texname; if (texct2 < 0) texname = texstr[++texct]; else texname = ++texct2; free(line); return oname; } void untext(void) { rstofill(); fprintf(tabout, ".nf\n"); fprintf(tabout, ".ll \\n(%du\n", SL); } char * nreg(char *space, size_t siz, const char *_n, int c) { int n = (intptr_t)_n; if (n < 128) snprintf(space, siz, "\\n(%c%c", n, c); else snprintf(space, siz, "\\n[%d%c]", n, c); return(space); } Index: projects/doctools/contrib/heirloom-doctools/tbl/tm.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/tbl/tm.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/tbl/tm.c (revision 307812) @@ -1,91 +1,91 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "tm.c 1.5 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)tm.c 1.5 (gritter) 9/15/05 */ /* tm.c: split numerical fields */ # include "t..c" char * maknew(char *str) { /* make two numerical fields */ int c; char *dpoint, *p, *q, *ba; p = str; for (ba= 0; (c = *str); str++) if (c == '\\' && *(str+1)== '&') ba=str; str=p; if (ba==0) { for (dpoint=0; *str; str++) { if ((*str&0377)==decimalpoint && !ineqn(str,p) && - ((str>p && digit(*(str-1))) || - digit(*(str+1)))) + ((str>p && isdigit(*(str-1))) || + isdigit(*(str+1)))) dpoint=str; } if (dpoint==0) for(; str>p; str--) { - if (digit( * (str-1) ) && !ineqn(str, p)) + if (isdigit( * (str-1) ) && !ineqn(str, p)) break; } if (!dpoint && p==str) /* not numerical, don't split */ return NULL; if (dpoint) str=dpoint; } else str = ba; p =str; if (exstore ==0 || exstore >exlim) { if (!(exstore = chspace())) return (char *)-1; exlim= exstore+MAXCHS; } q = exstore; ba = exstore + MAXSTR; do { if (exstore > ba) { error("numeric field too big"); return (char *)-1; } } while ((*exstore++ = *str++)); *p = 0; return(q); } int ineqn(char *s, char *p) { /* true if s is in a eqn within p */ int ineq = 0, c; while ((c = *p)) { if (s == p) return(ineq); p++; if ((ineq == 0) && (c == delim1)) ineq = 1; else if ((ineq == 1) && (c == delim2)) ineq = 0; } return(0); } Index: projects/doctools/contrib/heirloom-doctools/tbl/ts.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/tbl/ts.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/tbl/ts.c (revision 307812) @@ -1,91 +1,55 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "ts.c 1.3 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)ts.c 1.3 (gritter) 7/23/05 */ #include "t..c" /* ts.c: minor string processing subroutines */ -int -match(const char *s1, const char *s2) -{ - while (*s1 == *s2) - if (*s1++ == '\0') - return(1); - else - s2++; - return(0); -} -int -prefix(const char *small, const char *big) { - int c; - while ((c= *small++) == *big++) - if (c==0) return(1); - return(c==0); -} - /* returns: 1 for match, 0 else */ int cprefix(const char *ctl, const char *line) { char c; if (*line++ != '.') return 0; while (*line == ' ' || *line == '\t') line++; while ((c = *ctl++) == *line++) if (!c) return 1; return !c; } -int +int letter(int ch) - { +{ if (ch >= 'a' && ch <= 'z') return(1); if (ch >= 'A' && ch <= 'Z') return(1); return(0); - } -int -numb(char *str) - { - /* convert to integer */ - int k; - for (k=0; *str >= '0' && *str <= '9'; str++) - k = k*10 + *str - '0'; - return(k); - } -int -digit(int x) - { - return(x>= '0' && x<= '9'); - } -int -max(int a, int b) -{ -return( a>b ? a : b); } -void + +void tcopy(char *s, char *t) { while ((*s++ = *t++)); } Index: projects/doctools/contrib/heirloom-doctools/tbl/tt.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/tbl/tt.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/tbl/tt.c (revision 307812) @@ -1,117 +1,113 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. * All Rights Reserved. */ /* from OpenSolaris "tt.c 1.3 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)tt.c 1.3 (gritter) 7/23/05 */ /* tt.c: subroutines for drawing horizontal lines */ # include "t..c" # include int ctype(int il, int ic) { if (instead[il]) return(0); if (fullbot[il]) return(0); il = stynum[il]; return(style[il][ic]); } -int -min(int a, int b) -{ -return(arcol : pc->col); if (s==0 || (point((intptr_t)s) && *s==0)) return(1); if (vspen(s)) return(1); if ((t=barent( s))) return(t); return(0); } Index: projects/doctools/contrib/heirloom-doctools/troff/ext.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/ext.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/ext.h (revision 307812) @@ -1,604 +1,596 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "ext.h 1.10 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)ext.h 1.111 (gritter) 10/23/09 */ /* * Changes Copyright (c) 2014 Carsten Kunze */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ #include -#ifndef __unused -#define __unused __attribute__((unused)) -#endif - extern char **argp; extern char *chname; extern char *eibuf; extern char *ibufp; extern char *obufp; extern char *xbufp; extern char *xeibuf; extern char *cfname[NSO+1]; extern char devname[20]; extern char ibuf[IBUFSZ]; extern char **mfiles; extern char *nextf; extern char obuf[], *obufp; extern char *termtab, *fontfile; extern char xbuf[IBUFSZ]; extern filep apptr; extern filep ip; extern filep nextb; extern filep offset; extern filep roff; extern filep woff; #ifdef NROFF extern long lvmot; extern size_t *chtab; #else extern short *chtab; extern int html; #endif extern int *pnp; extern int *pstab; extern int app; extern int ascii; extern int bd; extern int *bdtab; extern int blmac; extern int lsmac; extern int glss; extern int lsn; extern int ccs; extern int charf; extern tchar **chartab; extern struct charout *charout; extern int charoutsz; extern int clonef; extern int copyf; extern int cs; extern int defaultpl; extern int defcf; extern int dfact; extern int dfactd; extern int diflg; extern int dilev; extern int donef; extern int donep; extern int dotT; extern int dpn; extern int dl; extern int ds; extern int ecs; extern int ejf; extern int em; extern int eqflg; extern int error; extern int esc; extern int eschar; extern int ev; extern int fc; extern char *fchartab; extern int flss; extern int fmtchar; extern int *fontlab; extern int gflag; extern int hflg; extern int ifi; extern int ifile; extern int ifl[NSO]; extern int iflg; extern int init; extern int lastkern; extern int lasttrack; extern int lead; extern int lg; extern int lgf; extern int macerr; extern int mb_cur_max; extern int mflg; extern int mfont; extern int minflg; extern int minspc; extern int mpts; extern int ndone; extern struct contab *newmn; extern int nflush; extern int nfo; extern int nfonts; extern int nform; extern int nhyp; extern int nlflg; extern int nmfi; extern int no_out; extern int nofeed; extern int nolt; extern int nonumb; extern int noscale; extern int npn; extern int npnflg; extern int nx; extern int oldbits; extern struct contab *oldmn; extern int *olt; extern int over; extern int padc; extern int padj; extern int pfont; extern int pfrom; extern pid_t pipeflg; extern int pl; extern int pnlist[]; extern int po1; extern int po; extern int ppts; extern int print; extern int ptid; extern int pto; extern int quiet; extern int ralss; extern int rargc; extern int raw; extern int rawwidth; extern long realpage; extern int res; extern int setwdf; extern int sfont; extern int smnt; extern int stdi; extern int stop; extern int sv; extern int tabch, ldrch; extern int tailflg; extern int tflg; extern int totout; extern int trap; extern int *trtab; extern int *trintab; extern int *trnttab; extern int tryglf; extern int tty; extern int ttyod; extern int Tflg; extern int ulfont; extern int vflag; extern int vpt; extern int wbfi; extern int widthp; extern int xflag; extern int xfont; extern int xpts; extern int no_out; extern int ejl; extern struct s *frame, *stk, *nxf; extern tchar **hyp; extern tchar *olinep; extern tchar *pbbuf; extern int pbsize; extern int pbp; extern int lastpbp; extern tchar ch; extern tchar nrbits; extern tchar *oline; extern size_t olinesz; extern struct widcache { /* width cache, indexed by character */ int fontpts; int rst; int rsb; int width; int track; char *evid; } *widcache; extern char *gchtab; extern struct d *d; extern struct d *dip; extern int initbdtab[]; #ifdef EUC #include extern int multi_locale; extern int csi_width[]; extern char mbbuf1[]; extern char *mbbuf1p; extern wchar_t twc; extern int (*wdbdg)(wchar_t, wchar_t, int); extern wchar_t *(*wddlm)(wchar_t, wchar_t, int); #endif /* EUC */ extern int **lhangtab; extern int **rhangtab; extern int **kernafter; extern int **kernbefore; extern int **ftrtab; extern char *lgmark; extern struct lgtab **lgtab; extern int ***lgrevtab; extern int spreadwarn; extern int spreadlimit; extern int lastrq; extern int noschr; extern int argdelim; extern int bol; extern int prdblesc; extern int gemu; extern int chomp; extern int chompend; /* n1.c */ extern void mainloop(void); extern int tryfile(const char *, char *, int); extern void catch(int); extern void kcatch(int); extern void init0(void); extern void init1(char); extern void init2(void); extern void cvtime(void); extern int ctoi(register char *); extern void mesg(int); extern void errprint(const char *, ...); -#define fdprintf xxfdprintf -extern void fdprintf(int, const char *, ...); extern char *roff_sprintf(char *, size_t, const char *, ...); extern int control(register int, register int); extern int getrq2(void); extern int getrq(int); extern tchar getch(void); extern void setxon(void); extern tchar getch0(void); extern void pushback(register tchar *); extern void cpushback(register const char *); extern tchar *growpbbuf(void); extern int nextfile(void); extern int popf(void); extern void flushi(void); extern int getach(void); extern int rgetach(void); extern void casenx(void); extern int getname(void); extern void caseso(void); extern void casepso(void); extern void caself(void); extern void casecf(void); extern void casesy(void); extern void getpn(register char *); extern void setrpt(void); extern void casedb(void); extern void casexflag(void); extern void casecp(void); extern void caserecursionlimit(void); extern void casechar(int); extern void casefchar(void); extern void caserchar(void); extern tchar setchar(tchar); extern tchar sfmask(tchar); extern int issame(tchar, tchar); /* n2.c */ extern int pchar(register tchar); extern void pchar1(register tchar); extern void outascii(tchar); extern void oputs(register const char *); extern void flusho(void); extern void caseoutput(void); extern void done(int); extern void done1(int); extern void done2(int); extern void done3(int); extern void edone(int); extern void casepi(void); /* n3.c */ extern void *growcontab(void); extern void *growblist(void); extern void caseig(void); extern void casern(void); extern void maddhash(register struct contab *); extern void munhash(register struct contab *); extern filep finds(register int, int, int); extern void caserm(void); extern void caseas(void); extern void caseds(void); extern void caseam(void); extern void casede(void); extern struct contab *findmn(register int); extern struct contab *findmx(register int); extern int skip(int); extern int copyb(void); extern void copys(void); extern filep alloc(void); extern void ffree(filep); extern void wbt(tchar); extern void wbf(register tchar); extern void wbfl(void); extern tchar rbf(void); extern tchar rbf0(register filep); extern filep incoff(register filep); extern tchar popi(void); extern int pushi(filep, int, enum flags); extern void sfree(struct s *); extern struct s *macframe(void); extern int getsn(int); extern int setstr(void); extern void collect(void); extern void seta(void); extern void casebox(void); extern void caseboxa(void); extern void caseda(int); extern void casedi(int); extern void casedt(void); extern void caseals(void); extern void casewatch(int); extern void caseunwatch(void); extern void prwatch(struct contab *, int, int); extern void casetl(void); extern void casepc(void); extern void casechop(void); extern void casepm(void); extern void stackdump(void); extern const char *macname(int); extern int maybemore(int, int); extern tchar setuc(void); extern int makerq(const char *); /* n4.c */ extern void *grownumtab(void); extern void setn(void); extern int wrc(tchar); extern void setn1(int, int, tchar); extern void nunhash(register struct numtab *); extern struct numtab *findr(register int); extern struct numtab *usedr(register int); extern int fnumb(register int, register int (*)(tchar)); extern int decml(register int, register int (*)(tchar)); extern int roman(int, int (*)(tchar)); extern int roman0(int, int (*)(tchar), const char *, const char *); extern int abc(int, int (*)(tchar)); extern int abc0(int, int (*)(tchar)); extern int hatoi(void); #undef atof #define atof xxatof extern float atof(void); extern long long atoi0(void); extern double atof0(void); extern void setnr(const char *, int, int); extern void setnrf(const char *, float, float); extern void caserr(void); extern void casernn(void); extern void casenr(void); extern void casenrf(void); extern void caselnr(void); extern void caselnrf(void); extern void setr(void); extern void caseaf(void); extern void setaf(void); extern void casealn(void); extern void casewatchn(int); extern void caseunwatchn(void); extern void prwatchn(struct numtab *); extern int vnumb(int *); extern int hnumb(int *); extern int inumb(int *); extern int inumb2(int *, int *); extern float atop(void); extern int quant(int, int); extern tchar moflo(int); /* n5.c */ extern void save_tty(void); extern void casead(void); extern void casena(void); extern void casefi(void); extern void casenf(void); extern void casepadj(void); extern void casers(void); extern void casens(void); extern void casespreadwarn(void); extern int chget(int); extern void casecc(void); extern void casec2(void); extern void casehc(void); extern void casetc(void); extern void caselc(void); extern void casehy(void); extern void casenh(void); extern void casehlm(void); extern void casehcode(void); extern void caseshc(void); extern void casehylen(void); extern void casehypp(void); extern void casepshape(void); extern void caselpfx(void); -extern int max(int, int); -extern int min(int, int); extern void casece(void); extern void caserj(void); extern void casebrnl(void); extern void casebrpnl(void); extern void casein(void); extern void casell(void); extern void caselt(void); extern void caseti(void); extern void casels(void); extern void casepo(void); extern void casepl(void); extern void casewh(void); extern void casedwh(void); extern void casech(void); extern void casedch(void); extern void casevpt(void); extern tchar setolt(void); extern int findn(struct d *, int); extern void casepn(void); extern void casebp(void); extern void casetm(int); extern void casetmc(void); extern void caseerrprint(void); extern void caseopen(void); extern void caseopena(void); extern void casewrite(void); extern void casewritec(void); extern void casewritem(void); extern void caseclose(void); extern void casesp(int); extern void casebrp(void); extern void caseblm(void); extern void caselsm(void); extern void casert(void); extern void caseem(void); extern void casefl(void); extern void caseev(void); extern void caseevc(void); extern void evc(struct env *, struct env *); extern void evcline(struct env *, struct env *); extern void relsev(struct env *); extern void caseel(void); extern void caseie(void); extern void caseif(int); extern void casenop(void); extern void casechomp(void); extern void casereturn(void); extern void casewhile(void); extern void casebreak(void); extern void casecontinue(int); extern void eatblk(int); extern int cmpstr(tchar); extern void caserd(void); extern int rdtty(void); extern void caseec(void); extern void caseeo(void); extern void caseecs(void); extern void caseecr(void); extern void caseescoff(void); extern void caseescon(void); extern void caseta(void); extern void casene(void); extern void casetr(int); extern void casetrin(void); extern void casetrnt(void); extern void casecu(void); extern void caseul(void); extern void caseuf(void); extern void caseit(int); extern void caseitc(void); extern void casemc(void); extern void casesentchar(void); extern void casetranschar(void); extern void casebreakchar(void); extern void casenhychar(void); extern void caseconnectchar(void); extern void casemk(void); extern void casesv(void); extern void caseos(void); extern void casenm(void); extern void getnm(int *, int); extern void casenn(void); extern void caseab(void); extern void restore_tty(void); extern void set_tty(void); extern void echo_off(void); extern void echo_on(void); /* n7.c */ extern int collectmb(tchar); extern void tbreak(void); extern void donum(void); extern void text(void); extern void nofill(void); extern void callsp(void); extern void ckul(void); extern int storeline(register tchar, int); extern void newline(int); extern int findn1(struct d *, int); extern void chkpn(void); extern int findt(struct d *, int); extern int findt1(void); extern void eject(struct s *); extern int movword(void); extern void horiz(int); extern void setnel(void); extern int getword(int); extern void storeword(register tchar, register int); extern void growpgsize(void); /* n8.c */ extern void hyphen(tchar *); extern int punct(tchar); extern int alph(tchar); extern void caseht(void); extern void casehw(void); extern int exword(void); extern int suffix(void); extern int maplow(tchar); extern int vowel(tchar); extern tchar *chkvow(tchar *); extern void digram(void); extern int dilook(tchar, tchar, const char [26][13]); extern void casehylang(void); /* n9.c */ extern tchar setz(void); extern void setline(void); extern tchar eat(tchar); extern void setov(void); extern void setbra(void); extern void setvline(void); extern void setdraw(void); extern void casefc(void); extern tchar setfield(int); extern tchar setpenalty(void); extern tchar setdpenal(void); extern tchar mkxfunc(int, int); extern void pushinlev(void); extern tchar popinlev(void); extern void localize(void); extern void caselc_ctype(void); extern void casepsbb(void); extern void casewarn(void); extern void nosuch(int); extern void illseq(int, const char *, int); extern void missing(void); extern void nodelim(int); extern void storerq(int); extern int fetchrq(tchar *); extern void morechars(int); #ifdef NROFF extern void caseutf8conv(void); extern int addch(char *); #endif Index: projects/doctools/contrib/heirloom-doctools/troff/n1.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/n1.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/n1.c (revision 307812) @@ -1,2603 +1,2307 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "n1.c 1.25 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)n1.c 1.144 (gritter) 8/19/08 */ /* * Changes Copyright (c) 2014 Carsten Kunze */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ /* const char *xxxvers = "@(#)roff:n1.c 2.13"; */ /* * n1.c * * consume options, initialization, main loop, * input routines, escape function calling */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef EUC #include #include #include #include #endif /* EUC */ #include "tdef.h" #include "ext.h" #ifdef NROFF #include "tw.h" #include "draw.h" #endif #include "pt.h" #define MAX_RECURSION_DEPTH 512 static int max_recursion_depth = MAX_RECURSION_DEPTH; static int max_tail_depth; jmp_buf sjbuf; static filep ipl[NSO]; static long offl[NSO]; static long ioff; static const char *ttyp; char *cfname[NSO+1]; /*file name stack*/ static int cfline[NSO]; /*input line count stack*/ static int cfpid[NSO+1]; /* .pso process IDs */ char *progname; /* program name (troff) */ #ifdef EUC char mbbuf1[MB_LEN_MAX + 1]; char *mbbuf1p = mbbuf1; wchar_t twc = 0; #endif /* EUC */ static unsigned char escoff[126-31]; static void initg(void); -static void printlong(long, int); -static void printn(long, long); -static char *sprintlong(char *s, long, int); -static char *sprintn(char *s, long n, int b); -#ifndef NROFF -#define vfdprintf xxvfdprintf -static void vfdprintf(int fd, const char *fmt, va_list ap); -#endif static tchar setyon(void); static void _setenv(void); static tchar setZ(void); static int setgA(void); static int setB(void); static void _caseesc(int); #ifdef DEBUG int debug = 0; /*debug flag*/ #endif /* DEBUG */ static int _xflag; int bol; int noschr; int prdblesc; int main(int argc, char **argv) { register char *p; register int j; char **oargv; const char *s; size_t l; setlocale(LC_CTYPE, ""); mb_cur_max = MB_CUR_MAX; progname = argv[0]; nextf = calloc(1, NS = 1); d = calloc(NDI = 5, sizeof *d); growblist(); growcontab(); grownumtab(); growpbbuf(); morechars(1); initg(); for (j = 0; j <= NSO; j++) cfpid[j] = -1; if (signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, catch); if (signal(SIGINT, catch) == SIG_IGN) { signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); } signal(SIGPIPE, catch); signal(SIGTERM, kcatch); oargv = argv; - s = ""; - l = strlen(s) + 1; - cfname[0] = malloc(l); - n_strcpy(cfname[0], s, l); + cfname[0] = strdup(""); init0(); #ifdef EUC localize(); #endif /* EUC */ if ((p = getenv("TYPESETTER")) != 0) n_strcpy(devname, p, sizeof(devname)); while (--argc > 0 && (++argv)[0][0] == '-') switch (argv[0][1]) { case 'F': /* switch font tables from default */ if (argv[0][2] != '\0') { termtab = &argv[0][2]; fontfile = &argv[0][2]; } else { argv++; argc--; if (argv[0] != '\0') { termtab = argv[0]; fontfile = argv[0]; } else errprint("missing the font directory"); } continue; case 0: goto start; case 'i': stdi++; continue; case 'q': #ifdef NROFF quiet++; save_tty(); #else errprint("-q option ignored in troff"); #endif /* NROFF */ continue; case 'n': npn = ctoi(&argv[0][2]); continue; case 'u': /* set emboldening amount */ initbdtab[3] = ctoi(&argv[0][2]); if (initbdtab[3] < 0 || initbdtab[3] > 50) initbdtab[3] = 0; continue; case 's': if (!(stop = ctoi(&argv[0][2]))) stop++; continue; case 't': ptid = 1; continue; case 'r': case 'd': if (&argv[0][2] != '\0' && strlen(&argv[0][2]) >= 2 && &argv[0][3] != '\0') { if ((p = strchr(&argv[0][3], '=')) != NULL) { *p = 0; l = strlen(ibuf); eibuf = roff_sprintf(ibuf + l, sizeof(ibuf) - l, ".do %s %s %s%s\n", argv[0][1] == 'd' ? "ds" : "nr", &argv[0][2], argv[0][1] == 'd' ? "\"" : "", &p[1]); *p = '='; } else { l = strlen(ibuf); eibuf = roff_sprintf(ibuf + l, sizeof(ibuf) - l, ".%s %c %s%s\n", argv[0][1] == 'd' ? "ds" : "nr", argv[0][2], argv[0][1] == 'd' ? "\"" : "", &argv[0][3]); } } else errprint("wrong options"); continue; case 'c': case 'm': if (mflg++ >= NMF && (mfiles = realloc(mfiles, ++NMF * sizeof *mfiles)) == 0) { errprint("Too many macro packages: %s", argv[0]); continue; } if (argv[0][2] == '\0') { errprint("No library provided with -m"); done(02); } if (getenv("TROFFMACS") != '\0') { if (tryfile(getenv("TROFFMACS"), &argv[0][2], nmfi)) nmfi++; } else if (tryfile(MACDIR "/", &argv[0][2], nmfi) || tryfile(MACDIR "/tmac.", &argv[0][2], nmfi)) nmfi++; else { errprint("Cannot find library %s\n", argv[0]); done(02); } continue; case 'o': getpn(&argv[0][2]); continue; case 'T': n_strcpy(devname, &argv[0][2], sizeof(devname)); dotT++; continue; case 'x': if (argv[0][2]) xflag = strtol(&argv[0][2], NULL, 10); else xflag = 2; continue; case 'X': xflag = 0; continue; #ifdef NROFF case 'h': hflg++; continue; case 'z': no_out++; continue; case 'e': eqflg++; continue; #endif #ifndef NROFF case 'z': no_out++; case 'a': ascii = 1; nofeed++; continue; case 'f': nofeed++; continue; #endif case '#': #ifdef DEBUG debug = ctoi(&argv[0][2]); #else errprint("DEBUG not enabled"); #endif /* DEBUG */ continue; case 'V': fprintf(stdout, "Heirloom doctools %croff, " RELEASE "\n", #ifdef NROFF 'n' #else 't' #endif ); exit(0); default: errprint("unknown option %s", argv[0]); done(02); } start: init1(oargv[0][0]); argp = argv; rargc = argc; nmfi = 0; init2(); mainloop(); /*NOTREACHED*/ return(0); } void mainloop(void) { register int j; register tchar i; int eileenct; /*count to test for "Eileen's loop"*/ #ifdef NROFF int ndo = 0; #endif _xflag = xflag; setjmp(sjbuf); eileenct = 0; /*reset count for "Eileen's loop"*/ loop: #ifdef NROFF if (ndo) { ndo = 0; npic(0); } #endif xflag = _xflag; defcf = charf = clonef = copyf = lgf = nb = nflush = nlflg = 0; if (ip && rbf0(ip) == 0 && dip == d && ejf && frame->pframe->tail_cnt <= ejl) { nflush++; trap = 0; eject((struct s *)0); #ifdef DEBUG if (debug & DB_LOOP) fprintf(stderr, "loop: NL=%d, ejf=%d, lss=%d, " "eileenct=%d\n", numtab[NL].val, ejf, lss, eileenct); #endif /* DEBUG */ if (eileenct > 20) { errprint("job looping; check abuse of macros"); ejf = 0; /*try to break Eileen's loop*/ eileenct = 0; } else eileenct++; goto loop; } eileenct = 0; /*reset count for "Eileen's loop"*/ bol = 1; i = getch(); bol = 0; if (!i) /* CK: Bugfix: .bp followed by .. */ goto loop; if (pendt) goto Lt; if ((j = cbits(i)) == XPAR) { copyf++; tflg++; while (cbits(i) != '\n') pchar(i = getch()); tflg = 0; copyf--; goto loop; } if (j == cc || j == c2 || isxfunc(i, CC)) { if (gflag && isdi(i)) goto Lt; if (j == c2) nb++; copyf++; while ((j = cbits(i = getch())) == ' ' || j == '\t') ; ch = i; copyf--; j = getrq(4); #ifdef NROFF if (j == PAIR('P', 'S')) npic(1); else if (ndraw && j == PAIR('d', 'o')) ndo = 1; else #endif if (xflag != 0 && j == PAIR('d', 'o')) { xflag = 3; skip(1); j = getrq(4); } noschr = 1; control(j, 1); noschr = 0; flushi(); goto loop; } Lt: ch = i; text(); if (nlflg) numtab[HP].val = 0; goto loop; } int tryfile(register const char *pat, register char *fn, int idx) { size_t l = strlen(pat) + strlen(fn) + 1; mfiles[idx] = malloc(l); n_strcpy(mfiles[idx], pat, l); n_strcat(mfiles[idx], fn, l); if (access(mfiles[idx], 4) == -1) return(0); else return(1); } void catch(int unused __unused) { done3(01); } void kcatch(int unused __unused) { signal(SIGTERM, SIG_IGN); done3(01); } void init0(void) { eibuf = ibufp = ibuf; ibuf[0] = 0; numtab[NL].val = -1; } void init1(char a __unused) { register int i; for (i = NTRTAB; --i; ) trnttab[i] = trtab[i] = i; trnttab[UNPAD] = trtab[UNPAD] = ' '; trnttab[STRETCH] = trtab[STRETCH] = ' '; } void init2(void) { register int i, j; size_t l; ttyod = 2; if ((ttyp=ttyname(j=0)) != 0 || (ttyp=ttyname(j=1)) != 0 || (ttyp=ttyname(j=2)) != 0) ; else ttyp = "notty"; iflg = j; if (ascii) mesg(0); obufp = obuf; ptinit(); mchbits(); cvtime(); setnr(".g", gflag, 0); numtab[PID].val = getpid(); spreadlimit = 3*EM; olinesz = LNSIZE; oline = malloc(olinesz * sizeof *oline); olinep = oline; ioff = 0; numtab[HP].val = init = 0; numtab[NL].val = -1; nfo = 0; ifile = 0; copyf = raw = 0; l = strlen(ibuf); eibuf = roff_sprintf(ibuf + l, sizeof(ibuf) - l, ".ds .T %s\n", devname); numtab[CD].val = -1; /* compensation */ cpushback(ibuf); ibufp = ibuf; nx = mflg; frame = stk = calloc(1, sizeof *stk); stk->frame_cnt = 0; dip = &d[0]; nxf = calloc(1, sizeof *nxf); initenv = env; for (i = 0; i < NEV; i++) { extern tchar *corebuf; ((struct env *)corebuf)[i] = env; } } void cvtime(void) { time_t tt; register struct tm *tm; tt = time((time_t *) 0); tm = localtime(&tt); numtab[DY].val = tm->tm_mday; numtab[DW].val = tm->tm_wday + 1; numtab[YR].val = tm->tm_year; numtab[MO].val = tm->tm_mon + 1; setnr("hours", tm->tm_hour, 0); setnr("minutes", tm->tm_min, 0); setnr("seconds", tm->tm_sec, 0); setnr("year", tm->tm_year + 1900, 0); } int ctoi(register char *s) { register int n; while (*s == ' ') s++; n = 0; while (isdigit((unsigned char)*s)) n = 10 * n + *s++ - '0'; return n; } void mesg(int f) { static int mode; struct stat stbuf; if (!f) { stat(ttyp, &stbuf); mode = stbuf.st_mode; chmod(ttyp, mode & ~0122); /* turn off writing for others */ } else { if (ttyp && *ttyp && mode) chmod(ttyp, mode); } } static void verrprint(const char *s, va_list ap) { fprintf(stderr, "%s: ", progname); vfprintf(stderr, s, ap); if (numtab[CD].val > 0) fprintf(stderr, "; line %d, file %s", numtab[CD].val + (nlflg == 0 && frame == stk), cfname[ifi] ? cfname[ifi] : ""); if (xflag && realpage) fprintf(stderr, "; page %ld", realpage); fprintf(stderr, "\n"); stackdump(); #ifdef DEBUG if (debug & DB_ABRT) abort(); #endif /* DEBUG */ } void errprint(const char *s, ...) /* error message printer */ { va_list ap; va_start(ap, s); verrprint(s, ap); va_end(ap); } - -#ifndef NROFF -/* - * Scaled down version of C Library printf. - * Only %s %u %d (==%u) %o %c %x %D are recognized. - */ -#undef putchar -#define putchar(n) (*pfbp++ = (n)) /* NO CHECKING! */ - -static char pfbuf[NTM]; -static char *pfbp = pfbuf; - -void -fdprintf(int fd, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfdprintf(fd, fmt, ap); - va_end(ap); -} - -static void -vfdprintf(int fd, const char *fmt, va_list ap) -{ - register int c; - char *s; - register int i; - - pfbp = pfbuf; -loop: - while ((c = *fmt++) != '%') { - if (c == '\0') { - if (fd == 2) - write(STDERR_FILENO, pfbuf, pfbp - pfbuf); - else { - *pfbp = 0; - pfbp = pfbuf; - while (*pfbp) { - *obufp++ = *pfbp++; - if (obufp >= &obuf[OBUFSZ]) - flusho(); - } - } - return; - } - putchar(c); - } - c = *fmt++; - if (c == 'd' || c == 'u' || c == 'o' || c == 'x') { - i = va_arg(ap, int); - printlong(i, c); - } else if (c == 'c') { - if (c > 0177 || c < 040) - putchar('\\'); - putchar(va_arg(ap, int) & 0177); - } else if (c == 's') { - s = va_arg(ap, char *); - while ((c = *s++)) - putchar(c); - } else if (c == 'D') { - printn(va_arg(ap, long), 10); - } else if (c == 'O') { - printn(va_arg(ap, long), 8); - } else if (c == 'e' || c == 'E' || - c == 'f' || c == 'F' || - c == 'g' || c == 'G') { - char tmp[40]; - char fmt[] = "%%"; - fmt[1] = c; - snprintf(s = tmp, sizeof(tmp), fmt, va_arg(ap, double)); - while ((c = *s++)) - putchar(c); - } else if (c == 'p') { - i = (intptr_t)va_arg(ap, void *); - putchar('0'); - putchar('x'); - printlong(i, 'x'); - } else if (c == 'l') { - c = *fmt++; - if (c == 'd' || c == 'u' || c == 'o' || c == 'x') { - i = va_arg(ap, long); - printlong(i, c); - } else if (c == 'c') { - i = va_arg(ap, int); - if (c & ~0177) { -#ifdef EUC - char mb[MB_LEN_MAX]; - int j, n; - n = wctomb(mb, i); - for (j = 0; j < n; j++) - putchar(mb[j]&0377); -#endif /* EUC */ - } else - putchar(i); - } - } else if (c == 'C') { - extern int nchtab; - tchar t = va_arg(ap, tchar); - if ((i = cbits(t)) < 0177) { - putchar(i); - } else if (i < 128 + nchtab) { - putchar('\\'); - putchar('('); - putchar(chname[chtab[i-128]]); - putchar(chname[chtab[i-128]+1]); - } - else if ((i = tr2un(i, fbits(t))) != -1) - goto U; - } else if (c == 'U') { - i = va_arg(ap, int); - U: - putchar('U'); - putchar('+'); - if (i < 0x1000) - putchar('0'); - if (i < 0x100) - putchar('0'); - if (i < 0x10) - putchar('0'); - printn((long)i, 16); -#ifdef EUC - if (iswprint(i)) { - char mb[MB_LEN_MAX]; - int j, n; - n = wctomb(mb, i); - putchar(' '); - putchar('('); - for (j = 0; j < n; j++) - putchar(mb[j]&0377); - putchar(')'); - } -#endif /* EUC */ - } - goto loop; -} -#endif /* !NROFF */ - - -static void -printlong(long i, int fmt) -{ - switch (fmt) { - case 'd': - if (i < 0) { - putchar('-'); - i = -i; - } - /*FALLTHRU*/ - case 'u': - printn(i, 10); - break; - case 'o': - printn(i, 8); - break; - case 'x': - printn(i, 16); - break; - } -} - -/* - * Print an unsigned integer in base b. - */ -static void printn(register long n, register long b) -{ - register long a; - - if (n < 0) { /* shouldn't happen */ - putchar('-'); - n = -n; - } - if ((a = n / b)) - printn(a, b); - putchar("0123456789ABCDEF"[(int)(n%b)]); -} - -/* scaled down version of library roff_sprintf */ -/* same limits as fdprintf */ /* returns pointer to \0 that ends the string */ /* VARARGS2 */ char *roff_sprintf(char *str, size_t size, const char *fmt, ...) { - register int c; - char *s; - long i; + int ret; va_list ap; - char *buf = str; va_start(ap, fmt); -loop: - while ((c = *fmt++) != '%') { - if (c == '\0') { - *str = 0; - va_end(ap); - return str; - } - *str++ = c; - } - c = *fmt++; - if (c == 'd' || c == 'u' || c == 'o' || c == 'x') { - i = va_arg(ap, int); - str = sprintlong(str, i, c); - } else if (c == 'c') { - if (c > 0177 || c < 040) - *str++ = '\\'; - *str++ = va_arg(ap, int) & 0177; - } else if (c == 's') { - s = va_arg(ap, char *); - while ((c = *s++)) - *str++ = c; - } else if (c == 'D') { - str = sprintn(str, va_arg(ap, long), 10); - } else if (c == 'O') { - str = sprintn(str, va_arg(ap, unsigned) , 8); - } else if (c == 'e' || c == 'E' || - c == 'f' || c == 'F' || - c == 'g' || c == 'G') { - char _fmt[] = "%%"; - _fmt[1] = c; - str += snprintf(str, size - (str - buf), _fmt, va_arg(ap, - double)); - } else if (c == 'p') { - i = (intptr_t)va_arg(ap, void *); - *str++ = '0'; - *str++ = 'x'; - str = sprintlong(str, i, 'x'); - } else if (c == 'l') { - c = *fmt++; - if (c == 'd' || c == 'u' || c == 'o' || c == 'x') { - i = va_arg(ap, long); - printlong(i, c); - } else if (c == 'c') { - i = va_arg(ap, int); - if (i & ~0177) { -#ifdef EUC - int n; - n = wctomb(str, i); - if (n > 0) - str += n; -#endif /* EUC */ - } else - *str++ = i; - } - } - goto loop; -} + ret = vsnprintf(str, size, fmt, ap); + va_end(ap); -static char * -sprintlong(char *s, long i, int fmt) -{ - switch (fmt) { - case 'd': - if (i < 0) { - *s++ = '-'; - i = -i; - } - /*FALLTHRU*/ - case 'u': - s = sprintn(s, i, 10); - break; - case 'o': - s = sprintn(s, i, 8); - break; - case 'x': - s = sprintn(s, i, 16); - break; - } - return s; + return (str + ret); } -/* - * Print an unsigned integer in base b. - */ -static char *sprintn(register char *s, register long n, int b) -{ - register long a; - - if (n < 0) { /* shouldn't happen */ - *s++ = '-'; - n = -n; - } - if ((a = n / b)) - s = sprintn(s, a, b); - *s++ = "0123456789ABCDEF"[(int)(n%b)]; - return s; -} - - int control(register int a, register int b) { struct contab *contp; int newip; struct s *p; if (a == 0 || (contp = findmx(a)) == NULL) { nosuch(a); return(0); } /* * Attempt to find endless recursion at runtime. Arbitrary * recursion limit of MAX_RECURSION_DEPTH was chosen as * it is extremely unlikely that a correct nroff/troff * invocation would exceed this value. * * The depth of tail-recursive macro calls is not limited * by default. */ if (max_recursion_depth > 0 && frame->frame_cnt > max_recursion_depth) { errprint( "Exceeded maximum stack size (%d) when " "executing macro %s. Stack dump follows", max_recursion_depth, macname(frame->mname)); edone(02); } if (max_tail_depth > 0 && frame->tail_cnt > max_tail_depth) { errprint( "Exceeded maximum recursion depth (%d) when " "executing macro %s. Stack dump follows", max_tail_depth, macname(frame->mname)); edone(02); } lastrq = a; #ifdef DEBUG if (debug & DB_MAC) fprintf(stderr, "control: macro %s, contab[%d]\n", macname(a), contp - contab); #endif /* DEBUG */ if (contp->f == 0) { nxf->nargs = 0; tailflg = 0; if (b) collect(); flushi(); newip = pushi((filep)contp->mx, a, contp->flags); p = frame->pframe; if (tailflg && b && p != stk && p->ppendt == 0 && p->pch == 0 && p->pip == frame->pip && p->lastpbp == frame->lastpbp) { frame->pframe = p->pframe; frame->frame_cnt--; sfree(p); *p = *frame; free(frame); frame = p; } contp->flags |= FLAG_USED; frame->contp = contp; tailflg = 0; return newip; } else if (b) { (*contp->f)(0); return 0; } else return(0); } int rgetach(void) { extern const char nmctab[]; int i; if ((i = getach()) == 0 || (xflag && i < ' ' && nmctab[i])) return(0); return(i); } int getrq2(void) { register int i, j; if (((i = rgetach()) == 0) || ((j = rgetach()) == 0)) goto rtn; i = PAIR(i, j); rtn: return(i); } int getrq(int flags) { int i; if ((i = getrq2()) >= 256) i = maybemore(i, flags); return(i); } /* * table encodes some special characters, to speed up tests * in getchar, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch */ static char _gchtab[] = { 000,004,000,000,010,000,000,000, /* fc, ldr */ 001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */ 000,000,000,000,000,000,000,000, 000,001,000,000,000,000,000,000, /* FLSS */ 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,001,000, /* f */ 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, }; static void initg(void) { memcpy(gchtab, _gchtab, sizeof _gchtab); } tchar getch(void) { register int k; register tchar i, j; struct numtab *np; g0: if ((i = ch)) { if (cbits(i) == '\n') { nlflg++; tailflg = istail(i); } ch = 0; return(i); } if (nlflg) return('\n'); i = getch0(); if (ismot(i)) return(i); k = cbits(i); if (k != ESC) { if (k >= NCHARS || gchtab[k]==0) return(i); if (k == '\n') { nl: if (cbits(i) == '\n') { nlflg++; tailflg = istail(i); } return(k); } if (k == FLSS) { copyf++; raw++; i = getch0(); if (!fi) flss = i; copyf--; raw--; goto g0; } if (k == RPT) { setrpt(); goto g0; } if (!copyf) { if (gchtab[k]&LGBIT && !isdi(i) && lg && !lgf) { k = cbits(i = getlg(i)); goto chartest; } if (k == fc || k == tabch || k == ldrch) { if ((i = setfield(k)) == 0) goto g0; else return(i); } if (k == '\b') { i = makem(-width(' ' | chbits)); return(i); } chartest: if ( #ifndef NROFF (!html || k < NCHARS) && #endif !lgf && !charf && chartab[trtab[k]] != NULL && !noschr && (!argdelim || k != argdelim) && !(bol && (k == cc || k == c2))) i = setchar(i); return(i); } return(i); } ge: k = cbits(j = getch0()); if (ismot(j)) return(j); if (k >= 32 && k <= 126 && escoff[k-32]) { if (clonef || copyf || tryglf) { pbbuf[pbp++] = j; return eschar; } return j; } switch (k) { case '\n': /* concealed newline */ if (fmtchar) goto nl; goto g0; case '{': /* LEFT */ i = LEFT; goto gx; case '}': /* RIGHT */ i = RIGHT; goto gx; case '#': /* comment including newline */ if (xflag == 0) break; /*FALLTHRU*/ case '"': /* comment */ while (cbits(i = getch0()) != '\n') ; if (k == '#') goto g0; nlflg++; tailflg = istail(i); return(i); case 'e': /* printable version of current eschar */ i = PRESC; goto gx; case ' ': /* unpaddable space */ i = UNPAD; goto gx; case '~': /* stretchable but unbreakable space */ if (xflag == 0) break; i = STRETCH; goto gx; case '\'': /* \(aa */ i = ACUTE; goto gx; case '`': /* \(ga */ i = GRAVE; goto gx; case '_': /* \(ul */ i = UNDERLINE; goto gx; case '-': /* current font minus */ i = MINUS; goto gx; case '&': /* filler */ i = FILLER; goto gx; case ')': /* transparent filler */ if (xflag == 0) break; i = FILLER|TRANBIT; goto gx; case 'c': /* to be continued */ i = CONT; goto gx; case '!': /* transparent indicator */ i = XPAR; goto gx; case 't': /* tab */ i = '\t'; return(i); case 'a': /* leader (SOH) */ i = LEADER; return(i); case '%': /* ohc */ i = OHC; return(i); case ':': /* optional line break but no hyphenation */ if (xflag == 0) break; i = OHC | BLBIT; return(i); } if (clonef) { pbbuf[pbp++] = j; return(eschar); } switch (k) { case 'n': /* number register */ setn(); goto g0; case '*': /* string indicator */ setstr(); goto g0; case '$': /* argument indicator */ seta(); goto g0; case ESC: /* double backslash */ if (prdblesc || dilev) i = PRESC; else i = eschar; goto gx; case 'g': /* return format of a number register */ setaf(); goto g0; case 'P': /* output line trap */ if (xflag == 0) break; i = setolt(); return(i); case 'V': /* environment variable */ if (xflag == 0) break; _setenv(); goto g0; case '.': /* . */ i = '.'; gx: setsfbits(i, sfbits(j)); return(i); } if (copyf) { copy: pbbuf[pbp++] = j; return(eschar); } switch (k) { case '[': if (defcf) goto copy; if (xflag == 0) goto dfl; /*FALLTHRU*/ case 'C': case '(': /* special char name */ if (defcf) goto copy; if ((i = setch(k)) == 0 && !tryglf) goto g0; k = cbits(i); goto chartest; case 'U': /* Unicode character */ if (xflag == 0) goto dfl; if ((i = setuc()) == 0 && !tryglf) goto g0; return(i); case 'N': /* absolute character number */ i = setabs(); goto gx; case 'E': /* eschar out of copy mode */ if (xflag == 0) goto dfl; goto ge; } if (tryglf) { pbbuf[pbp++] = j; return(eschar); } switch (k) { case 'X': /* \X'...' for copy through */ setxon(); goto g0; case 'Y': /* \Y(xx for indirect copy through */ if (xflag == 0) goto dfl; i = setyon(); return(i); case 'p': /* spread */ spread = 1; goto g0; case 's': /* size indicator */ setps(); goto g0; case 'H': /* character height */ return(setht()); case 'S': /* slant */ return(setslant()); case 'f': /* font indicator */ setfont(0); goto g0; case 'w': /* width function */ setwd(); goto g0; case 'v': /* vert mot */ if ((i = vmot())) return(i); goto g0; case 'h': /* horiz mot */ if ((i = hmot())) return(i); goto g0; case 'z': /* zero with char */ return(setz()); case 'l': /* hor line */ setline(); goto g0; case 'L': /* vert line */ setvline(); goto g0; case 'D': /* drawing function */ setdraw(); goto g0; case 'b': /* bracket */ setbra(); goto g0; case 'o': /* overstrike */ setov(); goto g0; case 'k': /* mark hor place */ if ((np = findr(getsn(1))) != NULL) { np->val = numtab[HP].val; prwatchn(np); } goto g0; case '0': /* number space */ return(makem(width('0' | chbits))); #ifdef NROFF case '/': case ',': if (!(gflag || gemu)) goto dfl; goto g0; case '|': case '^': goto g0; #else case '/': if (gflag == 0) goto dfl; return(makem((int)(EM)/12)); /* italic correction */ case ',': if (!(gflag || gemu)) goto dfl; return(makem(0)); /* left italic correction */ case '|': /* narrow space */ return(makem((int)(EM)/6)); case '^': /* half narrow space */ return(makem((int)(EM)/12)); #endif case 'x': /* extra line space */ if ((i = xlss())) return(i); goto g0; case 'u': /* half em up */ case 'r': /* full em up */ case 'd': /* half em down */ return(sethl(k)); case 'I': if (xflag) { i = setgA() + '0'; goto gx; } goto dfl; case 'A': /* set anchor */ if (gflag) { /* acceptable as name */ i = setgA() + '0'; goto gx; } if (xflag == 0) goto dfl; if ((j = setanchor()) == 0) goto g0; return(j); case 'B': /* acceptable as expression */ if (xflag) { i = setB() + '0'; goto gx; } goto dfl; case 'F': case 'm': case 'M': if (gflag || gemu) { /* font family, color */ if ((i = getsn(0)) > 0 && warn & WARN_ESCAPE) errprint("\\%c[%s] unimplemented", k, macname(i)); goto g0; } goto dfl; case 'T': if (xflag == 0) goto dfl; if ((j = setlink()) == 0) goto g0; return(j); case 'R': if (xflag) { setr(); goto g0; } goto dfl; case 'W': /* URI link */ if (xflag == 0) goto dfl; if ((j = setulink()) == 0) goto g0; return(j); case 'Z': if (xflag == 0) goto dfl; if ((j = setZ()) != 0) return(j); goto g0; case 'j': if (xflag == 0) goto dfl; if ((j = setpenalty()) != 0) return(j); goto g0; case 'J': if (xflag == 0) goto dfl; if ((j = setdpenal()) != 0) return(j); goto g0; case '@': if (xflag == 0) goto dfl; k = cbits(i = getch0()); switch (k) { case '{': pushinlev(); break; case '}': if ((i = popinlev()) != 0) return(i); break; default: if (warn & WARN_ESCAPE) errprint("undefined inline environment " "function \\@%c", k); pbbuf[pbp++] = i; goto dfl; } goto g0; case ';': /* ligature suppressor (only) */ if (xflag) goto g0; /*FALLTHRU*/ default: dfl: if (defcf) goto copy; if (warn & WARN_ESCAPE) errprint("undefined escape sequence \\%c", k); return(j); } /* NOTREACHED */ } void setxon(void) /* \X'...' for copy through */ { tchar _xbuf[NC]; register tchar *i; tchar c, delim; int k; if (ismot(c = getch())) return; delim = c; i = _xbuf; *i++ = XON; charf++; while (k = cbits(c = getch()), !issame(c, delim) && k != '\n' && i < _xbuf+NC-1) { if (k == ' ') setcbits(c, UNPAD); *i++ = c | ZBIT; } if (!issame(c, delim)) nodelim(delim); charf--; *i++ = XOFF; *i = 0; pushback(_xbuf); } static tchar setyon(void) /* \Y(xx for indirect copy through */ { storerq(getsn(0)); return mkxfunc(YON, 0); } char ifilt[32] = { 0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012}; tchar getch0(void) { register int j; register tchar i; #ifdef EUC size_t n; #endif /* EUC */ again: if (pbp > lastpbp) i = pbbuf[--pbp]; else if (ip) { extern tchar *corebuf; i = corebuf[ip]; if (i == 0) { /* CK: Bugfix: .bp followed by .. * The "<" is questionable */ if (ejf && frame->pframe->tail_cnt < ejl && dip == d) goto r; i = rbf(); } else { if ((++ip & (BLK - 1)) == 0) { --ip; (void)rbf(); } } } else { if (donef || ndone) done(0); if (nx || ibufp >= eibuf) { if (nfo==0) { g0: if (nextfile()) { if (ip) goto again; if (ibufp < eibuf) goto g2; } } nx = 0; if ((j = read(ifile, ibuf, IBUFSZ)) <= 0) goto g0; ibufp = ibuf; eibuf = ibuf + j; if (ip) goto again; } g2: #ifndef EUC i = *ibufp++ & 0177; ioff++; if (i >= 040 && i < 0177) #else /* EUC */ i = *ibufp++ & 0377; ioff++; *mbbuf1p++ = i; *mbbuf1p = 0; if (multi_locale && (*mbbuf1&~(wchar_t)0177)) { mbstate_t state; memset(&state, 0, sizeof state); if ((n = mbrtowc(&twc, mbbuf1, mbbuf1p-mbbuf1, &state)) == -1 || twc & ~(wchar_t)0x1FFFFF) { illseq(-1, mbbuf1, mbbuf1p-mbbuf1); mbbuf1p = mbbuf1; *mbbuf1p = 0; i &= 0177; } else if (n == -2) goto again; else { mbbuf1p = mbbuf1; *mbbuf1p = 0; i = twc | COPYBIT; goto g4; } } else { mbbuf1p = mbbuf1; *mbbuf1p = 0; if (!raw) i &= 0177; } if (i >= 040 && i < 0177) #endif /* EUC */ goto g4; if (i != 0177) { if (i != ifilt[i]) illseq(i, NULL, 0); i = ifilt[i]; } else illseq(i, NULL, 0); if (i == '\n') numtab[CD].val++; /* line number */ } if (cbits(i) == IMP && !raw) goto again; if ((i == 0 || i == 0177) && !init && !raw) { goto again; } g4: if (!copyf && iscopy(i)) i = setuc0(cbits(i)); if (copyf == 0 && (i & ~BYTEMASK) == 0) i |= chbits; if (cbits(i) == eschar && !raw) { if (gflag && isdi(i)) setcbits(i, PRESC); else setcbits(i, ESC); } r: return i; } void pushback(register tchar *b) { register tchar *ob = b; while (*b++) ; b--; while (b > ob) { if (pbp >= pbsize-3) if (growpbbuf() == NULL) { errprint("pushback overflow"); done(2); } pbbuf[pbp++] = *--b; } } void cpushback(register const char *b) { register const char *ob = b; while (*b++) ; b--; while (b > ob) { if (pbp >= pbsize-3) if (growpbbuf() == NULL) { errprint("cpushback overflow"); done(2); } pbbuf[pbp++] = *--b; } } tchar * growpbbuf(void) { tchar *npb; int inc = NC; if ((npb = realloc(pbbuf, (pbsize + inc) * sizeof *pbbuf)) == NULL) return NULL; pbsize += inc; return pbbuf = npb; } int nextfile(void) { register char *p; - const char *s; - size_t l; n0: if (ifile) close(ifile); if (nx || nmfi < mflg) { p = mfiles[nmfi++]; if (*p != 0) goto n1; } if (ifi > 0) { if (popf()) goto n0; /* popf error */ return(1); /* popf ok */ } if (rargc-- <= 0) { if ((nfo -= mflg) && !stdi) done(0); nfo++; numtab[CD].val = ifile = stdi = mflg = 0; free(cfname[ifi]); - s = ""; - l = strlen(s) + 1; - cfname[ifi] = malloc(l); - n_strcpy(cfname[ifi], s, l); + cfname[ifi] = strdup(""); ioff = 0; return(0); } p = (argp++)[0]; n1: numtab[CD].val = 0; if (p[0] == '-' && p[1] == 0) { ifile = 0; free(cfname[ifi]); - s = ""; - l = strlen(s) + 1; - cfname[ifi] = malloc(l); - n_strcpy(cfname[ifi], s, l); + cfname[ifi] = strdup(""); } else if ((ifile = open(p, O_RDONLY)) < 0) { errprint("cannot open file %s", p); nfo -= mflg; done(02); } else { free(cfname[ifi]); - l = strlen(p) + 1; - cfname[ifi] = malloc(l); - n_strcpy(cfname[ifi], p, l); + cfname[ifi] = strdup(p); } nfo++; ioff = 0; return(0); } int popf(void) { register int i; register char *p, *q; if (cfpid[ifi] != -1) { while (waitpid(cfpid[ifi], NULL, 0) != cfpid[ifi]); cfpid[ifi] = -1; } ioff = offl[--ifi]; numtab[CD].val = cfline[ifi]; /*restore line counter*/ ip = ipl[ifi]; if ((ifile = ifl[ifi]) == 0) { p = xbuf; q = ibuf; ibufp = xbufp; eibuf = xeibuf; while (q < eibuf) *q++ = *p++; return(0); } if (lseek(ifile, ioff & ~(IBUFSZ-1), SEEK_SET) == -1 || (i = read(ifile, ibuf, IBUFSZ)) < 0) return(1); eibuf = ibuf + i; ibufp = ibuf; if (ttyname(ifile) == 0) /* was >= ... */ if ((ibufp = ibuf + (ioff & (IBUFSZ - 1))) > eibuf) return(1); return(0); } void flushi(void) { if (nflush) return; ch = 0; copyf++; while (!nlflg) { if (donef && (frame == stk)) break; getch(); } copyf--; } int getach(void) { register tchar i; register int j; lgf++; i = getch(); while (isxfunc(i, CHAR)) i = charout[sbits(i)].ch; j = cbits(i); if (ismot(i) || (j == XFUNC && fbits(i)) || j == ' ' || j == '\n' || j & 0200) { if (!ismot(i) && j >= 0200) illseq(j, NULL, -3); else if (WARN_INPUT) { if (ismot(i) && !isadjmot(i)) errprint("motion terminates name"); else if (j == XFUNC && fbits(i)) errprint("illegal character terminates name"); } ch = i; j = 0; } lgf--; return(j & 0177); } void casenx(void) { struct s *pp; lgf++; skip(0); getname(); nx++; if (nmfi > 0) nmfi--; if (mfiles == NULL) mfiles = calloc(1, sizeof *mfiles); free(mfiles[nmfi]); mfiles[nmfi] = malloc(NS); n_strcpy(mfiles[nmfi], nextf, NS); nextfile(); nlflg++; tailflg = 0; ip = 0; pendt = 0; while (frame != stk) { pp = frame; frame = frame->pframe; sfree(pp); free(pp); } nxf = calloc(1, sizeof *nxf); } int getname(void) { register int j, k; tchar i; int delim = ' '; lgf++; k = 0; while (1) { if ((j = cbits(i = getch())) < 32 || j == delim || (!xflag && j > 0176)) break; if (xflag && !k && j == '"') { delim = j; continue; } if (k + 1 >= NS) nextf = realloc(nextf, NS += 14); nextf[k++] = j & BYTEMASK; } nextf[k] = 0; ch = i; lgf--; return(nextf[0]); } tchar setuc(void) { char c, _d, b[NC], *bp; int n; size_t i = 0; tchar r = 0; #ifndef NROFF extern int nchtab; #endif _d = getach(); do { c = getach(); if (i >= sizeof b) goto rtn; b[i++] = c; } while (c && c != _d); b[--i] = 0; if (i == 0 || c != _d) goto rtn; n = strtol(b, &bp, 16); if (n == 0 || *bp != '\0') goto rtn; #ifndef NROFF switch (n) { case '\'': bp = "aq"; break; case '`': bp = "ga"; break; case '-': r = MINUS; goto rtn; default: goto uc; } for (i = 0; i < nchtab; i++) if (strcmp(&chname[chtab[i]], bp) == 0) { r = (i + 128) | chbits; break; } goto rtn; uc: #endif r = setuc0(n); rtn: return r; } static void _setenv(void) { int a = 0, i = 0, c, delim; char *np = NULL, *vp; if ((delim = getach()) == 0) return; switch (delim) { case '[': for (;;) { if (i + 1 >= a) np = realloc(np, a += 32); if ((c = getach()) == 0) { nodelim(']'); break; } if (c == ']') break; np[i++] = c; } np[i] = 0; break; case '(': np = malloc(a = 3); np[0] = delim; np[1] = getach(); np[2] = 0; break; default: np = malloc(a = 2); np[0] = delim; np[1] = 0; } if ((vp = getenv(np)) != NULL) cpushback(vp); free(np); } static void sopso(int i, pid_t pid) { register char *p, *q; free(cfname[ifi+1]); cfname[ifi+1] = malloc(NS); n_strcpy(cfname[ifi+1], nextf, NS); cfline[ifi] = numtab[CD].val; /*hold line counter*/ numtab[CD].val = 0; flushi(); cfpid[ifi+1] = pid; ifl[ifi] = ifile; ifile = i; offl[ifi] = ioff; ioff = 0; ipl[ifi] = ip; ip = 0; nx++; nflush++; if (!ifl[ifi++]) { p = ibuf; q = xbuf; xbufp = ibufp; xeibuf = eibuf; while (p < eibuf) *q++ = *p++; } } void caseso(void) { register int i = 0; lgf++; nextf[0] = 0; if (skip(1)) done(02); if (!getname() || ((i = open(nextf, O_RDONLY)) < 0) || (ifi >= NSO)) { errprint("can't open file %s", nextf); if (gflag) return; done(02); } sopso(i, -1); } void casepso(void) { int pd[2]; int c, i, k; pid_t pid; lgf++; nextf[0] = 0; if (skip(1)) done(02); if (ifi >= NSO || pipe(pd) < 0) { errprint("can't .pso"); done(02); } for (k = 0; ; k++) { if ((c = cbits(i = getch())) == '\n' || c == 0) break; if (k + 1 >= NS) nextf = realloc(nextf, NS += 14); nextf[k] = c & BYTEMASK; } nextf[k] = 0; switch (pid = fork()) { case 0: close(pd[0]); close(1); dup(pd[1]); close(pd[1]); execl(SHELL, "sh", "-c", nextf, NULL); _exit(0177); /*NOTREACHED*/ case -1: errprint("can't fork"); done(02); /*NOTREACHED*/ } close(pd[1]); sopso(pd[0], pid); } void caself(void) /* set line number and file */ { int n; if (skip(1)) return; n = hatoi(); cfline[ifi] = numtab[CD].val = n - 2; if (skip(0)) return; if (getname()) { free(cfname[ifi]); cfname[ifi] = malloc(NS); n_strcpy(cfname[ifi], nextf, NS); } } void casecf(void) { /* copy file without change */ #ifndef NROFF int fd = -1, n; char buf[512]; extern int hpos, esc, po; nextf[0] = 0; if (skip(1)) return; if (!getname() || (fd = open(nextf, O_RDONLY)) < 0) { errprint("can't open file %s", nextf); done(02); } tbreak(); /* make it into a clean state, be sure that everything is out */ hpos = po; esc = un; ptesc(); ptlead(); ptps(); ptfont(); flusho(); while ((n = read(fd, buf, sizeof buf)) > 0) write(ptid, buf, n); close(fd); #endif } void casesy(void) /* call system */ { char sybuf[NTM]; int i; lgf++; copyf++; skip(1); for (i = 0; i < NTM - 2; i++) if ((sybuf[i] = getch()) == '\n') break; sybuf[i] = 0; system(sybuf); copyf--; lgf--; } void getpn(register char *a) { register int n, neg; if (*a == 0) return; neg = 0; for ( ; *a; a++) switch (*a) { case '+': case ',': continue; case '-': neg = 1; continue; default: n = 0; if (isdigit((unsigned char)*a)) { do n = 10 * n + *a++ - '0'; while (isdigit((unsigned char)*a)); a--; } else n = 9999; *pnp++ = neg ? -n : n; neg = 0; if (pnp >= &pnlist[NPN-2]) { errprint("too many page numbers"); done3(-3); } } if (neg) *pnp++ = -9999; *pnp = -32767; print = 0; pnp = pnlist; if (*pnp != -32767) chkpn(); } void setrpt(void) { tchar i, j; copyf++; raw++; i = getch0(); copyf--; raw--; if (i < 0 || cbits(j = getch0()) == RPT) return; i &= BYTEMASK; while (i>0) { if (pbp >= pbsize-3) if (growpbbuf() == NULL) break; i--; pbbuf[pbp++] = j; } } void casedb(void) { #ifdef DEBUG debug = 0; if (skip(1)) return; noscale++; debug = max(hatoi(), 0); noscale = 0; #endif /* DEBUG */ } void casexflag(void) { int i; #ifndef NROFF if (gflag == 1) zapwcache(1); #endif gflag = 0; setnr(".g", gflag, 0); gemu = 0; skip(1); noscale++; i = hatoi(); noscale--; if (!nonumb) _xflag = xflag = i & 3; } void casecp(void) { if (xflag) { #ifndef NROFF if (gflag == 0) zapwcache(1); #endif gflag = 1; noscale++; if (skip(1) || (hatoi() && !nonumb)) xflag = 1; else xflag = 3; noscale--; _xflag = xflag; setnr(".g", gflag, 0); setnr(".C", xflag == 1, 0); setnr(".x", 1, 0); setnr(".y", 18, 0); } } void caserecursionlimit(void) { skip(1); noscale++; max_recursion_depth = hatoi(); skip(0); max_tail_depth = hatoi(); noscale--; } void casechar(int flag __unused) { #ifndef NROFF extern int ps2cc(const char *); extern int nchtab; #endif char name[NC]; int i, k, size = 0; tchar c, *tp = NULL; defcf++; charf++; lgf++; if (skip(1)) return; c = getch(); while (isxfunc(c, CHAR)) c = charout[sbits(c)].ch; if ((k = cbits(c)) == eschar || k == WORDSP) { switch (cbits(c = getch())) { case '(': name[0] = getch(); name[1] = getch(); name[2] = 0; break; case '[': for (i = 0; cbits(c = getch()) != ']'; i++) if (i < sizeof name - 1) name[i] = c; name[i] = 0; break; default: errprint("mapping of escape sequences not permitted"); return; } #ifndef NROFF k = ps2cc(name) + nchtab + 128 + 32 + 128 - 32 + nchtab; #else if (!(k = findch(name))) k = addch(name); #endif } else if (iscopy(c)) k = cbits(c = setuc0(k)); if (k <= ' ') { errprint("mapping of special characters not permitted"); return; } defcf--; charf--; copyf++; size = 10; tp = malloc(size * sizeof *tp); i = 0; if (skip(0)) tp[i++] = FILLER; else { if (cbits(c = getch()) != '"') ch = c; while (c = getch(), !nlflg) { if (i + 3 >= size) { size += 10; tp = realloc(tp, size * sizeof *tp); } tp[i++] = c; } } tp[i++] = '\n'; tp[i] = 0; i = k; if (++i >= NCHARS) morechars(i); free(chartab[k]); chartab[k] = tp; gchtab[k] |= CHBIT; copyf--; #ifndef NROFF if (flag) fchartab[k] = 1; else fchartab[k] = 0; #endif } void casefchar(void) { #ifndef NROFF casechar(1); #endif } void caserchar(void) { tchar c; int k; lgf++; if (skip(1)) return; do { c = getch(); k = cbits(c); free(chartab[k]); chartab[k] = NULL; gchtab[k] &= ~CHBIT; } while (!skip(0)); } struct fmtchar { struct d newd, *savedip; struct env saveev; int savvflag; int savvpt; int savhp; int savnflush; tchar *csp; int charcount; }; static int prepchar(struct fmtchar *fp) { static int charcount; filep startb; tchar _t; if ((startb = alloc()) == 0) { errprint("out of space"); return -1; } _t = 0; setsbits(_t, charcount); charcount = sbits(_t); if (dip != d) wbt(0); if (charcount >= charoutsz) { charoutsz += 32; charout = realloc(charout, charoutsz * sizeof *charout); } memset(&charout[charcount], 0, sizeof *charout); fp->savedip = dip; memset(&fp->newd, 0, sizeof fp->newd); dip = &fp->newd; offset = dip->op = startb; charout[charcount].op = startb; fp->savnflush = nflush; fp->savvflag = vflag; vflag = 0; fp->savvpt = vpt; vpt = 0; fp->savhp = numtab[HP].val; fp->saveev = env; evc(&env, &env); in = in1 = 0; fi = 0; return charcount++; } static void restchar(struct fmtchar *fp, int keepf) { wbt(0); dip = fp->savedip; offset = dip->op; relsev(&env); if (keepf) { fp->saveev._apts = apts; fp->saveev._apts1 = apts1; fp->saveev._pts = pts; fp->saveev._pts1 = pts1; fp->saveev._font = font; fp->saveev._font1 = font1; fp->saveev._chbits = chbits; fp->saveev._spbits = spbits; } env = fp->saveev; nflush = fp->savnflush; vflag = fp->savvflag; vpt = fp->savvpt; numtab[HP].val = fp->savhp; } tchar setchar(tchar c) { struct fmtchar f; int k = trtab[cbits(c)]; tchar *csp; int charcount; int savxflag; int saveschar; #ifndef NROFF if (fchartab[k] && onfont(c)) return c; #endif if (iszbit(c)) return c; if ((charcount = prepchar(&f)) < 0) return ' '; fmtchar++; savxflag = xflag; xflag = 3; saveschar = eschar; eschar = '\\'; csp = chartab[k]; chartab[k] = NULL; pushback(csp); text(); tbreak(); nlflg = 0; charout[charcount].ch = c; if (iszbit(c)) charout[charcount].width = 0; else { charout[charcount].width = dip->maxl - lasttrack; width(' ' | sfmask(c)); charout[charcount].width += lasttrack; } charout[charcount].height = maxcht; charout[charcount].depth = maxcdp; restchar(&f, 0); chartab[k] = csp; eschar = saveschar; xflag = savxflag; fmtchar--; return mkxfunc(CHAR, charcount); } static tchar setZ(void) { struct fmtchar f; int charcount; tchar i; if (ismot(i = getch())) return 0; if ((charcount = prepchar(&f)) < 0) return 0; stopch = i; charout[charcount].ch = FILLER | sfmask(stopch); text(); if (nlflg) nodelim(stopch); charout[charcount].ch = 0; restchar(&f, 1); return mkxfunc(CHAR, charcount); } tchar sfmask(tchar _t) { while (isxfunc(_t, CHAR)) _t = charout[sbits(_t)].ch; if (_t == XFUNC || _t == SLANT || (_t & SFMASK) == 0) return chbits; return _t & SFMASK; } int issame(tchar c, tchar _d) { if (ismot(c) || ismot(_d)) return 0; while (isxfunc(c, CHAR)) c = charout[sbits(c)].ch; while (isxfunc(_d, CHAR)) _d = charout[sbits(_d)].ch; if (cbits(c) != cbits(_d)) return 0; if (cbits(c) == XFUNC && cbits(_d) == XFUNC) return fbits(c) == fbits(_d); return 1; } static int setgA(void) { extern const char nmctab[]; tchar c, delim; int k, y = 1; lgf++; delim = getch(); if (ismot(delim)) { lgf--; return 0; } while (k = cbits(c = getch()), !issame(c, delim) && !nlflg) if (ismot(c) || (k < ' ' && nmctab[k]) || k == ' ' || k >= 0200) y = 0; if (nlflg) y = 0; lgf--; return y; } static int setB(void) { tchar c, delim; int y = 1; lgf++; delim = getch(); if (ismot(delim)) { lgf--; return 0; } atoi0(); if (nonumb) y = 0; do { c = getch(); if (!ismot(c) && issame(c, delim)) break; y = 0; } while (!nlflg); lgf--; return y; } void caseescoff(void) { _caseesc(1); } void caseescon(void) { _caseesc(0); } static void _caseesc(int off) { int c; if (skip(1)) return; while (1) { c = cbits(getch()); if (c < 32 || c > 126) errprint("Invalid character '%c' for .esc%s\n", c, off ? "off" : "on"); else escoff[c-32] = (unsigned char)off; if (skip(0)) return; } } Index: projects/doctools/contrib/heirloom-doctools/troff/n2.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/n2.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/n2.c (revision 307812) @@ -1,511 +1,512 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1989 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "n2.c 1.9 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)n2.c 1.47 (gritter) 5/25/08 */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ /* * n2.c * * output, cleanup */ +#include #include #include #include #include #ifdef EUC #include #include #include #endif /* EUC */ #include "tdef.h" #ifdef NROFF #include "tw.h" #endif #include "pt.h" #include "ext.h" extern jmp_buf sjbuf; static int toolate; int error; static void outtp(tchar); int pchar(register tchar i) { register int j; static int hx = 0; /* records if have seen HX */ static int xon = 0; /* records if have seen XON */ static int drawfcn = 0; /* records if have seen DRAWFCN */ if (hx) { hx = 0; j = absmot(i); if (isnmot(i)) { if (j > dip->blss) dip->blss = j; } else { if (j > dip->alss) dip->alss = j; ralss = dip->alss; } return 1; } if (ismot(i)) { pchar1(i); return 1; } switch (j = cbits(i)) { case 0: case IMP: case RIGHT: case LEFT: if (xflag) { i = j = FILLER; /* avoid kerning in output routine */ goto dfl; } return 1; case HX: hx = 1; if (xflag) { i = j = FILLER; /* avoid kerning in output routine */ goto dfl; } return 1; case XON: xon = 1; goto dfl; case XOFF: xon = 0; goto dfl; case DRAWFCN: drawfcn = !drawfcn; goto dfl; case PRESC: if (dip == &d[0]) j = eschar; /* fall through */ default: dfl: #ifndef NROFF if (html) { if (!xflag || !isdi(i)) { setcbits(i, j >= NCHARS ? j : tflg ? trnttab[j] : trtab[j]); if (xon == 0 && drawfcn == 0 && i < NCHARS) setcbits(i, ftrans(fbits(i), cbits(i))); } } else #endif if (!xflag || !isdi(i)) { setcbits(i, tflg ? trnttab[j] : trtab[j]); if (xon == 0 && drawfcn == 0) setcbits(i, ftrans(fbits(i), cbits(i))); } } #ifdef NROFF if (xon && xflag) return 1; #endif /* NROFF */ pchar1(i); return 1; } void pchar1(register tchar i) { static int _olt; tchar _olp[1]; register int j; filep savip; extern void ptout(tchar); j = cbits(i); if (dip != &d[0]) { if (i == FLSS) dip->flss++; else if (dip->flss > 0) dip->flss--; else if (!ismot(i) && (cbits(i) > 32 || cbits(i) == XFUNC) && !tflg) i |= DIBIT; wbf(i); dip->op = offset; return; } if (!tflg && !print) { if (j == '\n') dip->alss = dip->blss = 0; return; } if (no_out) return; if (tflg) { /* transparent mode, undiverted */ outtp(i); return; } if (cbits(i) == XFUNC) { switch (fbits(i)) { case OLT: olt = realloc(olt, (nolt + 1) * sizeof *olt); _olt = 1; return; case CHAR: #ifndef NROFF if (!ascii) break; #endif /* !NROFF */ savip = ip; ip = charout[sbits(i)].op; app++; fmtchar++; while ((i = rbf()) != 0 && cbits(i) != '\n' && cbits(i) != FLSS) pchar(i); fmtchar--; app--; ip = savip; return; } } /* if (cbits(i) == 'x') fmtchar = fmtchar; */ if (_olt) { _olp[0] = i; olt[nolt++] = fetchrq(_olp); _olt = 0; } #ifndef NROFF if (ascii) outascii(i); else #endif ptout(i); } static void outtp(tchar i) { #ifndef NROFF int j = cbits(i); #ifdef EUC if (iscopy(i)) - fdprintf(ptid, "%lc", j); + dprintf(ptid, "%lc", j); else #endif /* EUC */ - fdprintf(ptid, "%c", j); + dprintf(ptid, "%c", j); #endif } #ifndef NROFF static void outmb(tchar i) { extern int nchtab; int j = cbits(i); #ifdef EUC wchar_t wc; char mb[MB_LEN_MAX+1]; int n; int f; #endif /* EUC */ if (j < 0177) { oput(j); return; } #ifdef EUC if (iscopy(i)) wc = cbits(i); else { if ((f = fbits(i)) == 0) f = font; wc = tr2un(j, f); } if (wc != -1 && (n = wctomb(mb, wc)) > 0) { mb[n] = 0; oputs(mb); } else #endif /* EUC */ if (j < 128 + nchtab) { oput('\\'); oput('('); oput(chname[chtab[j-128]]); oput(chname[chtab[j-128]+1]); } } void outascii ( /* print i in best-guess ascii */ tchar i ) { int j = cbits(i); int f = fbits(i); int k; if (j == FILLER) return; if (isadjspc(i)) return; if (ismot(i)) { oput(' '); return; } if ((j < 0177 && j >= ' ') || j == '\n') { oput(j); return; } if (f == 0) f = xfont; if (j == DRAWFCN) oputs("\\D"); else if (j == HYPHEN || j == MINUS) oput('-'); else if (j == XON) oputs("\\X"); else if (islig(i) && lgrevtab && lgrevtab[f] && lgrevtab[f][j]) { for (k = 0; lgrevtab[f][j][k]; k++) outmb(sfmask(i) | lgrevtab[f][j][k]); } else if (j == WORDSP) ; /* nothing at all */ else if (j > 0177) outmb(i); } #endif /* * now a macro oput(i) register int i; { *obufp++ = i; if (obufp >= &obuf[OBUFSZ]) flusho(); } */ void oputs(register const char *i) { while (*i != 0) oput(*i++&0377); } void flusho(void) { if (obufp == obuf) return; if (no_out == 0) { if (!toolate) { toolate++; #ifdef NROFF set_tty(); { char *p = t.twinit; while (*p++) ; if (p - t.twinit > 1) write(ptid, t.twinit, p - t.twinit - 1); } #endif } toolate += write(ptid, obuf, obufp - obuf); } obufp = obuf; } void caseoutput(void) { tchar i; copyf++; if (!skip(0)) { if (cbits(i = getch()) == '"') i = getch(); while (i != 0) { outtp(i); if (cbits(i) == '\n') break; i = getch(); } } copyf--; } void done(int x) { register int i; error |= x; dl = app = ds = lgf = 0; if (pgchars && !pglines) { donep = 1; tbreak(); donep = 0; } if ((i = em)) { donef = -1; em = 0; if (control(i, 0)) longjmp(sjbuf, 1); } if (!nfo) done3(0); mflg = 0; dip = &d[0]; if (woff) wbt((tchar)0); if (pendw) getword(1); pendnf = 0; if (donef == 1) done1(0); donef = 1; ip = 0; frame = stk; nxf = calloc(1, sizeof *nxf); if (!ejf) tbreak(); nflush++; eject((struct s *)0); longjmp(sjbuf, 1); } void done1(int x) { error |= x; if (numtab[NL].val) { trap = 0; eject((struct s *)0); longjmp(sjbuf, 1); } if (nofeed) { ptlead(); flusho(); done3(0); } else { pttrailer(); done2(0); } } void done2(int x) { ptlead(); #ifndef NROFF if (!ascii) ptstop(); #endif flusho(); done3(x); } void done3(int x) { error |= x; signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); #ifdef NROFF twdone(); #endif if (ascii) mesg(1); exit(error); } void edone(int x) { frame = stk; nxf = calloc(1, sizeof *nxf); ip = 0; done(x); } void casepi(void) { register pid_t i; int id[2]; if (skip(1)) return; if (toolate || !getname() || pipe(id) == -1 || (i = fork()) == -1) { errprint("Pipe not created."); return; } ptid = id[1]; if (i > 0) { close(id[0]); toolate++; pipeflg = i; return; } close(0); dup(id[0]); close(id[1]); execl(nextf, nextf, NULL); errprint("Cannot exec %s", nextf); exit(-4); } Index: projects/doctools/contrib/heirloom-doctools/troff/n3.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/n3.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/n3.c (revision 307812) @@ -1,2366 +1,2356 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "n3.c 1.11 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)n3.c 1.181 (gritter) 10/23/09 */ /* * Changes Copyright (c) 2014 Steffen Nurpmeso */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ /* * troff3.c * * macro and string routines, storage allocation */ #include #include #include #include #include #include "tdef.h" #ifdef NROFF #include "tw.h" #endif #include "pt.h" #include "ext.h" #include #define MHASH(x) ((x>>6)^x)&0177 static struct contab **mhash; /* size must be 128 == the 0177 on line above */ #define blisti(i) (((i)-ENV_BLK*BLK) / BLK) static filep *blist; static int nblist; static int pagech = '%'; static int strflg; static tchar *wbuf; tchar *corebuf; struct contab *oldmn; struct contab *newmn; static void mrehash(struct contab *, int, struct contab **); static void _collect(int); static struct contab *_findmn(int, int, int); static void clrmn(struct contab *); static void caselds(void); static void casewatchlength(void); static void caseshift(void); static void casesubstring(void); static void caselength(void); static void caseindex(void); static void caseasciify(void); static void caseunformat(int); static int getls(int, int *, int); -static void addcon(int, char *, void(*)(int)); +static void addcon(int, const char *, void(*)(int)); static const struct { const char *n; void (*f)(int); } longrequests[] = { { "aln", (void(*)(int))casealn }, { "als", (void(*)(int))caseals }, { "asciify", (void(*)(int))caseasciify }, { "bleedat", (void(*)(int))casebleedat }, { "blm", (void(*)(int))caseblm }, { "brnl", (void(*)(int))casebrnl }, { "brpnl", (void(*)(int))casebrpnl }, { "box", (void(*)(int))casebox}, { "boxa", (void(*)(int))caseboxa}, { "break", (void(*)(int))casebreak}, { "breakchar", (void(*)(int))casebreakchar }, { "brp", (void(*)(int))casebrp }, { "char", (void(*)(int))casechar }, { "chomp", (void(*)(int))casechomp }, { "chop", (void(*)(int))casechop }, { "close", (void(*)(int))caseclose }, { "connectchar", (void(*)(int))caseconnectchar }, { "continue", (void(*)(int))casecontinue }, { "cropat", (void(*)(int))casecropat }, { "dch", (void(*)(int))casedch }, { "dwh", (void(*)(int))casedwh }, { "ecs", (void(*)(int))caseecs }, { "ecr", (void(*)(int))caseecr }, { "errprint", (void(*)(int))caseerrprint }, { "escoff", (void(*)(int))caseescoff }, { "escon", (void(*)(int))caseescon }, { "evc", (void(*)(int))caseevc }, { "fallback", (void(*)(int))casefallback }, { "fchar", (void(*)(int))casefchar }, { "fdeferlig", (void(*)(int))casefdeferlig }, { "feature", (void(*)(int))casefeature }, { "fkern", (void(*)(int))casefkern }, { "flig", (void(*)(int))caseflig }, { "fps", (void(*)(int))casefps }, { "fspacewidth", (void(*)(int))casefspacewidth }, { "ftr", (void(*)(int))caseftr }, { "fzoom", (void(*)(int))casefzoom }, { "hcode", (void(*)(int))casehcode }, { "hidechar", (void(*)(int))casehidechar }, { "hlm", (void(*)(int))casehlm }, { "hylang", (void(*)(int))casehylang }, { "hylen", (void(*)(int))casehylen }, { "hypp", (void(*)(int))casehypp }, { "index", (void(*)(int))caseindex }, { "itc", (void(*)(int))caseitc }, { "kern", (void(*)(int))casekern }, { "kernafter", (void(*)(int))casekernafter }, { "kernbefore", (void(*)(int))casekernbefore }, { "kernpair", (void(*)(int))casekernpair }, { "lc_ctype", (void(*)(int))caselc_ctype }, { "lds", (void(*)(int))caselds }, { "length", (void(*)(int))caselength }, { "letadj", (void(*)(int))caseletadj }, { "lhang", (void(*)(int))caselhang }, { "lnr", (void(*)(int))caselnr }, { "lnrf", (void(*)(int))caselnrf }, { "lpfx", (void(*)(int))caselpfx }, { "lsm", (void(*)(int))caselsm }, { "mediasize", (void(*)(int))casemediasize }, { "minss", (void(*)(int))caseminss }, { "nhychar", (void(*)(int))casenhychar }, { "nop", (void(*)(int))casenop }, { "nrf", (void(*)(int))casenrf }, { "open", (void(*)(int))caseopen }, { "opena", (void(*)(int))caseopena }, { "output", (void(*)(int))caseoutput }, { "padj", (void(*)(int))casepadj }, { "papersize", (void(*)(int))casepapersize }, { "psbb", (void(*)(int))casepsbb }, { "pshape", (void(*)(int))casepshape }, { "pso", (void(*)(int))casepso }, { "rchar", (void(*)(int))caserchar }, { "recursionlimit", (void(*)(int))caserecursionlimit }, { "return", (void(*)(int))casereturn }, { "rhang", (void(*)(int))caserhang }, { "rnn", (void(*)(int))casernn }, { "sentchar", (void(*)(int))casesentchar }, { "shc", (void(*)(int))caseshc }, { "shift", (void(*)(int))caseshift }, { "spacewidth", (void(*)(int))casespacewidth }, { "spreadwarn", (void(*)(int))casespreadwarn }, { "substring", (void(*)(int))casesubstring }, { "tmc", (void(*)(int))casetmc }, { "track", (void(*)(int))casetrack }, { "transchar", (void(*)(int))casetranschar }, { "trimat", (void(*)(int))casetrimat }, { "trin", (void(*)(int))casetrin }, { "trnt", (void(*)(int))casetrnt }, { "unformat", (void(*)(int))caseunformat }, { "unwatch", (void(*)(int))caseunwatch }, { "unwatchn", (void(*)(int))caseunwatchn }, #ifdef NROFF { "utf8conv", (void(*)(int))caseutf8conv }, #endif { "vpt", (void(*)(int))casevpt }, { "warn", (void(*)(int))casewarn }, { "watch", (void(*)(int))casewatch }, { "watchlength", (void(*)(int))casewatchlength }, { "watchn", (void(*)(int))casewatchn }, { "while", (void(*)(int))casewhile }, { "write", (void(*)(int))casewrite }, { "writec", (void(*)(int))casewritec }, { "writem", (void(*)(int))casewritem }, { "xflag", (void(*)(int))casexflag }, { NULL, NULL } }; static void * _growcontab(struct contab **contp, int *NMp, struct contab ***hashp) { int i, j, inc = 256; ptrdiff_t sft; struct contab *onc; struct s *s; onc = *contp; if ((*contp = realloc(*contp, (*NMp+inc) * sizeof **contp)) == NULL) return NULL; memset(&(*contp)[*NMp], 0, inc * sizeof **contp); if (*NMp == 0) { if (contp == &contab) { for (i = 0; initcontab[i].f; i++) (*contp)[i] = initcontab[i]; for (j = 0; longrequests[j].f; j++) addcon(i++, longrequests[j].n, longrequests[j].f); } *hashp = calloc(128, sizeof **hashp); mrehash(*contp, inc, *hashp); } else { sft = (char *)*contp - (char *)onc; for (i = 0; i < 128; i++) if ((*hashp)[i]) (*hashp)[i] = (struct contab *) ((char *)((*hashp)[i]) + sft); for (i = 0; i < *NMp; i++) if ((*contp)[i].link) (*contp)[i].link = (struct contab *) ((char *)((*contp)[i].link) + sft); for (s = frame; s != stk; s = s->pframe) if (s->contp >= onc && s->contp < &onc[*NMp]) s->contp = (struct contab *) ((char *)(s->contp) + sft); for (i = 0; i <= dilev; i++) if (d[i].soff >= onc && d[i].soff < &onc[*NMp]) d[i].soff = (struct contab *) ((char *)(d[i].soff) + sft); } *NMp += inc; return *contp; } void * growcontab(void) { return _growcontab(&contab, &NM, &mhash); } void * growblist(void) { static tchar *_corebuf; int inc = 512; tchar *ocb; if ((blist = realloc(blist, (nblist+inc) * sizeof *blist)) == NULL) return NULL; memset(&blist[nblist], 0, inc * sizeof *blist); ocb = _corebuf; if ((_corebuf = realloc(_corebuf, ((ENV_BLK+nblist+inc+1) * BLK + 1) * sizeof *_corebuf)) == NULL) return NULL; if (ocb == NULL) memset(_corebuf, 0, ((ENV_BLK+1) * BLK + 1) * sizeof *_corebuf); corebuf = &_corebuf[1]; memset(&corebuf[(ENV_BLK+nblist+1) * BLK], 0, inc * BLK * sizeof *corebuf); if (wbuf) wbuf = (tchar *)((char *)wbuf + ((char *)corebuf-(char *)ocb)); nblist += inc; return blist; } void caseig(void) { register int i; register filep oldoff; oldoff = offset; offset = 0; i = copyb(); offset = oldoff; if (i != '.') control(i, 1); } void casern(void) { register int i, j; lgf++; skip(1); if ((i = getrq(0)) == 0) return; if ((oldmn = _findmn(i, 0, 0)) == NULL) { nosuch(i); return; } skip(1); j = getrq(1); clrmn(_findmn(j, 0, oldmn->flags & FLAG_LOCAL)); if (j) { munhash(oldmn); oldmn->rq = j; maddhash(oldmn); if (oldmn->flags & FLAG_WATCH) errprint("%s: %s%s renamed to %s", macname(lastrq), oldmn->flags & FLAG_LOCAL ? "local " : "", macname(i), macname(j)); } } static struct contab ** gethash(struct contab *mp) { struct s *sp; struct contab **mh; if (mp >= contab && mp < &contab[NM]) mh = mhash; else { sp = macframe(); if (mp >= sp->contab && mp < &sp->contab[sp->NM]) mh = sp->mhash; else mh = NULL; } return mh; } void maddhash(register struct contab *rp) { register struct contab **hp; struct contab **mh; if (rp->rq == 0) return; if ((mh = gethash(rp)) == NULL) return; hp = &mh[MHASH(rp->rq)]; rp->link = *hp; *hp = rp; } void munhash(register struct contab *mp) { register struct contab *p; register struct contab **lp; struct contab **mh; if (mp->rq == 0) return; if ((mh = gethash(mp)) == NULL) return; lp = &mh[MHASH(mp->rq)]; p = *lp; while (p) { if (p == mp) { *lp = p->link; p->link = 0; return; } lp = &p->link; p = p->link; } } static void mrehash(struct contab *contp, int n, struct contab **hashp) { register struct contab *p; register int i; for (i=0; i<128; i++) hashp[i] = 0; for (p=contp; p < &contp[n]; p++) p->link = 0; for (p=contp; p < &contp[n]; p++) { if (p->rq == 0) continue; i = MHASH(p->rq); p->link = hashp[i]; hashp[i] = p; } } void caserm(void) { struct contab *contp, *contt; int j, cnt = 0; lgf++; while (!skip(!cnt++)) { if ((j = getrq(2)) <= 0) continue; if ((contp = _findmn(j, 0, 0)) == NULL) continue; if (contp->als) { contt = _findmn(j, 1, contp->flags & FLAG_LOCAL); /* bugfix by S.N. */ if (contt != NULL && --contt->nlink <= 0) clrmn(contt); } if (contp->nlink > 0) contp->nlink--; if (contp->flags & FLAG_WATCH) errprint("%s: %s%s removed", macname(lastrq), contp->flags & FLAG_LOCAL ? "local " : "", macname(j)); if (contp->nlink <= 0) clrmn(contp); } lgf--; } void caseas(void) { app++; caseds(); } void caseds(void) { ds++; casede(); } void caseam(void) { app++; casede(); } static void caselds(void) { dl += macframe() != stk; caseds(); } void casede(void) { register int i, req; register filep savoff; int k, nlink; if (dip != d) wbfl(); req = '.'; lgf++; skip(1); if ((i = getrq(1)) == 0) goto de1; if ((offset = finds(i, 1, !ds)) == 0) goto de1; if (ds) copys(); else req = copyb(); wbfl(); if (oldmn != NULL && (nlink = oldmn->nlink) > 0) k = oldmn->rq; else { k = i; nlink = 0; } clrmn(oldmn); if (newmn != NULL) { if (newmn->rq) munhash(newmn); newmn->rq = k; newmn->nlink = nlink; newmn->flags &= ~FLAG_DIVERSION; if (ds) newmn->flags |= FLAG_STRING; else newmn->flags &= ~FLAG_STRING; maddhash(newmn); prwatch(newmn, i, 1); } else if (apptr) prwatch(findmn(i), i, 1); if (apptr) { savoff = offset; offset = apptr; wbt((tchar) IMP); offset = savoff; } offset = dip->op; if (req != '.') control(req, 1); de1: ds = app = 0; return; } static struct contab * findmn1(struct contab **hashp, register int i, int als) { register struct contab *p; for (p = hashp[MHASH(i)]; p; p = p->link) if (i == p->rq) { if (als && p->als) return(findmn1(hashp, p->als, als)); return(p); } return(NULL); } static struct contab * _findmn(register int i, int als, int forcelocal) { struct s *s; struct contab *contp; s = macframe(); if (forcelocal || (s != stk && s->mhash)) { if (s->mhash == NULL) return NULL; if ((contp = findmn1(s->mhash, i, als)) != NULL) return contp; if (forcelocal) return NULL; } return findmn1(mhash, i, als); } struct contab * findmn(int i) { return _findmn(i, 1, 0); } struct contab * findmx(int i) { return findmn1(mhash, i, 1); } void clrmn(struct contab *contp) { struct s *s; if (contp != NULL) { if (contp->flags & FLAG_USED) { if (warn & WARN_MAC) errprint("Macro %s removed while in use", macname(contp->rq)); for (s = frame; s != stk; s = s->pframe) if (s->contp == contp) s->contp = NULL; } else if (contp->mx) ffree((filep)contp->mx); munhash(contp); memset(contp, 0, sizeof *contp); contp->rq = 0; contp->mx = 0; contp->f = 0; contp->als = 0; contp->nlink = 0; } } /* * Note: finds() may invalidate the result of a previous findmn() * for another macro since it may call growcontab(). */ filep finds(register int mn, int als, int globonly) { register tchar i; register filep savip; enum flags flags = 0; struct s *s; struct contab **contp, ***hashp; int *NMp; oldmn = _findmn(mn, als, dl); newmn = NULL; apptr = (filep)0; if (oldmn != NULL) flags = oldmn->flags; if (globonly && (dl || (oldmn && oldmn->flags & FLAG_LOCAL))) { errprint("refusing to create local %s %s", diflg || (oldmn && oldmn->flags & FLAG_DIVERSION) ? "diversion" : "macro", macname(mn)); app = 0; return(0); } if (app && oldmn != NULL && oldmn->mx) { savip = ip; ip = (filep)oldmn->mx; oldmn = NULL; while ((i = rbf()) != 0) { if (!diflg && istail(i)) corebuf[ip - 1] &= ~(tchar)TAILBIT; } apptr = ip; if (!diflg) ip = incoff(ip); nextb = ip; ip = savip; } else { if (oldmn && oldmn->flags & FLAG_LOCAL) dl++; if (dl && (s = macframe()) != stk) { contp = &s->contab; NMp = &s->NM; hashp = &s->mhash; } else { dl = 0; contp = &contab; NMp = &NM; hashp = &mhash; } for (i = 0; i < *NMp; i++) { if ((*contp)[i].rq == 0) break; } nextb = 0; if ((i == *NMp && _growcontab(contp, NMp, hashp) == NULL) || (als && (nextb = alloc()) == 0)) { app = 0; if (macerr++ > 1) done2(02); errprint("Too many (%d) string/macro names", NM); edone(04); return(als ? offset = 0 : 0); } oldmn = _findmn(mn, als, dl); (*contp)[i].mx = (unsigned) nextb; newmn = &(*contp)[i]; if (!diflg) { if (oldmn == NULL) newmn->rq = -1; } else { newmn->rq = mn; maddhash(newmn); } newmn->flags = flags&(FLAG_WATCH|FLAG_STRING|FLAG_DIVERSION); if (dl) newmn->flags |= FLAG_LOCAL; } dl = app = 0; return(als ? offset = nextb : 1); } int skip (int required) /*skip over blanks; return nlflg*/ { register tchar i; while (cbits(i = getch()) == ' ') ; ch = i; if (nlflg && required) missing(); return(nlflg); } int copyb(void) { register int i, j, state; register tchar ii; int req; filep savoff = 0, tailoff = 0; tchar tailc = 0; const char *contp; char *mn; - size_t l; if (skip(0) || !(j = getrq(1))) j = '.'; req = j; contp = macname(req); - l = strlen(contp) + 1; - mn = malloc(l); - n_strcpy(mn, contp, l); + mn = strdup(contp); copyf++; flushi(); nlflg = 0; state = 1; /* state 0 eat up * state 1 look for . * state 2 look for chars of end macro */ while (1) { i = cbits(ii = getch()); if (state == 2 && mn[j] == 0) { ch = ii; if (!getach()) break; state = 0; goto c0; } if (i == '\n') { state = 1; nlflg = 0; tailoff = offset; tailc = ii; ii &= ~(tchar)TAILBIT; goto c0; } if (state == 1 && i == '.') { state++; savoff = offset; j = 0; goto c0; } if (state == 2) { if (i == mn[j]) { j++; goto c0; } else if (i == ' ' || i == '\t') { goto c0; } } state = 0; c0: if (offset) wbf(ii); } if (offset) { wbfl(); offset = savoff; wbt((tchar)0); if (tailoff) { offset = tailoff; wbt(tailc | TAILBIT); } } copyf--; free(mn); return(req); } void copys(void) { register tchar i; copyf++; if (skip(0)) goto c0; if (cbits(i = getch()) != '"') wbf(i); while (cbits(i = getch()) != '\n') wbf(i); c0: wbt((tchar)0); copyf--; } filep alloc (void) /*return free blist[] block in nextb*/ { register int i; register filep j; do { for (i = 0; i < nblist; i++) { if (blist[i] == 0) break; } } while (i == nblist && growblist() != NULL); if (i == nblist) { j = 0; } else { blist[i] = -1; j = (filep)i * BLK + ENV_BLK * BLK; } #ifdef DEBUG if (debug & DB_ALLC) { char cc1, cc2; fprintf(stderr, "alloc: "); if (oldmn != NULL) { cc1 = oldmn->rq & 0177; if ((cc2 = (oldmn->rq >> BYTE) & 0177) == 0) cc2 = ' '; fprintf(stderr, "oldmn %p %c%c, ", oldmn, cc1, cc2); } fprintf(stderr, "newmn %p; nextb was %lx, will be %lx\n", newmn, (long)nextb, (long)j); } #endif /* DEBUG */ return(nextb = j); } void ffree ( /*free blist[i] and blocks pointed to*/ filep i ) { register int j; while (blist[j = blisti(i)] != (int) ~0) { i = (filep) blist[j]; blist[j] = 0; } blist[j] = 0; } void wbt(tchar i) { wbf(i); wbfl(); } void wbf ( /*store i into blist[offset] (?) */ register tchar i ) { register int j; if (!offset) return; if (!woff) { woff = offset; wbuf = &corebuf[woff]; wbfi = 0; } wbuf[wbfi++] = i; if (!((++offset) & (BLK - 1))) { wbfl(); j = blisti(--offset); if (j < 0 || (j >= nblist && growblist() == NULL)) { errprint("Out of temp file space"); done2(01); } if (blist[j] == (int) ~0) { if (alloc() == 0) { errprint("Out of temp file space"); done2(01); } blist[j] = (unsigned)(nextb); } offset = ((filep)blist[j]); } if (wbfi >= BLK) wbfl(); } void wbfl (void) /*flush current blist[] block*/ { if (woff == 0) return; if ((woff & (~(BLK - 1))) == (roff & (~(BLK - 1)))) roff = -1; woff = 0; } tchar rbf (void) /*return next char from blist[] block*/ { register tchar i; register filep j, p; if (ip == -1) { /* for rdtty */ if ((j = rdtty())) return(j); else return(popi()); } if (ip == -2) { errprint("Bad storage while processing paragraph"); ip = 0; done2(-5); } /* this is an inline expansion of rbf0: dirty! */ i = corebuf[ip]; /* end of rbf0 */ if (i == 0) { if (!app) i = popi(); return(i); } /* this is an inline expansion of incoff: also dirty */ p = ++ip; if ((p & (BLK - 1)) == 0) { if ((ip = blist[blisti(p-1)]) == (int) ~0) { errprint("Bad storage allocation"); ip = 0; done2(-5); } /* this was meant to protect against people removing * the macro they were standing on, but it's too * sensitive to block boundaries. * if (ip == 0) { * errprint("Block removed while in use"); * done2(-6); * } */ } return(i); } tchar rbf0(register filep p) { return(corebuf[p]); } filep incoff ( /*get next blist[] block*/ register filep p ) { p++; if ((p & (BLK - 1)) == 0) { if ((p = blist[blisti(p-1)]) == (int) ~0) { errprint("Bad storage allocation"); done2(-5); } } return(p); } tchar popi(void) { register struct s *p; tchar c, _d; if (frame == stk) return(0); if (strflg) strflg--; p = frame; sfree(p); if (p->contp != NULL) p->contp->flags &= ~FLAG_USED; frame = p->pframe; ip = p->pip; pendt = p->ppendt; lastpbp = p->lastpbp; c = p->pch; if (p->loopf & LOOP_NEXT) { _d = ch; ch = c; pushi(p->newip, p->mname, p->flags); c = 0; ch = _d; } else if (p->loopf & LOOP_FREE) ffree(p->newip); free(p); if (frame->flags & FLAG_PARAGRAPH) longjmp(*frame->jmp, 1); return(c); } int pushi(filep newip, int mname, enum flags flags) { register struct s *p; p = nxf; p->pframe = frame; p->pip = ip; p->ppendt = pendt; p->pch = ch; p->lastpbp = lastpbp; p->mname = mname; p->flags = flags; if (mname != LOOP) { p->frame_cnt = frame->frame_cnt + 1; p->tail_cnt = frame->tail_cnt + 1; } else { p->frame_cnt = frame->frame_cnt; p->tail_cnt = frame->tail_cnt; p->loopf = LOOP_EVAL; } p->newip = newip; lastpbp = pbp; pendt = ch = 0; frame = nxf; nxf = calloc(1, sizeof *nxf); return(ip = newip); } void sfree(struct s *p) { int i; if (p->nargs > 0) { free(p->argt); free(p->argsp); } free(p->numtab); free(p->nhash); if (p->contab) { for (i = 0; i < p->NM; i++) if (p->contab[i].mx > 0) ffree((filep)p->contab[i].mx); free(p->contab); free(p->mhash); } } struct s * macframe(void) { struct s *p; for (p = frame; p != stk && (p->flags & (FLAG_STRING|FLAG_DIVERSION) || p->loopf); p = p->pframe); return(p); } static int _getsn(int *strp, int create) { register int i; if ((i = getach()) == 0) return(0); if (i == '(') return(getrq2()); else if (i == '[' && xflag > 1) return(getls(']', strp, create)); else return(i); } int getsn(int create) { return _getsn(0, create); } int setstr(void) { struct contab *contp; register int i, k; int space = 0; tchar c; lgf++; if ((i = _getsn(&space, 0)) == 0 || (contp = findmn(i)) == NULL || !contp->mx) { if (space) { do { if (cbits(c = getch()) == ']') break; } while (!nlflg); if (nlflg) nodelim(']'); } nosuch(i); lgf--; return(0); } else { if (space) _collect(']'); else nxf->nargs = 0; strflg++; lgf--; contp->flags |= FLAG_USED; k = pushi((filep)contp->mx, i, contp->flags); frame->contp = contp; return(k); } } void collect(void) { _collect(0); } static void _collect(int termc) { register tchar i = 0; int at = 0, asp = 0; int nt = 0, nsp = 0, nsp0; int quote, right; struct s *savnxf; copyf++; nxf->nargs = 0; nxf->argt = NULL; nxf->argsp = NULL; savnxf = nxf; nxf = calloc(1, sizeof *nxf); if (skip(0)) goto rtn; strflg = 0; while (!skip(0)) { if (nt >= at) savnxf->argt = realloc(savnxf->argt, (at += 10) * sizeof *savnxf->argt); savnxf->argt[nt] = nsp0 = nsp; /* CK: Bugfix: \} counts \n(.$ */ quote = right = 0; if (cbits(i = getch()) == '"') quote++; else ch = i; while (1) { i = getch(); if (termc && !quote && i == termc) { if (nsp >= asp) savnxf->argsp = realloc(savnxf->argsp, ++asp * sizeof *savnxf->argsp); nt++; savnxf->argsp[nsp++] = 0; goto rtn; } if (nlflg || (!quote && cbits(i) == ' ')) break; if ( quote && (cbits(i) == '"') && (cbits(i = getch()) != '"')) { ch = i; break; } if (nsp >= asp) savnxf->argsp = realloc(savnxf->argsp, (asp += 200) * sizeof *savnxf->argsp); if (cbits(i) == RIGHT) /* CK: Bugfix: \} counts \n(.$ */ right = 1; else savnxf->argsp[nsp++] = i; } if (nsp >= asp) savnxf->argsp = realloc(savnxf->argsp, ++asp * sizeof *savnxf->argsp); if (!right || nsp != nsp0) { /* CK: Bugfix: \} counts \n(.$ */ nt++; savnxf->argsp[nsp++] = 0; } } rtn: if (termc && i != termc) nodelim(termc); free(nxf); nxf = savnxf; nxf->nargs = nt; copyf--; } void seta(void) { register int c, i; char q[] = { 0, 0 }; struct s *s; for (s = frame; s != stk; s = s->pframe) { if (s->loopf) continue; if (gflag && s->contp && s->contp->flags & FLAG_STRING && s->nargs == 0) continue; break; } switch (c = cbits(getch())) { case '@': q[0] = '"'; /*FALLTHRU*/ case '*': if (xflag == 0) goto dfl; for (i = s->nargs; i >= 1; i--) { if (q[0]) cpushback(q); pushback(&s->argsp[s->argt[i - 1]]); if (q[0]) cpushback(q); if (i > 1) cpushback(" "); } break; case '(': if (xflag == 0) goto dfl; c = cbits(getch()); i = 10 * (c - '0'); c = cbits(getch()); i += c - '0'; goto assign; case '[': if (xflag == 0) goto dfl; i = 0; while ((c = cbits(getch())) != ']' && c != '\n' && c != 0) i = 10 * i + (c - '0'); goto assign; default: dfl: i = c - '0'; assign: if (i > 0 && i <= s->nargs) pushback(&s->argsp[s->argt[i - 1]]); else if (i == 0) cpushback(macname(s->mname)); } } static void caseshift(void) { int i, j; struct s *s; for (s = frame; s->loopf && s != stk; s = s->pframe); if (skip(0)) i = 1; else { noscale++; i = hatoi(); noscale--; if (nonumb) return; } if (i > 0 && i <= s->nargs) { s->nargs -= i; for (j = 1; j <= s->nargs; j++) s->argt[j - 1] = s->argt[j + i - 1]; } } void casebox(void) { casedi(1); } void caseboxa(void) { caseda(1); } void caseda(int box) { app++; casedi(box); } void casedi(int box) { register int i, j; register int *k; int nlink; lgf++; if (skip(0) || (i = getrq(1)) == 0) { if (dip != d) wbt((tchar)0); if (dilev > 0) { #ifdef DEBUG if (debug & DB_MAC) fprintf(stderr, "ending diversion %s\n", macname(dip->curd)); #endif /* DEBUG */ numtab[DN].val = dip->dnl; numtab[DL].val = dip->maxl; prwatchn(&numtab[DN]); prwatchn(&numtab[DL]); if (dip->boxenv) { relsev(&env); env = *dip->boxenv; free(dip->boxenv); } prwatch(dip->soff, dip->curd, 1); dip = &d[--dilev]; offset = dip->op; } else if (warn & WARN_DI) errprint(".di outside active diversion"); goto rtn; } #ifdef DEBUG if (debug & DB_MAC) fprintf(stderr, "starting diversion %s\n", macname(i)); #endif /* DEBUG */ if (++dilev == NDI) { struct d *nd; const int inc = 5; if ((nd = realloc(d, (NDI+inc) * sizeof *d)) == NULL) { --dilev; errprint("Diversions nested too deep"); edone(02); } d = nd; memset(&d[NDI], 0, inc * sizeof *d); NDI += inc; } if (dip != d) wbt((tchar)0); diflg++; dip = &d[dilev]; if ((dip->op = finds(i, 1, 1)) == 0) { dip = &d[--dilev]; goto rtn; } dip->curd = i; if (newmn && oldmn != NULL && (nlink = oldmn->nlink) > 0) { munhash(newmn); j = oldmn->rq; } else { j = i; nlink = 0; } clrmn(oldmn); if (newmn) { newmn->rq = j; newmn->nlink = nlink; newmn->flags &= ~FLAG_STRING; newmn->flags |= FLAG_DIVERSION; if (i != j) maddhash(newmn); prwatch(newmn, i, 0); } dip->soff = newmn; k = &dip->dnl; dip->flss = 0; for (j = 0; j < 10; j++) k[j] = 0; /*not op and curd*/ memset(dip->mlist, 0, sizeof dip->mlist); memset(dip->nlist, 0, sizeof dip->nlist); if (box) { dip->boxenv = malloc(sizeof *dip->boxenv); *dip->boxenv = env; evc(&env, &env); } else dip->boxenv = 0; rtn: app = 0; diflg = 0; } void casedt(void) { lgf++; dip->dimac = dip->ditrap = dip->ditf = 0; skip(0); dip->ditrap = vnumb((int *)0); if (nonumb) return; skip(0); dip->dimac = getrq(1); } void caseals(void) { struct contab *contp; int i, j, _t; int flags = 0; if (skip(1)) return; i = getrq(1); if (skip(1)) return; j = getrq(1); if ((contp = findmn(j)) == NULL) { nosuch(j); return; } if (contp->nlink == 0) { munhash(contp); _t = makerq(NULL); contp->rq = _t; maddhash(contp); if (contp->flags & FLAG_LOCAL) dl++; if (finds(j, 0, 0) != 0 && newmn) { newmn->als = _t; newmn->rq = j; maddhash(newmn); contp->nlink = 1; } } else _t = j; if (contp->flags & FLAG_LOCAL) dl++; if (finds(i, 0, !dl) != 0) { if (oldmn != NULL && newmn != NULL) flags = oldmn->flags | newmn->flags; flags &= FLAG_WATCH|FLAG_STRING|FLAG_DIVERSION; clrmn(oldmn); if (newmn) { if (newmn->rq) munhash(newmn); newmn->als = _t; newmn->rq = i; newmn->flags |= flags; maddhash(newmn); contp = findmn(j); contp->nlink++; if (flags & FLAG_WATCH) errprint("%s: creating alias %s to %s%s %s", macname(lastrq), contp->flags & FLAG_LOCAL ? "local " : "", contp->flags & FLAG_STRING ? "string" : contp->flags & FLAG_DIVERSION ? "diversion" : "macro", macname(i), macname(j)); } } } void casewatch(int unwatch) { struct contab *contp; int j; lgf++; if (skip(1)) return; do { if (!(j = getrq(1))) break; if ((contp = findmn(j)) == NULL) { if (finds(j, 0, 0) == 0 || newmn == NULL) continue; if (newmn->rq) munhash(newmn); newmn->rq = j; maddhash(newmn); contp = newmn; } if (unwatch) contp->flags &= ~FLAG_WATCH; else contp->flags |= FLAG_WATCH; } while (!skip(0)); } void caseunwatch(void) { casewatch(1); } static int watchlength = 30; static void casewatchlength(void) { int i; if (!skip(1)) { noscale++; i = hatoi(); noscale--; if (!nonumb) watchlength = i; if (watchlength < 0) watchlength = 0; } } void prwatch(struct contab *contp, int rq, int prc) { const char prtab[] = { 'a',000,000,000,000,000,000,000, 'b','t','n',000,000,000,000,000, '{','}','&',000,'%','c','e',' ', '!',000,000,000,000,000,000,'~', 000 }; char *buf = NULL; const char *local; filep savip; tchar c; int j, k; if (contp == NULL) return; if (rq == 0) rq = contp->rq; local = contp->flags & FLAG_LOCAL ? "local " : ""; if (contp->flags & FLAG_WATCH) { if (watchlength <= 10 || !prc) { errprint("%s: %s%s %s redefined", macname(lastrq), local, contp->flags & FLAG_STRING ? "string" : contp->flags & FLAG_DIVERSION ? "diversion" : "macro", macname(rq)); return; } savip = ip; ip = (filep)contp->mx; app++; j = 0; buf = malloc(watchlength); while ((c = rbf()) != 0) { while (isxfunc(c, CHAR)) c = charout[sbits(c)].ch; if (iscopy(c) && (k = wctomb(&buf[j], cbits(c))) > 0) j += k; else if (ismot(c)) buf[j++] = '?'; else if ((k = cbits(c)) < 0177) { if (isprint(k)) buf[j++] = k; else if (istrans(c)) { buf[j++] = '\\'; buf[j++] = ')'; } else if (k < ' ' && prtab[k]) { buf[j++] = '\\'; buf[j++] = prtab[k]; } else if (k < ' ') { buf[j++] = '^'; buf[j++] = k + 0100; } else buf[j++] = '?'; } else if (k == ACUTE) buf[j++] = '\''; else if (k == GRAVE) buf[j++] = '`'; else if (j == UNDERLINE) buf[j++] = '_'; else if (j == MINUS) buf[j++] = '-'; else buf[j++] = '?'; if (j >= watchlength - 5 - mb_cur_max) { buf[j++] = '.'; buf[j++] = '.'; buf[j++] = '.'; break; } } buf[j] = 0; ip = savip; app--; errprint("%s: %s%s %s redefined to \"%s\"", macname(lastrq), local, contp->flags & FLAG_STRING ? "string" : contp->flags & FLAG_DIVERSION ? "diversion" : "macro", macname(rq), buf); free(buf); } } void casetl(void) { register int j; int w[3]; tchar *buf = NULL; int bufsz = 0; register tchar *tp; tchar i, delim, nexti; int oev; dip->nls = 0; skip(1); if (ismot(delim = getch())) { ch = delim; delim = '\''; } else delim = cbits(delim); noschr = 0; argdelim = delim; bufsz = LNSIZE; buf = malloc(bufsz * sizeof *buf); tp = buf; numtab[HP].val = 0; w[0] = w[1] = w[2] = 0; j = 0; nexti = getch(); while (cbits(i = nexti) != '\n') { if (cbits(i) == cbits(delim)) { if (j < 3) w[j] = numtab[HP].val; numtab[HP].val = 0; j++; *tp++ = 0; nexti = getch(); } else { if (cbits(i) == pagech) { setn1(numtab[PN].val, findr('%')->fmt, sfmask(i)); nexti = getch(); continue; } numtab[HP].val += width(i); oev = ev; nexti = getch(); if (ev == oev) numtab[HP].val += kernadjust(i, nexti); if (tp >= &buf[bufsz-10]) { tchar *k; bufsz += 100; k = realloc(buf, bufsz * sizeof *buf); tp = (tchar *) ((char *)tp + ((char *)k - (char *)buf)); buf = k; } *tp++ = i; } } argdelim = 0; if (j<3) w[j] = numtab[HP].val; *tp++ = 0; *tp++ = 0; *tp++ = 0; tp = buf; #ifdef NROFF horiz(po); #endif while ((i = *tp++)) pchar(i); if (w[1] || w[2]) { #ifdef NROFF if (gemu) horiz(j = quant((lt + HOR - w[1]) / 2 - w[0], HOR)); else #endif horiz(j = quant((lt - w[1]) / 2 - w[0], HOR)); } while ((i = *tp++)) pchar(i); if (w[2]) { horiz(lt - w[0] - w[1] - w[2] - j); while ((i = *tp++)) pchar(i); } newline(0); if (dip != d) { if (dip->dnl > dip->hnl) dip->hnl = dip->dnl; } else { if (numtab[NL].val > dip->hnl) dip->hnl = numtab[NL].val; } free(buf); } void casepc(void) { pagech = chget(IMP); } void casechop(void) { int i; struct contab *contp; filep savip; if (dip != d) wbfl(); lgf++; skip(1); if ((i = getrq(0)) == 0) return; if ((contp = findmn(i)) == NULL || !contp->mx) { nosuch(i); return; } savip = ip; ip = (filep)contp->mx; app = 1; while (rbf() != 0); app = 0; if (ip > (filep)contp->mx) { offset = ip - 1; wbt(0); } ip = savip; offset = dip->op; prwatch(contp, i, 1); } void casesubstring(void) { struct contab *contp; int i, j, k, sz = 0, st; int n1, n2 = -1, nlink; tchar *tp = NULL, c; filep savip; if (dip != d) wbfl(); lgf++; skip(1); if ((i = getrq(0)) == 0) return; if ((contp = findmn(i)) == NULL || !contp->mx) { nosuch(i); return; } if (skip(1)) return; noscale++; n1 = hatoi(); if (skip(0) == 0) n2 = hatoi(); noscale--; savip = ip; ip = (filep)contp->mx; k = 0; app = 1; while ((c = rbf()) != 0) { if (k >= sz) { sz += 512; tp = realloc(tp, sz * sizeof *tp); } tp[k++] = c; } app = 0; ip = savip; if ((offset = finds(i, 1, 0)) != 0) { st = 0; if (n1 < 0) n1 = k + n1; if (n2 < 0) n2 = k + n2; if (n1 >= 0 || n2 >= 0) { if (n2 < n1) { j = n1; n1 = n2; n2 = j; } for (j = 0; j <= k; j++) { if (st == 0) { if (j >= n1) st = 1; } if (st == 1) { if (tp) wbf(tp[j]); if (j >= n2) break; } } } wbt(0); if (oldmn != NULL && (nlink = oldmn->nlink) > 0) k = oldmn->rq; else { k = i; nlink = 0; } clrmn(oldmn); if (newmn) { if (newmn->rq) munhash(newmn); newmn->rq = k; newmn->nlink = nlink; maddhash(newmn); prwatch(newmn, i, 1); } } free(tp); offset = dip->op; ip = savip; } void caselength(void) { tchar c; int i, j; struct numtab *numtp; lgf++; skip(1); if ((i = getrq(1)) == 0) return; j = 0; lgf--; copyf++; if (skip(1) == 0) { if (cbits(c = getch()) != '"' || ismot(c)) ch = c; while(cbits(getch()) != '\n') j++; } copyf--; numtp = findr(i); numtp->val = j; prwatchn(numtp); } void caseindex(void) { int i, j, n, N; struct contab *contp; int *sp = NULL, as = 0, ns = 0, *np; tchar c; filep savip; struct numtab *numtp; lgf++; skip(1); if ((N = getrq(1)) == 0) return; skip(1); if ((i = getrq(1)) == 0) return; if ((contp = findmn(i)) == NULL || !contp->mx) { nosuch(i); return; } copyf++; if (!skip(0)) { if (cbits(c = getch()) != '"' || ismot(c)) ch = c; while ((c = getch()) != 0 && !ismot(c) && (i = cbits(c)) != '\n') { if (ns >= as) sp = realloc(sp, (as += 10) * sizeof *sp); sp[ns++] = i; } np = malloc((ns + 1) * sizeof *np); i = 0; j = -1; for (;;) { np[i++] = j++; if (i >= ns) break; while (j >= 0 && sp[i] != sp[j]) j = np[j]; } savip = ip; ip = (filep)contp->mx; app = 1; j = 0; n = 0; while ((c = rbf()) != 0 && j < ns) { while (j >= 0 && cbits(c) != sp[j]) j = np[j]; j++; n++; } n = j == ns ? n - ns : -1; app = 0; ip = savip; free(sp); free(np); } else n = -1; copyf--; numtp = findr(N); numtp->val = n; prwatchn(numtp); } static void caseasciify(void) { caseunformat(1); } static void caseunformat(int flag) { struct contab *contp; int i, j, k, nlink; int ns = 0, as = 0; tchar *tp = NULL, c; filep savip; int noout = 0; if (dip != d) wbfl(); lgf++; skip(1); if ((i = getrq(0)) == 0) return; if ((contp = findmn(i)) == NULL || !contp->mx) { nosuch(i); return; } savip = ip; ip = (filep)contp->mx; ns = 0; app = 1; while ((c = rbf()) != 0) { if (ns >= as) { as += 512; tp = realloc(tp, as * sizeof *tp); } tp[ns++] = c; } app = 0; ip = savip; if ((offset = finds(i, 1, 0)) != 0) { for (j = 0; j < ns; j++) { if (!ismot(c) && cbits(c) == '\n') noout = 0; else if (j+1 < ns && isxfunc(tp[j+1], HYPHED)) noout = 1; c = tp[j]; while (flag & 1 && isxfunc(c, CHAR)) c = charout[sbits(c)].ch; if (isadjspc(c)) { if (cbits(c) == WORDSP) setcbits(c, ' '); c &= ~ADJBIT; } else if (c == WORDSP) { j++; continue; } else if (c == FLSS) { j++; continue; } else if (cbits(c) == XFUNC) { switch (fbits(c)) { case FLDMARK: if ((c = sbits(c)) == 0) continue; break; case LETSP: case NLETSP: case LETSH: case NLETSH: case INDENT: continue; } } else if (isadjmot(c)) continue; else if (cbits(c) == PRESC) { if (!noout) { wbf(eschar); wbf('e'); } continue; } if (flag & 1 && !ismot(c) && cbits(c) != SLANT) { #ifndef NROFF int m = cbits(c); int f = fbits(c); int k; if (islig(c) && lgrevtab && lgrevtab[f] && lgrevtab[f][m]) { for (k = 0; lgrevtab[f][m][k]; k++) if (!noout) wbf(lgrevtab[f][m][k]); continue; } else #endif c = cbits(c); } if (flag & 1 && !ismot(c) && (k = trintab[c]) != 0) c = k; if (!noout) wbf(c); } wbt(0); if (oldmn != NULL && (nlink = oldmn->nlink) > 0) k = oldmn->rq; else { k = i; nlink = 0; } clrmn(oldmn); if (newmn) { if (newmn->rq) munhash(newmn); newmn->rq = k; newmn->nlink = nlink; maddhash(newmn); prwatch(newmn, i, 1); } } free(tp); offset = dip->op; } /* * Tables for names with more than two characters. Any number in * contab.rq or numtab.rq that is greater or equal to MAXRQ2 refers * to a long name. */ #define MAXRQ2 0200000 static struct map { struct map *link; int n; } *map[128]; static char **had; static int hadn; static int alcd; #define maphash(cp) (_pjw(cp) & 0177) static unsigned _pjw(const char *cp) { unsigned h = 0, g; cp--; while (*++cp) { h = (h << 4 & 0xffffffff) + (*cp&0377); if ((g = h & 0xf0000000) != 0) { h = h ^ g >> 24; h = h ^ g; } } return h; } static int mapget(const char *cp) { int h = maphash(cp); struct map *mp; for (mp = map[h]; mp; mp = mp->link) if (strcmp(had[mp->n], cp) == 0) return mp->n; return hadn; } static void mapadd(const char *cp, int n) { int h = maphash(cp); struct map *mp; mp = calloc(1, sizeof *mp); mp->n = n; mp->link = map[h]; map[h] = mp; } void casepm(void) { struct contab *contp; register int i, k; int xx, cnt, tcnt, kk, tot; filep j; kk = cnt = tcnt = 0; tot = !skip(0); for (i = 0; i < NM; i++) { if ((xx = contab[i].rq) == 0 || contab[i].mx == 0) { if (contab[i].als && (contp = findmx(xx)) != NULL) { k = contp - contab; if (contab[k].rq == 0 || contab[k].mx == 0) continue; } else continue; } tcnt++; if (contab[i].als == 0 && (j = (filep) contab[i].mx) != 0) { k = 1; while ((j = blist[blisti(j)]) != (unsigned) ~0) { k++; } cnt++; } else k = 0; kk += k; if (!tot && contab[i].nlink == 0) fprintf(stderr, "%s %d\n", macname(xx), k); } fprintf(stderr, "pm: total %d, macros %d, space %d\n", tcnt, cnt, kk); } void stackdump (void) /* dumps stack of macros in process */ { struct s *p; if (frame != stk) { for (p = frame; p != stk; p = p->pframe) if (p->mname != LOOP) fprintf(stderr, "%s ", macname(p->mname)); fprintf(stderr, "\n"); } } static char laststr[NC+1]; const char * macname(int rq) { static char buf[4][3]; static int i; if (rq < 0) { return laststr; } else if (rq < MAXRQ2) { i &= 3; buf[i][0] = rq&0177; buf[i][1] = (rq>>BYTE)&0177; buf[i][2] = 0; return buf[i++]; } else if (rq - MAXRQ2 < hadn) return had[rq - MAXRQ2]; else return "???"; } const char nmctab[] = { 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 001,002,003,000,004,005,000,006, 000,000,000,000,000,000,000,000, 000 }; static tchar mgetach(void) { tchar i; size_t j; lgf++; i = getch(); while (isxfunc(i, CHAR)) i = charout[sbits(i)].ch; j = cbits(i); if (ismot(i) || j == ' ' || j == '\n' || j >= 0200 || (j < sizeof nmctab && nmctab[j])) { if (!ismot(i) && j >= 0200) illseq(j, NULL, -3); ch = i; j = 0; } lgf--; return j & 0177; } /* * To handle requests with more than two characters, an additional * table is maintained. On places where more than two characters are * allowed, the characters collected are passed in "sofar", and "flags" * specifies whether the request is a new one. The routine returns an * integer which is above the regular PAIR() values. */ int maybemore(int sofar, int flags) { char c, buf[NC+1], pb[] = { '\n', 0 }; int n, _raw = raw, _init = init, _app = app; - size_t i = 2, l; + size_t i = 2; if (xflag < 2) return sofar; if (xflag == 2) raw = 1; else app = 0; buf[0] = sofar&BYTEMASK; buf[1] = (sofar>>BYTE)&BYTEMASK; do { c = xflag < 3 ? getch0() : mgetach(); if (i+1 >= sizeof buf) { buf[i] = 0; goto retn; } buf[i++] = c; } while (c && c != ' ' && c != '\t' && c != '\n'); buf[i-1] = 0; buf[i] = 0; if (i == 3) goto retn; if ((n = mapget(buf)) >= hadn) { if ((flags & 1) == 0) { n_strcpy(laststr, buf, sizeof(laststr)); retn: buf[i-1] = c; if (xflag < 3) cpushback(&buf[2]); raw = _raw; init = _init; app = _app; if (flags & 2) { if (i > 3 && xflag >= 3) sofar = -2; } else if (i > 3 && xflag >= 3) { buf[i-1] = 0; if (warn & WARN_MAC) errprint("%s: no such request", buf); sofar = 0; } else if (warn & WARN_SPACE && i > 3 && _findmn(sofar, 0, 0) != NULL) { buf[i-1] = 0; errprint("%s: missing space", macname(sofar)); } return sofar; } if (n >= alcd) had = realloc(had, (alcd += 20) * sizeof *had); - l = strlen(buf) + 1; - had[n] = malloc(l); - n_strcpy(had[n], buf, l); + had[n] = strdup(buf); hadn = n+1; mapadd(buf, n); } pb[0] = c; if (xflag < 3) cpushback(pb); raw = _raw; init = _init; app = _app; return MAXRQ2 + n; } static int getls(int termc, int *strp, int create) { char c, buf[NC+1]; int j = -1, n = -1; - size_t i = 0, l; + size_t i = 0; do { c = xflag < 3 ? getach() : mgetach(); if (i >= sizeof buf) return -1; buf[i++] = c; } while (c && c != termc); if (strp) *strp = 0; if (c != termc) { if (strp && !nlflg) *strp = 1; else nodelim(termc); } buf[--i] = 0; if (i == 0 || (c != termc && (!strp || nlflg))) j = 0; else if (i <= 2) { j = PAIR(buf[0], buf[1]); } else { if ((n = mapget(buf)) >= hadn) { if (create) { if (hadn++ >= alcd) had = realloc(had, (alcd += 20) * sizeof *had); - l = strlen(buf) + 1; - had[n] = malloc(l); - n_strcpy(had[n], buf, l); + had[n] = strdup(buf); hadn = n + 1; mapadd(buf, n); } else { n = -1; n_strcpy(laststr, buf, sizeof(laststr)); } } } return n >= 0 ? MAXRQ2 + n : j; } int makerq(const char *name) { static int t; char _name[20]; int n; - size_t l; if (name == NULL) { roff_sprintf(_name, sizeof(_name), "\13%d", ++t); name = _name; } if (name[0] == 0 || name[1] == 0 || name[2] == 0) return PAIR(name[0], name[1]); if ((n = mapget(name)) < hadn) return MAXRQ2 + n; if (hadn++ >= alcd) had = realloc(had, (alcd += 20) * sizeof *had); - l = strlen(name) + 1; - had[n] = malloc(l); - n_strcpy(had[n], name, l); + had[n] = strdup(name); hadn = n + 1; mapadd(name, n); return MAXRQ2 + n; } static void -addcon(int _t, char *rs, void(*f)(int)) +addcon(int _t, const char *rs, void(*f)(int)) { int n = hadn; if (hadn++ >= alcd) had = realloc(had, (alcd += 20) * sizeof *had); had[n] = rs; contab[_t].rq = MAXRQ2 + n; contab[_t].f = f; mapadd(rs, n); } Index: projects/doctools/contrib/heirloom-doctools/troff/n5.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/n5.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/n5.c (revision 307812) @@ -1,2536 +1,2517 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "n5.c 1.10 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)n5.c 1.130 (gritter) 10/23/09 */ /* * Changes Copyright (c) 2014, 2015 Carsten Kunze */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ #include #include #include #include #include #include #include #if defined (EUC) #include #include #endif /* EUC */ #include #include #include "tdef.h" #include "ext.h" #ifdef NROFF #include "tw.h" #endif #include "pt.h" /* * troff5.c * * misc processing requests */ void casead(void) { register int i; ad = 1; /*leave admod alone*/ if (skip(0)) return; pa = 0; loop: switch (i = cbits(getch())) { case 'r': /*right adj, left ragged*/ admod = 2; break; case 'l': /*left adj, right ragged*/ admod = ad = 0; /*same as casena*/ break; case 'c': /*centered adj*/ admod = 1; break; case 'b': case 'n': admod = 0; break; case '0': case '2': case '4': ad = 0; case '1': case '3': case '5': admod = (i - '0') / 2; break; case 'p': case '7': if (xflag) { pa = 1; admod = 0; goto loop; } } } void casena(void) { ad = 0; } void casefi(void) { tbreak(); fi++; pendnf = 0; } void casenf(void) { tbreak(); fi = 0; } void casepadj(void) { int n; if (skip(0)) padj = 1; else { n = hatoi(); if (!nonumb) padj = n; } } void casers(void) { dip->nls = 0; } void casens(void) { dip->nls++; } void casespreadwarn(void) { if (skip(0)) spreadwarn = !spreadwarn; else { dfact = EM; spreadlimit = inumb(&spreadlimit); spreadwarn = 1; } } int chget(int c) { tchar i = 0; charf++; if (skip(0) || ismot(i = getch()) || cbits(i) == ' ' || cbits(i) == '\n') { ch = i; return(c); } else return(cbits(i)); } void casecc(void) { cc = chget('.'); } void casec2(void) { c2 = chget('\''); } void casehc(void) { ohc = chget(OHC); } void casetc(void) { tabc = chget(0); } void caselc(void) { dotc = chget(0); } void casehy(void) { register int i; hyf = 1; if (skip(0)) return; noscale++; i = hatoi(); noscale = 0; if (nonumb) return; hyf = max(i, 0); } void casenh(void) { hyf = 0; } void casehlm(void) { int i; if (!skip(0)) { noscale++; i = hatoi(); noscale = 0; if (!nonumb) hlm = i; } else hlm = -1; } void casehcode(void) { tchar c, _d; int k; lgf++; if (skip(1)) return; do { c = getch(); if (skip(1)) break; _d = getch(); if (c && _d && !ismot(c) && !ismot(_d)) { if ((k = cbits(c)) >= nhcode) { hcode = realloc(hcode, (k+1) * sizeof *hcode); memset(&hcode[nhcode], 0, (k+1-nhcode) * sizeof *hcode); nhcode = k+1; } hcode[k] = cbits(_d); } } while (!skip(0)); } void caseshc(void) { shc = skip(0) ? 0 : getch(); } void casehylen(void) { int n; if (skip(0)) hylen = 5; else { n = hatoi(); if (!nonumb) hylen = n; } } void casehypp(void) { float _t; if (skip(0)) hypp = hypp2 = hypp3 = 0; else { _t = atop(); if (!nonumb) hypp = _t; if (skip(0)) hypp2 = hypp3 = 0; else { _t = atop(); if (!nonumb) hypp2 = _t; if (skip(0)) hypp3 = 0; else { _t = atop(); if (!nonumb) hypp3 = _t; } } } } static void chkin(int indent, int linelength, const char *note) { if (indent > linelength - INCH / 10) { if (warn & WARN_RANGE) errprint("excess of %sindent", note); } } void casepshape(void) { int i, l; int lastin = in, lastll = ll; pshapes = 0; if (skip(0)) { pshapes = 0; return; } do { i = max(hnumb(&lastin), 0); if (nonumb) break; if (skip(0)) l = ll; else { l = max(hnumb(&lastll), INCH / 10); if (nonumb) break; } if (pshapes >= pgsize) growpgsize(); chkin(i, l, ""); pgin[pshapes] = i; pgll[pshapes] = l; pshapes++; lastin = i; lastll = l; } while (!skip(0)); } void caselpfx(void) { int n; tchar c; if (skip(0)) { free(lpfx); lpfx = NULL; nlpfx = 0; } else { for (n = 0; ; n++) { if (n+1 >= nlpfx) { nlpfx += 10; lpfx = realloc(lpfx, nlpfx * sizeof *lpfx); } c = getch(); if (nlflg) break; if (n == 0 && cbits(c) == '"') continue; lpfx[n] = c; } lpfx[n] = 0; } } -int -max(int aa, int bb) -{ - if (aa > bb) - return(aa); - else - return(bb); -} - -int -min(int aa, int bb) -{ - if (aa < bb) - return(aa); - else - return(bb); -} - - static void cerj(int dorj) { register int i; noscale++; skip(0); i = max(hatoi(), 0); if (nonumb) i = 1; tbreak(); if (dorj) { rj = i; ce = 0; } else { ce = i; rj = 0; } noscale = 0; } void casece(void) { cerj(0); } void caserj(void) { if (xflag) cerj(1); } static void _brnl(int p) { int n; noscale++; if (skip(0)) n = INT_MAX; else { n = hatoi(); if (nonumb || n < 0) n = p ? brpnl : brpnl; } noscale--; tbreak(); if (p) { brpnl = n; brnl = 0; } else { brnl = n; brpnl = 0; } } void casebrnl(void) { _brnl(0); } void casebrpnl(void) { _brnl(1); } void casein(void) { register int i; if ((pa || padj) && pglines == 0 && pgchars) tbreak(); if (skip(0)) i = in1; else i = max(hnumb(&in), 0); tbreak(); in1 = in; in = i; chkin(in, ll, ""); if (!nc && !pgwords) { un = in; setnel(); } else if (pgwords) { pgflags[pgwords] |= PG_NEWIN; pgwdin[pgwords] = in; } } void casell(void) { register int i; if (skip(0)) i = ll1; else i = max(hnumb(&ll), INCH / 10); ll1 = ll; ll = i; chkin(in, ll, ""); setnel(); if (pgwords) { pgflags[pgwords] |= PG_NEWLL; pgwdll[pgwords] = ll; } } void caselt(void) { register int i; if (skip(0)) i = lt1; else i = max(hnumb(<), 0); lt1 = lt; lt = i; } void caseti(void) { register int i; if (skip(1)) return; if ((pa || padj) && pglines == 0 && pgchars) tbreak(); i = max(hnumb(&in), 0); tbreak(); un1 = i; chkin(i, ll, "temporary "); setnel(); } void casels(void) { register int i; noscale++; if (skip(0)) i = ls1; else i = max(inumb(&ls), 1); ls1 = ls; ls = i; noscale = 0; } void casepo(void) { register int i; if (skip(0)) i = po1; else i = max(hnumb(&po), 0); po1 = po; po = i; #ifndef NROFF if (!ascii) esc += po - po1; #endif } void casepl(void) { register int i; skip(0); if ((i = vnumb(&pl)) == 0) pl = defaultpl ? defaultpl : 11 * INCH; /*11in*/ else pl = i; if (numtab[NL].val > pl) { numtab[NL].val = pl; prwatchn(&numtab[NL]); } } static void chkt(struct d *dp, int n) { if (n <= 0 && dp != d) if (warn & WARN_RANGE) errprint("trap at %d not effective in diversion", n); } static void _casewh(struct d *dp) { register int i, j, k; lgf++; skip(1); i = vnumb((int *)0); if (nonumb) return; skip(0); j = getrq(1); if ((k = findn(dp, i)) != NTRAP) { dp->mlist[k] = j; return; } for (k = 0; k < NTRAP; k++) if (dp->mlist[k] == 0) break; if (k == NTRAP) { flusho(); errprint("cannot plant trap."); return; } dp->mlist[k] = j; dp->nlist[k] = i; chkt(dp, i); } void casewh(void) { _casewh(d); } void casedwh(void) { _casewh(dip); } static void _casech(struct d *dp) { register int i, j, k; lgf++; skip(1); if (!(j = getrq(0))) return; else { for (k = 0; k < NTRAP; k++) if (dp->mlist[k] == j) break; } if (k == NTRAP) return; skip(0); i = vnumb((int *)0); if (nonumb) dp->mlist[k] = 0; dp->nlist[k] = i; chkt(dp, i); } void casech(void) { _casech(d); } void casedch(void) { _casech(dip); } void casevpt(void) { if (skip(1)) return; vpt = hatoi() != 0; } tchar setolt(void) { storerq(getsn(1)); return mkxfunc(OLT, 0); } int findn(struct d *dp, int i) { register int k; for (k = 0; k < NTRAP; k++) if ((dp->nlist[k] == i) && (dp->mlist[k] != 0)) break; return(k); } void casepn(void) { register int i; skip(1); noscale++; i = max(inumb(&numtab[PN].val), 0); prwatchn(&numtab[PN]); noscale = 0; if (!nonumb) { npn = i; npnflg++; } } void casebp(void) { register int i; register struct s *savframe; if (dip != d) return; savframe = frame; if (skip(0)) i = -1; else { if ((i = inumb(&numtab[PN].val)) < 0) i = 0; if (nonumb) i = -1; } tbreak(); if (i >= 0) { npn = i; npnflg++; } else if (dip->nls && donef < 1) return; eject(savframe); } static void tmtmcwr(int ab, int tmc, int wr, int ep, int tmm) { const char tmtab[] = { 'a',000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, '{','}','&',000,'%','c','e',' ', '!',000,000,000,000,000,000,'~', 000 }; struct contab *cp; register int i, j; tchar c; char tmbuf[NTM]; filep savip = ip; int discard = 0; lgf++; if (tmm) { if (skip(1) || (i = getrq(0)) == 0) return; if ((cp = findmn(i)) == NULL || !cp->mx) { nosuch(i); return; } savip = ip; ip = (filep)cp->mx; app++; copyf++; } else { copyf++; if (skip(0) && ab) errprint("User Abort"); } loop: for (i = 0; i < NTM - 5 - mb_cur_max; ) { if (tmm) { if ((c = rbf()) == 0) { ip = savip; tmm = 0; app--; break; } } else c = getch(); if (discard) { discard--; continue; } if (c == '\n') { tmbuf[i++] = '\n'; break; } c: j = cbits(c); if (iscopy(c)) { int n; if ((n = wctomb(&tmbuf[i], j)) > 0) { i += n; continue; } } if (xflag == 0) { tmbuf[i++] = c; continue; } if (ismot(c)) continue; tmbuf[i++] = '\\'; if (c == (OHC|BLBIT)) j = ':'; else if (istrans(c)) j = ')'; else if (j >= 0 && j < sizeof tmtab && tmtab[j]) j = tmtab[j]; else if (j == ACUTE) j = '\''; else if (j == GRAVE) j = '`'; else if (j == UNDERLINE) j = '_'; else if (j == MINUS) j = '-'; else { i--; if (c == WORDSP) j = ' '; else if (j == WORDSP) continue; else if (j == FLSS) { discard++; continue; } } if (j == XFUNC) switch (fbits(c)) { case CHAR: c = charout[sbits(c)].ch; goto c; default: continue; } tmbuf[i++] = j; } if (i == NTM - 2) tmbuf[i++] = '\n'; if (tmc) i--; tmbuf[i] = 0; if (ab) /* truncate output */ obufp = obuf; /* should be a function in n2.c */ if (ep) { flusho(); errprint("%s", tmbuf); } else if (wr < 0) { flusho(); fprintf(stderr, "%s", tmbuf); } else if (i) write(wr, tmbuf, i); if (tmm) goto loop; copyf--; lgf--; } void casetm(int ab) { tmtmcwr(ab, 0, -1, 0, 0); } void casetmc(void) { tmtmcwr(0, 1, -1, 0, 0); } void caseerrprint(void) { tmtmcwr(0, 1, -1, 1, 0); } static struct stream { char *name; int fd; } *streams; static int nstreams; static void open1(int flags) { int ns = nstreams; lgf++; if (skip(1) || !getname() || skip(1)) return; streams = realloc(streams, sizeof *streams * ++nstreams); streams[ns].name = malloc(NS); n_strcpy(streams[ns].name, nextf, NS); getname(); if ((streams[ns].fd = open(nextf, flags, 0666)) < 0) { errprint("can't open file %s", nextf); done(02); } } void caseopen(void) { open1(O_WRONLY|O_CREAT|O_TRUNC); } void caseopena(void) { open1(O_WRONLY|O_CREAT|O_APPEND); } static int getstream(const char *name) { int i; for (i = 0; i < nstreams; i++) if (strcmp(streams[i].name, name) == 0) return i; errprint("no such stream %s", name); return -1; } static void write1(int writec, int writem) { int i; lgf++; if (skip(1) || !getname()) return; if ((i = getstream(nextf)) < 0) return; tmtmcwr(0, writec, streams[i].fd, 0, writem); } void casewrite(void) { write1(0, 0); } void casewritec(void) { write1(1, 0); } void casewritem(void) { write1(0, 1); } void caseclose(void) { int i; lgf++; if (skip(1) || !getname()) return; if ((i = getstream(nextf)) < 0) return; free(streams[i].name); memmove(&streams[i], &streams[i+1], (nstreams-i-1) * sizeof *streams); nstreams--; } void casesp(int a) { register int i, j, savlss; tbreak(); if (dip->nls || trap) return; i = findt1(); if (!a) { skip(0); j = vnumb((int *)0); if (nonumb) j = lss; } else j = a; if (j == 0) return; if (i < j) j = i; savlss = lss; if (dip != d) i = dip->dnl; else i = numtab[NL].val; if ((i + j) < 0) j = -i; lss = j; newline(0); lss = savlss; } void casebrp(void) { if (nc || pgchars) { spread = 2; flushi(); if (pgchars) tbreak(); else { pendt++; text(); } } else tbreak(); } void caseblm(void) { if (!skip(0)) blmac = getrq(1); else blmac = 0; } void caselsm(void) { if (!skip(0)) lsmac = getrq(1); else lsmac = 0; } void casert(void) { register int a, *p; skip(0); if (dip != d) p = &dip->dnl; else p = &numtab[NL].val; a = vnumb(p); if (nonumb) a = dip->mkline; if ((a < 0) || (a >= *p)) return; nb++; casesp(a - *p); } void caseem(void) { lgf++; skip(1); em = getrq(1); } void casefl(void) { tbreak(); flusho(); } static struct evnames { int number; char *name; } *evnames; static struct env *evp; static int *evlist; static int evi; static int evlsz; static int Nev = NEV; static struct env * findev(int *number, char *name) { int i; if (*number < 0) return &evp[-1 - (*number)]; else if (name) { for (i = 0; i < Nev-NEV; i++) if (evnames[i].name != NULL && strcmp(evnames[i].name, name) == 0) { *number = -1 - i; return &evp[i]; } *number = -1 - i; return NULL; } else if (*number >= NEV) { for (i = 0; i < Nev-NEV; i++) if (evnames[i].name == NULL && evnames[i].number == *number) return &evp[i]; *number = -1 - i; return NULL; } else { extern tchar *corebuf; return &((struct env *)corebuf)[*number]; } } static int getev(int *nxevp, char **namep) { char *name = NULL; int nxev = 0; int c; int i = 0, sz = 0, valid = 1; *namep = NULL; *nxevp = 0; if (skip(0)) return 0; c = cbits(ch); if (xflag == 0 || isdigit(c) || c == '(') { noscale++; nxev = hatoi(); noscale = 0; if (nonumb) { flushi(); return 0; } } else { do { c = rgetach(); if (i >= sz) name = realloc(name, (sz += 8) * sizeof *name); name[i++] = c; } while (c); if (*name == 0) { free(name); name = NULL; valid = 0; } } flushi(); *namep = name; *nxevp = nxev; return valid; } void caseev(void) { char *name; int nxev; struct env *np, *op; if (getev(&nxev, &name) == 0) { if (evi == 0) return; nxev = evlist[--evi]; goto e1; } if (xflag == 0 && ((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ))) goto cannot; if (evi >= evlsz) { evlsz = evi + 1; if ((evlist = realloc(evlist, evlsz * sizeof *evlist)) == NULL) goto cannot; } if ((name && findev(&nxev, name) == NULL) || nxev >= Nev) { if ((evp = realloc(evp, (Nev-NEV+1) * sizeof *evp)) == NULL || (evnames = realloc(evnames, (Nev-NEV+1) * sizeof *evnames)) == NULL) goto cannot; evnames[Nev-NEV].number = nxev; evnames[Nev-NEV].name = name; evp[Nev-NEV] = initenv; Nev++; } if (name == NULL && nxev < 0) { flusho(); cannot: errprint("cannot do ev."); if (error) done2(040); else edone(040); return; } evlist[evi++] = ev; e1: if (ev == nxev) return; if ((np = findev(&nxev, name)) == NULL || (op = findev(&ev, NULL)) == NULL) goto cannot; *op = env; env = *np; ev = nxev; if (evname == NULL) { if (name) evname = name; else { size_t l = 20; evname = malloc(l); roff_sprintf(evname, l, "%d", ev); } } } void caseevc(void) { char *name; int nxev; struct env *ep; if (getev(&nxev, &name) == 0 || (ep = findev(&nxev, name)) == NULL) return; relsev(&env); evc(&env, ep); } void evc(struct env *dp, struct env *sp) { if (dp != sp) { char *name; name = dp->_evname; memcpy(dp, sp, sizeof *dp); dp->_evname = name; } if (sp->_hcode) { dp->_hcode = malloc(dp->_nhcode * sizeof *dp->_hcode); memcpy(dp->_hcode, sp->_hcode, dp->_nhcode * sizeof *dp->_hcode); } if (sp->_lpfx) { dp->_lpfx = malloc(dp->_nlpfx * sizeof *dp->_lpfx); memcpy(dp->_lpfx, sp->_lpfx, dp->_nlpfx * sizeof *dp->_lpfx); } dp->_pendnf = 0; dp->_pendw = 0; dp->_pendt = 0; dp->_wch = 0; dp->_wne = 0; dp->_wsp = 0; dp->_wdstart = 0; dp->_wdend = 0; dp->_lnsize = 0; dp->_line = NULL; dp->_linep = NULL; dp->_wdsize = 0; dp->_word = 0; dp->_wdpenal = 0; dp->_wordp = 0; dp->_spflg = 0; dp->_seflg = 0; dp->_ce = 0; dp->_rj = 0; dp->_pgsize = 0; dp->_pgcsize = 0; dp->_pgssize = 0; dp->_pglines = 0; dp->_pgwords = 0; dp->_pgchars = 0; dp->_pgspacs = 0; dp->_para = NULL; dp->_parsp = NULL; dp->_pgwordp = NULL; dp->_pgspacp = NULL; dp->_pgwordw = NULL; dp->_pghyphw = NULL; dp->_pgadspc = NULL; dp->_pglsphc = NULL; dp->_pgopt = NULL; dp->_pgspacw = NULL; dp->_pglgsc = NULL; dp->_pglgec = NULL; dp->_pglgsw = NULL; dp->_pglgew = NULL; dp->_pglgsh = NULL; dp->_pglgeh = NULL; dp->_pgin = NULL; dp->_pgll = NULL; dp->_pgwdin = NULL; dp->_pgwdll = NULL; dp->_pgflags = NULL; dp->_pglno = NULL; dp->_pgpenal = NULL; dp->_inlevp = NULL; if (dp->_brnl < INT_MAX) dp->_brnl = 0; if (dp->_brpnl < INT_MAX) dp->_brpnl = 0; dp->_nn = 0; dp->_ndf = 0; dp->_nms = 0; dp->_ni = 0; dp->_ul = 0; dp->_cu = 0; dp->_it = 0; dp->_itc = 0; dp->_itmac = 0; dp->_nc = 0; dp->_un = 0; dp->_un1 = -1; dp->_nwd = 0; dp->_hyoff = 0; dp->_nb = 0; dp->_spread = 0; dp->_lnmod = 0; dp->_hlc = 0; dp->_cht = 0; dp->_cdp = 0; dp->_maxcht = 0; dp->_maxcdp = 0; setnel(); } void evcline(struct env *dp, struct env *sp) { if (dp == sp) return; #ifndef NROFF dp->_lspnc = sp->_lspnc; dp->_lsplow = sp->_lsplow; dp->_lsphigh = sp->_lsphigh; dp->_lspcur = sp->_lspcur; dp->_lsplast = sp->_lsplast; dp->_lshwid = sp->_lshwid; dp->_lshlow = sp->_lshlow; dp->_lshhigh = sp->_lshhigh; dp->_lshcur = sp->_lshcur; #endif dp->_fldcnt = sp->_fldcnt; dp->_hyoff = sp->_hyoff; dp->_hlc = sp->_hlc; dp->_nel = sp->_nel; dp->_adflg = sp->_adflg; dp->_adspc = sp->_adspc; dp->_wne = sp->_wne; dp->_wsp = sp->_wsp; dp->_ne = sp->_ne; dp->_nc = sp->_nc; dp->_nwd = sp->_nwd; dp->_un = sp->_un; dp->_wch = sp->_wch; dp->_rhang = sp->_rhang; dp->_cht = sp->_cht; dp->_cdp = sp->_cdp; dp->_maxcht = sp->_maxcht; dp->_maxcdp = sp->_maxcdp; if (icf == 0) dp->_ic = sp->_ic; memcpy(dp->_hyptr, sp->_hyptr, NHYP * sizeof *sp->_hyptr); dp->_line = malloc((dp->_lnsize = sp->_lnsize) * sizeof *dp->_line); memcpy(dp->_line, sp->_line, sp->_lnsize * sizeof *sp->_line); dp->_word = malloc((dp->_wdsize = sp->_wdsize) * sizeof *dp->_word); memcpy(dp->_word, sp->_word, sp->_wdsize * sizeof *sp->_word); dp->_wdpenal = malloc((dp->_wdsize = sp->_wdsize) * sizeof *dp->_wdpenal); memcpy(dp->_wdpenal, sp->_wdpenal, sp->_wdsize * sizeof *sp->_wdpenal); dp->_linep = sp->_linep + (dp->_line - sp->_line); dp->_wordp = sp->_wordp + (dp->_word - sp->_word); dp->_wdend = sp->_wdend + (dp->_word - sp->_word); dp->_wdstart = sp->_wdstart + (dp->_word - sp->_word); dp->_para = malloc((dp->_pgcsize = sp->_pgcsize) * sizeof *dp->_para); memcpy(dp->_para, sp->_para, dp->_pgcsize * sizeof *sp->_para); dp->_parsp = malloc((dp->_pgssize = sp->_pgssize) * sizeof *dp->_parsp); memcpy(dp->_parsp, sp->_parsp, dp->_pgssize * sizeof *sp->_parsp); dp->_pgsize = sp->_pgsize; dp->_pgwordp = malloc(dp->_pgsize * sizeof *dp->_pgwordp); memcpy(dp->_pgwordp, sp->_pgwordp, dp->_pgsize * sizeof *dp->_pgwordp); dp->_pgwordw = malloc(dp->_pgsize * sizeof *dp->_pgwordw); memcpy(dp->_pgwordw, sp->_pgwordw, dp->_pgsize * sizeof *dp->_pgwordw); dp->_pghyphw = malloc(dp->_pgsize * sizeof *dp->_pghyphw); memcpy(dp->_pghyphw, sp->_pghyphw, dp->_pgsize * sizeof *dp->_pghyphw); dp->_pgadspc = malloc(dp->_pgsize * sizeof *dp->_pgadspc); memcpy(dp->_pgadspc, sp->_pgadspc, dp->_pgsize * sizeof *dp->_pgadspc); dp->_pglsphc = malloc(dp->_pgsize * sizeof *dp->_pglsphc); memcpy(dp->_pglsphc, sp->_pglsphc, dp->_pgsize * sizeof *dp->_pglsphc); dp->_pgopt = malloc(dp->_pgsize * sizeof *dp->_pgopt); memcpy(dp->_pgopt, sp->_pgopt, dp->_pgsize * sizeof *dp->_pgopt); dp->_pgspacw = malloc(dp->_pgsize * sizeof *dp->_pgspacw); memcpy(dp->_pgspacw, sp->_pgspacw, dp->_pgsize * sizeof *dp->_pgspacw); dp->_pgspacp = malloc(dp->_pgsize * sizeof *dp->_pgspacp); memcpy(dp->_pgspacp, sp->_pgspacp, dp->_pgsize * sizeof *dp->_pgspacp); dp->_pglgsc = malloc(dp->_pgsize * sizeof *dp->_pglgsc); memcpy(dp->_pglgsc, sp->_pglgsc, dp->_pgsize * sizeof *dp->_pglgsc); dp->_pglgec = malloc(dp->_pgsize * sizeof *dp->_pglgec); memcpy(dp->_pglgec, sp->_pglgec, dp->_pgsize * sizeof *dp->_pglgec); dp->_pglgsw = malloc(dp->_pgsize * sizeof *dp->_pglgsw); memcpy(dp->_pglgsw, sp->_pglgsw, dp->_pgsize * sizeof *dp->_pglgsw); dp->_pglgew = malloc(dp->_pgsize * sizeof *dp->_pglgew); memcpy(dp->_pglgew, sp->_pglgew, dp->_pgsize * sizeof *dp->_pglgew); dp->_pglgsh = malloc(dp->_pgsize * sizeof *dp->_pglgsh); memcpy(dp->_pglgsh, sp->_pglgsh, dp->_pgsize * sizeof *dp->_pglgsh); dp->_pglgeh = malloc(dp->_pgsize * sizeof *dp->_pglgeh); memcpy(dp->_pglgeh, sp->_pglgeh, dp->_pgsize * sizeof *dp->_pglgeh); dp->_pgin = malloc(dp->_pgsize * sizeof *dp->_pgin); memcpy(dp->_pgin, sp->_pgin, dp->_pgsize * sizeof *dp->_pgin); dp->_pgll = malloc(dp->_pgsize * sizeof *dp->_pgll); memcpy(dp->_pgll, sp->_pgll, dp->_pgsize * sizeof *dp->_pgll); dp->_pgwdin = malloc(dp->_pgsize * sizeof *dp->_pgwdin); memcpy(dp->_pgwdin, sp->_pgwdin, dp->_pgsize * sizeof *dp->_pgwdin); dp->_pgwdll = malloc(dp->_pgsize * sizeof *dp->_pgwdll); memcpy(dp->_pgwdll, sp->_pgwdll, dp->_pgsize * sizeof *dp->_pgwdll); dp->_pgflags = malloc(dp->_pgsize * sizeof *dp->_pgflags); memcpy(dp->_pgflags, sp->_pgflags, dp->_pgsize * sizeof *dp->_pgflags); dp->_pglno = malloc(dp->_pgsize * sizeof *dp->_pglno); memcpy(dp->_pglno, sp->_pglno, dp->_pgsize * sizeof *dp->_pglno); dp->_pgpenal = malloc(dp->_pgsize * sizeof *dp->_pgpenal); memcpy(dp->_pgpenal, sp->_pgpenal, dp->_pgsize * sizeof *dp->_pgpenal); dp->_inlevp = malloc(dp->_ainlev * sizeof *dp->_inlevp); memcpy(dp->_inlevp, sp->_inlevp, dp->_ninlev * sizeof *dp->_inlevp); dp->_pgwords = sp->_pgwords; dp->_pgchars = sp->_pgchars; dp->_pgspacs = sp->_pgspacs; dp->_pglines = sp->_pglines; } void relsev(struct env *ep) { free(ep->_hcode); ep->_hcode = NULL; ep->_nhcode = 0; free(ep->_line); ep->_line = NULL; ep->_lnsize = 0; free(ep->_word); ep->_word = NULL; free(ep->_wdpenal); ep->_wdpenal = NULL; ep->_wdsize = 0; free(ep->_para); ep->_para = NULL; ep->_pgcsize = 0; free(ep->_pgwordp); ep->_pgwordp = NULL; free(ep->_pgwordw); ep->_pgwordw = NULL; free(ep->_pghyphw); ep->_pghyphw = NULL; free(ep->_pgadspc); ep->_pgadspc = NULL; free(ep->_pglsphc); ep->_pglsphc = NULL; free(ep->_pgopt); ep->_pgopt = NULL; free(ep->_pgspacw); ep->_pgspacw = NULL; free(ep->_pgspacp); ep->_pgspacp = NULL; free(ep->_pglgsc); ep->_pglgsc = NULL; free(ep->_pglgec); ep->_pglgec = NULL; free(ep->_pglgsw); ep->_pglgsw = NULL; free(ep->_pglgew); ep->_pglgew = NULL; free(ep->_pglgsh); ep->_pglgsh = NULL; free(ep->_pglgeh); ep->_pglgeh = NULL; free(ep->_pgin); ep->_pgin = NULL; free(ep->_pgll); ep->_pgll = NULL; free(ep->_pgwdin); ep->_pgwdin = NULL; free(ep->_pgwdll); ep->_pgwdll = NULL; free(ep->_pgflags); ep->_pgflags = NULL; free(ep->_pglno); ep->_pglno = NULL; free(ep->_pgpenal); ep->_pgpenal = NULL; ep->_pgsize = 0; free(ep->_inlevp); ep->_inlevp = NULL; ep->_ninlev = 0; ep->_ainlev = 0; } void caseel(void) { caseif(2); } void caseie(void) { caseif(1); } int tryglf; void caseif(int x) { extern int falsef; register int notflag, true; tchar i, j; enum warn w = warn; int flt = 0; static int el; if (x == 3) goto i2; if (x == 2) { notflag = 0; true = el; el = 0; goto i1; } true = 0; skip(1); if ((cbits(i = getch())) == '!') { notflag = 1; if (xflag == 0) /*EMPTY*/; else if ((cbits(i = getch())) == 'f') flt = 1; else ch = i; } else if (xflag && cbits(i) == 'f') { flt = 1; notflag = 0; } else { notflag = 0; ch = i; } if (flt) i = atof0() > 0; else i = (int)atoi0(); if (!nonumb) { if (i > 0) true++; goto i1; } i = getch(); switch (cbits(i)) { case 'e': if (!(numtab[PN].val & 01)) true++; break; case 'o': if (numtab[PN].val & 01) true++; break; #ifdef NROFF case 'n': true++; case 't': #endif #ifndef NROFF case 't': true++; case 'n': #endif break; case 'c': if (xflag == 0) goto dfl; warn &= ~WARN_CHAR; tryglf++; if (!skip(1)) { j = getch(); true = !ismot(j) && cbits(j) && cbits(j) != ' '; } tryglf--; warn = w; break; case 'r': case 'd': if (xflag == 0) goto dfl; warn &= ~(WARN_MAC|WARN_SPACE|WARN_REG); if (!skip(1)) { j = getrq(2); true = (cbits(i) == 'r' ? usedr(j) != NULL : findmn(j) != NULL); } warn = w; break; case 'F': if (xflag == 0) goto dfl; if (!skip(1)) { j = getrq(3); true = findft(j, 0) != -1; } break; case 'v': /* break; */ case ' ': break; default: dfl: true = cmpstr(i); } i1: true ^= notflag; if (x == 1) { el = !true; } if (true) { if (frame->loopf & LOOP_EVAL) { if (nonumb) goto i3; frame->loopf &= ~LOOP_EVAL; frame->loopf |= LOOP_NEXT; } i2: noschr = 0; bol = 1; while ((cbits(i = getch())) == ' ') ; bol = 0; if (cbits(i) == LEFT) goto i2; ch = i; nflush++; } else { i3: if (frame->loopf & LOOP_EVAL) frame->loopf = LOOP_FREE; copyf++; falsef++; eatblk(0); copyf--; falsef--; } } void casenop(void) { caseif(3); } void casechomp(void) { chomp = 1; caseif(3); } void casereturn(void) { flushi(); nflush++; while (frame->loopf) { frame->loopf = LOOP_FREE; popi(); } popi(); } void casewhile(void) { tchar c; int k, level; filep newip; if (dip != d) wbfl(); if ((nextb = alloc()) == 0) { errprint("out of space"); edone(04); return; } newip = offset = nextb; wbf(mkxfunc(CC, 0)); wbf(XFUNC); /* caseif */ wbf(' '); copyf++, clonef++; level = 0; do { nlflg = 0; k = cbits(c = getch()); switch (k) { case LEFT: level++; break; case RIGHT: level--; break; } wbf(c); } while (!nlflg || level > 0); if (level < 0 && warn & WARN_DELIM) errprint("%d excess delimiter(s)", -level); wbt(0); copyf--, clonef--; pushi(newip, LOOP, 0); offset = dip->op; } void casebreak(void) { casecontinue(1); } void casecontinue(int _break) { int i, j; struct s *s; noscale++; if (skip(0) || (i = hatoi()) <= 0 || nonumb) i = 1; noscale--; j = 0; for (s = frame; s != stk; s = s->pframe) if (s->loopf && ++j >= i) break; if (j != i) { if (i == 1) { if (warn & WARN_RANGE) errprint("%s outside loop", macname(lastrq)); return; } if (warn & WARN_RANGE) errprint("%s: breaking out of %d current loop " "levels but %d requested", macname(lastrq), j, i); _break = 1; i = j; } flushi(); nflush++; while (i > 1 || (_break && i > 0)) { if (frame->loopf) { frame->loopf = LOOP_FREE; i--; } popi(); } if (i == 1) { while (frame->loopf == 0) popi(); popi(); } } void eatblk(int inblk) { register int cnt, i; tchar ii; cnt = 0; do { if (ch) { i = cbits(ii = ch); ch = 0; } else i = cbits(ii = getch0()); if (i == ESC) cnt++; else { if (cnt == 1) switch (i) { case '{': i = LEFT; break; case '}': i = RIGHT; break; case '\n': i = 'x'; break; } cnt = 0; } if (i == LEFT) eatblk(1); } while ((!inblk && (i != '\n')) || (inblk && (i != RIGHT))); if (i == '\n') { nlflg++; tailflg = istail(ii); } } int cmpstr(tchar c) { register int j, delim; register tchar i; register int val; int savapts, savapts1, savfont, savfont1, savpts, savpts1; tchar string[1280]; register tchar *sp; if (ismot(c)) return(0); argdelim = delim = cbits(c); savapts = apts; savapts1 = apts1; savfont = font; savfont1 = font1; savpts = pts; savpts1 = pts1; sp = string; while ((j = cbits(i = getch()))!=delim && j!='\n' && sp<&string[1280-1]) *sp++ = i; if (j != delim) nodelim(delim); if (sp >= string + 1280) { errprint("too-long string compare."); edone(0100); } if (nlflg) { val = sp==string; goto rtn; } *sp++ = 0; apts = savapts; apts1 = savapts1; font = savfont; font1 = savfont1; pts = savpts; pts1 = savpts1; mchbits(); val = 1; sp = string; while ((j = cbits(i = getch())) != delim && j != '\n') { if (*sp != i) { eat(delim); val = 0; goto rtn; } sp++; } if (j != delim) nodelim(delim); if (*sp) val = 0; rtn: apts = savapts; apts1 = savapts1; font = savfont; font1 = savfont1; pts = savpts; pts1 = savpts1; mchbits(); argdelim = 0; return(val); } void caserd(void) { lgf++; skip(0); getname(); if (!iflg) { if (quiet) { #ifdef NROFF echo_off(); flusho(); #endif /* NROFF */ fprintf(stderr, "\007"); /*bell*/ } else { if (nextf[0]) { fprintf(stderr, "%s:", nextf); } else { fprintf(stderr, "\007"); /*bell*/ } } } collect(); tty++; pushi(-1, PAIR('r','d'), 0); } int rdtty(void) { char onechar; #if defined (EUC) int i, n; loop: #endif /* EUC */ onechar = 0; if (read(0, &onechar, 1) == 1) { if (onechar == '\n') tty++; else tty = 1; #if !defined (EUC) if (tty != 3) return(onechar); #else /* EUC */ if (tty != 3) { if (!multi_locale) return(onechar); i = onechar & 0377; *mbbuf1p++ = i; *mbbuf1p = 0; if ((*mbbuf1&~(wchar_t)0177) == 0) { twc = 0; mbbuf1p = mbbuf1; } else if ((n = mbtowc(&twc, mbbuf1, mb_cur_max)) <= 0) { if (mbbuf1p >= mbbuf1 + mb_cur_max) { illseq(-1, mbbuf1, mbbuf1p-mbbuf1); twc = 0; mbbuf1p = mbbuf1; *mbbuf1p = 0; i &= 0177; } else { goto loop; } } else { i = twc | COPYBIT; twc = 0; mbbuf1p = mbbuf1; } return(i); } #endif /* EUC */ } popi(); tty = 0; #ifdef NROFF if (quiet) echo_on(); #endif /* NROFF */ return(0); } void caseec(void) { eschar = chget('\\'); } void caseeo(void) { eschar = 0; } void caseecs(void) { ecs = eschar; } void caseecr(void) { eschar = ecs; } void caseta(void) { int T[NTAB]; register int i, j, n = 0; tabtab[0] = nonumb = 0; Tflg = 1; for (i = 0; ((i < (NTAB - 1)) && !nonumb); i++) { if (skip(0)) break; tabtab[i] = max(hnumb(&tabtab[max(i-1,0)]), 0) & TABMASK; if (nonumb && cbits(ch) == 'T') { ch = 0; nonumb = 0; Tflg = 0; goto T; } if (!nonumb) switch (cbits(ch)) { case 'C': tabtab[i] |= CTAB; break; case 'R': tabtab[i] |= RTAB; break; default: /*includes L*/ break; } nonumb = ch = 0; } Tflg = 0; tabtab[i] = 0; return; T: for (j = 0; j < NTAB - 1 && !nonumb; j++) { if (skip(0)) break; T[j] = hatoi() & TABMASK; if (!nonumb) switch (cbits(ch)) { case 'C': T[j] |= CTAB; break; case 'R': T[j] |= RTAB; break; default: break; } nonumb = ch = 0; } T[j] = 0; while (i < NTAB - 1) { if (T[j] == 0) { j = 0; n = (i ? tabtab[i-1] : 0) & TABMASK; } tabtab[i++] = (n + (T[j] & TABMASK)) | (T[j] & ~TABMASK); j++; } tabtab[i] = 0; } void casene(void) { register int i, j; skip(0); i = vnumb((int *)0); if (nonumb) i = lss; if (i > (j = findt1())) { i = lss; lss = j; dip->nls = 0; newline(0); lss = i; } } void casetr(int flag) { register int i, j; tchar k; lgf++; tryglf++; skip(1); if (!ch && cbits(getch()) == '\n') goto r; while ((i = cbits(k=getch())) != '\n') { if (ismot(k)) goto r; if (ismot(k = getch())) goto r; if ((j = cbits(k)) == '\n') j = ' '; trtab[i] = j; if (flag & 1) trintab[j] = i; else trintab[j] = 0; if (flag & 2) trnttab[i] = i; else trnttab[i] = j; } r: tryglf--; } void casetrin(void) { casetr(1); } void casetrnt(void) { casetr(2); } void casecu(void) { cu++; caseul(); } void caseul(void) { register int i; noscale++; if (skip(0)) i = 1; else i = hatoi(); if (ul && (i == 0)) { font = sfont; ul = cu = 0; } if (i) { if (!ul) { sfont = font; font = ulfont; } ul = i; } noscale = 0; mchbits(); } void caseuf(void) { register int i, j; extern int findft(int, int); if (skip(0) || !(i = getrq(2)) || i == 'S' || (j = findft(i, 1)) == -1) ulfont = ULFONT; /*default underline position*/ else ulfont = j; #ifdef NROFF if (ulfont == FT) ulfont = ULFONT; #endif } void caseit(int cflag) { register int i; lgf++; it = itc = itmac = 0; noscale++; skip(0); i = hatoi(); skip(0); if (!nonumb && (itmac = getrq(1))) { it = i; itc = cflag; } noscale = 0; } void caseitc(void) { caseit(1); } void casemc(void) { register int i; if (icf > 1) ic = 0; icf = 0; if (skip(0)) return; ic = getch(); icf = 1; skip(0); i = max(hnumb((int *)0), 0); if (!nonumb) ics = i; } static void propchar(int *tp) { int c, *tpp; tchar i; if (skip(0)) { *tp = IMP; return; } tpp = tp; do { while (!ismot(c = cbits(i = getch())) && c != ' ' && c != '\n') if (tpp < &tp[NSENT]) *tpp++ = c; } while (!skip(0)); } void casesentchar(void) { propchar(sentch); } void casetranschar(void) { propchar(transch); } void casebreakchar(void) { propchar(breakch); } void casenhychar(void) { propchar(nhych); } void caseconnectchar(void) { propchar(connectch); } void casemk(void) { register int i, j; struct numtab *np; if (dip != d) j = dip->dnl; else j = numtab[NL].val; if (skip(0)) { dip->mkline = j; return; } if ((i = getrq(1)) == 0) return; np = findr(i); np->val = j; prwatchn(np); } void casesv(void) { register int i; skip(0); if ((i = vnumb((int *)0)) < 0) return; if (nonumb) i = 1; sv += i; caseos(); } void caseos(void) { register int savlss; if (sv <= findt1()) { savlss = lss; lss = sv; newline(0); lss = savlss; sv = 0; } } void casenm(void) { register int i; lnmod = nn = 0; if (skip(0)) return; lnmod++; noscale++; i = inumb(&numtab[LN].val); if (!nonumb) numtab[LN].val = max(i, 0); prwatchn(&numtab[LN]); getnm(&ndf, 1); getnm(&nms, 0); getnm(&ni, 0); noscale = 0; nmbits = chbits; } void getnm(int *p, int min) { register int i; eat(' '); if (skip(0)) return; i = atoi0(); if (nonumb) return; *p = max(i, min); } void casenn(void) { noscale++; skip(0); nn = max(hatoi(), 1); noscale = 0; } void caseab(void) { casetm(1); done3(0); } #ifdef NROFF /* * The following routines are concerned with setting terminal options. * The manner of doing this differs between research/Berkeley systems * and UNIX System V systems (i.e. DOCUMENTER'S WORKBENCH) * The distinction is controlled by the #define'd variable USG, * which must be set by System V users. */ #ifdef USG #include #define ECHO_USG (ECHO | ECHOE | ECHOK | ECHONL) static struct termios ttys; #else #include struct sgttyb ttys[2]; #endif /* USG */ static int ttysave[2] = {-1, -1}; void save_tty(void) /*save any tty settings that may be changed*/ { #ifdef USG if (tcgetattr(0, &ttys) >= 0) ttysave[0] = ttys.c_lflag; #else if (gtty(0, &ttys[0]) >= 0) ttysave[0] = ttys[0].sg_flags; if (gtty(1, &ttys[1]) >= 0) ttysave[1] = ttys[1].sg_flags; #endif /* USG */ } void restore_tty (void) /*restore tty settings from beginning*/ { if (ttysave[0] != -1) { #ifdef USG ttys.c_lflag = ttysave[0]; tcsetattr(0, TCSADRAIN, &ttys); #else ttys[0].sg_flags = ttysave[0]; stty(0, &ttys[0]); } if (ttysave[1] != -1) { ttys[1].sg_flags = ttysave[1]; stty(1, &ttys[1]); #endif /* USG */ } } void set_tty (void) /*this replaces the use of bset and breset*/ { #ifndef USG /*for research/BSD only, reset CRMOD*/ if (ttysave[1] == -1) save_tty(); if (ttysave[1] != -1) { ttys[1].sg_flags &= ~CRMOD; stty(1, &ttys[1]); } #endif /* USG */ } void echo_off (void) /*turn off ECHO for .rd in "-q" mode*/ { if (ttysave[0] == -1) return; #ifdef USG ttys.c_lflag &= ~ECHO_USG; tcsetattr(0, TCSADRAIN, &ttys); #else ttys[0].sg_flags &= ~ECHO; stty(0, &ttys[0]); #endif /* USG */ } void echo_on (void) /*restore ECHO after .rd in "-q" mode*/ { if (ttysave[0] == -1) return; #ifdef USG ttys.c_lflag |= ECHO_USG; tcsetattr(0, TCSADRAIN, &ttys); #else ttys[0].sg_flags |= ECHO; stty(0, &ttys[0]); #endif /* USG */ } #endif /* NROFF */ Index: projects/doctools/contrib/heirloom-doctools/troff/n8.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/n8.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/n8.c (revision 307812) @@ -1,650 +1,648 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "n8.c 1.8 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)n8.c 1.44 (gritter) 9/26/10 */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ #include #include #ifdef EUC #include #endif #include #include #include #include "tdef.h" #include "ext.h" #include "pt.h" #include "libhnj/hyphen.h" #define HY_BIT 0200 /* generic stuff in here only works for ascii */ #define HY_BIT2 0x80000000 /* * troff8.c * * hyphenation */ static int *hbuf; static int NHEX; static int *nexth; static tchar *hyend; #define THRESH 160 /*digram goodness threshold*/ static int thresh = THRESH; static void hyphenhnj(void); static int * growhbuf(int **pp) { int *nhbuf; int inc = 4; ptrdiff_t j; if ((nhbuf = realloc(hbuf, (NHEX+inc) * sizeof *hbuf)) == NULL) return NULL; NHEX += inc; j = (char *)nhbuf - (char *)hbuf; nexth = (int *)((char *)nexth + j); if (pp) *pp = (int *)((char *)*pp + j); return hbuf = nhbuf; } void hyphen(tchar *wp) { register int j; register tchar *i; tchar *_wdstart, *_wdend; i = wp; while (punct(*i++)) ; if (!alph(*--i)) return; wdstart = i++; while (hyext ? *i++ : alph(*i++)) ; hyend = wdend = --i - 1; while (punct(*i++)) ; if (*--i) return; if (!(wdhyf & 060) && (wdend - wdstart - (hylen - 1)) < 0) return; hyp = hyptr; *hyp = 0; hyoff = 2; if (dicthnj) { i = _wdstart = wdstart; _wdend = wdend; do { if (cbits(*i) == '-' || cbits(*i) == EMDASH || i == _wdend) { while (wdstart <= i && (punct(*wdstart) || (cbits(*wdstart) >= '0' && cbits(*wdstart) <= '9'))) wdstart++; for (wdend = wdstart; wdend <= i; wdend++) { if (!alph(*wdend) || (cbits(*wdend) >= '0' && cbits(*wdend) <= '9')) break; } hyend = --wdend; if ((wdhyf & 060 || wdstart + 3 <= wdend) && !exword()) hyphenhnj(); wdstart = &i[1]; if (i < _wdend) { *hyp++ = &i[1]; if (hyp > (hyptr + NHYP - 1)) hyp = hyptr + NHYP - 1; } } } while (i++ <= _wdend); wdstart = _wdstart; wdend = _wdend; } else if (!exword() && !suffix()) digram(); *hyp++ = 0; if (*hyptr) for (j = 1; j; ) { j = 0; for (hyp = hyptr + 1; *hyp != 0; hyp++) { if (*(hyp - 1) > *hyp) { j++; i = *hyp; *hyp = *(hyp - 1); *(hyp - 1) = i; } } } } int punct(tchar i) { if (!cbits(i) || alph(i)) return(0); else return(1); } int alph(tchar j) { int i; int f; int h; while (isxfunc(j, CHAR)) j = charout[sbits(j)].ch; i = cbits(j); f = fbits(j); if (!ismot(j) && i < nhcode && (h = hcode[i]) != 0) { if (h & ~0177) h = tr2un(h, f); #ifdef EUC return hyext ? iswalnum(h) : iswalpha(h); } else #else /* !EUC */ i = h; } #endif /* !EUC */ #ifdef EUC if (!ismot(j) && i & ~0177) { int u; #ifndef NROFF if (islig(j) && hyext && lgrevtab && lgrevtab[f] && lgrevtab[f][i]) return 1; #endif /* !NROFF */ u = tr2un(i, f); if (u == 0x017F) /* longs */ u = 's'; return hyext ? iswalnum(u) : iswalpha(u); } else #endif /* EUC */ if ((!ismot(j) && i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z') || (hyext && i >= '0' && i <= '9')) return(1); else return(0); } void caseht(void) { thresh = THRESH; if (skip(0)) return; noscale++; thresh = hatoi(); noscale = 0; } void casehw(void) { register int i, k; int *j; tchar t; int cnt = 0; lgf++; if (nexth == NULL) growhbuf(NULL); k = 0; while (!skip(!cnt++)) { if ((j = nexth) >= (hbuf + NHEX - 2) && growhbuf(&j) == NULL) goto full; for (; ; ) { if (ismot(t = getch())) continue; i = cbits(t); if (i == ' ' || i == '\n') { *j++ = 0; nexth = j; *j = 0; if (i == ' ') break; else return; } if (i == '-') { k = HY_BIT2; continue; } *j++ = maplow(t) | k; k = 0; if (j >= (hbuf + NHEX - 2) && growhbuf(&j) == NULL) goto full; } } return; full: errprint("exception word list full."); *nexth = 0; } int exword(void) { register tchar *w; register int *e; int *save; e = hbuf; while (1) { save = e; if (e == NULL || *e == 0) return(0); w = wdstart; while (*e && w <= hyend) { #ifndef NROFF int i, m, f; m = cbits(*w); f = fbits(*w); if (islig(*w) && lgrevtab && lgrevtab[f] && lgrevtab[f][m]) { for (i = 0; lgrevtab[f][m][i]; i++) { if ((*e&~HY_BIT2) == maplow(lgrevtab[f][m][i])) { e++; } else goto end; } w++; } else #endif { if ((*e&~HY_BIT2) == maplow(*w)) { e++; w++; } else goto end; } } end: if (!*e) { if (w-1 == hyend || (w == wdend && maplow(*w) == 's')) { w = wdstart; for (e = save; *e; e++) { #ifndef NROFF int i, m, f; m = cbits(*w); f = fbits(*w); if (islig(*w) && lgrevtab && lgrevtab[f] && lgrevtab[f][m]) { for (i = 0; lgrevtab[f][m][i]; i++) { if (*e++ & HY_BIT2) { *hyp = (void *) ((intptr_t)w | i); hyp++; } } e--; } else #endif { if (*e & HY_BIT2) *hyp++ = w; } w++; if (hyp > (hyptr + NHYP - 1)) hyp = hyptr + NHYP - 1; } return(1); } else { e++; continue; } } else while (*e++) ; } } int suffix(void) { register tchar *w; register const char *s, *s0; tchar i; extern const char *suftab[]; again: i = cbits(*hyend); if (i >= 128 || !alph(*hyend)) return(0); if (i < 'a') i -= 'A' - 'a'; if ((s0 = suftab[i-'a']) == 0) return(0); for (; ; ) { if ((i = *s0 & 017) == 0) return(0); s = s0 + i - 1; w = hyend - 1; while (s > s0 && w >= wdstart && (*s & 0177) == maplow(*w)) { s--; w--; } if (s == s0) break; s0 += i; } s = s0 + i - 1; w = hyend; if (*s0 & HY_BIT) goto mark; while (s > s0) { w--; if (*s-- & HY_BIT) { mark: hyend = w - 1; if (*s0 & 0100) continue; if (!chkvow(w)) return(0); *hyp++ = w; } } if (*s0 & 040) return(0); if (exword()) return(1); goto again; } int maplow(tchar t) { int h, i, f; while (isxfunc(t, CHAR)) t = charout[sbits(t)].ch; i = cbits(t); f = fbits(t); if (!ismot(t) && i < nhcode && (h = hcode[i]) != 0) { if (h & ~0177) h = tr2un(h, f); h = tr2un(h, f); return(h); } else #ifdef EUC if (!ismot(t) && i & ~0177) { i = tr2un(i, f); if (i == 0x017F) /* longs */ i = 's'; if (iswupper(i)) i = towlower(i); } else #endif /* EUC */ if (ischar(i) && isupper(i)) i = tolower(i); return(i); } int vowel(tchar i) { switch (maplow(i)) { case 'a': case 'e': case 'i': case 'o': case 'u': case 'y': return(1); default: return(0); } } tchar * chkvow(tchar *w) { while (--w >= wdstart) if (vowel(*w)) return(w); return(0); } void digram(void) { register tchar *w; register int val; tchar * nhyend, *maxw = 0; int maxval; extern const char bxh[26][13], bxxh[26][13], xxh[26][13], xhx[26][13], hxx[26][13]; for (w = wdstart; w <= wdend; w++) if (cbits(*w) & ~0177) return; again: if (!(w = chkvow(hyend + 1))) return; hyend = w; if (!(w = chkvow(hyend))) return; nhyend = w; maxval = 0; w--; while ((++w < hyend) && (w < (wdend - 1))) { val = 1; if (w == wdstart) val *= dilook('a', *w, bxh); else if (w == wdstart + 1) val *= dilook(*(w-1), *w, bxxh); else val *= dilook(*(w-1), *w, xxh); val *= dilook(*w, *(w+1), xhx); val *= dilook(*(w+1), *(w+2), hxx); if (val > maxval) { maxval = val; maxw = w + 1; } } hyend = nhyend; if (maxval > thresh) *hyp++ = maxw; goto again; } int dilook(tchar a, tchar b, const char t[26][13]) { register int i, j; i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2]; if (!(j & 01)) i >>= 4; return(i & 017); } void casehylang(void) { int c, i = 0, sz = 0; char *path = NULL; size_t l; dicthnj = NULL; free(hylang); hylang = NULL; hyext = 0; skip(0); do { c = getach(); if (i >= sz) hylang = realloc(hylang, (sz += 8) * sizeof *hylang); hylang[i++] = c; } while (c); if (i == 1) { free(hylang); hylang = NULL; return; } if (strchr(hylang, '/') == NULL) { l = strlen(hylang) + strlen(HYPDIR) + 12; path = malloc(l); snprintf(path, l, "%s/hyph_%s.dic", HYPDIR, hylang); } else { - l = strlen(hylang) + 1; - path = malloc(l); - n_strcpy(path, hylang, l); + path = strdup(hylang); } if ((dicthnj = hnj_hyphen_load(path)) == NULL) { errprint("Can't load %s", path); free(hylang); hylang = NULL; free(path); return; } free(path); hyext = 1; } static int addc(int m, char **cp, tchar **wp, int **wpp, int distance) { tchar t; t = m ? m | sfmask(**wp) : **wp; m = maplow(t); if (m > 0 && m <= 0x7f) { *(*cp)++ = m; *(*wpp)++ = distance; } else if (m >= 0x80 && m <= 0x7ff) { *(*cp)++ = (m >> 6 & 037) | 0300; *(*wpp)++ = distance; *(*cp)++ = (m & 077) | 0200; *(*wpp)++ = -1000; } else if (m >= 0x800 && m <= 0xffff) { *(*cp)++ = (m >> 12 & 017) | 0340; *(*wpp)++ = distance; *(*cp)++ = (m >> 6 & 077) | 0200; *(*wpp)++ = -1000; *(*cp)++ = (m & 077) | 0200; *(*wpp)++ = -1000; } else return 0; return 1; } static void hyphenhnj(void) { tchar *wp; char *cb, *cp, *hb; int *wpos, *wpp; int i, j, k; i = 12 * (wdend - wdstart) + 1; cb = malloc(i * sizeof *cb); hb = malloc(i * sizeof *hb); wpos = malloc(i * sizeof *wpos); cp = cb; wpp = wpos; for (wp = wdstart; wp <= wdend; wp++) { #ifndef NROFF int m = cbits(*wp); int f = fbits(*wp); if (islig(*wp) && lgrevtab && lgrevtab[f] && lgrevtab[f][m]) { for (i = 0; lgrevtab[f][m][i]; i++) { if (addc(lgrevtab[f][m][i], &cp, &wp, &wpp, i ? -i : wp-wdstart) == 0) goto retn; } } else #endif { if (addc(0, &cp, &wp, &wpp, wp - wdstart) == 0) goto retn; } } *cp = '\0'; j = cp - cb; while (wpp <= &wpos[j]) *wpp++ = -1000; hnj_hyphen_hyphenate(dicthnj, cb, j, hb); k = 0; for (i = 0; i < j; i++) { if (wpos[i+1] >= 0) k = wpos[i+1]; if ((hb[i] - '0') & 1 && wpos[i+1] >= -3) { if (wpos[i+1] >= 0) *hyp = &wdstart[wpos[i+1]]; else { *hyp = &wdstart[k]; *hyp = (void *)((intptr_t)*hyp | -wpos[i+1]); } if (++hyp > (hyptr + NHYP - 1)) hyp = hyptr + NHYP - 1; } } retn: free(cb); free(hb); free(wpos); } Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/Makefile.mk (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/Makefile.mk (revision 307812) @@ -1,66 +1,66 @@ LIBHNJ = ../libhnj BST = ../../stuff/bst VPATH=.. OBJ = t10.o t6.o hytab.o n1.o n2.o n3.o n4.o n5.o \ n7.o n8.o n9.o ni.o nii.o suftab.o makedev.o afm.o otf.o unimap.o \ version.o fontmap.o $(BST)/bst.o FLAGS = -DUSG $(EUC) -I. -I.. -I../../include -DMACDIR='"$(MACDIR)"' \ -DFNTDIR='"$(FNTDIR)"' -DTABDIR='"$(TABDIR)"' -DHYPDIR='"$(HYPDIR)"' \ -DSHELL='"$(SHELL)"' -DRELEASE='"$(RELEASE)"' $(DEFINES) -I$(BST) .c.o: $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< all: troff ta otfdump troff: $(OBJ) $(LIBHNJ)/libhnj.a $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -L$(LIBHNJ) -lhnj $(LIBS) -o troff ta: draw.o ta.o $(CC) $(CFLAGS) $(LDFLAGS) draw.o ta.o $(LIBS) -lm -o $@ otfdump: otfdump.o otfdump_vs.o $(CC) $(CFLAGS) $(LDFLAGS) otfdump.o otfdump_vs.o $(LIBS) -o $@ install: $(INSTALL) -c troff $(ROOT)$(BINDIR)/troff $(STRIP) $(ROOT)$(BINDIR)/troff $(INSTALL) -c ta $(ROOT)$(BINDIR)/ta $(STRIP) $(ROOT)$(BINDIR)/ta $(INSTALL) -c otfdump $(ROOT)$(BINDIR)/otf_info $(STRIP) $(ROOT)$(BINDIR)/otf_info $(INSTALL) -c -m 644 troff.1 $(ROOT)$(MANDIR)/man1/troff.1 $(INSTALL) -c -m 644 otfdump.1 $(ROOT)$(MANDIR)/man1/otf_info.1 clean: rm -f $(OBJ) draw.o ta.o troff ta otfdump otfdump.o otfdump_vs.o \ core log *~ mrproper: clean draw.o: draw.c makedev.o: makedev.c dev.h t10.o: t10.c ../tdef.h ../ext.h dev.h afm.h unimap.h troff.h t6.o: t6.c ../tdef.h dev.h ../ext.h afm.h unimap.h troff.h unimap.o: unimap.h ta.o: ta.c dev.h hytab.o: ../hytab.c malloc.o: ../malloc.c ../mallint.h n1.o: ../n1.c ../tdef.h ../ext.h ./pt.h n2.o: ../n2.c ../tdef.h ./pt.h ../ext.h n3.o: ../n3.c ../tdef.h ./pt.h ../ext.h n4.o: ../n4.c ../tdef.h ./pt.h ../ext.h n5.o: ../n5.c ../tdef.h ./pt.h ../ext.h n7.o: ../n7.c ../tdef.h ./pt.h ../ext.h n8.o: ../n8.c ../tdef.h ../ext.h ./pt.h n9.o: ../n9.c ../tdef.h ./pt.h ../ext.h ni.o: ../ni.c ../tdef.h ./pt.h ../ext.h nii.o: ../nii.c ../tdef.h ./pt.h ../ext.h suftab.o: ../suftab.c version.o: ../version.c otfdump_vs.o: ../version.c afm.o: dev.h afm.h otf.o: dev.h afm.h unimap.h -otfdump.o: afm.h afm.c otf.c otfdump.c dpost.d/getopt.c dev.h +otfdump.o: afm.h afm.c otf.c otfdump.c dev.h fontmap.o: fontmap.h Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/afm.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/afm.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/afm.c (revision 307812) @@ -1,1205 +1,1203 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)afm.c 1.65 (gritter) 1/14/10 */ #include #include #include "dev.h" #include "afm.h" #ifndef __unused #define __unused __attribute__((unused)) #endif extern char *chname; extern short *chtab; extern int nchtab; extern void errprint(const char *, ...); #if !defined (DPOST) && !defined (DUMP) static void addkernpair(struct afmtab *, char *_line); #endif /* * This table maps troff special characters to PostScript names. */ static const struct names { const char *trname; const char *psname; } names[] = { { "hy", "hyphen" }, { "ct", "cent" }, { "fi", "fi" }, { "fi", "f_i" }, { "fl", "fl" }, { "fl", "f_l" }, { "ff", "ff" }, { "ff", "f_f" }, { "Fi", "ffi" }, { "Fi", "f_f_i" }, { "Fl", "ffl" }, { "Fl", "f_f_l" }, { "dg", "dagger" }, { "dd", "daggerdbl" }, { "bu", "bullet" }, { "de", "ring" }, { "em", "emdash" }, { "en", "endash" }, { "sc", "section" }, { "``", "quotedblleft" }, { "''", "quotedblright" }, { "12", "onehalf" }, { "14", "onequarter" }, { "34", "threequarters" }, { "aq", "quotesingle" }, { "oq", "quoteleft" }, { "cq", "quoteright" }, { 0, 0 } }; /* * Names for Symbol fonts only. */ static const struct names greeknames[] = { { "*A", "Alpha" }, { "*B", "Beta" }, { "*C", "Xi" }, { "*D", "Delta" }, { "*E", "Epsilon" }, { "*F", "Phi" }, { "*G", "Gamma" }, { "*H", "Theta" }, { "*I", "Iota" }, { "*K", "Kappa" }, { "*L", "Lambda" }, { "*M", "Mu" }, { "*N", "Nu" }, { "*O", "Omicron" }, { "*P", "Pi" }, { "*Q", "Psi" }, { "*R", "Rho" }, { "*S", "Sigma" }, { "*T", "Tau" }, { "*U", "Upsilon" }, { "*W", "Omega" }, { "*X", "Chi" }, { "*Y", "Eta" }, { "*Z", "Zeta" }, { "*a", "alpha" }, { "*b", "beta" }, { "*c", "xi" }, { "*d", "delta" }, { "*e", "epsilon" }, { "*f", "phi" }, { "*g", "gamma" }, { "*h", "theta" }, { "*i", "iota" }, { "*k", "kappa" }, { "*l", "lambda" }, { "*m", "mu" }, { "*n", "nu" }, { "*o", "omicron" }, { "*p", "pi" }, { "*q", "psi" }, { "*r", "rho" }, { "*s", "sigma" }, { "*t", "tau" }, { "*u", "upsilon" }, { "*w", "omega" }, { "*x", "chi" }, { "*y", "eta" }, { "*z", "zeta" }, { 0, 0 } }; static const struct names mathnames[] = { { "!=", "notequal" }, { "**", "asteriskmath" }, { "+-", "plusminus" }, { "->", "arrowright" }, { "<", "less" }, { "<-", "arrowleft" }, { "<=", "lessequal" }, { "==", "equivalence" }, { ">", "greater" }, { ">=", "greaterequal" }, { "O+", "circleplus" }, { "Ox", "circlemultiply" }, { "^", "logicaland" }, { "al", "aleph" }, { "ap", "similar" }, { "bu", "bullet" }, { "ca", "intersection" }, { "co", "copyrightserif" }, { "cu", "union" }, { "da", "arrowdown" }, { "de", "degree" }, { "di", "divide" }, { "eq", "equal" }, { "es", "emptyset" }, { "fa", "universal" }, { "fm", "minute" }, { "gr", "gradient" }, { "ib", "reflexsubset" }, { "if", "infinity" }, { "ip", "reflexsuperset" }, { "is", "integral" }, { "mi", "minus" }, { "mo", "element" }, { "mu", "multiply" }, { "no", "logicalnot" }, { "or", "bar" }, { "or", "logicalor" }, { "pd", "partialdiff" }, { "pl", "plus" }, { "pt", "proportional" }, { "rg", "registerserif" }, { "sb", "propersubset" }, { "sl", "fraction" }, { "sp", "propersuperset" }, { "sr", "radical" }, { "te", "existential" }, { "tm", "trademarkserif" }, { "ts", "sigma1" }, { "ua", "arrowup" }, { "~~", "approxequal" }, { 0, 0 }, }; static const struct names largenames[] = { { "bv", "braceex" }, { "lb", "braceleftbt" }, { "lc", "bracketlefttp" }, { "lf", "bracketleftbt" }, { "lk", "braceleftmid" }, { "lt", "bracelefttp" }, { "rb", "bracerightbt" }, { "rc", "bracketrighttp" }, { "rf", "bracketrightbt" }, { "rk", "bracerightmid" }, { "rn", "radicalex" }, { "rt", "bracerighttp" }, { 0, 0 } }; static const struct names punctnames[] = { { "or", "bar" }, { "\\-","endash" }, { "aa","acute" }, { "ga","grave" }, { "rs","backslash" }, { "dq","quotedbl" }, { 0, 0 } }; /* * These names are only used with the S font. */ static const struct names Snames[] = { { "br", "parenleftex" }, { "ul", "underscore" }, { "vr", "bracketleftex" }, { 0, 0 } }; /* * These names are only used with the S1 font. */ static const struct names S1names[] = { { "ru", "underscore" }, { 0, 0 } }; /* * Figures from charlib. */ #define NCHARLIB 16 static const struct charlib { const char *name; int width; int kern; int code; int symbol; enum { NEEDS_F = 01, NEEDS_I = 02, NEEDS_L = 04 } needs; } charlib[] = { { "bx", 500, 2, 1, 0, 0 }, { "ci", 750, 0, 1, 0, 0 }, { "sq", 500, 2, 1, 0, 0 }, { "ff", 600, 2, 1, 0, 1 }, /* widths of the ligatures */ { "Fi", 840, 2, 1, 0, 3 }, /* are likely wrong, but */ { "Fl", 840, 2, 1, 0, 5 }, /* they are normally not used */ { "~=", 550, 0, 1, 1, 0 }, { "L1", 1100, 1, 2, 1, 0 }, { "LA", 1100, 1, 2, 1, 0 }, { "LV", 1100, 3, 2, 1, 0 }, { "LH", 2100, 1, 2, 1, 0 }, { "Lb", 2100, 1, 2, 1, 0 }, { "lh", 1000, 0, 2, 1, 0 }, { "rh", 1000, 0, 2, 1, 0 }, { "Sl", 500, 2, 1, 1, 0 }, { "ob", 380, 0, 1, 1, 0 }, { 0, 0, 0, 0, 0, 0 } }; /* * The values in this table determine if a character that is found on an * ASCII position in a PostScript font actually is that ASCII character. * If not, the position in fitab remains empty, and the fallback sequence * is used to find it in another font. */ static const struct asciimap { int code; const char *psc; } asciimap[] = { { 0x0020, "space" }, { 0x0021, "exclam" }, { 0x0024, "dollar" }, { 0x0024, "dollaralt" }, /* FournierMT-RegularAlt */ { 0x0025, "percent" }, { 0x0026, "ampersand" }, { 0x0026, "ampersandalt" }, /* AGaramondAlt-Italic */ { 0x0027, "quoteright" }, { 0x0028, "parenleft" }, { 0x0029, "parenright" }, { 0x002A, "asterisk" }, { 0x002B, "plus" }, { 0x002C, "comma" }, { 0x002D, "hyphen" }, { 0x002E, "period" }, { 0x002F, "slash" }, { 0x0030, "zero" }, { 0x0030, "zerooldstyle" }, { 0x0030, "zeroalt" }, /* BulmerMT-RegularAlt */ { 0x0031, "one" }, { 0x0031, "oneoldstyle" }, { 0x0031, "onefitted" }, { 0x0031, "onealtfitted" }, /* BulmerMT-ItalicAlt */ { 0x0032, "two" }, { 0x0032, "twooldstyle" }, { 0x0032, "twoalt" }, /* BulmerMT-RegularAlt */ { 0x0033, "three" }, { 0x0033, "threeoldstyle" }, { 0x0033, "threealt" }, /* BulmerMT-RegularAlt */ { 0x0034, "four" }, { 0x0034, "fouroldstyle" }, { 0x0034, "fouralt" }, /* BulmerMT-RegularAlt */ { 0x0035, "five" }, { 0x0035, "fiveoldstyle" }, { 0x0035, "fivealt" }, /* BulmerMT-RegularAlt */ { 0x0036, "six" }, { 0x0036, "sixoldstyle" }, { 0x0036, "sixalt" }, /* BulmerMT-RegularAlt */ { 0x0037, "seven" }, { 0x0037, "sevenoldstyle" }, { 0x0037, "sevenalt" }, /* BulmerMT-RegularAlt */ { 0x0038, "eight" }, { 0x0038, "eightoldstyle" }, { 0x0038, "eightalt" }, /* BulmerMT-RegularAlt */ { 0x0039, "nine" }, { 0x0039, "nineoldstyle" }, { 0x0039, "ninealt" }, /* BulmerMT-RegularAlt */ { 0x003A, "colon" }, { 0x003B, "semicolon" }, { 0x003D, "equal" }, { 0x003F, "question" }, { 0x0041, "A" }, { 0x0041, "Aswash" }, /* AGaramondAlt-Italic */ { 0x0042, "B" }, { 0x0042, "Bswash" }, /* AGaramondAlt-Italic */ { 0x0043, "C" }, { 0x0043, "Cswash" }, /* AGaramondAlt-Italic */ { 0x0044, "D" }, { 0x0044, "Dswash" }, /* AGaramondAlt-Italic */ { 0x0045, "E" }, { 0x0045, "Eswash" }, /* AGaramondAlt-Italic */ { 0x0046, "F" }, { 0x0046, "Fswash" }, /* AGaramondAlt-Italic */ { 0x0047, "G" }, { 0x0047, "Gswash" }, /* AGaramondAlt-Italic */ { 0x0048, "H" }, { 0x0048, "Hswash" }, /* AGaramondAlt-Italic */ { 0x0049, "I" }, { 0x0049, "Iswash" }, /* AGaramondAlt-Italic */ { 0x004A, "J" }, { 0x004A, "Jalt" }, /* FournierMT-RegularAlt */ { 0x004A, "Jalttwo" }, /* BulmerMT-ItalicAlt */ { 0x004A, "Jswash" }, /* AGaramondAlt-Italic */ { 0x004A, "JTallCapalt" }, /* FournierMT-RegularAlt */ { 0x004B, "K" }, { 0x004B, "Kalt" }, /* BulmerMT-ItalicAlt */ { 0x004B, "Kswash" }, /* AGaramondAlt-Italic */ { 0x004C, "L" }, { 0x004C, "Lswash" }, /* AGaramondAlt-Italic */ { 0x004D, "M" }, { 0x004D, "Mswash" }, /* AGaramondAlt-Italic */ { 0x004E, "N" }, { 0x004E, "Nalt" }, /* BulmerMT-ItalicAlt */ { 0x004E, "Nswash" }, /* AGaramondAlt-Italic */ { 0x004F, "O" }, { 0x004F, "Oalt" }, /* BulmerMT-ItalicAlt */ { 0x004F, "Oswash" }, /* AGaramondAlt-Italic */ { 0x0050, "P" }, { 0x0050, "Pswash" }, /* AGaramondAlt-Italic */ { 0x0051, "Q" }, { 0x0051, "Qalt" }, /* FournierMT-RegularAlt */ { 0x0051, "Qalttitling" }, /* AGaramondAlt-Regular */ { 0x0051, "Qswash" }, /* AGaramondAlt-Italic */ { 0x0051, "QTallCapalt" }, /* FournierMT-RegularAlt */ { 0x0052, "R" }, { 0x0052, "Ralternate" }, /* Bembo-Alt */ { 0x0052, "Rswash" }, /* AGaramondAlt-Italic */ { 0x0053, "S" }, { 0x0053, "Sswash" }, /* AGaramondAlt-Italic */ { 0x0054, "T" }, { 0x0054, "Talt" }, /* BulmerMT-ItalicAlt */ { 0x0054, "Tswash" }, /* AGaramondAlt-Italic */ { 0x0055, "U" }, { 0x0055, "Uswash" }, /* AGaramondAlt-Italic */ { 0x0056, "V" }, { 0x0056, "Vswash" }, /* AGaramondAlt-Italic */ { 0x0057, "W" }, { 0x0057, "Wswash" }, /* AGaramondAlt-Italic */ { 0x0058, "X" }, { 0x0058, "Xswash" }, /* AGaramondAlt-Italic */ { 0x0059, "Y" }, { 0x0059, "Yalt" }, /* BulmerMT-ItalicAlt */ { 0x0059, "Yswash" }, /* AGaramondAlt-Italic */ { 0x005A, "Z" }, { 0x005A, "Zswash" }, /* AGaramondAlt-Italic */ { 0x005B, "bracketleft" }, { 0x005D, "bracketright" }, { 0x005F, "underscore" }, { 0x0060, "quoteleft" }, { 0x0060, "quotealtleft" }, /* BulmerMT-RegularAlt */ { 0x0061, "a" }, { 0x0061, "Asmall" }, { 0x0061, "aswash" }, /* AGaramondAlt-Regular */ { 0x0062, "b" }, { 0x0062, "Bsmall" }, { 0x0063, "c" }, { 0x0063, "Csmall" }, { 0x0064, "d" }, { 0x0064, "Dsmall" }, { 0x0065, "e" }, { 0x0065, "Esmall" }, { 0x0065, "eswash" }, /* AGaramondAlt-Regular */ { 0x0066, "f" }, { 0x0066, "Fsmall" }, { 0x0067, "g" }, { 0x0067, "Gsmall" }, { 0x0068, "h" }, { 0x0068, "Hsmall" }, { 0x0069, "i" }, { 0x0069, "Ismall" }, { 0x006A, "j" }, { 0x006A, "Jsmall" }, { 0x006A, "Jsmallalt" }, /* FournierMT-RegularAlt */ { 0x006B, "k" }, { 0x006B, "Ksmall" }, { 0x006C, "l" }, { 0x006C, "Lsmall" }, { 0x006D, "m" }, { 0x006D, "Msmall" }, { 0x006E, "n" }, { 0x006E, "Nsmall" }, { 0x006E, "nswash" }, /* AGaramondAlt-Regular */ { 0x006F, "o" }, { 0x006F, "Osmall" }, { 0x0070, "p" }, { 0x0070, "Psmall" }, { 0x0071, "q" }, { 0x0071, "Qsmall" }, { 0x0072, "r" }, { 0x0072, "Rsmall" }, { 0x0072, "rswash" }, /* AGaramondAlt-Regular */ { 0x0073, "s" }, { 0x0073, "Ssmall" }, { 0x0074, "t" }, { 0x0074, "Tsmall" }, { 0x0074, "tswash" }, /* AGaramondAlt-Regular */ { 0x0074, "tswashalt" }, /* AGaramondAlt-Regular */ { 0x0075, "u" }, { 0x0075, "Usmall" }, { 0x0076, "v" }, { 0x0076, "Vsmall" }, { 0x0076, "vswash" }, /* AGaramondAlt-Italic */ { 0x0077, "w" }, { 0x0077, "Wsmall" }, { 0x0077, "walt" }, /* FournierMT-RegularAlt */ { 0x0078, "x" }, { 0x0078, "Xsmall" }, { 0x0079, "y" }, { 0x0079, "Ysmall" }, { 0x007A, "z" }, { 0x007A, "Zsmall" }, { 0x007A, "zalt" }, /* FournierMT-ItalicAlt */ { 0x007A, "zswash" }, /* AGaramondAlt-Regular */ { 0x007B, "braceleft" }, { 0x007C, "bar" }, { 0x007D, "braceright" }, { 0, 0 } }; /* * ASCII characters that are always taken from the S (math) font. */ static const struct asciimap mathascii[] = { { 0x002D, "minus" }, { 0x007E, "similar" }, { 0, 0 } }; /* * ASCII characters that are always taken from the S1 (punct) font. */ static const struct asciimap punctascii[] = { { 0x0022, "quotedbl" }, { 0x0023, "numbersign" }, { 0x003C, "less" }, { 0x003E, "greater" }, { 0x0040, "at" }, { 0x005C, "backslash" }, { 0x005E, "circumflex" }, { 0x007E, "tilde" }, { 0, NULL } }; int nextprime(int n) { const int primes[] = { 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393, 67108859, 134217689, 268435399, 536870909, 1073741789, 2147483647 }; int mprime = 7; size_t i; for (i = 0; i < sizeof primes / sizeof *primes; i++) if ((mprime = primes[i]) >= (n < 65536 ? n*4 : n < 262144 ? n*2 : n)) break; if (i == sizeof primes / sizeof *primes) mprime = n; /* not so prime, but better than failure */ return mprime; } unsigned pjw(const char *cp) { unsigned h = 0, g; cp--; while (*++cp) { h = (h << 4 & 0xffffffff) + (*cp&0377); if ((g = h & 0xf0000000) != 0) { h = h ^ g >> 24; h = h ^ g; } } return h; } struct namecache * afmnamelook(struct afmtab *a, const char *name) { struct namecache *np; int h, c, n = 0; h = pjw(name) % a->nameprime; np = &a->namecache[c = h]; while (np->afpos != 0) { if (a->nametab[np->afpos] == 0 || strcmp(a->nametab[np->afpos], name) == 0) break; h = (n + 1) / 2; h *= h; if (n & 1) c -= h; else c += h; n++; while (c >= a->nameprime) c -= a->nameprime; np = &a->namecache[c]; } return np; } static int mapname1(const char *psname, const struct names *np) { int i, j; for (i = 0; np[i].trname; i++) if (strcmp(np[i].psname, psname) == 0) break; if (np[i].trname) for (j = 0; j < nchtab; j++) if (strcmp(np[i].trname, &chname[chtab[j]]) == 0) return j + 128; return 0; } int afmmapname(const char *psname, enum spec s) { int k; if (s & SPEC_S && (k = mapname1(psname, Snames)) > 0) return k; if (s & SPEC_S1 && (k = mapname1(psname, S1names)) > 0) return k; if (s & (SPEC_MATH|SPEC_S) && (k = mapname1(psname, mathnames)) > 0) return k; if (s & (SPEC_GREEK|SPEC_S) && (k = mapname1(psname, greeknames)) > 0) return k; if (s & (SPEC_LARGE|SPEC_S) && (k = mapname1(psname, largenames)) > 0) return k; if (s & (SPEC_PUNCT|SPEC_S1) && (k = mapname1(psname, punctnames)) > 0) return k; return mapname1(psname, names); } /* * After all characters have been read, construct a font-specific * encoding for the rest. Also move the name table to permanent space. */ void afmremap(struct afmtab *a) { int i, j = 128 - 32 + nchtab; char *space, *tp; struct namecache *np; for (i = 1; i < a->nchars; i++) { if (a->codetab[i] == NOCODE && a->nametab[i] != NULL) { #if defined (DPOST) || defined (DUMP) while (a->fitab[j] != 0) j++; #else /* TROFF */ extern int ps2cc(const char *); j = ps2cc(a->nametab[i]) + 128 - 32 + nchtab; #endif /* TROFF */ a->fitab[j] = i; np = afmnamelook(a, a->nametab[i]); np->afpos = i; np->fival[0] = j; if (np->gid != 0 && a->gid2tr) a->gid2tr[np->gid].ch1 = j + 32 + nchtab + 128; if (strcmp(a->nametab[i], "space") == 0) { np->fival[1] = 0; if (np->gid != 0 && a->gid2tr) a->gid2tr[np->gid].ch2 = 32; } } } space = malloc(a->nspace); for (i = 0; i < a->nchars; i++) { if (a->nametab[i]) { tp = a->nametab[i]; a->nametab[i] = space; while ((*space++ = *tp++)); } } } #ifndef DUMP static int asciiequiv(int code __unused, const char *psc, enum spec s) { int i; if (psc != NULL) { for (i = 0; asciimap[i].psc; i++) if (strcmp(asciimap[i].psc, psc) == 0) return asciimap[i].code; if (s & (SPEC_MATH|SPEC_S)) { for (i = 0; mathascii[i].psc; i++) if (strcmp(mathascii[i].psc, psc) == 0) return mathascii[i].code; } if (s & (SPEC_PUNCT|SPEC_S1)) { for (i = 0; punctascii[i].psc; i++) if (strcmp(punctascii[i].psc, psc) == 0) return punctascii[i].code; } } return 0; } static char * thisword(char *text, const char *wrd) { while (*text == *wrd) text++, wrd++; if (*wrd != 0) return 0; if (*text == 0 || *text == ' ' || *text == '\t' || *text == '\n' || *text == '\r') { while (*text != 0 && (*text == ' ' || *text == '\t')) text++; return text; } return NULL; } #endif /* !DUMP */ int unitconv(int i) { if (unitsPerEm * 72 != dev.unitwidth * dev.res) i = i * dev.unitwidth * dev.res / 72 / unitsPerEm; return i; } #ifndef DUMP void afmaddchar(struct afmtab *a, int C, int tp, int cl, int WX, int B[4], char *N, enum spec s, int gid) { struct namecache *np = NULL; if (N != NULL) { np = afmnamelook(a, N); np->afpos = a->nchars; np->gid = gid; if (a->isFixedPitch && strcmp(N, "space") == 0) a->fontab[0] = _unitconv(WX); } a->fontab[a->nchars] = _unitconv(WX); if (B) { a->bbtab[a->nchars] = malloc(4 * sizeof **a->bbtab); a->bbtab[a->nchars][0] = _unitconv(B[0]); a->bbtab[a->nchars][1] = _unitconv(B[1]); a->bbtab[a->nchars][2] = _unitconv(B[2]); a->bbtab[a->nchars][3] = _unitconv(B[3]); /* * Crude heuristics mainly based on observations with the existing * fonts for -Tpost and on tests with eqn. */ if (B[1] <= -10) a->kerntab[a->nchars] |= 1; if (B[3] > (a->xheight + a->capheight) / 2) a->kerntab[a->nchars] |= 2; } /* * Only map a character directly if it maps to an ASCII * equivalent or to a troff special character. */ C = asciiequiv(C, N, s); if (cl) a->codetab[a->nchars] = cl; else if (tp) a->codetab[a->nchars] = tp; else if (C > 32 && C < 127 && a->fitab[C - 32] == 0) a->codetab[a->nchars] = C; else a->codetab[a->nchars] = NOCODE; if (C > 32 && C < 127 && a->fitab[C - 32] == 0) { a->fitab[C - 32] = a->nchars; if (gid && a->gid2tr) a->gid2tr[gid].ch1 = C; if (np) np->fival[0] = C - 32; } else if (C == 32 && np) np->fival[0] = 0; if (tp) { a->fitab[tp - 32] = a->nchars; if (gid && a->gid2tr) a->gid2tr[gid].ch2 = tp; if (np) np->fival[1] = tp - 32; } a->nametab[a->nchars] = N; a->nchars++; } /* * Add charlib figues. */ static void addcharlib(struct afmtab *a, int symbol) { int i, j; int B[4] = { 0, 0, 0, 0 }; for (j = 0; j < nchtab; j++) for (i = 0; charlib[i].name; i++) { if (charlib[i].symbol && !symbol) continue; if (charlib[i].needs & NEEDS_F && a->fitab['f'-32] == 0) continue; if (charlib[i].needs & NEEDS_I && a->fitab['i'-32] == 0) continue; if (charlib[i].needs & NEEDS_L && a->fitab['l'-32] == 0) continue; if (strcmp(charlib[i].name, &chname[chtab[j]]) == 0) { B[1] = charlib[i].kern & 1 ? -11 : 0; B[3] = charlib[i].kern & 2 ? a->capheight + 1 : 0; afmaddchar(a, NOCODE, j+128, charlib[i].code, charlib[i].width * unitsPerEm / 1024, B, NULL, SPEC_NONE, 0); } } } static void addmetrics(struct afmtab *a, char *_line, enum spec s) { char *lp = _line, c, *xp; int C = NOCODE, WX = 0, tp; char *N = NULL; int B[4] = { -1, -1, -1, -1 }; while (*lp && *lp != '\n' && *lp != '\r') { switch (*lp) { case 'C': C = strtol(&lp[1], NULL, 10); break; case 'W': if (lp[1] == 'X') WX = strtol(&lp[2], NULL, 10); break; case 'N': for (N = &lp[1]; *N == ' ' || *N == '\t'; N++); for (lp = N; *lp && *lp != '\n' && *lp != '\r' && *lp != ' ' && *lp != '\t' && *lp != ';'; lp++); c = *lp; *lp++ = 0; a->nspace += lp - N; if (c == ';') continue; break; case 'B': xp = &lp[1]; B[0] = strtol(xp, &xp, 10); B[1] = strtol(xp, &xp, 10); B[2] = strtol(xp, &xp, 10); B[3] = strtol(xp, &xp, 10); break; case 'L': if (C == 'f') { xp = &lp[1]; while (*xp == ' ' || *xp == '\t') xp++; switch (*xp) { case 'i': a->Font.ligfont |= LFI; break; case 'l': a->Font.ligfont |= LFL; break; } } break; default: lp++; } while (*lp && *lp != '\n' && *lp != '\r' && *lp != ';') lp++; if (*lp == ';') { while (*lp && *lp != '\n' && *lp != '\r' && (*lp == ' ' || *lp == '\t' || *lp == ';')) lp++; } } if (N == NULL) return; tp = afmmapname(N, s); afmaddchar(a, C, tp, 0, WX, B, N, s, 0); } void afmalloc(struct afmtab *a, int n) { int i; #if defined (DPOST) || defined (DUMP) a->fichars = n+NCHARLIB+1 + 128 - 32 + nchtab; #else /* TROFF */ extern int psmaxcode; a->fichars = n+NCHARLIB+1 + 128 - 32 + nchtab + psmaxcode+1; #endif /* TROFF */ a->fitab = calloc(a->fichars, sizeof *a->fitab); a->fontab = malloc((n+NCHARLIB+1)*sizeof *a->fontab); a->fontab[0] = dev.res * dev.unitwidth / 72 / 3; a->bbtab = calloc(n+NCHARLIB+1, sizeof *a->bbtab); a->kerntab = calloc(n+NCHARLIB+1, sizeof *a->kerntab); a->codetab = malloc((n+NCHARLIB+1)*sizeof *a->codetab); a->codetab[0] = 0; for (i = 1; i < n+NCHARLIB+1; i++) a->codetab[i] = NOCODE; a->nametab = malloc((n+NCHARLIB+1)*sizeof *a->nametab); a->nametab[0] = 0; a->nchars = 1; addcharlib(a, (a->base[0]=='S' && a->base[1]==0) || a->spec&SPEC_S); a->nameprime = nextprime(n+NCHARLIB+1); a->namecache = calloc(a->nameprime, sizeof *a->namecache); for (i = 0; i < a->nameprime; i++) { a->namecache[i].fival[0] = NOCODE; a->namecache[i].fival[1] = NOCODE; } } int afmget(struct afmtab *a, char *contents, size_t size) { enum { NONE, FONTMETRICS, CHARMETRICS, KERNDATA, KERNPAIRS } state = NONE; char *cp, *th, *tp; int n = 0; enum spec s; size_t l; if ((cp = strrchr(a->file, '/')) == NULL) cp = a->file; else cp++; - l = strlen(cp) + 1; - a->base = malloc(l); - n_strcpy(a->base, cp, l); + a->base = strdup(cp); if ((cp = strrchr(a->base, '.')) != NULL) *cp = '\0'; if (dev.allpunct) a->spec |= SPEC_PUNCT; if (a->base[0]=='S' && a->base[1]==0) a->spec |= SPEC_S; if (a->base[0]=='S' && a->base[1]=='1' && a->base[2]==0) a->spec |= SPEC_S1; s = a->spec; a->xheight = 500; a->capheight = 700; unitsPerEm = 1000; if (memcmp(contents, "OTTO", 4) == 0 || memcmp(contents, "\0\1\0\0", 4) == 0 || memcmp(contents, "true", 4) == 0) return otfget(a, contents, size); a->lineno = 1; for (cp = contents; cp < &contents[size]; a->lineno++, cp++) { while (*cp == ' ' || *cp == '\t' || *cp == '\r') cp++; if (*cp == '\n') continue; if (thisword(cp, "Comment")) /*EMPTY*/; else if (state == NONE && thisword(cp, "StartFontMetrics")) state = FONTMETRICS; else if (state == FONTMETRICS && thisword(cp, "EndFontMetrics")) state = NONE; else if (state == FONTMETRICS && (th = thisword(cp, "FontName")) != NULL) { for (tp = th; *tp && *tp != ' ' && *tp != '\t' && *tp != '\n' && *tp != '\r'; tp++); a->fontname = malloc(tp - th + 1); memcpy(a->fontname, th, tp - th); a->fontname[tp - th] = 0; } else if (state == FONTMETRICS && (th = thisword(cp, "IsFixedPitch")) != NULL) { a->isFixedPitch = strncmp(th, "true", 4) == 0; } else if (state == FONTMETRICS && (th = thisword(cp, "XHeight")) != NULL) { a->xheight = strtol(th, NULL, 10); } else if (state == FONTMETRICS && (th = thisword(cp, "CapHeight")) != NULL) { a->capheight = strtol(th, NULL, 10); } else if (state == FONTMETRICS && (th = thisword(cp, "Ascender")) != NULL) { a->ascender = strtol(th, NULL, 10); } else if (state == FONTMETRICS && (th = thisword(cp, "Descender")) != NULL) { a->descender = strtol(th, NULL, 10); } else if (state == FONTMETRICS && (th = thisword(cp, "StartCharMetrics")) != 0) { n = strtol(th, NULL, 10); state = CHARMETRICS; afmalloc(a, n); } else if (state == CHARMETRICS && thisword(cp, "EndCharMetrics")) { state = FONTMETRICS; afmremap(a); } else if (state == CHARMETRICS && n-- > 0) { addmetrics(a, cp, s); #ifndef DPOST } else if (state == FONTMETRICS && thisword(cp, "StartKernData") != 0) { state = KERNDATA; } else if (state == KERNDATA && (th = thisword(cp, "StartKernPairs")) != 0) { n = strtol(th, NULL, 10); state = KERNPAIRS; } else if (state == KERNPAIRS && thisword(cp, "EndKernPairs")) { state = KERNDATA; } else if (state == KERNPAIRS && n-- > 0) { addkernpair(a, cp); } else if (state == KERNDATA && thisword(cp, "EndKernData")) { state = FONTMETRICS; #endif /* !DPOST */ } while (cp < &contents[size] && *cp != '\n') cp++; } if (a->fontname == NULL) { errprint("Missing \"FontName\" in %s", a->path); return -1; } a->Font.nwfont = a->nchars > 255 ? 255 : a->nchars; return 0; } /* * This is for legacy font support. It exists at this place because both * troff and dpost need it in combination with AFM support. */ void -makefont(int nf, char *devfontab, char *devkerntab, char *devcodetab, - char *devfitab, int nw) +makefont(int nf, const char *devfontab, const char *devkerntab, + const char *devcodetab, const char *devfitab, int nw) { int i; free(fontab[nf]); free(kerntab[nf]); free(codetab[nf]); free(fitab[nf]); fontab[nf] = calloc(nw, sizeof *fontab); kerntab[nf] = calloc(nw, sizeof *kerntab); codetab[nf] = calloc(nw, sizeof *codetab); fitab[nf] = calloc(NCHARS ? NCHARS : 128 - 32 + nchtab, sizeof *fitab); if (devfontab) for (i = 0; i < nw; i++) fontab[nf][i] = devfontab[i]&0377; if (devkerntab) for (i = 0; i < nw; i++) kerntab[nf][i] = devkerntab[i]&0377; if (devcodetab) for (i = 0; i < nw; i++) codetab[nf][i] = devcodetab[i]&0377; if (devfitab) for (i = 0; i < 128 - 32 + nchtab; i++) fitab[nf][i] = devfitab[i]&0377; fontbase[nf]->spacewidth = fontab[nf][0]; fontbase[nf]->cspacewidth = -1; } #ifndef DPOST /* * For short to medium-sized documents, the run time is dominated by * the time required to read kerning pairs for fonts with many pairs. * Kerning pairs are thus simply dumped in the order they occur at * this point. Later when a kerning pair is actually looked up, the * structures accessed are sorted (eliding duplicates), leading to * better performance with large documents. */ void afmaddkernpair(struct afmtab *a, int ch1, int ch2, int k) { struct kernpairs *kp; if (k == 0) return; if (a->kernpairs == NULL) a->kernpairs = calloc(a->fichars, sizeof *a->kernpairs); kp = &a->kernpairs[ch1]; while (kp->cnt == NKERNPAIRS) { if (kp->next == NULL) kp->next = calloc(1, sizeof *kp->next); kp = kp->next; } kp->ch2[kp->cnt] = ch2; kp->k[kp->cnt] = k; kp->cnt++; } static void addkernpair(struct afmtab *a, char *_line) { struct namecache *np1, *np2; char *lp = _line, c, *cp; int n, i, j; if (lp[0] == 'K' && lp[1] == 'P') { lp += 2; if (*lp == 'X') lp++; while ((*lp && *lp == ' ') || *lp == '\t') lp++; cp = lp; while (*lp && *lp != '\n' && *lp != '\r' && *lp != ' ' && *lp != '\t') lp++; if ((c = *lp) == 0) return; *lp = 0; np1 = afmnamelook(a, cp); *lp = c; while ((*lp && *lp == ' ') || *lp == '\t') lp++; cp = lp; while (*lp && *lp != '\n' && *lp != '\r' && *lp != ' ' && *lp != '\t') lp++; if ((c = *lp) == 0) return; *lp = 0; np2 = afmnamelook(a, cp); *lp = c; n = _unitconv(strtol(&lp[1], NULL, 10)); for (i = 0; i < 2; i++) if (np1->fival[i] != NOCODE) for (j = 0; j < 2; j++) if (np2->fival[j] != NOCODE) afmaddkernpair(a, np1->fival[i], np2->fival[j], n); } } static void sortkernpairs(struct kernpairs *kp) { int i, j, s, t; do { s = 0; for (i = 0; i < kp->cnt-1; i++) if (kp->ch2[i] > kp->ch2[i+1]) { t = kp->ch2[i]; kp->ch2[i] = kp->ch2[i+1]; kp->ch2[i+1] = t; t = kp->k[i]; kp->k[i] = kp->k[i+1]; kp->k[i+1] = t; s = 1; } } while (s); for (j = 0; j < kp->cnt-1; j++) if (kp->ch2[j] == kp->ch2[j+1]) { for (i = j+1; i < kp->cnt-1; i++) { kp->ch2[i] = kp->ch2[i+1]; kp->k[i] = kp->k[i+1]; } kp->cnt--; j--; } kp->sorted = 1; } int afmgetkern(struct afmtab *a, int ch1, int ch2) { struct kernpairs *kp; int l, m, r; if (a->kernpairs) { kp = &a->kernpairs[ch1]; do { if (kp->sorted == 0) sortkernpairs(kp); r = kp->cnt - 1; if (ch2 >= kp->ch2[0] && r >= 0 && ch2 <= kp->ch2[r]) { l = 0; do { m = (l+r) / 2; if (ch2 < kp->ch2[m]) r = m-1; else l = m+1; } while (ch2 != kp->ch2[m] && l <= r); if (kp->ch2[m] == ch2) return kp->k[m]; } } while ((kp = kp->next) != NULL); } return 0; } #endif /* !DPOST */ char * afmencodepath(const char *cp) { const char hex[] = "0123456789ABCDEF"; char *enc, *ep; ep = enc = malloc(3 * strlen(cp) + 1); while (*cp) { if (*cp&0200 || *cp <= 040 || *cp == 0177) { *ep++ = '%'; *ep++ = hex[(*cp&0360) >> 4]; *ep++ = hex[*cp++&017]; } else *ep++ = *cp++; } *ep = 0; return enc; } static int unhex(int c) { if (c >= 'A' && c <= 'F') return c - 'A'; if (c >= 'a' && c <= 'f') return c - 'a'; return c - '0'; } static int xdigit(int c) { return (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9'); } char * afmdecodepath(const char *cp) { char *dec, *dp; dec = dp = malloc(strlen(cp) + 1); while (*cp) { if (cp[0] == '%' && xdigit(cp[1]&0377) && xdigit(cp[2]&0377)) { *dp++ = unhex(cp[1]) << 4 | unhex(cp[2]); cp += 3; } else *dp++ = *cp++; } *dp = 0; return dec; } #endif /* !DUMP */ Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/afm.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/afm.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/afm.h (revision 307812) @@ -1,149 +1,149 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)afm.h 1.35 (gritter) 10/5/06 */ #ifndef TROFF_AFM_H #define TROFF_AFM_H enum spec { SPEC_NONE = 00000, SPEC_MATH = 00001, SPEC_GREEK = 00002, SPEC_PUNCT = 00004, SPEC_LARGE = 00010, SPEC_S1 = 01000, SPEC_S = 02000 }; #define NOCODE ((unsigned short)-1) #define NKERNPAIRS 45 struct kernpairs { struct kernpairs *next; int sorted; int cnt; unsigned short ch2[NKERNPAIRS]; short k[NKERNPAIRS]; }; struct namecache { unsigned short afpos; unsigned short fival[2]; unsigned short gid; }; struct charpair { unsigned short ch1; unsigned short ch2; }; struct feature { char *name; struct charpair *pairs; int npairs; }; extern struct afmtab { struct Font Font; char *encpath; char *path; char *file; char *base; char *fontname; char *supply; int *fontab; short **bbtab; char *kerntab; unsigned short *codetab; unsigned short *fitab; char **nametab; int *unitab; int nunitab; void *unimap; int *encmap; struct namecache *namecache; int nameprime; struct kernpairs *kernpairs; struct charpair *gid2tr; int nspace; struct feature **features; int rq; int lineno; int nchars; int fichars; int capheight; int xheight; int isFixedPitch; int ascender; int descender; enum spec spec; enum { TYPE_AFM, TYPE_OTF, TYPE_TTF } type; } **afmtab; extern int nafm; extern unsigned short **fitab; extern int **fontab; extern char **kerntab; extern unsigned short **codetab; extern struct Font **fontbase; extern int NCHARS; extern unsigned short unitsPerEm; extern int afmget(struct afmtab *, char *, size_t); extern int otfget(struct afmtab *, char *, size_t); extern struct namecache *afmnamelook(struct afmtab *, const char *); extern int afmgetkern(struct afmtab *, int, int); -extern void makefont(int, char *, char *, char *, char *, int); +extern void makefont(int, const char *, const char *, const char *, const char *, int); extern int unitconv(int); extern void afmalloc(struct afmtab *, int); extern void afmremap(struct afmtab *); extern int afmmapname(const char *, enum spec); extern void afmaddchar(struct afmtab *, int, int, int, int, int[], char *, enum spec, int); extern void afmaddkernpair(struct afmtab *, int, int, int); extern int nextprime(int n); extern unsigned pjw(const char *); extern char *afmencodepath(const char *); extern char *afmdecodepath(const char *); #ifdef DPOST #include extern int otfcff(const char *, char *, size_t, size_t *, size_t *); extern int otft42(char *, char *, char *, size_t, FILE *); extern int fprintenc(FILE *, const char *); #endif extern struct dev dev; #define _unitconv(i) (unitsPerEm * 72 == dev.res ? (i) : unitconv(i)) #endif /* !TROFF_AFM_H */ Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/getopt.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/getopt.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/getopt.c (nonexistent) @@ -1,222 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany - * - * Sccsid @(#)getopt.c 1.10 (gritter) 12/16/07 - */ -/* from OpenSolaris "getopt.c 1.23 05/06/08 SMI" */ - -/* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ - - -/* - * See getopt(3C) and SUS/XPG getopt() for function definition and - * requirements. - * - * This actual implementation is a bit looser than the specification - * as it allows any character other than ':' to be used as an option - * character - The specification only guarantees the alnum characters - * ([a-z][A-Z][0-9]). - */ - -#include -#include -#include - -extern ssize_t write(int, const void *, size_t); - -char *optarg = NULL; -int optind = 1; -int opterr = 1; -int optopt = 0; - -#define ERR(s, c) err(s, c, optstring, argv[0]) -static void -err(const char *s, int c, const char *optstring, const char *argv0) -{ - char errbuf[256], *ep = errbuf; - const char *cp; - - if (opterr && optstring[0] != ':') { - for (cp = argv0; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - for (cp = ": "; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - for (cp = s; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - for (cp = " -- "; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - if (ep<&errbuf[sizeof errbuf]) - *ep++ = c; - if (ep<&errbuf[sizeof errbuf]) - *ep++ = '\n'; - write(2, errbuf, ep - errbuf); - } -} - -/* - * getopt_sp is required to keep state between successive calls to getopt() - * while extracting aggregated options (ie: -abcd). Hence, getopt() is not - * thread safe or reentrant, but it really doesn't matter. - * - * So, why isn't this "static" you ask? Because the historical Bourne - * shell has actually latched on to this little piece of private data. - */ -int getopt_sp = 1; - -/* - * Determine if the specified character (c) is present in the string - * (optstring) as a regular, single character option. If the option is found, - * return a pointer into optstring pointing at the option character, - * otherwise return null. The character ':' is not allowed. - */ -static char * -parse(const char *optstring, const char c) -{ - char *cp = (char *)optstring; - - if (c == ':') - return (NULL); - do { - if (*cp == c) - return (cp); - } while (*cp++ != '\0'); - return (NULL); -} - -/* - * External function entry point. - */ -int -getopt(int argc, char *const *argv, const char *optstring) -{ - char c; - char *cp; - - /* - * Has the end of the options been encountered? The following - * implements the SUS requirements: - * - * If, when getopt() is called: - * argv[optind] is a null pointer - * *argv[optind] is not the character '-' - * argv[optind] points to the string "-" - * getopt() returns -1 without changing optind. If - * argv[optind] points to the string "--" - * getopt() returns -1 after incrementing optind. - */ - if (getopt_sp == 1) { - if (optind >= argc || argv[optind][0] != '-' || - argv[optind] == NULL || argv[optind][1] == '\0') - return (EOF); - else if (strcmp(argv[optind], "--") == 0) { - optind++; - return (EOF); - } - } - - /* - * Getting this far indicates that an option has been encountered. - * Note that the syntax of optstring applies special meanings to - * the characters ':' and '(', so they are not permissible as - * option letters. A special meaning is also applied to the ')' - * character, but its meaning can be determined from context. - * Note that the specification only requires that the alnum - * characters be accepted. - */ - optopt = c = (unsigned char)argv[optind][getopt_sp]; - optarg = NULL; - if ((cp = parse(optstring, c)) == NULL) { - /* LINTED: variable format specifier */ - ERR("illegal option", c); - if (argv[optind][++getopt_sp] == '\0') { - optind++; - getopt_sp = 1; - } - return ('?'); - } - optopt = c = *cp; - - /* - * A valid option has been identified. If it should have an - * option-argument, process that now. SUS defines the setting - * of optarg as follows: - * - * 1. If the option was the last character in the string pointed to - * by an element of argv, then optarg contains the next element - * of argv, and optind is incremented by 2. If the resulting - * value of optind is not less than argc, this indicates a - * missing option-argument, and getopt() returns an error - * indication. - * - * 2. Otherwise, optarg points to the string following the option - * character in that element of argv, and optind is incremented - * by 1. - * - * The second clause allows -abcd (where b requires an option-argument) - * to be interpreted as "-a -b cd". - */ - if (*(cp + 1) == ':') { - /* The option takes an argument */ - if (argv[optind][getopt_sp+1] != '\0') { - optarg = &argv[optind++][getopt_sp+1]; - } else if (++optind >= argc) { - /* LINTED: variable format specifier */ - ERR("option requires an argument", c); - getopt_sp = 1; - optarg = NULL; - return (optstring[0] == ':' ? ':' : '?'); - } else - optarg = argv[optind++]; - getopt_sp = 1; - } else { - /* The option does NOT take an argument */ - if (argv[optind][++getopt_sp] == '\0') { - getopt_sp = 1; - optind++; - } - optarg = NULL; - } - return (c); -} /* getopt() */ - -#ifdef __APPLE__ -/* - * Starting with Mac OS 10.5 Leopard, turns getopt() - * into getopt$UNIX2003() by default. Consequently, this function - * is called instead of the one defined above. However, optind is - * still taken from this file, so in effect, options are not - * properly handled. Defining an own getopt$UNIX2003() function - * works around this issue. - */ -int -getopt$UNIX2003(int argc, char *const argv[], const char *optstring) -{ - return getopt(argc, argv, optstring); -} -#endif /* __APPLE__ */ Property changes on: projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/getopt.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/Makefile.mk (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/Makefile.mk (revision 307812) @@ -1,48 +1,48 @@ -OBJ = daps.o build.o draw.o getopt.o version.o +OBJ = daps.o build.o draw.o version.o FONTS = B I R S CT CW CX GB GI GR GS HI HK HX PO PX S1 SC SM TX DESC \ C G H BI CE CI HB HL MB MI MR MX PA PB PI TB FLAGS = -I. -I.. -DFNTDIR='"$(FNTDIR)"' .c.o: $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< all: daps makedev fonts HM.out daps: $(OBJ) $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -lm -o daps makedev: makedev.o $(CC) $(LDFLAGS) makedev.o $(LIBS) -o makedev fonts: makedev for i in $(FONTS); \ do \ ./makedev $$i || exit; \ done HM.out: HB.out rm -f $@ ln -s HB.out $@ HB.out: fonts install: all $(INSTALL) -c daps $(ROOT)$(BINDIR)/daps $(STRIP) $(ROOT)$(BINDIR)/daps mkdir -p $(ROOT)$(FNTDIR)/devaps for i in $(FONTS) *.add *.out version; \ do \ $(INSTALL) -c -m 644 $$i $(ROOT)$(FNTDIR)/devaps/$$i || exit; \ done clean: rm -f $(OBJ) daps makedev.o makedev *.add *.out core log *~ mrproper: clean build.o: build.c daps.h daps.o: daps.c aps.h dev.h daps.h daps.g makedev.o: makedev.c dev.h draw.o: draw.c ../draw.c Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/getopt.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/getopt.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/getopt.c (nonexistent) @@ -1,222 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* - * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany - * - * Sccsid @(#)getopt.c 1.10 (gritter) 12/16/07 - */ -/* from OpenSolaris "getopt.c 1.23 05/06/08 SMI" */ - -/* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ - - -/* - * See getopt(3C) and SUS/XPG getopt() for function definition and - * requirements. - * - * This actual implementation is a bit looser than the specification - * as it allows any character other than ':' to be used as an option - * character - The specification only guarantees the alnum characters - * ([a-z][A-Z][0-9]). - */ - -#include -#include -#include - -extern ssize_t write(int, const void *, size_t); - -char *optarg = NULL; -int optind = 1; -int opterr = 1; -int optopt = 0; - -#define ERR(s, c) err(s, c, optstring, argv[0]) -static void -err(const char *s, int c, const char *optstring, const char *argv0) -{ - char errbuf[256], *ep = errbuf; - const char *cp; - - if (opterr && optstring[0] != ':') { - for (cp = argv0; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - for (cp = ": "; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - for (cp = s; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - for (cp = " -- "; *cp && ep<&errbuf[sizeof errbuf]; cp++, ep++) - *ep = *cp; - if (ep<&errbuf[sizeof errbuf]) - *ep++ = c; - if (ep<&errbuf[sizeof errbuf]) - *ep++ = '\n'; - write(2, errbuf, ep - errbuf); - } -} - -/* - * getopt_sp is required to keep state between successive calls to getopt() - * while extracting aggregated options (ie: -abcd). Hence, getopt() is not - * thread safe or reentrant, but it really doesn't matter. - * - * So, why isn't this "static" you ask? Because the historical Bourne - * shell has actually latched on to this little piece of private data. - */ -int getopt_sp = 1; - -/* - * Determine if the specified character (c) is present in the string - * (optstring) as a regular, single character option. If the option is found, - * return a pointer into optstring pointing at the option character, - * otherwise return null. The character ':' is not allowed. - */ -static char * -parse(const char *optstring, const char c) -{ - char *cp = (char *)optstring; - - if (c == ':') - return (NULL); - do { - if (*cp == c) - return (cp); - } while (*cp++ != '\0'); - return (NULL); -} - -/* - * External function entry point. - */ -int -getopt(int argc, char *const *argv, const char *optstring) -{ - char c; - char *cp; - - /* - * Has the end of the options been encountered? The following - * implements the SUS requirements: - * - * If, when getopt() is called: - * argv[optind] is a null pointer - * *argv[optind] is not the character '-' - * argv[optind] points to the string "-" - * getopt() returns -1 without changing optind. If - * argv[optind] points to the string "--" - * getopt() returns -1 after incrementing optind. - */ - if (getopt_sp == 1) { - if (optind >= argc || argv[optind][0] != '-' || - argv[optind] == NULL || argv[optind][1] == '\0') - return (EOF); - else if (strcmp(argv[optind], "--") == 0) { - optind++; - return (EOF); - } - } - - /* - * Getting this far indicates that an option has been encountered. - * Note that the syntax of optstring applies special meanings to - * the characters ':' and '(', so they are not permissible as - * option letters. A special meaning is also applied to the ')' - * character, but its meaning can be determined from context. - * Note that the specification only requires that the alnum - * characters be accepted. - */ - optopt = c = (unsigned char)argv[optind][getopt_sp]; - optarg = NULL; - if ((cp = parse(optstring, c)) == NULL) { - /* LINTED: variable format specifier */ - ERR("illegal option", c); - if (argv[optind][++getopt_sp] == '\0') { - optind++; - getopt_sp = 1; - } - return ('?'); - } - optopt = c = *cp; - - /* - * A valid option has been identified. If it should have an - * option-argument, process that now. SUS defines the setting - * of optarg as follows: - * - * 1. If the option was the last character in the string pointed to - * by an element of argv, then optarg contains the next element - * of argv, and optind is incremented by 2. If the resulting - * value of optind is not less than argc, this indicates a - * missing option-argument, and getopt() returns an error - * indication. - * - * 2. Otherwise, optarg points to the string following the option - * character in that element of argv, and optind is incremented - * by 1. - * - * The second clause allows -abcd (where b requires an option-argument) - * to be interpreted as "-a -b cd". - */ - if (*(cp + 1) == ':') { - /* The option takes an argument */ - if (argv[optind][getopt_sp+1] != '\0') { - optarg = &argv[optind++][getopt_sp+1]; - } else if (++optind >= argc) { - /* LINTED: variable format specifier */ - ERR("option requires an argument", c); - getopt_sp = 1; - optarg = NULL; - return (optstring[0] == ':' ? ':' : '?'); - } else - optarg = argv[optind++]; - getopt_sp = 1; - } else { - /* The option does NOT take an argument */ - if (argv[optind][++getopt_sp] == '\0') { - getopt_sp = 1; - optind++; - } - optarg = NULL; - } - return (c); -} /* getopt() */ - -#ifdef __APPLE__ -/* - * Starting with Mac OS 10.5 Leopard, turns getopt() - * into getopt$UNIX2003() by default. Consequently, this function - * is called instead of the one defined above. However, optind is - * still taken from this file, so in effect, options are not - * properly handled. Defining an own getopt$UNIX2003() function - * works around this issue. - */ -int -getopt$UNIX2003(int argc, char *const argv[], const char *optstring) -{ - return getopt(argc, argv, optstring); -} -#endif /* __APPLE__ */ Property changes on: projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/getopt.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/Makefile.mk (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/Makefile.mk (revision 307812) @@ -1,42 +1,42 @@ BST = ../../../stuff/bst OBJ = dpost.o draw.o color.o pictures.o ps_include.o afm.o \ - makedev.o glob.o misc.o request.o version.o getopt.o \ + makedev.o glob.o misc.o request.o version.o \ asciitype.o otf.o ../fontmap.o $(BST)/bst.o FLAGS = -I. -I.. -DFNTDIR='"$(FNTDIR)"' -DPSTDIR='"$(PSTDIR)"' $(EUC) \ $(DEFINES) -I../../../include -I.. -I$(BST) .c.o: $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< all: dpost dpost: $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o dpost install: $(INSTALL) -c dpost $(ROOT)$(BINDIR)/dpost $(STRIP) $(ROOT)$(BINDIR)/dpost mkdir -p $(ROOT)$(MANDIR)/man1 $(INSTALL) -c -m 644 dpost.1 $(ROOT)$(MANDIR)/man1/dpost.1 clean: rm -f $(OBJ) dpost core log *~ mrproper: clean color.o: color.c gen.h ext.h dpost.o: dpost.c comments.h gen.h path.h ext.h ../dev.h dpost.h ../afm.h \ asciitype.h draw.o: draw.c gen.h ext.h glob.o: glob.c gen.h misc.o: misc.c gen.h ext.h path.h asciitype.h pictures.o: pictures.c comments.h gen.h path.h ps_include.o: ps_include.c ext.h gen.h asciitype.h path.h request.o: request.c gen.h request.h path.h afm.o: afm.c ../dev.h ../afm.h ../afm.c otf.o: otf.c ../dev.h ../afm.h ../otf.c makedev.o: makedev.c ../dev.h ../makedev.c asciitype.o: asciitype.h version.o: version.c ../../version.c Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/dpost.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/dpost.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/dpost.c (revision 307812) @@ -1,4835 +1,4814 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1994 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "dpost.c 1.11 05/06/08 SMI" SVr4.0 1.2 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)dpost.c 1.176 (gritter) 8/19/08 */ /* * * dpost - troff post-processor for PostScript printers. * * A program that translates output generated by the device independent troff * into PostScript. Much was borrowed from dimpress and dps (formally dlzw), * and even though the code has been changed, credit has to be given to Richard * Flood for his early work on the PostScript driver. * * Among the most interesting new features are color support (see devcntrl() and * file color.c) and code to handle complex paths pieced together using any of the * standard drawing commands (see devcntrl() and file draw.c). Reverse video mode * has also been included as a special case of the color support. Two encoding * schemes based on widthshow are also new additions. The safe one is obtained when * you set encoding to 2 (eg. using the -e2 option). The slightly faster method * is obtained by setting encoding to 3 (eg. using the -e3 option), although it's * not recommended. Rounding errors in character widths can accumulate and become * quite noticeable by the time you get to the right margin. More often than not * you end up getting a ragged right margin. * * The program handles files formatted for any device, although the best and * most efficient output is generated when the font and description files match * PostScript's resident fonts. Device emulation is relatively expensive, and * can produce output files that are more than twice the size of the input files. * In most cases output files will be smaller than input files, perhaps by up to * 40 percent, although the results you get depend on what you're doing and the * text encoding you're using. You'll get the worst results if you're emulating * another device, using special bitmap characters, like the logo, or doing lots * of vertical motion or drawing. * * PostScript fonts don't support all of troff's characters, so some have to * be built by special PostScript procedures. Those routines can be found in * *fontdir/devpost/charlib, and are only used when we try to print a character * that has been assigned a code less than 32. Definitions are only made the * first time each character is used. Subsequent requests to print the character * only generate a call to the PostScript procedure that's been copied to the * output file. For example you'll find a file called sq in directory * *fontdir/devpost/charlib. It defines a PostScript procedure called build_sq * that's called whenever we need to print a square. Special characters that * have been assigned a code of 2 are expected to come in two pieces. The * definition part and bitmap part (or whatever). The definition is only made * once, but the contents of the character's .map file are copied to the output * file each time, immediately after charlib() generates the call to the * PostScript procedure (build_?? ) that builds the character. That's typically * how logos built from bitmaps would be handled. * * Several different methods can be used to encode lines of text. What's done * depends on the value assigned to encoding. Print time should decrease as * encoding increases (up to MAXENCODING). Setting encoding to 0, which should * probably be the default, produces output essentially identical to the original * version of dpost. It's the slowest but most stable method of encoding lines of * text, and won't be bothered by rounding errors in the font width tables that * could become noticeable by the time you get to the end of a line. Other schemes * seem to work, but aren't well tested and are not guaranteed for all possible * jobs. encoding can be changed on the command line using the -e option. Part of * the support for different encoding schemes was to move control of all text * related output to separate routines. It makes dpost work harder, but changing * things is easy. For example adding stuff to support widthshow took less than * an hour. * * I've also added code that handles the DOCUMENTFONTS comment, although it's * only produced for those fonts in directory /usr/lib/font/devpost that have an * associated .name file. The first string in a .name file should be the (long) * PostScript name (eg. Times-Roman in R.name). For now everything else in the * .name file is ignored, although that may also change. You'll find .name files * for all the supported fonts in the devpost source directory, although they may * not be installed in /usr/lib/font/devpost. * * The PostScript prologue is copied from *prologue before any of the input files * are translated. The program expects the following procedures are avaliable: * * setup * * mark ... setup - * * Handles special initialization stuff that depends on how the program * was called. Expects to find a mark followed by key/value pairs on the * stack. The def operator is applied to each pair up to the mark, then * the default state is set up. An 'x res' command must preceed the * 'x init' command! * * pagesetup * * page pagesetup - * * Called at the start of each page, immediately after the page level * save, to do special initialization on a per page basis. Right now the * only argument is the current page number, and actually nothing of any * importance is currently done. * * setdecoding * * num setdecoding - * * Selects the text decoding procedure (ie. what's assigned to PostScript * procedure t) from the decodingdefs array defined in the prologue. num * should be the value assigned to variable encoding (in dpost) and will * remain constant throughout a job, unless special features, like reverse * video printing, are requested. The text encoding scheme can be set on * the command line using the -e option. Print time and the size of the * output file will usually decrease as the value assigned to encoding * increases. * * f * * size font f - * * Selects the size and font to be used for character imaging. Font names * are defined, in *prologue, so they agree with the one or two character * names used by troff. * * m * * x y m - * * Moves to point (x, y). Normally only used when the vertical position * changes. Horizontal positioning between words (or letters) is handled * in procedure t (below). * * t * * mark text t mark * * Processes everything on the stack, up to the mark, as a single line * of text to be printed at a fixed vertical position. What's put out as * text depends on the encoding scheme. Setting encoding to 0 produces * output essentially identical to the original version of dpost. In that * case everything on the stack, up to a mark, is interpreted (from top * down) as an absolute horizontal position and a string to be printed at * that point. For example the stack might look like, * * mark(this)1000(is)1100(an)1200(example)1300 t * * Procedure t would go through the stack, up to the mark, adjusting the * horizontal position before printing each string. In other encoding * schemes, like the one based on widthshow, strings containing several * space separated words would appear on the stack, and each one would be * preceeded by a number that's expected to be added to the width of a * space. For example we might have, * * mark(an example)30(this is)40 2 1000 2000 t * * where (1000, 2000) is where the first string starts and 2 is the repeat * count (ie. number of string and space pairs on the stack). * * w * * string x y w - * * Prints a single word starting at position (x, y). Only used in the more * complicated encoding schemes (eg. the ones based on widthshow). * * done * * Makes sure the last page is printed. Only needed when we're printing * more than one page on each sheet of paper. * * The PostScript procedures that support troff's drawing commands have been moved * out of *prologue and put in a separate file (ie. DRAW as defined in path.h). * The procedures are used by the routines in file draw.c, and are copied to the * prologue. * * Many default values, like the magnification and orientation, are defined in * the prologue, which is where they belong. If they're changed (by options), an * appropriate definition is made after the prologue is added to the output file. * The -P option passes arbitrary PostScript through to the output file. Among * other things it can be used to set (or change) values that can't be accessed by * other options. * * * output language from troff: * all numbers are character strings * * sn size in points * fn font as number from 1-n * cx ascii character x * Cxyz funny char xyz. terminated by white space * Hn go to absolute horizontal position n * Vn go to absolute vertical position n (down is positive) * hn go n units horizontally (relative) * vn ditto vertically * nnc move right nn, then print c (exactly 2 digits!) * (this wart is an optimization that shrinks output file size * about 35% and run-time about 15% while preserving ascii-ness) * Dt ...\n draw operation 't': * Dl x y line from here by x,y * Dc d circle of diameter d with left side here * De x y ellipse of axes x,y with left side here * Da x1 y1 x2 y2 arc counter-clockwise from current point (x, y) to * (x + x1 + x2, y + y1 + y2) * D~ x y x y ... wiggly line by x,y then x,y ... * nb a end of line (information only -- no action needed) * b = space before line, a = after * p new page begins -- set v to 0 * #...\n comment * x ...\n device control functions: * x i init * x T s name of device is s * x r n h v resolution is n/inch * h = min horizontal motion, v = min vert * x p pause (can restart) * x s stop -- done forever * x t generate trailer * x f n s font position n contains font s * x H n set character height to n * x S n set slant to N * * Subcommands like "i" are often spelled out like "init". * * * * To get dpost output conforming to Adobe's structuring conventions (DSC), * all output is accumulated in temporary files first. When the document is * completed, files that contain global data are output first, followed by * regular commands, all surrounded by DSC comments. Speed problems, which * were the reason why this was not done by previous versions of dpost, are * no longer of concern in 2005 since several hundred pages of text are * processed now in less than a second. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "comments.h" /* PostScript file structuring comments */ #include "gen.h" /* general purpose definitions */ #include "path.h" /* for the prologue and a few other files */ #include "ext.h" /* external variable definitions */ #include "dev.h" /* typesetter and font descriptions */ #include "dpost.h" /* a few definitions just used here */ #include "asciitype.h" #include "afm.h" #include "fontmap.h" - -#if defined (__GLIBC__) && defined (_IO_getc_unlocked) -#undef getc -#define getc(f) _IO_getc_unlocked(f) -#endif -#if defined (__GLIBC__) && defined (_IO_putc_unlocked) -#undef putc -#define putc(c, f) _IO_putc_unlocked(c, f) -#endif - - char *progname; static const char *prologue = DPOST; /* the basic PostScript prologue */ const char *colorfile = COLOR; /* things needed for color support */ const char *drawfile = DRAW; /* and drawing */ static const char *cutmarksfile = CUTMARKS; static const char *formfile = FORMFILE; /* stuff for multiple pages per sheet */ const char *baselinefile = BASELINE; static const char *fontdir = FONTDIR; /* binary device directories found here */ static char *hostfontdir = NULL; /* host resident font directory */ static int formsperpage = 1; /* page images on each piece of paper */ static int copies = 1; /* and this many copies of each sheet */ int picflag = ON; /* enable/disable picture inclusion */ /* * * encoding selects the encoding scheme used to output lines of text. Change it * to something other than 0 at your own risk. The other methods seem to work but * aren't well tested and are not guaranteed. Some special features, like reverse * video, may temporarily change the encoding scheme and reset it to realencoding * when done. * * Encoding 4 is new as of 9/8/05. It stores only the distances between words and * thus saves a bit of output size. It is automatically enabled at high resolutions. * */ int encoding = DFLTENCODING; int realencoding = DFLTENCODING; int maxencoding = MAXENCODING; static int eflag; int LanguageLevel; /* PostScript output language level */ static int Binary; /* PostScript output contains binary data */ /* * * seenfonts[] keeps track of the fonts we've used, based on internal numbers. It * helps manage host resident fonts and the DOCUMENTFONTS comment, but only works * if all fonts have internal numbers less than MAXINTERNAL. *docfonts counts the * number of font names we've recorded in *temp_file. If it's positive routine * done() adds *temp_file to the output file before quitting. * */ static char seenfonts[MAXINTERNAL+1]; static int docfonts = 0; static struct afmtab **afmfonts; static int afmcount = 0; /* * * devname[] is the device troff used when the job was formatted, while *realdev * is combined with *fontdir and used to locate the font and device tables that * that control the translation of the input files into PostScript. *realdev can * be changed using the -T option, but if you do you may end up getting garbage. * The character code field must agree with PostScript's font encoding and font * names must be properly mapped into PostScript font names in the prologue. * */ #define devname troff_devname static char devname[20] = ""; /* job is formatted for this printer */ static const char *realdev = DEVNAME; /* a good description of target printer */ /* * * Standard things that come from binary font and description files for *realdev. * Most are initialized in fontinit() or loadfont(). * */ struct dev dev; /* DESC starts this way */ struct Font **fontbase; /* FONT files begin this way */ static int *pstab; /* list of available sizes */ static int nsizes = 1; /* and the number of sizes in that list */ static int smnt; /* index of first special font */ int nchtab; /* number of special character names */ static int fsize; /* max size of a font files in bytes */ static int unitwidth; /* set to dev.unitwidth */ char *chname; /* special character strings */ short *chtab; /* used to locate character names */ unsigned short **fitab; /* locates char info on each font */ int **fontab; /* character width data for each font */ unsigned short **codetab; /* and codes to get characters printed */ char **kerntab; /* for makefont() */ /* * * Special characters missing from standard PostScript fonts are defined by files * in directory *fontdir/devpost/charlib. Files have the same names as the troff * special character names (for now at least) and each one defines a PostScript * procedure that begins with the prefix build_ and ends with the character's * name. * * For example, the routine used to build character \(12, would be build_12. * downloaded[] points to an array, allocated in fontinit(), that keeps track of * the characters that have already been defined - so we only do it once. * */ static char *downloaded; /* nonzero means it's been downloaded */ /* * * Variables that keep track of troff's requests. All are set from values in the * input files. nfonts is adjusted in t_fp() as new fonts are mounted. * */ int nfonts = 0; /* number of font positions */ int size = 1; /* current size - internal value */ #define FRACTSIZE -23 /* if size == FRACTSIZE then ... */ static float fractsize = 0; /* fractional point size */ static int font = 0; /* font position we're using now */ static int subfont = 0; /* extra encoding vector */ int hpos = 0; /* where troff wants to be - horizontally */ int vpos = 0; /* same but vertically */ static float lastw = 0; /* width of the last input character */ static int track = 0; /* tracking hint from troff */ static int lasttrack = 0; /* previous tracking hint */ static int tracked; /* records need to flush track */ static int lastc = 0; /* and its name (or index) */ int res; /* resolution assumed in input file */ static float widthfac = 1.0; /* for emulation = res/dev.res */ static float horscale = 1.0; /* horizontal font scaling */ static float lasthorscale = 1.0; /* last horizontal font scaling */ static int wordspace = 0; /* w command was last */ /* * * Remember some of the same things, but this time for the printer. lastend is only * used when we're doing reverse video, and is where the last character on the * current line was printed. * */ static int lastsize = -1; /* last internal size we used */ static float lastfractsize = -1; /* last fractional size */ static int lastfont = -1; /* last font we told printer about */ static int lastsubfont = -1; /* last extra encoding vector */ static float lastx = -1; /* printer's current position */ static int lasty = -1; static int savey = -1; int lastend; /* where last character on this line was */ /* * * fontname[] keeps track of the mounted fonts. Filled in (by t_fp()) from data * in the binary font files. * * When font metrics are directly read from AFM files, all characters that * are not ASCII are put into the remaining positions in PostScript encoding * vectors. Their position in these vectors in recorded in afm->encmap, and * characters from troff are translated if necessary. * */ static struct { struct afmtab *afm; /* AFM data, if any */ char *name; /* name of the font loaded here */ int number; /* its internal number */ float fontheight; /* points from x H ... */ int fontslant; /* angle from x S ... */ } fontname[NFONT+1]; /* * * All the special fonts will be mounted after the last legitimate font position. * It helps when we're translating files prepared for devices, like the 202, that * have a different set of special fonts. The set of special fonts needed when * *realdev's tables are used may not get mounted when we're emulating another * device. gotspecial keeps track of whether we've done it yet. seenpage is set * to TRUE after we've seen the first page command in the input file. It controls * what's done in t_font() and is needed because nfonts is no longer set when the * DESC file is read, but rather is updated from "x font" commands in the * input files. gotregular ensures that at least one regular font is mounted. * */ static int gotspecial = FALSE; static int gotregular = FALSE; static int seenpage = FALSE; /* * * The amount of horizontal positioning error we accept controls both the size * of the output file and the appearance of the printed text. It's probably most * important when we're emulating other devices, like the APS-5. The error can be * set using the -S option. It's converted from points to machine units in t_init() * after the resolution is known. rvslop is also set in t_init() and only used to * adjust the width of the box that's drawn around text when we're printing in * reverse video mode. * */ static float pointslop = SLOP; /* horizontal error in points */ static int Sflag; /* unless -S gives explicit slop */ static int slop; /* and machine units */ static int rvslop; /* to extend box in reverse video mode */ /* * * Characters are accumulated and saved in PostScript strings that are eventually * processed by making a single call to procedure t. textcount counts the number * of individual strings collected but not yet processed, and is primarily used to * make sure PostScript's stack doesn't get too big. When textcount is positive * we've started accumulating strings and need to generate a call to PostScript * procedure t to process the text before anything else (like a font change) is * done. * */ static int textcount = 0; /* strings accumulated so far */ static int stringstart = 0; /* where the next one starts */ static int laststrstart = INT_MIN; /* save for optimization */ static int spacecount = 0; /* spaces seen so far on current line */ static int charcount = 0; /* characters on current line */ /* * * Things that can be used by text line encoding schemes that need to read and * remember an entire line before doing any output. The strings that make up the * line can be saved in array strings[] and accessed by fields in line[]. *strptr * points to the next free slot in strings[]. * */ static char strings[STRINGSPACE]; static char *strptr; static Line line[MAXSTACK+3]; /* * * When we're emulating another device we may want to map font name requests that * come in as "x font pos name" commands into some other font name before anything * else is done (ie. calling loadfont()). Font names can collide or we may just * want to a mapping that depends on the device troff used to format the input * files. devfontmap points to a structure that's filled in by getdevmap() if the * mapping file /usr/lib/font/dev*realdev/fontmaps/devname exists. mapdevfont() * then uses that table to translate font name requests into something else before * loadfont() gets called. * * fontmap[] provides a simple minded translation that maps an unrecognized font * name (in loadfont()) into another font name that we know will be available. It * doesn't provide the fine control available with *devfontmap, but should be good * enough for most jobs. Both structures are only needed when emulating another * device using *realdev's font tables. * */ static Devfontmap *devfontmap = NULL; /* device level */ static Fontmap fontmap[] = FONTMAP; /* and general mapping tables - emulation */ /* * * Variables and functions for the pdfmark operator. * */ static char *Author; /* DOCINFO /Author */ static char *Title; /* DOCINFO /Title */ static char *Subject; /* DOCINFO /Subject */ static char *Keywords; /* DOCINFO /Keywords */ static struct Bookmark { char *Title; /* OUT /Title */ char *title; /* unencoded title */ int Count; /* OUT /Count */ int level; /* used to generate count */ int closed; /* the bookmark is closed initially */ } *Bookmarks; static size_t nBookmarks; static double pagelength = 792; /* lenght of page in points */ #define MAXBOOKMARKLEVEL 20 static void orderbookmarks(void); static struct box { int val[4]; int flag; } mediasize, bleedat, trimat, cropat; /* * * For the -M option. * */ static enum { M_NONE = 000, M_CUT = 001, M_STAR = 002, M_REG = 004, M_COL = 010, M_ALL = 077 } Mflag; static void setmarks(char *); /* * * A few variables that are really only used if we're doing accounting. Designed * for our use at Murray Hill and probably won't suit your needs. Changes should * be easy and can be made in routine account(). * */ int printed = 0; /* charge for this many pages */ /* * * Output and accounting file definitions. The PostScript output always goes to * stdout or /dev/null, while the accounting file can be selected using the -A * option. * */ FILE *tf = NULL; /* PostScript output goes here */ FILE *gf = NULL; /* global data goes here */ FILE *rf = NULL; /* resource data goes here */ FILE *sf = NULL; /* supplied resource comments go here */ FILE *nf = NULL; /* needed resource comments go here */ FILE *pf = NULL; /* elements of _custompagesetup */ static int sfcount; /* count of supplied resources */ static int nfcount; /* count of needed resources */ static int ostdout; /* old standard output */ static FILE *fp_acct = NULL; /* accounting stuff written here */ /* * * Very temporary space that can be used to do things like building up pathnames * immediately before opening a file. Contents may not be preserved across calls * to subroutines defined in this file, so it probably should only be used in low * level subroutines like loadfont() or fontinit() and nowhere else. * */ static char temp[4096]; /*****************************************************************************/ static char *linkborderstyle; static char *ulinkborderstyle; static void sethorscale(char *); static void t_papersize(char *); static void t_cutat(const char *, struct box *, char *); static void t_track(char *); static void t_strack(void); static void t_pdfmark(char *); static void t_locale(char *); static void t_anchor(char *); static void t_link(char *); static void t_linkcolor(char *); static void t_linkborder(char *); static void t_ulink(char *); static void t_ulinkcolor(char *); static void t_ulinkborder(char *); static char *t_linkborderstyle(char *); static int mb_cur_max; /*****************************************************************************/ int main(int agc, char *agv[]) { const char template[] = "/var/tmp/dpostXXXXXX"; char *tp; FILE *fp; /* * * A program that translates troff output into PostScript. All the input files * must have been formatted for the same device, which doesn't necessarily have to * be *realdev. If there's more than one input file, each begins on a new page. * */ setlocale(LC_CTYPE, ""); mb_cur_max = MB_CUR_MAX; ostdout = dup(1); if (close(mkstemp(tp = strdup(template))) < 0 || freopen(tp, "r+", stdout) == NULL) { perror(tp); return 2; } unlink(tp); if (close(mkstemp(tp = strdup(template))) < 0 || (gf = fopen(tp, "r+")) == NULL) { perror(tp); return 2; } unlink(tp); if (close(mkstemp(tp = strdup(template))) < 0 || (rf = fopen(tp, "r+")) == NULL) { perror(tp); return 2; } unlink(tp); if (close(mkstemp(tp = strdup(template))) < 0 || (sf = fopen(tp, "r+")) == NULL) { perror(tp); return 2; } unlink(tp); if (close(mkstemp(tp = strdup(template))) < 0 || (nf = fopen(tp, "r+")) == NULL) { perror(tp); return 2; } unlink(tp); if (close(mkstemp(tp = strdup(template))) < 0 || (pf = fopen(tp, "r+")) == NULL) { perror(tp); return 2; } unlink(tp); argc = agc; /* global so everyone can use them */ argv = agv; progname = prog_name = argv[0]; /* just for error messages */ init_signals(); /* sets up interrupt handling */ options(); /* command line options */ arguments(); /* translate all the input files */ done(); /* add trailing comments etc. */ fp = fdopen(ostdout, "w"); header(fp); /* PostScript file structuring comments */ account(); /* job accounting data */ return(x_stat); /* everything probably went OK */ } /* End of main */ /*****************************************************************************/ static int putint(int n, FILE *fp) { char buf[20]; int c = 0, i; /* * * Print an integer in PostScript binary token representation. * */ if (n >= -128 && n <= 127) { buf[c++] = 136; buf[c++] = n; } else if (n >= -32768 && n <= 32767) { buf[c++] = 134; buf[c++] = (n&0xff00) >> 8; buf[c++] = (n&0x00ff); } else { buf[c++] = 132; buf[c++] = (n&0xff000000) >> 24; buf[c++] = (n&0x00ff0000) >> 16; buf[c++] = (n&0x0000ff00) >> 8; buf[c++] = (n&0x000000ff); } for (i = 0; i < c; i++) putc(buf[i]&0377, fp); return c; } static int putstring1(const char *sp, int n, FILE *fp) { /* * * Print a string in PostScript binary token representation. * */ putc(142, fp); putc(n, fp); fwrite(sp, 1, n, fp); return n + 2; } static int putstring(const char *sp, int n, FILE *fp) { int c = 0, m; do { m = n > 250 ? 250 : n; c += putstring1(sp, m, fp); sp += m; n -= m; } while (n > 0); return c; } /*****************************************************************************/ void init_signals(void) { void interrupt(int); /* signal handler */ /* * * Make sure we handle interrupts. * */ if ( signal(SIGINT, interrupt) == SIG_IGN ) { signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGHUP, SIG_IGN); } else { signal(SIGHUP, interrupt); signal(SIGQUIT, interrupt); } /* End else */ signal(SIGTERM, interrupt); } /* End of init_signals */ /*****************************************************************************/ static char * pdfdate(time_t *tp, char *buf, size_t sz) { struct tm *tmptr; int tzdiff, tzdiff_hour, tzdiff_min; tzdiff = *tp - mktime(gmtime(tp)); tzdiff_hour = (int)(tzdiff / 60); tzdiff_min = tzdiff_hour % 60; tzdiff_hour /= 60; tmptr = localtime(tp); if (tmptr->tm_isdst > 0) tzdiff_hour++; snprintf(buf, sz, "(D:%04d%02d%02d%02d%02d%02d%+03d'%02d')", tmptr->tm_year + 1900, tmptr->tm_mon + 1, tmptr->tm_mday, tmptr->tm_hour, tmptr->tm_min, tmptr->tm_sec, tzdiff_hour, tzdiff_min); return buf; } /*****************************************************************************/ static void pdfbox(const char *boxname, struct box *bp, FILE *fp, int perpage) { double llx, lly, urx, ury; if (bp->flag == 0) return; llx = bp->val[0] * 72.0 / res; lly = pagelength - ((bp->val[1] + bp->val[3]) * 72.0 / res); urx = (bp->val[0] + bp->val[2]) * 72.0 / res; ury = pagelength - (bp->val[1] * 72.0 / res); fprintf(gf, "/_%s [%g %g %g %g] def\n", boxname, llx, lly, urx, ury); if (perpage) fprintf(fp, "[ {ThisPage} 1 dict dup /%s _%s put /PUT pdfmark\n", boxname, boxname); else fprintf(gf, "[ /%s _%s /PAGES pdfmark\n", boxname, boxname); } /*****************************************************************************/ void header(FILE *fp) { /* * * Print the DSC header, followed by the data generated so far. This function * is now called after all input has been processed. * */ struct Bookmark *bp; time_t now; int n; double x = 0, y = 0; char buf[4096]; char crdbuf[40]; time(&now); if (mediasize.flag) { x = mediasize.val[2] * 72.0 / res; y = mediasize.val[3] * 72.0 / res; } fprintf(fp, "%s", CONFORMING); fprintf(fp, "%s %s\n", CREATOR, creator); fprintf(fp, "%s %s", CREATIONDATE, ctime(&now)); if (LanguageLevel > 1) fprintf(fp, "%%%%LanguageLevel: %d\n", LanguageLevel); if (Binary) fprintf(fp, "%%%%DocumentData: Binary\n"); if ( temp_file != NULL ) { if ( docfonts > 0 ) { cat(temp_file, fp); putc('\n', fp); } /* End if */ unlink(temp_file); } /* End if */ fprintf(fp, "%s %d\n", PAGES, printed); if (mediasize.flag & 2) fprintf(fp, "%%%%DocumentMedia: x%gy%g %g %g 0 () ()\n", x, y, x, y); fflush(nf); rewind(nf); while ((n = fread(buf, 1, sizeof buf, nf)) > 0) fwrite(buf, 1, n, fp); fflush(sf); rewind(sf); while ((n = fread(buf, 1, sizeof buf, sf)) > 0) fwrite(buf, 1, n, fp); fprintf(fp, "%s", ENDCOMMENTS); fprintf(fp, "%s\n", "%%BeginProlog"); if ( cat(prologue, fp) == FALSE ) error(FATAL, "can't read %s", prologue); fflush(rf); rewind(rf); while ((n = fread(buf, 1, sizeof buf, rf)) > 0) fwrite(buf, 1, n, fp); fprintf(fp, "%s", ENDPROLOG); fprintf(fp, "%s", BEGINSETUP); fprintf(fp, "\ [ /CreationDate %s\n\ /Creator (%s)\n", pdfdate(&now, crdbuf, sizeof crdbuf), creator); if (Author) fprintf(fp, " /Author %s\n", Author); if (Title) fprintf(fp, " /Title %s\n", Title); if (Subject) fprintf(fp, " /Subject %s\n", Subject); if (Keywords) fprintf(fp, " /Keywords %s\n", Keywords); fprintf(fp, "/DOCINFO pdfmark\n"); if (Bookmarks) { orderbookmarks(); for (bp = &Bookmarks[0]; bp < &Bookmarks[nBookmarks]; bp++) { fprintf(fp, "[ /Title %s\n", bp->Title); if (bp->Count) fprintf(fp, " /Count %d\n", bp->closed ? -bp->Count : bp->Count); fprintf(fp, " /Dest /Bookmark$%d\n" "/OUT pdfmark\n", (int)(bp - &Bookmarks[0])); } } fflush(pf); rewind(pf); fprintf(fp, "/_custompagesetup {\n"); pdfbox("TrimBox", &trimat, fp, 1); pdfbox("BleedBox", &bleedat, fp, 1); pdfbox("CropBox", &cropat, fp, 0); while ((n = fread(buf, 1, sizeof buf, pf)) > 0) fwrite(buf, 1, n, fp); fprintf(fp, "} def\n"); fprintf(fp, "/_marks {\n"); if (Mflag & M_CUT) fprintf(fp, "_cutmarks\n"); if (Mflag & M_REG) fprintf(fp, "_regmarks\n"); if (Mflag & M_STAR) fprintf(fp, "_startargets\n"); if (Mflag & M_COL) fprintf(fp, "_colorbars\n"); fprintf(fp, "} def\n"); fflush(gf); rewind(gf); while ((n = fread(buf, 1, sizeof buf, gf)) > 0) fwrite(buf, 1, n, fp); if (mediasize.flag) { fprintf(fp, "/pagebbox [0 0 %g %g] def\n", x, y); fprintf(fp, "userdict /gotpagebbox true put\n"); if (mediasize.flag & 2) fprintf(fp, "/setpagedevice where {pop " "1 dict dup /PageSize [%g %g] put setpagedevice" "} if\n", x, y); } fprintf(fp, "mark\n"); fflush(stdout); rewind(stdout); while ((n = fread(buf, 1, sizeof buf, stdout)) > 0) fwrite(buf, 1, n, fp); fprintf(fp, "%s", ENDOFFILE); } /* End of header */ /*****************************************************************************/ void options(void) { const char optnames[] = "a:c:e:m:n:o:p:tw:x:y:A:C:J:F:H:L:M:OP:R:S:T:DI"; int ch; /* name returned by getopt() */ /* * * Reads and processes the command line options. There are, without a doubt, too * many options! * */ while ( (ch = getopt(argc, argv, optnames)) != EOF ) { switch ( ch ) { case 'a': /* aspect ratio */ fprintf(stdout, "/aspectratio %s def\n", optarg); break; case 'c': /* number of copies */ copies = atoi(optarg); fprintf(stdout, "/#copies %s store\n", optarg); break; case 'e': /* change the encoding scheme */ if ( (encoding = atoi(optarg)) < 0 || encoding > MAXENCODING ) encoding = DFLTENCODING; else eflag = 1; realencoding = encoding; break; case 'm': /* magnification */ fprintf(stdout, "/magnification %s def\n", optarg); break; case 'n': /* forms per page */ formsperpage = atoi(optarg); fprintf(stdout, "%s %s\n", FORMSPERPAGE, optarg); fprintf(stdout, "/formsperpage %s def\n", optarg); break; case 'o': /* output page list */ out_list(optarg); break; case 'p': /* landscape or portrait mode */ if ( *optarg == 'l' ) fprintf(stdout, "/landscape true def\n"); else fprintf(stdout, "/landscape false def\n"); break; case 't': /* just for compatibility */ break; case 'w': /* line width for drawing */ fprintf(stdout, "/linewidth %s def\n", optarg); break; case 'x': /* shift horizontally */ fprintf(stdout, "/xoffset %s def\n", optarg); break; case 'y': /* and vertically on the page */ fprintf(stdout, "/yoffset %s def\n", optarg); break; case 'A': /* force job accounting */ case 'J': if ( (fp_acct = fopen(optarg, "a")) == NULL ) error(FATAL, "can't open accounting file %s", optarg); break; case 'C': /* copy file to straight to output */ if ( cat(optarg, stdout) == FALSE ) error(FATAL, "can't read %s", optarg); break; case 'F': /* font table directory */ fontdir = optarg; break; case 'H': /* host resident font directory */ hostfontdir = optarg; break; case 'L': /* PostScript prologue file */ setpaths(optarg); break; case 'M': /* print cut marks */ setmarks(optarg); break; case 'O': /* turn picture inclusion off */ picflag = OFF; break; case 'P': /* PostScript pass through */ fprintf(stdout, "%s\n", optarg); break; case 'R': /* special global or page level request */ saverequest(optarg); break; case 'S': /* horizontal position error */ if ( (pointslop = atof(optarg)) < 0 ) pointslop = 0; Sflag = 1; break; case 'T': /* target printer */ realdev = optarg; break; case 'D': /* debug flag */ debug = ON; tf = stdout; break; case 'I': /* ignore FATAL errors */ ignore = ON; break; case '?': /* don't know the option */ error(FATAL, ""); break; default: error(FATAL, "missing case for option %c", ch); break; } /* End switch */ } /* End while */ argc -= optind; /* get ready for non-options args */ argv += optind; if (Mflag) { FILE *otf = tf; tf = stdout; doglobal(cutmarksfile); tf = otf; } } /* End of options */ /*****************************************************************************/ void setpaths ( char *name /* string that followed the -L option */ ) { char *path; /* start of the pathname */ /* * * Extends the -L option to permit run time modification of pathnames that were * fixed or didn't exist in previous versions of dpost. For example, the PostScript * drawing procedures have been moved out of *prologue and put in *drawfile. The * new syntax can be either -Lfile or -Lname:file. If the "name:" prefix is omitted * file will be used as the prologue, otherwise name should be one of "prologue", * "font", "draw", "color", or "form" and is used to select the pointer that gets * set to string "file". * */ for ( path = name; *path; path++ ) if ( *path == ':' || *path == ' ' ) { while ( *path == ':' || *path == ' ' ) path++; break; } /* End if */ if ( *path == '\0' ) /* didn't find a "name:" prefix */ path = name; if ( path == name || strncmp(name, "prologue", strlen("prologue")) == 0 ) prologue = path; else if ( strncmp(name, "draw", strlen("draw")) == 0 ) drawfile = path; else if ( strncmp(name, "color", strlen("color")) == 0 ) colorfile = path; else if ( strncmp(name, "form", strlen("form")) == 0 ) formfile = path; else if ( strncmp(name, "baseline", strlen("baseline")) == 0 ) baselinefile = path; else if ( strncmp(name, "cutmarks", strlen("cutmarks")) == 0 ) cutmarksfile = path; } /* End of setpaths */ /*****************************************************************************/ -static int -prefix(const char *str, const char *pfx) -{ - while (*pfx && *str == *pfx) - str++, pfx++; - return *str == 0; -} - static void setmarks(char *str) { char *sp; int c; do { for (sp = str; *sp && *sp != ':'; sp++); c = *sp; *sp = 0; if (prefix(str, "cutmarks")) Mflag |= M_CUT; else if (prefix(str, "registrationmarks")) Mflag |= M_REG; else if (prefix(str, "startargets")) Mflag |= M_STAR; else if (prefix(str, "colorbars")) Mflag |= M_COL; else if (prefix(str, "all")) Mflag |= M_ALL; else error(FATAL, "unknown mark: -M %s", str); *sp = c; str = &sp[1]; } while (c); } /*****************************************************************************/ void setup(void) { /* * Handles things that must be done after the options are read but before the * input files are processed. Called from t_init() after an "x init" command is * read, because we need the resolution before we can generate the call to the * setup procedure defined in *prologue. Only allowing one call to setup assumes * all the input files have been prepared for the same device. * */ writerequest(0, stdout); /* global requests eg. manual feed */ fprintf(stdout, "/resolution %d def\n", res); fprintf(stdout, "setup\n"); fprintf(stdout, "%d setdecoding\n", encoding); if ( formsperpage > 1 ) { /* followed by stuff for multiple pages */ if ( cat(formfile, stdout) == FALSE ) error(FATAL, "can't read %s", formfile); fprintf(stdout, "%d setupforms\n", formsperpage); } /* End if */ fprintf(stdout, "%s", ENDSETUP); } /* End of setup */ /*****************************************************************************/ void arguments(void) { FILE *fp; /* next input file */ /* * * Makes sure all the non-option command line arguments are processed. If we get * here and there aren't any arguments left, or if '-' is one of the input files * we'll translate stdin. * */ if ( argc < 1 ) conv(stdin); else while ( argc > 0 ) { if ( strcmp(*argv, "-") == 0 ) fp = stdin; else if ( (fp = fopen(*argv, "r")) == NULL ) error(FATAL, "can't open %s", *argv); conv(fp); if ( fp != stdin ) fclose(fp); argc--; argv++; } /* End while */ } /* End of arguments */ /*****************************************************************************/ void done(void) { /* * * Finished with all the input files, so mark the end of the pages with a TRAILER * comment, make sure the last page prints, and add things like the DOCUMENTFONTS * and PAGES comments that can only be determined after all the input files have * been read. * */ fprintf(stdout, "%s", TRAILER); fprintf(stdout, "done\n"); } /* End of done */ /*****************************************************************************/ void account(void) { /* * * Writes an accounting record to *fp_acct provided it's not NULL. Accounting is * requested using the -A or -J options. * */ if ( fp_acct != NULL ) fprintf(fp_acct, " print %d\n copies %d\n", printed, copies); } /* End of account */ /*****************************************************************************/ void conv( register FILE *fp /* next input file */ ) { register int c; /* usually first char in next command */ int m, n, n1, m1; /* when we need to read integers */ char str[4096]; /* for special chars and font numbers */ char b; /* * * Controls the translation of troff's device independent output language into * PostScript. The call to t_page() that prints the last page is made when we * exit the loop, but probably belongs in t_trailer(). * */ redirect(-1); /* only do output after a page command */ lineno = 1; /* line in current file */ while ((c = getc(fp)) != EOF) { switch (c) { case '\n': /* just count this line */ lineno++; break; case ' ': /* when input is text */ case 0: /* occasional noise creeps in */ break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* two motion digits plus a character */ hmot((c-'0')*10 + getc(fp)-'0'); put1(getc(fp)); break; case 'c': /* single ascii character */ put1(getc(fp)); break; case 'C': /* special character */ sget(str, sizeof str, fp); put1s(str); break; case 'N': /* character at position n */ fscanf(fp, "%d", &m); endtext(); oput(m); endtext(); break; case 'D': /* drawing functions */ endtext(); getdraw(); if ( size != lastsize || (size == FRACTSIZE && fractsize != lastfractsize) || horscale != lasthorscale) { subfont = 0; t_sf(0); } switch ((c=getc(fp))) { case 'p': /* draw a path */ while (fscanf(fp, "%d %d", &n, &m) == 2) drawline(n, m); lineno++; break; case 'P': /* solid polygon */ fprintf(tf, "newpath %d %d neg moveto\n", hpos, vpos); while (fscanf(fp, "%d %d", &n, &m) == 2) { hpos += n; vpos += m; fprintf(tf, "%d %d neg lineto\n", hpos, vpos); } fprintf(tf, "closepath fill\n"); lineno++; break; case 'l': /* draw a line */ fscanf(fp, "%d %d %c", &n, &m, &b); n1 = b; drawline(n, m); break; case 'c': /* circle */ case 'C': /* filled circle */ fscanf(fp, "%d", &n); drawcirc(n, c); break; case 'e': /* ellipse */ case 'E': /* filled ellipse */ fscanf(fp, "%d %d", &m, &n); drawellip(m, n, c); break; case 'a': /* counter-clockwise arc */ case 'A': /* clockwise arc */ fscanf(fp, "%d %d %d %d", &n, &m, &n1, &m1); drawarc(n, m, n1, m1, c); break; case 'q': /* spline without end points */ drawspline(fp, 1); lineno++; break; case '~': /* wiggly line */ drawspline(fp, 2); lineno++; break; case 't': /* set line width, ignore */ fscanf(fp, "%d %d", &m, &n); hgoto(hpos + m); lineno++; break; case 'F': /* color scheme, ignore */ case 'f': /* filling color, ignore */ fgets(str, sizeof str, fp); lineno++; break; default: error(FATAL, "unknown drawing function %c", c); break; } /* End switch */ break; case 's': /* use this point size */ fscanf(fp, "%d", &n); /* ignore fractional sizes */ if (n != FRACTSIZE) setsize(t_size(n), 0); else { float f; fscanf(fp, "%f", &f); setsize(FRACTSIZE, f); } break; case 'f': /* use font mounted here */ sget(str, sizeof str, fp); setfont(t_font(str)); break; case 'H': /* absolute horizontal motion */ fscanf(fp, "%d", &n); hgoto(n); break; case 'h': /* relative horizontal motion */ fscanf(fp, "%d", &n); hmot(n); break; case 'w': /* word space */ wordspace++; break; case 'V': /* absolute vertical position */ fscanf(fp, "%d", &n); vgoto(n); break; case 'v': /* relative vertical motion */ fscanf(fp, "%d", &n); vmot(n); break; case 'p': /* new page */ fscanf(fp, "%d", &n); t_page(n); break; case 'n': /* end of line */ while ( (c = getc(fp)) != '\n' && c != EOF ) ; t_newline(); lineno++; break; case '#': /* comment */ while ( (c = getc(fp)) != '\n' && c != EOF ) ; lineno++; break; case 'x': /* device control function */ devcntrl(fp); lineno++; break; default: error(FATAL, "unknown input character %o %c", c, c); done(); } /* End switch */ } /* End while */ t_page(-1); /* print the last page */ endtext(); } /* End of conv */ /*****************************************************************************/ void devcntrl( FILE *fp /* current input file */ ) { char str[4096], *buf, str1[4096]; int c, n, sz; /* * * Called from conv() to process the rest of a device control function. There's * a whole family of them and they all start with the string "x ", which we've * already read. The "x X ..." commands are an extensible (and device dependent) * family that we use here for things like picture inclusion. Unrecognized device * control commands are ignored. * */ buf = malloc(sz = 4096); sget(str, sizeof str, fp); /* get the control function name */ switch ( str[0] ) { /* only the first character counts */ case 'i': /* initialize */ t_init(); break; case 'T': /* device name */ sget(devname, sizeof devname, fp); getdevmap(); /* * This used to be "strcpy(devname, realdev);" but * it does not work when DESC is a text file because * the fonts are in a different directory. */ if (dev.afmfonts || (devname[0] == 'p' && devname[1] == 's')) realdev = devname; else n_strcpy(devname, realdev, sizeof(devname)); break; case 't': /* trailer */ t_trailer(); break; case 'p': /* pause -- can restart */ t_reset('p'); break; case 's': /* stop */ t_reset('s'); break; case 'r': /* resolution assumed when prepared */ fscanf(fp, "%d", &res); break; case 'f': /* load font in a position */ fscanf(fp, "%d", &n); sget(str, sizeof str, fp); fgets(buf, sz, fp); /* in case there's a filename */ ungetc('\n', fp); /* fgets() goes too far */ str1[0] = '\0'; /* in case there's nothing to come in */ c = 0; sscanf(buf, "%s %d", str1, &c); loadfont(n, mapdevfont(str), str1, 0, c); break; /* these don't belong here... */ case 'H': /* char height */ fscanf(fp, "%d", &n); if (n != FRACTSIZE) t_charht(n, 0); else { float f; fscanf(fp, "%f", &f); t_charht(FRACTSIZE, f); } break; case 'S': /* slant */ fscanf(fp, "%d", &n); t_slant(n); break; case 'X': /* copy through - from troff */ do c = getc(fp); while (spacechar(c)); n = 0; if (c != EOF) do { if (n + 1 < sizeof str) str[n++] = c; c = getc(fp); } while (c != EOF && !spacechar(c) && c != ':'); str[n] = 0; if (c != ':') ungetc(c, fp); n = 0; for (;;) { fgets(&buf[n], sz - n, fp); if ((c = getc(fp)) != '+') { ungetc(c, fp); break; } while (buf[n]) n++; if (sz - n < 4096) buf = realloc(buf, sz += 4096); lineno++; } if ( strcmp(str, "PI") == 0 || strcmp(str, "PictureInclusion") == 0 ) picture(buf); else if ( strcmp(str, "InlinePicture") == 0 ) inlinepic(fp, buf); else if ( strcmp(str, "SupplyFont") == 0 ) t_supply(buf); else if ( strcmp(str, "PaperSize") == 0 ) t_papersize(buf); else if ( strcmp(str, "TrimAt") == 0 ) t_cutat("Trim size", &trimat, buf); else if ( strcmp(str, "BleedAt") == 0 ) t_cutat("Bleed size", &bleedat, buf); else if ( strcmp(str, "CropAt") == 0 ) t_cutat("Crop size", &cropat, buf); else if ( strcmp(str, "Track") == 0 ) t_track(buf); else if ( strcmp(str, "PDFMark") == 0 ) t_pdfmark(buf); else if ( strcmp(str, "LC_CTYPE") == 0 ) t_locale(buf); else if ( strcmp(str, "Anchor") == 0 ) t_anchor(buf); else if ( strcmp(str, "Link") == 0 ) t_link(buf); else if ( strcmp(str, "SetLinkColor") == 0 ) t_linkcolor(buf); else if ( strcmp(str, "SetLinkBorder") == 0 ) t_linkborder(buf); else if ( strcmp(str, "SetBorderStyle") == 0 ) linkborderstyle = t_linkborderstyle(buf); else if ( strcmp(str, "SetUBorderStyle") == 0 ) ulinkborderstyle = t_linkborderstyle(buf); else if ( strcmp(str, "ULink") == 0 ) t_ulink(buf); else if ( strcmp(str, "SetULinkColor") == 0 ) t_ulinkcolor(buf); else if ( strcmp(str, "SetULinkBorder") == 0 ) t_ulinkborder(buf); else if ( strcmp(str, "HorScale") == 0 ) sethorscale(buf); else if ( strcmp(str, "BeginPath") == 0 ) beginpath(buf, FALSE); else if ( strcmp(str, "DrawPath") == 0 ) drawpath(buf, FALSE); else if ( strcmp(str, "BeginObject") == 0 ) beginpath(buf, TRUE); else if ( strcmp(str, "EndObject") == 0 ) drawpath(buf, TRUE); else if ( strcmp(str, "NewBaseline") == 0 ) newbaseline(buf); else if ( strcmp(str, "DrawText") == 0 ) drawtext(buf); else if ( strcmp(str, "SetText") == 0 ) settext(buf); else if ( strcmp(str, "SetColor") == 0 ) { newcolor(buf); setcolor(); } else if ( strcmp(str, "Sync") == 0 ) { if (tracked) tracked = -1; subfont = 0; t_sf(1); xymove(hpos, vpos); } else if ( strcmp(str, "PSSetup") == 0 ) { fprintf(gf, "%s", buf); } else if ( strcmp(str, "PS") == 0 || strcmp(str, "PostScript") == 0 ) { endtext(); /* xymove(hpos, vpos); ul90-22006 */ fprintf(tf, "%s", buf); } /* End else */ goto done; } /* End switch */ while ( (c = getc(fp)) != '\n' && c != EOF ) ; done: free(buf); } /* End of devcntrl */ /*****************************************************************************/ void fontinit(void) { char *descp; /* for reading the DESC file */ char *filebase; /* the whole thing goes here */ int i; /* loop index */ /* * * Reads *realdev's DESC file and uses what's there to initialize things like * the list of available point sizes. Old versions of the program used *devname's * DESC file to initialize nfonts, but that meant we needed to have *devname's * binary font files available for emulation. That restriction has been removed * and we now set nfonts using the "x font" commands in the input file, so by the * time we get here all we really need is *realdev. In fact devcntrl() reads the * device name from the "x T ..." command, but almost immediately replaces it with * string *realdev so we end up using *realdev's DESC file. Later on (in * t_font()) we mount all of *realdev's special fonts after the last legitimate * font position, just to be sure device emulation works reasonably well - there's * no guarantee *devname's special fonts match what's needed when *realdev's tables * are used. * */ snprintf(temp, sizeof temp, "%s/dev%s/FONTMAP", fontdir, devname); rdftmap(temp); snprintf(temp, sizeof temp, "%s/dev%s/DESC", fontdir, devname); if ( (descp = readdesc(temp)) == 0 ) error(FATAL, "can't open tables for %s", temp); memcpy(&dev, descp, sizeof dev); nfonts = 0; /* was dev.nfonts - now set in t_fp() */ nsizes = dev.nsizes; nchtab = dev.nchtab; unitwidth = dev.unitwidth; filebase = &descp[sizeof dev]; pstab = (int *) filebase; chtab = (short *)(pstab + nsizes + 1); chname = (char *) (chtab + nchtab); fsize = 3 * 255 + nchtab + 128 - 32 + sizeof(struct Font); fitab = calloc(NFONT+1, sizeof *fitab); fontab = calloc(NFONT+1, sizeof *fontab); codetab = calloc(NFONT+1, sizeof *codetab); kerntab = calloc(NFONT+1, sizeof *kerntab); fontbase = calloc(NFONT+1, sizeof *fontbase); for ( i = 1; i <= NFONT; i++ ) { /* so loadfont() knows nothing's there */ fontbase[i] = NULL; } /* End for */ if ( (downloaded = (char *) calloc(nchtab + 128, sizeof(char))) == NULL ) error(FATAL, "no memory"); } /* End of fontinit */ /*****************************************************************************/ void loadfont ( int n, /* load this font position */ const char *s, /* with the file for this font */ char *s1, /* taken from here - possibly */ int forcespecial, /* this is definitively a special font */ int spec /* map specification */ ) { char *fpout = NULL; /* for reading *s file */ int fin; /* for reading *s.afm file */ int nw; /* number of width table entries */ - char *p; + const char *p; char *path; size_t l; /* * * Loads font position n with the binary font file for *s provided it's not * already there. If *s1 is NULL or points to the empty string we read files from * directory *fontdir/dev*devname, otherwise directory *s1 is used. If the first * open fails we try to map font *s into one we expect will be available, and then * we try again. * */ if ( n < 0 || n > NFONT ) /* make sure it's a legal position */ error(FATAL, "illegal fp command %d %s", n, s); if ( fontbase[n] != NULL && strcmp(s, fontbase[n]->namefont) == 0 ) return; path = temp; if (s1 && strchr(s1, '/') != NULL) path = afmdecodepath(s1); else if (s1 && strstr(s1, ".afm") != NULL) snprintf(temp, sizeof temp, "%s/dev%s/%s", fontdir, devname, s1); else if (strchr(s, '/') != NULL) { path = afmdecodepath(s); if (spec == 0 && s1) spec = atoi(s1); } else if (strstr(s, ".afm") != NULL) { snprintf(temp, sizeof temp, "%s/dev%s/%s", fontdir, devname, s); if (spec == 0 && s1) spec = atoi(s1); } else snprintf(temp, sizeof temp, "%s/dev%s/%s.afm", fontdir, devname, s); if ( (fin = open(path, O_RDONLY)) >= 0 ) { struct afmtab *a; struct stat st; char *contents; int i; if ((p = strrchr(s, '/')) == NULL) p = s; else p++; if (p[0] == 'S' && (p[1] == '\0' || (digitchar(p[1]&0377) && p[2] == '\0') || p[2] == '.')) forcespecial = 1; for (i = 0; i < afmcount; i++) if (afmfonts[i] && strcmp(afmfonts[i]->path, path) == 0 && afmfonts[i]->spec == spec) { a = afmfonts[i]; close(fin); goto have; } if ((a = calloc(1, sizeof *a)) == NULL || fstat(fin, &st) < 0 || (contents = malloc(st.st_size+1)) == NULL || read(fin, contents, st.st_size) != st.st_size) { free(a); close(fin); goto fail; } close(fin); - l = strlen(path) + 1; - a->path = malloc(l); - n_strcpy(a->path, path, l); + a->path = strdup(path); if (path != temp) free(path); a->file = s; a->spec = spec; if (afmget(a, contents, st.st_size) < 0) { free(a); free(contents); goto fail; } free(contents); afmfonts = realloc(afmfonts, (afmcount+1) * sizeof *afmfonts); afmfonts[afmcount] = a; snprintf(a->Font.intname, sizeof a->Font.intname, "%d", dev.nfonts + ++afmcount); if (forcespecial) a->Font.specfont = 1; have: fontbase[n] = &a->Font; fontab[n] = a->fontab; codetab[n] = a->codetab; fitab[n] = a->fitab; t_fp(n, a->fontname, fontbase[n]->intname, a); goto done; } if (strchr(s, '/') != NULL) goto fail; if ( s1 == NULL || s1[0] == '\0' ) snprintf(temp, sizeof temp, "%s/dev%s/%s", fontdir, devname, s); else snprintf(temp, sizeof temp, "%s/%s", s1, s); if ( access(temp, R_OK) < 0 ) snprintf(temp, sizeof temp, "%s/dev%s/%s", fontdir, devname, mapfont(s)); if ((fpout = readfont(temp, &dev, 0)) == NULL) fail: error(FATAL, "can't open font table %s", temp); if ( fontbase[n] != NULL ) /* something's already there */ free(fontbase[n]); /* so release the memory first */ fontbase[n] = (struct Font *)fpout; p = (char *) fontbase[n] + sizeof(struct Font); nw = fontbase[n]->nwfont & BMASK; makefont(n, p, NULL, p + 2 * nw, p + 3 * nw, nw); t_fp(n, fontbase[n]->namefont, fontbase[n]->intname, NULL); done: if ( smnt == 0 && (fontbase[n]->specfont == 1 || forcespecial) ) smnt = n; if (fontbase[n]->specfont == 1 || forcespecial) gotregular = TRUE; if ( debug == ON ) fontprint(n); } /* End of loadfont */ /*****************************************************************************/ void loadspecial(void) { char *p; /* for next binary font file */ int nw; /* width entries in next font */ int i; /* loop index */ /* * * Loads all the special fonts after the last legal font position. Mostly used * for device emulation, but we'll do it no matter what. Needed because there's * no consistency in special fonts across different devices, and relying on having * them mounted in the input file doesn't guarantee the whole collection will be * there. The special fonts are determined and mounted using the copy of the * DESC file that's been read into memory. Initially had this stuff at the * end of fontinit(), but we now don't know nfonts until much later. * */ if ( gotregular == FALSE ) loadfont(++nfonts, ((struct Font *)(&chname[dev.lchname]))->namefont, NULL, 0, 0); if ( gotspecial == FALSE ) for ( i = 1, p = chname + dev.lchname; i <= dev.nfonts; i++ ) { nw = *p & BMASK; if ( ((struct Font *) p)->specfont == 1 ) loadfont(++nfonts, ((struct Font *)p)->namefont, NULL, 1, 0); p += 3 * nw + dev.nchtab + 128 - 32 + sizeof(struct Font); } /* End for */ gotregular = TRUE; gotspecial = TRUE; } /* End of loadspecial */ /*****************************************************************************/ static const char *defaultFonts[] = { "R", "I", "B", "BI", "CW", "H", "HB", "HX", "S1", "S", NULL }; void loaddefault(void) { int i; for (i = 0; defaultFonts[i] != NULL ; i++) loadfont(++nfonts, defaultFonts[i], NULL, defaultFonts[i][0] == 'S', 0); } void fontprint ( int i /* font's index in fontbase[] */ ) { int j, n; char *p; /* * * Debugging routine that dumps data about the font mounted in position i. * */ fprintf(tf, "font %d:\n", i); p = (char *) fontbase[i]; n = fontbase[i]->nwfont & BMASK; fprintf(tf, "base=0%lo, nchars=%d, spec=%d, name=%s, widtab=0%lo, fitab=0%lo\n", (long)p, n, fontbase[i]->specfont, fontbase[i]->namefont, (long)fontab[i], (long)fitab[i]); fprintf(tf, "widths:\n"); for ( j = 0; j <= n; j++ ) { fprintf(tf, " %2d", fontab[i][j]); if ( j % 20 == 19 ) putc('\n', tf); } /* End for */ fprintf(tf, "\ncodetab:\n"); for ( j = 0; j <= n; j++ ) { fprintf(tf, " %2d", codetab[i][j]); if ( j % 20 == 19 ) putc('\n', tf); } /* End for */ fprintf(tf, "\nfitab:\n"); for ( j = 0; j <= dev.nchtab + 128-32; j++ ) { fprintf(tf, " %2d", fitab[i][j]); if ( j % 20 == 19 ) putc('\n', tf); } /* End for */ putc('\n', tf); } /* End of fontprint */ /*****************************************************************************/ const char * mapfont ( - char *name /* troff wanted this font */ + const char *name /* troff wanted this font */ ) { int i; /* loop index */ /* * * If loadfont() can't find font *name we map it into something else that should * be available and return a pointer to the new name. Used mostly for emulating * devices like the APS-5. * */ name = mapft(name); for ( i = 0; fontmap[i].name != NULL; i++ ) if ( strcmp(name, fontmap[i].name) == 0 ) return(fontmap[i].use); switch ( *++name ) { case 'I': return("I"); case 'B': return("B"); case 'X': return("BI"); default: return("R"); } /* End switch */ } /* End of mapfont */ /*****************************************************************************/ void getdevmap(void) { FILE *fp; /* for reading the device fontmap file */ int i = 0; /* number of mapping pairs we've read */ int c; /* for skipping lines */ /* * * Looks for the device font mapping file *fontdir/dev*realdev/fontmaps/devname. * The file, if it exists, should be an ASCII file containing pairs of one or two * character font names per line. The first name is the font troff will be asking * for and the second is the one we'll use. Comments are lines that begin with * a '#' as the first non-white space character on a line. The devfontmap list * ends with a member that has the empty string in the name field. * */ snprintf(temp, sizeof temp, "%s/dev%s/fontmaps/%s", fontdir, realdev, devname); if ( devfontmap == NULL && (fp = fopen(temp, "r")) != NULL ) { devfontmap = (Devfontmap *) malloc(10 * sizeof(Devfontmap)); while ( sget(temp, sizeof temp, fp) == 1 ) { if ( temp[0] != '#' && strlen(temp) < 3 ) if ( sget(&temp[3], sizeof temp - 3, fp) == 1 && strlen(&temp[3]) < 3 ) { n_strcpy((devfontmap + i)->name, temp, sizeof(devfontmap->name)); n_strcpy((devfontmap + i)->use, &temp[3], sizeof(devfontmap->use)); if ( ++i % 10 == 0 ) devfontmap = (Devfontmap *) realloc(devfontmap, (i + 10) * sizeof(Devfontmap)); } /* End if */ while ( (c = getc(fp)) != '\n' && c != EOF ) ; } /* End while */ (devfontmap + i)->name[0] = '\0'; /* end the list we just read */ fclose(fp); } /* End if */ } /* End of getdevmap */ /*****************************************************************************/ char * mapdevfont(char *str) { int i; /* * * Called immediately before loadfont() after an 'x font' command is recognized. * Takes the font name that troff asked for, looks it up in the devfontmap list, * and returns the mapped name to the caller. No mapping is done if the devfontmap * list is empty or font *str isn't found in the list. * */ if ( devfontmap != NULL ) for ( i = 0; (devfontmap + i)->name[0] != '\0'; i++ ) if ( strcmp((devfontmap + i)->name, str) == 0 ) return((devfontmap + i)->use); return(str); } /* End of mapdevfont */ /*****************************************************************************/ void reset(void) { /* * * Resets the variables that keep track of the printer's current position, font, * and size. Typically used after a restore/save pair (eg. when we finish with a * page) to make sure we force the printer back into sync (in terms of the font * and current point) before text is printed. * */ lastx = -(slop + 1); savey = lasty = -1; lastfont = lastsubfont = lastsize = -1; if (tracked) tracked = -1; } /* End of reset */ /*****************************************************************************/ void resetpos(void) { /* * * Resets the variables that keep track of the printer's current position. Used * when there's a chance we've lost track of the printer's current position or * done something that may have wiped it out, and we want to force dpost to set * the printer's position before printing text or whatever. For example stroke or * fill implicitly do a newpath, and that wipes out the current point, unless the * calls were bracketed by a gsave/grestore pair. * */ lastx = -(slop + 1); savey = lasty = -1; } /* End of resetpos */ /*****************************************************************************/ void t_init(void) { static int initialized = FALSE; /* only do most things once */ /* * * Called from devcntrl() after an "x init" command is read. Things only work if * we've already seen the "x res" command, and much of the stuff, including the * call to setup, should only be done once. Restricting everything to one call of * setup (ie. the one in the prologue) means all the input files must have been * formatted for the same device. * */ endtext(); /* moved - for cat'ed troff files */ if ( initialized == FALSE ) { /* only do this stuff once per job */ fontinit(); gotspecial = FALSE; gotregular = FALSE; widthfac = (float) res /dev.res; if (dev.afmfonts) { if (Sflag == 0) pointslop = 0; } if (eflag == 0) realencoding = encoding = dev.encoding; if (encoding == 5) { - LanguageLevel = MAX(LanguageLevel, 2); + LanguageLevel = max(LanguageLevel, 2); Binary++; } slop = pointslop * res / POINTS + .5; rvslop = res * .025; setup(); initialized = TRUE; } /* End if */ hpos = vpos = 0; /* upper left corner */ setsize(t_size(10), 0); /* start somewhere */ reset(); /* force position and font stuff - later */ } /* End of t_init */ /*****************************************************************************/ void needresource(const char *s, ...) { va_list ap; if (nfcount++ == 0) fprintf(nf, "%%%%DocumentNeededResources: "); else fprintf(nf, "%%%%+ "); va_start(ap, s); vfprintf(nf, s, ap); va_end(ap); putc('\n', nf); } static struct supplylist { struct supplylist *next; char *font; char *file; char *type; int done; } *supplylist; void t_supply(char *fnt) /* supply a font */ { struct supplylist *sp; char *np, *file, *type = NULL, c; while (*fnt == ' ' || *fnt == '\t') fnt++; for (np = font; *np && *np != ' ' && *np != '\t' && *np != '\n'; np++); if (*np == '\0' || *np == '\n') return; *np = '\0'; file = &np[1]; while (*file == ' ' || *file == '\t') file++; for (np = file; *np && *np != ' ' && *np != '\t' && *np != '\n'; np++); c = *np; *np = '\0'; if (c != '\0' && c != '\n') { type = &np[1]; while (*type == ' ' || *type == '\t') type++; for (np = type; *np && *np != ' ' && *np != '\t' && *np != '\n'; np++); *np = '\0'; } for (sp = supplylist; sp; sp = sp->next) if (strcmp(sp->font, fnt) == 0) return; sp = calloc(1, sizeof *sp); sp->font = strdup(fnt); sp->file = afmdecodepath(file); sp->type = type && *type ? strdup(type) : NULL; sp->next = supplylist; supplylist = sp; } static unsigned long ple32(const char *cp) { return (unsigned long)(cp[0]&0377) + ((unsigned long)(cp[1]&0377) << 8) + ((unsigned long)(cp[2]&0377) << 16) + ((unsigned long)(cp[3]&0377) << 24); } static const char ps_adobe_font_[] = "%!PS-AdobeFont-"; static const char ps_truetypefont[] = "%!PS-TrueTypeFont"; static const char hex[] = "0123456789abcdef"; static void supplypfb(char *fnt, char *path, FILE *fp) { char buf[30]; size_t i, n, length; int c = EOF, type = 0, lastch = EOF; if (fread(buf, 1, 6, fp) != 6) error(FATAL, "no data in %s", path); if ((buf[0]&0377) != 0200 || (type = buf[1]) != 1) error(FATAL, "invalid header in %s", path); length = ple32(&buf[2]); n = 0; while (ps_adobe_font_[n] && --length > 0 && (c = getc(fp)) != EOF) { if (c != ps_adobe_font_[n++]) error(FATAL, "file %s does not start with \"%s\"", path, ps_adobe_font_); } while (--length > 0 && (c = getc(fp)) != EOF && c != '\r' && c != '\n'); if (c != '\n') { if ((c = getc(fp)) != '\n') ungetc(c, fp); else length--; } if (sfcount++ == 0) fprintf(sf, "%%%%DocumentSuppliedResources: font %s\n", fnt); else fprintf(sf, "%%%%+ font %s\n", fnt); fprintf(rf, "%%%%BeginResource: font %s\n", fnt); for (;;) { switch (type) { case 1: while (length > 0 && (c = getc(fp)) != EOF) { length--; switch (c) { case '\r': if ((c = getc(fp)) != '\n') ungetc(c, fp); else length--; putc('\n', rf); lastch = '\n'; break; case 0: continue; default: putc(c, rf); lastch = c; } } if (c == EOF) error(FATAL, "short text data in %s", path); break; case 2: while (length) { n = length > sizeof buf ? sizeof buf : length; if (fread(buf, 1, n, fp) != n) error(FATAL, "short binary data in %s", path); for (i = 0; i < n; i++) { putc(hex[(buf[i]&0360)>>4], rf); putc(hex[buf[i]&017], rf); } putc('\n', rf); lastch = '\n'; length -= n; } break; case 3: if (lastch != '\n') putc('\n', rf); fprintf(rf, "%%%%EndResource\n"); fclose(fp); return; default: error(FATAL, "invalid header type %d in %s", path, type); } if ((n = fread(buf, 1, 6, fp)) != 6 && (buf[1] != 3 || n < 2)) error(FATAL, "missing header in %s", path); if ((buf[0]&0377) != 0200) error(FATAL, "invalid header in %s", path); if ((type = buf[1]) != 3) length = ple32(&buf[2]); } } static void supplyotf(char *fnt, char *path, FILE *fp) { static int cffcount; struct stat st; char *contents; size_t sz, offset, length, i; int fsType; const char StartData[] = " StartData "; if (fstat(fileno(fp), &st) < 0) error(FATAL, "cannot stat %s", path); sz = st.st_size; contents = malloc(sz); if (fread(contents, 1, sz, fp) != sz) error(FATAL, "cannot read %s", path); fclose(fp); if ((fsType = otfcff(path, contents, sz, &offset, &length)) < 0) { free(contents); return; } /* * Adobe Technical Note #5176, "The Compact Font Format * Specification", Version 1.0, 12/4/2003, p. 53 proposes * a weird syntax for CFF DSC comments ("ProcSet" etc.); * Adobe Distiller 7 complains about it with DSC warnings * enabled. What follows is an attempt to fix this. */ if (cffcount++ == 0) { fprintf(rf, "%%%%IncludeResource: procset FontSetInit 0 0\n"); needresource("procset FontSetInit 0 0"); } if (sfcount++ == 0) fprintf(sf, "%%%%DocumentSuppliedResources: font %s\n", fnt); else fprintf(sf, "%%%%+ font %s\n", fnt); fprintf(rf, "%%%%BeginResource: font %s\n", fnt); fprintf(rf, "/FontSetInit /ProcSet findresource begin\n"); if (encoding == 5) { fprintf(rf, "%%%%BeginData: %ld Binary Bytes\n", (long)(length + 13 + strlen(fnt) + 12)); fprintf(rf, "/%s %12ld StartData ", fnt, (long)length); fwrite(&contents[offset], 1, length, rf); fprintf(rf, "\n%%%%EndData\n"); } else { fprintf(rf, "/%s %ld ", fnt, (long)length); fprintf(rf, "currentfile /ASCIIHexDecode filter cvx exec\n"); for (i = 0; StartData[i]; i++) { putc(hex[(StartData[i]&0360)>>4], rf); putc(hex[StartData[i]&017], rf); } putc('\n', rf); for (i = offset; i < offset+length; i++) { putc(hex[(contents[i]&0360)>>4], rf); putc(hex[contents[i]&017], rf); if (i > offset && (i - offset + 1) % 34 == 0) putc('\n', rf); } fprintf(rf, ">\n"); } fprintf(rf, "%%%%EndResource\n"); free(contents); - LanguageLevel = MAX(LanguageLevel, 3); + LanguageLevel = max(LanguageLevel, 3); } static void supplyttf(char *fnt, char *path, FILE *fp) { struct stat st; char *contents; size_t sz; if (fstat(fileno(fp), &st) < 0) error(FATAL, "cannot stat %s", path); sz = st.st_size; contents = malloc(sz); if (fread(contents, 1, sz, fp) != sz) error(FATAL, "cannot read %s", path); fclose(fp); if (sfcount++ == 0) fprintf(sf, "%%%%DocumentSuppliedResources: font %s\n", fnt); else fprintf(sf, "%%%%+ font %s\n", fnt); fprintf(rf, "%%%%BeginResource: font %s\n", fnt); otft42(fnt, path, contents, sz, rf); fprintf(rf, "%%%%EndResource\n"); free(contents); - LanguageLevel = MAX(LanguageLevel, 2); + LanguageLevel = max(LanguageLevel, 2); } static void supply1(char *fnt, char *file, char *type) { FILE *fp; char linebuf[4096], c; if (strchr(file, '/') == 0) { snprintf(temp, sizeof temp, "%s/dev%s/%s.%s", fontdir, devname, file, type); file = temp; } if ((fp = fopen(file, "r")) == NULL) error(FATAL, "can't open %s", file); if (type == NULL) { c = getc(fp); ungetc(c, fp); type = c == '\200' ? "pfb" : c == 'O' ? "otf" : c == 0 || c == 't' ? "ttf" : "anything"; } if (strcmp(type, "pfb") == 0) { supplypfb(fnt, file, fp); return; } if (strcmp(type, "otf") == 0) { supplyotf(fnt, file, fp); return; } if (strcmp(type, "ttf") == 0) { supplyttf(fnt, file, fp); return; } if (fgets(linebuf, sizeof linebuf, fp) == NULL) error(FATAL, "missing data in %s", file); if (strncmp(linebuf, ps_adobe_font_, strlen(ps_adobe_font_)) && strncmp(linebuf, ps_truetypefont, strlen(ps_truetypefont))) error(FATAL, "file %s does not start with \"%s\" or \"%s\"", file, ps_adobe_font_, ps_truetypefont); if (sfcount++ == 0) fprintf(sf, "%%%%DocumentSuppliedResources: font %s\n", fnt); else fprintf(sf, "%%%%+ font %s\n", fnt); fprintf(rf, "%%%%BeginResource: font %s\n", fnt); while (fgets(linebuf, sizeof linebuf, fp) != NULL) fputs(linebuf, rf); fclose(fp); fprintf(rf, "%%%%EndResource\n"); } static void t_dosupply(const char *fnt) { struct supplylist *sp; for (sp = supplylist; sp; sp = sp->next) if (strcmp(sp->font, fnt) == 0) { if (sp->done == 0) { supply1(sp->font, sp->file, sp->type); sp->done = 1; } return; } needresource("font %s", fnt); } /*****************************************************************************/ static void boxcmp(const char *name, struct box *bp, int a, int b, int c, int d) { if (bp->flag && (a != bp->val[0] || b != bp->val[1] || c != bp->val[2] || d != bp->val[3])) error(NON_FATAL, "%s has changed, using new values", name); } static void t_papersize(char *buf) { int x, y, setmedia = 0; if (sscanf(buf, "%d %d %d", &x, &y, &setmedia) < 2) return; boxcmp("Media size", &mediasize, 0, 0, x, y); mediasize.val[2] = x; mediasize.val[3] = y; mediasize.flag |= 1; if (setmedia) mediasize.flag |= 2; pagelength = y * 72.0 / res; } static void t_cutat(const char *name, struct box *bp, char *buf) { int c[4], i; if (sscanf(buf, "%d %d %d %d", &c[0], &c[1], &c[2], &c[3]) < 4) return; boxcmp(name, bp, c[0], c[1], c[2], c[3]); for (i = 0; i < 4; i++) bp->val[i] = c[i]; bp->flag |= 1; } /*****************************************************************************/ void t_page ( int pg /* troff's current page number */ ) { static int lastpg = 0; /* last one we started - for ENDPAGE */ /* * * Called whenever we've finished the last page and want to get ready for the * next one. Also used at the end of each input file, so we have to be careful * about what's done. The first time through (up to the redirect(pg) call) output * goes to /dev/null because of the redirect(-1) call made in conv(). * * Adobe now recommends that the showpage operator occur after the page level * restore so it can be easily redefined to have side-effects in the printer's VM. * Although it seems reasonable I haven't implemented it, because it makes other * things, like selectively setting manual feed or choosing an alternate paper * tray, clumsy - at least on a per page basis. * */ if ( tf == stdout ) /* count the last page */ printed++; endtext(); /* print the last line? */ fprintf(tf, "_marks\n"); fprintf(tf, "cleartomark\n"); fprintf(tf, "showpage\n"); fprintf(tf, "restore\n"); fprintf(tf, "%s %d %d\n", ENDPAGE, lastpg, printed); redirect(pg); fprintf(tf, "%s %d %d\n", PAGE, pg, printed+1); fprintf(tf, "save\n"); fprintf(tf, "mark\n"); writerequest(printed+1, tf); fprintf(tf, "%d pagesetup\n", printed+1); setcolor(); lastpg = pg; /* for the next ENDPAGE comment */ hpos = vpos = 0; /* get ready for the next page */ reset(); /* force position and font stuff - later */ seenpage = TRUE; } /* End of t_page */ /*****************************************************************************/ void t_newline(void) { /* * * Just finished the last line. All we do is set the horizontal position to 0, * although even that probably isn't necessary. * */ hpos = 0; } /* End of t_newline */ /*****************************************************************************/ int t_size ( int n /* convert this to an internal size */ ) { int i; /* loop index */ /* * * Converts a point size into an internal size that can be used as an index into * pstab[]. The internal size is one plus the index of the least upper bound of * n in pstab[], or nsizes if n is larger than all the listed sizes. * */ if ( n <= pstab[0] ) return(1); else if (n >= pstab[nsizes-1]) return(nsizes); for ( i = 0; n > pstab[i]; i++ ) ; return(i+1); } /* End of t_size */ /*****************************************************************************/ void setsize ( int n, float f /* new internal size */ ) { /* * * Now using internal size n, where pstab[n-1] is the best available approximation * to the size troff asked for. * */ size = n; fractsize = f; lasthorscale = horscale = 1.0; } /* End of setsize */ /*****************************************************************************/ void t_fp ( int n, /* this position */ char *s, /* now has this font mounted */ char *si, /* its internal number */ void *a ) { /* * * Updates nfonts and the array that keeps track of the mounted fonts. Called from * loadfont() after an "x font pos font" command is read, and if pos is larger than * the current value assigned to nfonts we set gotspecial to FALSE to make sure * t_font() loads all the special fonts after the last legitimate font position. * */ fontname[n].name = s; fontname[n].number = atoi(si); fontname[n].afm = a; if ( n == lastfont ) /* force a call to t_sf() */ lastfont = lastsubfont = -1; if ( n > nfonts ) { /* got more positions */ nfonts = n; gotspecial = FALSE; gotregular = FALSE; } /* End if */ } /* End of t_fp */ /*****************************************************************************/ int t_font ( char *s /* use font in this position next */ ) { int n; /* * * Converts the string *s into an integer and checks to make sure it's a legal * font position. Also arranges to mount all the special fonts after the last * legitimate font (by calling loadspecial()), provided it hasn't already been * done. * */ n = atoi(s); if ( seenpage == TRUE ) { if ( n < 0 || n > nfonts ) error(FATAL, "illegal font position %d", n); if ( gotspecial == FALSE || gotregular == FALSE ) loadspecial(); } /* End if */ if (tracked) tracked = -1; track = 0; return(n); } /* End of t_font */ /*****************************************************************************/ static void sethorscale(char *buf) { horscale = atof(buf); } /*****************************************************************************/ static void t_track(char *buf) { int t; /* * Handling of track kerning. troff provides this parameter as a hint * only. dpost can use it in combination with the PostScript "ashow" * operator. When the variable "track" is not zero, the printer is * advised to perform tracking by the given amount. This relieves us * of the need to adjust the character position explicitly after each * character and thus greatly reduces the size of the output. * * Currently this is done in encodings 0, 4, and 5 only. */ if (sscanf(buf, "%d", &t) != 1) t = 0; if (t != lasttrack) { tracked = -1; } else if (t && tracked != -1) tracked = 1; track = t; } static void t_strack(void) { endtext(); fprintf(tf, "%d T\n", track); if (tf == stdout) { tracked = track != 0; lasttrack = track; } } /*****************************************************************************/ void setfont ( int n /* use the font mounted here */ ) { /* * * troff wants to use the font that's been mounted in position n. All we do here * is update the variable that keeps track of the current position. PostScript * font changes are handled in t_sf(), and are only generated right before we're * ready to print or draw something. * */ if ( n < 0 || n > NFONT ) error(FATAL, "illegal font %d", n); if ( fontname[n].name == NULL && fontname[n].number == 0) loaddefault(); if ( fontname[n].name == NULL && fontname[n].number == 0) error(FATAL, "font %d not loaded: check 'dpost' input for 'x font %d XXX' before 'f%d'", n, n, n); font = n; subfont = 0; lasthorscale = horscale = 1.0; } /* End of setfont */ /*****************************************************************************/ static void endvec(struct afmtab *a, int n) { fprintf(gf, "] def\n"); fprintf(gf, "\ /%s findfont\n\ dup length dict begin\n\ {1 index /FID ne {def} {pop pop} ifelse} forall\n\ /Encoding Encoding-@%s@%d def\n\ currentdict\n\ end\n", a->fontname, a->Font.intname, n); if (a->spec & SPEC_S) { fprintf(gf, "/%s-tmp-@%s", a->fontname, a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " exch definefont pop\n"); fprintf(gf, "_Sdefsadj\n"); fprintf(gf, "/%s-tmp-@%s", a->fontname, a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " /%s-@%s", a->fontname, a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " Sdefs cf\n"); fprintf(gf, "/%s-tmp-@%s", a->fontname, a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " undefinefont\n"); } else if (a->spec & SPEC_S1) { fprintf(gf, "/%s-tmp-@%s", a->fontname, a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " exch definefont pop\n"); fprintf(gf, "/%s-tmp-@%s", a->fontname, a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " /%s-@%s", a->fontname, a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " S1defs cf\n"); fprintf(gf, "/%s-tmp-@%s", a->fontname, a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " undefinefont\n"); } else if (n) fprintf(gf, "/%s-@%s@%d exch definefont pop\n", a->fontname, a->Font.intname, n); else fprintf(gf, "/%s-@%s exch definefont pop\n", a->fontname, a->Font.intname); fprintf(gf, "/@%s", a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " /%s-@%s", a->fontname, a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " def\n"); fprintf(gf, "/&%s", a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " {@%s", a->Font.intname); if (n) fprintf(gf, "@%d", n); fprintf(gf, " F} bind def\n"); } static void printencsep(int *colp) { if (*colp >= 60) { putc('\n', gf); *colp = 0; } else { putc(' ', gf); (*colp)++; } } static int * printencvector(struct afmtab *a) { int i, j, k, n, col = 0, s; int *encmap = NULL; fprintf(gf, "/Encoding-@%s@0 [\n", a->Font.intname); col = 0; /* * First, write excess entries into the positions from 1 to 31 * for later squeezing of characters >= 0400. */ s = 128 - 32; encmap = calloc(256 + nchtab + a->nchars, sizeof *encmap); col += fprintf(gf, "/.notdef"); printencsep(&col); for (j = 1; j < 32; j++) { while (s < a->nchars + 128 - 32 + nchtab && ((k = a->fitab[s]) == 0 || a->nametab[k] == NULL)) s++; if (s < a->nchars + 128 - 32 + nchtab && (k = a->fitab[s]) != 0 && k < a->nchars && a->nametab[k] != NULL) { encmap[s - 128 + 32] = j; col += fprintenc(gf, a->nametab[k]); printencsep(&col); s++; } else { col += fprintf(gf, "/.notdef"); printencsep(&col); } } col += fprintf(gf, "/space"); printencsep(&col); for (i = 1; i < a->nchars + 128 - 32 + nchtab && i < 256 - 32; i++) { if (i < 128 - 32 && (k = a->fitab[i]) != 0 && k < a->nchars && a->nametab[k] != NULL) { col += fprintenc(gf, a->nametab[k]); printencsep(&col); } else { while (s < a->nchars + 128 - 32 + nchtab && ((k = a->fitab[s]) == 0 || a->nametab[k] == NULL)) s++; if (s < a->nchars + 128 - 32 + nchtab && (k = a->fitab[s]) != 0 && k < a->nchars && a->nametab[k] != NULL) { encmap[s - 128 + 32] = i + 32; col += fprintenc(gf, a->nametab[k]); printencsep(&col); s++; } else { col += fprintf(gf, "/.notdef"); printencsep(&col); } } } endvec(a, 0); n = 1; while (s < a->nchars + 128 - 32 + nchtab) { fprintf(gf, "/Encoding-@%s@%d [\n", a->Font.intname, n); col = 0; for (i = 0; i < 256; i++) { while (s < a->nchars + 128 - 32 + nchtab && ((k = a->fitab[s]) == 0 || a->nametab[k] == NULL)) s++; if (s < a->nchars + 128 - 32 + nchtab && (k = a->fitab[s]) != 0 && k < a->nchars && a->nametab[k] != NULL) { encmap[s - 128 + 32] = i | n << 8; col += fprintenc(gf, a->nametab[k]); printencsep(&col); s++; } else { col += fprintf(gf, "/.notdef"); printencsep(&col); } } endvec(a, n++); } return encmap; } /*****************************************************************************/ void t_sf(int forceflush) { int fnum; /* internal font number */ int cmd; /* command to execute */ /* * * Called whenever we need to use a new font or size. Only done right before we * print a character. The seenfonts[] array keeps track of the fonts we've used. * Helps manage host resident fonts and the DOCUMENTFONTS comment that's put out * at the end of the job. The array is indexed by internal number. Only works for * fonts that have internal numbers less than or equal to MAXINTERNAL. * */ if ( fontname[font].name == NULL ) return; endtext(); if ( (fnum = fontname[font].number) > MAXINTERNAL || fnum < 0 ) fnum = 0; if ( fnum > 0 && seenfonts[fnum] == 0 && hostfontdir != NULL ) { snprintf(temp, sizeof temp, "%s/%s", hostfontdir, fontname[font].name); if ( access(temp, 04) == 0 ) doglobal(temp); } /* End if */ cmd = 'f'; if (forceflush == 0) { if (font == lastfont && subfont == lastsubfont) cmd = 's'; else if (size == lastsize && fractsize == lastfractsize) cmd = 'F'; } if (horscale != 1.0) cmd = 'h'; if ( tf == stdout ) { lastfont = font; lastsubfont = subfont; lastsize = size; lastfractsize = fractsize; lasthorscale = horscale; if ( seenfonts[fnum] == 0 ) { documentfonts(); } if (fontname[font].afm && fontname[font].afm->encmap == NULL) fontname[font].afm->encmap = printencvector(fontname[font].afm); seenfonts[fnum] = 1; } /* End if */ if (cmd == 'f' || cmd == 's' || cmd == 'h') { if (size != FRACTSIZE) fprintf(tf, "%d ", pstab[size-1]); else fprintf(tf, "%g ", (double)fractsize); } if (fontname[font].afm && cmd == 'F') { if (subfont) fprintf(tf, "&%s@%d\n", fontname[font].afm->Font.intname, subfont); else fprintf(tf, "&%s\n", fontname[font].afm->Font.intname); cmd = 0; } else if (cmd == 'f' || cmd == 'F' || cmd == 'h') { if (fontname[font].afm && subfont) fprintf(tf, "@%s@%d ", fontname[font].afm->Font.intname, subfont); else if (fontname[font].afm) fprintf(tf, "@%s ", fontname[font].afm->Font.intname); else fprintf(tf, "%s ", fontname[font].name); } if (cmd == 'h') fprintf(tf, "%g ", horscale); if (cmd) fprintf(tf, "%c\n", cmd); if ( fontname[font].fontheight != 0 || fontname[font].fontslant != 0 ) { if (size != FRACTSIZE) fprintf(tf, "%d %g changefont\n", fontname[font].fontslant, (fontname[font].fontheight != 0) ? (double)fontname[font].fontheight : pstab[size-1]); else fprintf(tf, "%d %g changefont\n", fontname[font].fontslant, (fontname[font].fontheight != 0) ? (double)fontname[font].fontheight : (double)fractsize); } if (tracked < 0 || tracked > 0 && forceflush) t_strack(); } /* End of t_sf */ /*****************************************************************************/ void t_charht ( int n, float f /* use this as the character height */ ) { /* * * Remembers the requested height, from 'x H n'. Forces a call to t_sf(), which * is where the real work is done, by setting lastfont to -1. * */ if (n == FRACTSIZE) fontname[font].fontheight = f; else fontname[font].fontheight = (n == pstab[size-1]) ? 0 : n; lastfont = lastsubfont = -1; } /* End of t_charht */ /*****************************************************************************/ void t_slant ( int n /* slant characters this many degrees */ ) { /* * * Remembers the requested slant, from 'x X n'. Forces a call to t_sf(), which * is where the real work is done, by setting lastfont to -1. * */ fontname[font].fontslant = n; lastfont = lastsubfont = -1; } /* End of t_slant */ /*****************************************************************************/ void t_reset ( int c __unused /* pause or restart */ ) { /* * * Found an "x stop" or "x pause" command. Although nothing's done here we could * add code to reset everything so dpost could handle multiple files formatted for * different devices. * */ } /* End of t_reset */ /*****************************************************************************/ void t_trailer(void) { /* * * Called after we find an "x trailer" in the input file. Forcing out the last * page is done at the end of conv(), but probably belongs here. * */ endtext(); } /* End of t_trailer */ /*****************************************************************************/ void hgoto ( int n /* new horizontal position */ ) { /* * * Want to be at this absolute horizontal position next. Actual motion commands * are generated in oput(), charlib(), and the drawing routines. * */ hpos = n; } /* End of hgoto */ /*****************************************************************************/ void hmot ( int n /* move this far horizontally */ ) { /* * * Handles relative horizontal motion. troff's current positon, as recorded in * in hpos, is changed by n units. Usually called right before we're supposed to * print a character. * */ hpos += n; } /* End of hmot */ /*****************************************************************************/ void vgoto ( int n /* new vertical position */ ) { /* * * Moves vertically in troff's coordinate system to absolute position n. * */ vpos = n; } /* End of vgoto */ /*****************************************************************************/ void vmot ( int n /* move this far vertically */ ) { /* * * Handles relative vertical motion of n units in troff's coordinate system. * */ vpos += n; } /* End of vmot */ /*****************************************************************************/ void xymove ( int x, int y /* this is where we want to be */ ) { /* * * Makes sure the post-processor and printer agree about the current position. * */ hgoto(x); vgoto(y); fprintf(tf, "%d %d m\n", hpos, vpos); lastx = hpos; savey = lasty = vpos; } /* End of xymove */ /*****************************************************************************/ void put1s ( register char *s /* find and print this character */ ) { static int i = 0; /* last one we found - usually */ /* * * *s points to the start of a two character string that represents one of troff's * special characters. To print it we first look for *s in the chname[] array using * chtab[i] to find the string representing character i in chname[]. If the lookup * is successful we add 128 to i and ask put1() to finish printing the character. * We remember the index where the last character was found because requests to * print a special character often come in bunches (eg. drawing lines with \(ru). * */ if (s[0] == 'P' && s[1] == 'S' && s[2] != 0) { /* PostScript name */ int m; struct namecache *np; struct afmtab *a; if ((a = fontname[font].afm) != NULL && (np = afmnamelook(a, &s[2])) != NULL && ((m = np->fival[0]) != NOCODE || (m = np->fival[1]) != NOCODE)) { put1(m+32); return; } } if ( strcmp(s, &chname[chtab[i]]) != 0 ) for ( i = 0; i < nchtab; i++ ) if ( strcmp(&chname[chtab[i]], s) == 0 ) break; if ( i < nchtab ) put1(i + 128); else i = 0; } /* End of put1s */ /*****************************************************************************/ void put1 ( register int c /* want to print this character */ ) { register int i = 0; /* character code from fitab */ register int j; /* number of fonts we've checked so far */ register int k; /* font we're currently looking at */ int *pw = NULL; /* font widthtab and */ unsigned short *p = NULL; /* and codetab where c was found */ int code; /* code used to get c printed */ int ofont; /* font when we started */ /* * * Arranges to have character c printed. If c < 128 it's a simple ASCII character, * otherwise it's a special character. Things done here have to agree with the way * the font tables were built by makedev, and work as follows. First we subtract * 32 from c because the tables don't record the non-graphic ASCII characters. * If fitab[k][c] isn't zero the character is on font k and the value is an index * that can be used to recover width and character code data from the other two * tables. If fitab[k][c] is zero the character isn't defined on font k and we * check the next font, which is found as follows. The current font is the first * one we check, and it's followed by a circular search of all the remaining fonts * that starts with the first special font and skips font position 0. If character * c is found somewhere besides the current font we change to that font and use * fitab[k][c] to locate missing data in the other two tables. The width of the * character can be found at fontab[k][c] while codetab[k][c] is whatever we * need to tell the printer to have character c printed. lastc records the real * name of the character because it's lost by the time oput() gets called but * charlib() may need it. * * Took all the debugging stuff out because at least this part of the program is * reasonably solid. * */ lastc = c; /* charlib() needs the name not the code */ if ( (c -= 32) <= 0 ) /* probably never happens */ return; k = ofont = font; if ( fitab[k] && (i = fitab[k][c]) != 0 ) { /* it's on this font */ p = codetab[font]; pw = fontab[font]; } else if ( smnt > 0 ) { /* on special (we hope) */ for ( k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1) ) { if ( k == 0 ) continue; if ( fitab[k] && (i = fitab[k][c]) != 0 ) { p = codetab[k]; pw = fontab[k]; setfont(k); break; } /* End if */ } /* End for */ } /* End else */ lastw = 0; if ( i != 0 && (code = p[i]) != 0 ) { if (size != FRACTSIZE) lastw = horscale * widthfac * ((pw[i] * pstab[size-1] + unitwidth/2) / unitwidth); else lastw = horscale * widthfac * (int)((pw[i] * fractsize + unitwidth/2) / unitwidth); if (widthfac == 1) /* ignore fractional parts since troff */ lastw = (int)lastw; /* does the same */ if (track && encoding != MAXENCODING+2) lastw += track; if (code == NOCODE && fontname[k].afm) code = c + 32; oput(code); } /* End if */ if ( font != ofont ) setfont(ofont); } /* End of put1 */ /*****************************************************************************/ static void oprep(int stext) { if ( textcount > MAXSTACK ) /* don't put too much on the stack? */ endtext(); if ( font != lastfont || size != lastsize || subfont != lastsubfont || (size == FRACTSIZE && fractsize != lastfractsize) || horscale != lasthorscale) { t_sf(0); } if (tracked < 0) t_strack(); if ( vpos != lasty ) endline(); if (stext) { starttext(); - if ( ABS(hpos - lastx) > slop ) + if ( fabsf(hpos - lastx) > slop ) endstring(); } wordspace = 0; } void oput ( int c /* want to print this character */ ) { /* * * Arranges to print the character whose code is c in the current font. All the * actual positioning is done here, in charlib(), or in the drawing routines. * */ if ( asciichar(c) && printchar(c) ) switch ( c ) { case '(': case ')': case '\\': if (encoding != 5) addchar('\\'); default: addchar(c); } /* End switch */ else if ( c > 040 ) addoctal(c); else charlib(c); lastx += lastw; } /* End of oput */ /*****************************************************************************/ void starttext(void) { /* * Called whenever we want to be sure we're ready to start collecting characters * for the next call to PostScript procedure t (ie. the one that prints them). If * textcount is positive we've already started, so there's nothing to do. The more * complicated encoding schemes save text strings in the strings[] array and need * detailed information about the strings when they're written to the output file * in endtext(). * */ if ( textcount < 1 ) { switch ( encoding ) { case 0: case 1: case 4: putc('(', tf); charcount = 1; break; case 5: strptr = strings; break; case 2: case 3: strptr = strings; spacecount = 0; line[1].str = strptr; line[1].dx = 0; line[1].spaces = 0; line[1].start = hpos; line[1].width = 0; charcount = 0; break; case MAXENCODING+1: /* reverse video */ if ( lastend == -1 ) lastend = hpos; putc('(', tf); charcount = 1; break; case MAXENCODING+2: /* follow a funny baseline */ putc('(', tf); charcount = 1; break; } /* End switch */ textcount = 1; lastx = stringstart = hpos; laststrstart = INT_MIN; } /* End if */ } /* End of starttext */ /*****************************************************************************/ void endtext(void) { char buf[STRINGSPACE+100]; int i; /* loop index */ int n, m; /* * * Generates a call to the PostScript procedure that processes all the text we've * accumulated - provided textcount is positive. * */ if ( textcount > 0 ) { /* started working on some text */ switch ( encoding ) { case 0: fprintf(tf, ")%d t\n", stringstart); break; case 4: if (laststrstart != INT_MIN) fprintf(tf, ")%d %d t\n", stringstart - laststrstart, stringstart); else fprintf(tf, ")%d t\n", stringstart); break; case 5: putstring(strings, strptr - strings, tf); strptr = strings; if (laststrstart != INT_MIN) putint(stringstart - laststrstart, tf); putint(stringstart, tf); putc('t', tf); putc('\n', tf); break; case 1: fprintf(tf, ")%d %d t\n", stringstart, lasty); break; case 2: *strptr = '\0'; line[textcount].width = lastx - line[textcount].start; if ( spacecount != 0 || textcount != 1 ) { n = 0; for ( i = textcount; i > 0; i-- ) { m = snprintf(buf, sizeof buf, "(%s)%d %d", line[i].str, line[i].spaces, line[i].width); if (i < textcount && n + m >= 80) { putc('\n', tf); n = 0; } fputs(buf, tf); n += m; } if (lasty != savey) fprintf(tf, " %d %d %d t\n", textcount, stringstart, lasty); else fprintf(tf, " %d %d u\n", textcount, stringstart); } else { if (lasty != savey) fprintf(tf, "(%s)%d %d w\n", line[1].str, stringstart, lasty); else fprintf(tf, "(%s)%d v\n", line[1].str, stringstart); } savey = lasty; break; case 3: *strptr = '\0'; if ( spacecount != 0 || textcount != 1 ) { n = 0; for ( i = textcount; i > 0; i-- ) { m = snprintf(buf, sizeof buf, "(%s)%d", line[i].str, line[i].dx); if (i < textcount && n + m >= 80) { putc('\n', tf); n = 0; } fputs(buf, tf); n += m; } if (lasty != savey) fprintf(tf, " %d %d %d t\n", textcount, stringstart, lasty); else fprintf(tf, " %d %d u\n", textcount, stringstart); } else { if (lasty != savey) fprintf(tf, "(%s)%d %d w\n", line[1].str, stringstart, lasty); else fprintf(tf, "(%s)%d v\n", line[1].str, stringstart); } savey = lasty; break; case MAXENCODING+1: fprintf(tf, ")%d ", stringstart); fprintf(tf, "%d %d drawrvbox ", lastend - rvslop, (int)(lastx + .5) + rvslop); fprintf(tf, "t\n"/*, stringstart*/); lastend = (lastx + .5) + 2 * rvslop; break; case MAXENCODING+2: fprintf(tf, ")%d %d t\n", stringstart, lasty); break; } /* End switch */ charcount = 0; } /* End if */ textcount = 0; } /* End of endtext */ /*****************************************************************************/ void endstring(void) { int dx; /* * * Horizontal positions are out of sync. End the last open string, adjust the * printer's position, and start a new string. Assumes we've already started * accumulating text. * */ switch ( encoding ) { case 4: if (laststrstart != INT_MIN) charcount += fprintf(tf, ")%d", stringstart - laststrstart); else { putc(')', tf); charcount++; } laststrstart = stringstart; goto nx; case 5: putstring(strings, strptr - strings, tf); strptr = strings; charcount++; if (laststrstart != INT_MIN) charcount += putint(stringstart - laststrstart, tf); laststrstart = stringstart; textcount++; lastx = stringstart = hpos; break; case 0: case 1: charcount += fprintf(tf, ")%d", stringstart); nx: if (charcount >= 60) { putc('\n', tf); charcount = 0; } putc('(', tf); charcount++; textcount++; lastx = stringstart = hpos; break; case 2: case 3: if (!wordspace) { endtext(); starttext(); break; } dx = hpos - lastx; if ( spacecount++ == 0 ) line[textcount].dx = dx; if ( line[textcount].dx != dx ) { *strptr++ = '\0'; line[textcount].width = lastx - line[textcount].start; line[++textcount].str = strptr; *strptr++ = ' '; line[textcount].dx = dx; line[textcount].start = lastx; line[textcount].width = 0; line[textcount].spaces = 1; charcount = 1; } else { *strptr++ = ' '; line[textcount].spaces++; charcount++; } /* End else */ lastx += dx; break; case MAXENCODING+1: charcount += fprintf(tf, ")%d", stringstart); if (charcount >= 60) { putc('\n', tf); charcount = 0; } putc('(', tf); charcount++; textcount++; lastx = stringstart = hpos; break; case MAXENCODING+2: endtext(); starttext(); break; } /* End switch */ } /* End of endstring */ /*****************************************************************************/ void endline(void) { /* * * The vertical position has changed. Dump any accumulated text, then adjust * the printer's vertical position. * */ endtext(); if ( encoding == 0 || encoding == 4 || encoding == MAXENCODING+1 ) { fprintf(tf, "%d %d m\n", hpos, vpos); savey = vpos; } else if (encoding == 5) { putint(hpos, tf); putint(vpos, tf); putc('m', tf); putc('\n', tf); } lastx = stringstart = lastend = hpos; lasty = vpos; } /* End of endline */ /*****************************************************************************/ void addchar ( int c /* next character in current string */ ) { /* * * Does whatever is needed to add character c to the current string. * */ static int lastc; subfont = 0; if (lastc != '\\') oprep(1); lastc = c; switch ( encoding ) { case 0: case 1: case 4: putc(c, tf); if (charcount++ >= 72 && c != '\\') { putc('\\', tf); putc('\n', tf); charcount = 0; } break; case 5: *strptr++ = c; break; case 2: case 3: *strptr++ = c; if (charcount++ >= 72 && c != '\\') { *strptr++ = '\\'; *strptr++ = '\n'; charcount = 0; } break; case MAXENCODING+1: case MAXENCODING+2: putc(c, tf); if (charcount++ >= 72 && c != '\\') { putc('\\', tf); putc('\n', tf); charcount = 0; } break; } /* End switch */ } /* End of addchar */ /*****************************************************************************/ void addoctal ( int c /* add it as an octal escape */ ) { int n; /* * * Adds c to the current string as an octal escape \ddd. * * * If c is not a byte, try to squeeze it into the control area. */ oprep(0); if (c >= 128 && fontname[font].afm && fontname[font].afm->encmap) { c = fontname[font].afm->encmap[c - 128]; subfont = c >> 8; c &= 0377; } else subfont = 0; oprep(1); switch ( encoding ) { case 0: case 1: case 4: charcount += fprintf(tf, "\\%03o", c); if (charcount >= 72) { putc('\\', tf); putc('\n', tf); charcount = 0; } break; case 5: *strptr++ = c; break; case 2: case 3: snprintf(strptr, sizeof strings - (strptr - strings), "\\%03o", c); n = strlen(strptr); strptr += n; charcount += n; if (charcount >= 72) { *strptr++ = '\\'; *strptr++ = '\n'; charcount = 0; } break; case MAXENCODING+1: case MAXENCODING+2: charcount += fprintf(tf, "\\%03o", c); if (charcount >= 72) { putc('\\', tf); putc('\n', tf); charcount = 0; } break; } /* End switch */ } /* End of addoctal */ /*****************************************************************************/ void charlib ( int code /* either 1 or 2 */ ) { char *name; /* name of the character */ char tname[10]; /* in case it's a single ASCII character */ const char *filename; /* real file name */ /* * * Called from oput() for characters having codes less than 040. Special files * that define PostScript procedures for certain characters can be found in * directory *fontdir/devpost/charlib. If there's a file that has the same name as * the character we're trying to print it's copied to the output file, otherwise * nothing, except some positioning, is done. * * All character definitions are only made once. Subsequent requests to print the * character generate a call to a procedure that begins with the prefix build_ and * ends with the character's name. Special characters that are assigned codes * other than 1 are assumed to have additional data files that should be copied * to the output file immediately after the build_ call. Those data files should * end in the suffix .map, and usually will be a hex representation of a bitmap. * */ subfont = 0; oprep(1); endtext(); if ( lastc < 128 ) { /* just a simple ASCII character */ snprintf(tname, sizeof tname, "%.3o", lastc); name = tname; } else name = &chname[chtab[lastc - 128]]; /* * This is just a kludge of course. But since only one file exists which * needs a name mapping, no more general method had been implemented. */ if (*name == 'L' && name[1] == 'H' && !name[2]) filename = "LH_uc"; else filename = name; if ( downloaded[lastc] == 0 ) { snprintf(temp, sizeof temp, "%s/dev%s/charlib/%s", fontdir, realdev, filename); if ( access(temp, 04) == 0 && doglobal(temp) == TRUE ) { downloaded[lastc] = 1; t_sf(0); } /* End if */ } /* End if */ if ( downloaded[lastc] == 1 ) { xymove(hpos, vpos); fprintf(tf, "%d build_%s\n", (int) lastw, name); if ( code != 1 ) { /* get the bitmap or whatever */ snprintf(temp, sizeof temp, "%s/dev%s/charlib/%s.map", fontdir, realdev, name); if ( access(temp, 04) == 0 && tf == stdout ) cat(temp, tf); } /* End if */ fprintf(tf, "%d %d m\n", stringstart = hpos + lastw, vpos); savey = vpos; } /* End if */ } /* End of charlib */ /*****************************************************************************/ int doglobal ( const char *name /* copy this to the output - globally */ ) { int val = FALSE; /* returned to the caller */ /* * * Copies file *name to the output file and brackets it with whatever commands are * needed to have it exported to the global environment. TRUE is returned if we * successfully add file *name to the output file. * * Actually, all files included this way are procsets, so they go into * the resource section of the PostScript output and not in the global * setup file. * */ if ( tf == stdout ) { val = cat(name, rf); reset(); } /* End if */ return(val); } /* End of doglobal */ /*****************************************************************************/ void documentfont(const char *name) { static FILE *fp_out; /* PostScript name added to this file */ static int pos; static struct fn { struct fn *next; const char *name; } *fn; struct fn *ft; int n; if ( temp_file == NULL ) /* generate a temp file name */ if ( (temp_file = tempname("dpost")) == NULL ) return; if ( fp_out == NULL && (fp_out = fopen(temp_file, "w")) == NULL ) return; for (ft = fn; ft; ft = ft->next) if (strcmp(name, ft->name) == 0) return; ft = calloc(1, sizeof *ft); ft->name = strdup(name); ft->next = fn; fn = ft; if ( docfonts++ == 0 ) pos += fprintf(fp_out, "%s", DOCUMENTFONTS); else { n = strlen(name); if (pos + n >= 80) { fprintf(fp_out, "\n%s", CONTINUECOMMENT); pos = 0; } } pos += fprintf(fp_out, " %s", name); fflush(fp_out); t_dosupply(name); } void documentfonts(void) { FILE *fp_in = NULL; /* PostScript font name read from here */ /* * * Whenever a new font is used we try to record the appropriate PostScript font * name in *temp_file for the DOCUMENTFONTS comment that's put out in done(). * By default PostScript font names are found in /usr/lib/font/devpost. Fonts * that have a .name file are recorded in *temp_file. The first string in that * file is expected to be that font's (long) PostScript name. * */ snprintf(temp, sizeof temp, "%s/dev%s/%s.name", fontdir, realdev, fontname[font].name); if (fontname[font].afm == NULL && (fp_in = fopen(temp, "r")) != NULL ) { if ( sget(temp, sizeof temp, fp_in) == 1 ) { documentfont(temp); } /* End if */ if (fp_in != NULL) fclose(fp_in); } else if (fontname[font].afm != NULL){ documentfont(fontname[font].afm->fontname); } /* End if */ } /* End of documentfonts */ /*****************************************************************************/ void redirect ( int pg /* next page we're printing */ ) { static FILE *fp_null = NULL; /* if output is turned off */ /* * * If we're not supposed to print page pg, tf will be directed to /dev/null, * otherwise output goes to stdout. * */ if ( pg >= 0 && in_olist(pg) == ON ) tf = stdout; else if ( (tf = fp_null) == NULL ) tf = fp_null = fopen("/dev/null", "w"); } /* End of redirect */ /*****************************************************************************/ static char * mbs2pdf(char *mp) { char *ustr, *tp; int c, i, sz; #ifdef EUC int n = 0, w; wchar_t wc; #endif for (tp = mp; *tp && (*tp&~0177) == 0 && *tp&~037; tp++); if (*tp == 0) { ustr = malloc(sz = 16); *ustr = '('; c = i = 1; while (*mp) { switch (*mp) { case '(': case ')': case '\\': ustr[i++] = '\\'; c++; /*FALLTHRU*/ default: ustr[i++] = *mp++; c++; } if (i + 4 >= sz) ustr = realloc(ustr, sz += 16); if (c >= 60) { ustr[i++] = '\\'; ustr[i++] = '\n'; c = 0; } } ustr[i++] = ')'; ustr[i++] = 0; return ustr; } #ifdef EUC ustr = malloc(sz = 16); c = i = snprintf(ustr, sz, " 0xFFFF) { error(NON_FATAL, "only BMP values allowed for PDFMark"); continue; } if (i + 8 >= sz) ustr = realloc(ustr, sz += 16); w = snprintf(&ustr[i], sz - i * sizeof(*ustr), "%04X", (int)wc); i += w; c += w; if (c >= 60) { ustr[i++] = '\n'; c = 0; } } ustr[i++] = '>'; ustr[i] = 0; return ustr; #else /* !EUC */ error(NON_FATAL, "this instance of dpost only supports ASCII with PDFMark"); return NULL; #endif /* !EUC */ } static void t_pdfmark(char *buf) { char *bp, *tp; int n; while (spacechar(*buf&0377)) buf++; for (bp = buf; *bp && !spacechar(*bp&0377); bp++); *bp++ = '\0'; while (spacechar(*bp&0377)) bp++; for (tp = bp; *tp; tp++) if (*tp == '\n') { *tp = '\0'; break; } if (strcmp(buf, "Author") == 0) Author = mbs2pdf(bp); else if (strcmp(buf, "Title") == 0) Title = mbs2pdf(bp); else if (strcmp(buf, "Subject") == 0) Subject = mbs2pdf(bp); else if (strcmp(buf, "Keywords") == 0) Keywords = mbs2pdf(bp); else if (strcmp(buf, "Bookmark") == 0 || strcmp(buf, "BookmarkClosed") == 0) { n = strtol(bp, &bp, 10); while (spacechar(*bp&0377)) bp++; if (n < 0 || n > MAXBOOKMARKLEVEL) { error(NON_FATAL, "invalid PDFMark Bookmark level %d," "maximum is %d\n", n, MAXBOOKMARKLEVEL); return; } Bookmarks = realloc(Bookmarks, ++nBookmarks*sizeof *Bookmarks); Bookmarks[nBookmarks-1].level = n; Bookmarks[nBookmarks-1].Title = mbs2pdf(bp); Bookmarks[nBookmarks-1].title = strdup(bp); Bookmarks[nBookmarks-1].Count = 0; Bookmarks[nBookmarks-1].closed = strcmp(buf, "BookmarkClosed") == 0; endtext(); fprintf(tf, "[ /Dest /Bookmark$%ld\n" " /View [/XYZ -4 %g 0]\n" "/DEST pdfmark\n", (long)nBookmarks - 1, pagelength - (lasty >= 0 ? vpos * 72.0 / res : -4)); } else error(NON_FATAL, "unknown PDFMark attribute %s", buf); } static void orderbookmarks(void) { int counts[MAXBOOKMARKLEVEL+1]; int refs[MAXBOOKMARKLEVEL+1]; size_t i, j, k, t; int lvl = 0; /* * Generate the Count parameter from the given levels. */ memset(&counts, 0, sizeof counts); for (i = 0; i <= MAXBOOKMARKLEVEL; i++) refs[i] = -1; for (i = 0; i <= nBookmarks; i++) { k = i < nBookmarks ? Bookmarks[i].level : 0; if (i == nBookmarks || k <= lvl) { for (j = k+1; j <= MAXBOOKMARKLEVEL; j++) { t = j - 1; if (refs[t] >= 0) { Bookmarks[refs[t]].Count += counts[j]; refs[t] = -1; } counts[j] = 0; } } if (k > 0 && refs[k-1] < 0) { while (k > 0 && refs[k-1] < 0) k--; error(NON_FATAL, "PDFMark Bookmark \"%s\" at level %d " "has no direct parent, " "using level %d\n", Bookmarks[i].title, Bookmarks[i].level, k); } counts[k]++; refs[k] = i; lvl = k; } } static void t_locale(char *lp) { static char *savlp; if (savlp && strcmp(lp, savlp) == 0) return; free(savlp); savlp = malloc(strlen(lp) + 1); sscanf(lp, "%s", savlp); setlocale(LC_CTYPE, savlp); mb_cur_max = MB_CUR_MAX; } static void pref(const char *lp, FILE *fp) { int c; while ((c = *lp++ & 0377) != 0 && c != '\n') { if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) putc(c, fp); else fprintf(fp, "$%2x", c); } } static void pref_uri(const char *lp, FILE *fp) { int c; /* Don't do any escaping here to avoid double-escaping. */ while ((c = *lp++ & 0377) != 0 && c != '\n') { putc(c, fp); } } static void t_anchor(char *lp) { int v; v = strtol(lp, &lp, 10); if ((lp = strchr(lp, ' ')) != NULL) { lp++; endtext(); fprintf(tf, "[ /Dest /Anchor$"); pref(lp, tf); fprintf(tf, "\n" " /View [/XYZ -4 %g 0]\n" "/DEST pdfmark\n", pagelength - (v >= 0 ? v * 72.0 / res : -4)); } } static char linkcolor[60] = "0 0 1"; static char linkborder[60] = "0 0 1"; static char * t_linkborderstyle(char *arg) { char c, *s; s = arg; for (s = arg; (c = *s) && c != '\n'; s++); *s = 0; return strdup(arg); } static void t_link(char *lp) { int llx, lly, urx, ury; llx = strtol(lp, &lp, 10); if (*lp) { while (*lp == ',') lp++; lly = strtol(lp, &lp, 10); if (*lp) { while (*lp == ',') lp++; urx = strtol(lp, &lp, 10); if (*lp) { while (*lp == ',') lp++; ury = strtol(lp, &lp, 10); if ((lp = strchr(lp, ' ')) != NULL) { lp++; endtext(); fprintf(tf, "[ /Dest /Anchor$"); pref(lp, tf); fprintf(tf, "\n" "/Rect [%d %d %d %d]\n" "/Color [%s]\n", llx, -lly, urx, -ury, linkcolor); if (linkborderstyle) fprintf(tf, "/BS << %s >>\n", linkborderstyle); else fprintf(tf, "/Border [%s]\n", linkborder); fprintf(tf, "/Subtype /Link\n" "/ANN pdfmark\n"); } } } } } static void t_linkcolor(char *lp) { float r, g, b; r = strtod(lp, &lp); g = strtod(lp, &lp); b = strtod(lp, &lp); snprintf(linkcolor, sizeof linkcolor, "%g %g %g", r, g, b); } static void t_linkborder(char *lp) { float bx, by, c; bx = strtod(lp, &lp); by = strtod(lp, &lp); c = strtod(lp, &lp); snprintf(linkborder, sizeof linkborder, "%g %g %g", bx, by, c); free(linkborderstyle); linkborderstyle = NULL; } static char ulinkcolor[60] = "0 0 1"; static char ulinkborder[60] = "0 0 1"; static void t_ulink(char *lp) { int llx, lly, urx, ury; llx = strtol(lp, &lp, 10); if (*lp) { while (*lp == ',') lp++; lly = strtol(lp, &lp, 10); if (*lp) { while (*lp == ',') lp++; urx = strtol(lp, &lp, 10); if (*lp) { while (*lp == ',') lp++; ury = strtol(lp, &lp, 10); if ((lp = strchr(lp, ' ')) != NULL) { lp++; endtext(); fprintf(tf, "[ /Rect [%d %d %d %d]\n" "/Color [%s]\n", llx, -lly, urx, -ury, ulinkcolor); if (ulinkborderstyle) fprintf(tf, "/BS << %s >>\n", ulinkborderstyle); else fprintf(tf, "/Border [%s]\n", ulinkborder); fprintf(tf, "/Action << /Subtype /URI\n" "/URI ("); pref_uri(lp, tf); fprintf(tf, ") >>\n" "/Subtype /Link\n" "/ANN pdfmark\n"); } } } } } static void t_ulinkcolor(char *lp) { float r, g, b; r = strtod(lp, &lp); g = strtod(lp, &lp); b = strtod(lp, &lp); snprintf(ulinkcolor, sizeof ulinkcolor, "%g %g %g", r, g, b); } static void t_ulinkborder(char *lp) { float bx, by, c; bx = strtod(lp, &lp); by = strtod(lp, &lp); c = strtod(lp, &lp); snprintf(ulinkborder, sizeof ulinkborder, "%g %g %g", bx, by, c); free(ulinkborderstyle); ulinkborderstyle = NULL; } Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/gen.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/gen.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/gen.h (revision 307812) @@ -1,178 +1,161 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "gen.h 1.5 05/06/08 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)gen.h 1.16 (gritter) 10/15/06 */ /* * * A few definitions that shouldn't have to change. They're used by most of the * programs in this package. * */ -#ifndef __unused -#define __unused __attribute__((unused)) -#endif extern const char creator[]; #define NON_FATAL 0 #define FATAL 1 #define USER_FATAL 2 #define OFF 0 #define ON 1 #define FALSE 0 #define TRUE 1 #define BYTE 8 #define BMASK 0377 #define POINTS 72.3 #ifndef PI #define PI 3.141592654 #endif - -/* - * - * A few simple macros. - * - */ - - -#define ABS(A) ((A) >= 0 ? (A) : -(A)) -#undef MIN -#define MIN(A, B) ((A) < (B) ? (A) : (B)) -#undef MAX -#define MAX(A, B) ((A) > (B) ? (A) : (B)) - /* color.c */ void getcolor(void); void newcolor(char *); void setcolor(void); /* dpost.c */ void init_signals(void); void header(FILE *); void options(void); void setpaths(char *); void setup(void); void arguments(void); void done(void); void account(void); void conv(register FILE *); void devcntrl(FILE *); void fontinit(void); void loadfont(int, const char *, char *, int, int); void loadspecial(void); void loaddefault(void); void fontprint(int); -const char *mapfont(char *); +const char *mapfont(const char *); void getdevmap(void); char *mapdevfont(char *); void reset(void); void resetpos(void); void t_init(void); void t_page(int); void t_newline(void); int t_size(int); void setsize(int, float); void t_fp(int, char *, char *, void *); int t_font(char *); void setfont(int); void t_sf(int); void t_charht(int, float); void t_slant(int); void needresource(const char *, ...); void t_supply(char *); void t_reset(int); void t_trailer(void); void hgoto(int); void hmot(int); void vgoto(int); void vmot(int); void xymove(int, int); void put1s(register char *); void put1(register int); void oput(int); void starttext(void); void endtext(void); void endstring(void); void endline(void); void addchar(int); void addoctal(int); void charlib(int); int doglobal(const char *); void documentfont(const char *); void documentfonts(void); void redirect(int); /* draw.c */ void getdraw(void); void drawline(int, int); void drawcirc(int, int); void drawellip(int, int, int); void drawarc(int, int, int, int, int); void drawspline(FILE *, int); void beginpath(char *, int); void drawpath(char *, int); void parsebuf(char *); void getbaseline(void); void newbaseline(char *); void drawtext(char *); void settext(char *); /* glob.c */ /* misc.c */ void interrupt(int); void error(int, const char *, ...); void out_list(char *); int in_olist(int); int cat(const char *, FILE *); int str_convert(char **, int); char *tempname(const char *); int psskip(size_t, FILE *); char *psgetline(char **, size_t *, size_t *, FILE *); int sget(char *, size_t, FILE *); /* pictures.c */ void picture(char *); FILE *picopen(char *); void inlinepic(FILE *, char *); void piccopy(FILE *, FILE *, long); /* ps_include.c */ void ps_include(const char *, FILE *, FILE *, int, int, int, int, double, double, double, double, double, double, double); /* request.c */ void saverequest(char *); void writerequest(int, FILE *); -void dumprequest(char *, char *, FILE *); +void dumprequest(char *, const char *, FILE *); /* tempnam.c */ Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/misc.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/misc.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/misc.c (revision 307812) @@ -1,392 +1,388 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Copyright 2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* from OpenSolaris "misc.c 1.6 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)misc.c 1.14 (gritter) 12/25/06 */ /* * * A few general purpose routines. * */ #include #include #include #include #include #include #include +#include "global.h" #include "gen.h" /* a few general purpose definitions */ #include "ext.h" /* external variable declarations */ #include "path.h" #include "asciitype.h" static size_t nolist = 0; /* number of specified ranges */ static int olist[512]; /* processing range pairs */ void error(int kind, const char *mesg, ...) { /* * * Called when we've run into some kind of program error. *mesg is printed using * the control string arguments a?. We'll quit if we're not ignoring errors and * kind is FATAL. * */ if ( mesg != NULL && *mesg != '\0' ) { va_list ap; fprintf(stderr, "%s: ", prog_name); va_start(ap, mesg); vfprintf(stderr, mesg, ap); va_end(ap); if ( lineno > 0 ) fprintf(stderr, " (line %ld)", lineno); if ( position > 0 ) fprintf(stderr, " (near byte %ld)", position); if ( printed > 0 ) fprintf(stderr, " (page %d)", printed); putc('\n', stderr); } /* End if */ if ( kind == FATAL && ignore == OFF ) { if ( temp_file != NULL ) unlink(temp_file); exit(x_stat | 01); } /* End if */ } /* End of error */ /*****************************************************************************/ /* for the AFM handling functions from troff */ static void verrprint(char *fmt, va_list ap) { fprintf(stderr, "%s: ", prog_name); vfprintf(stderr, fmt, ap); putc('\n', stderr); } void errprint(char *fmt, ...) { va_list ap; va_start(ap, fmt); verrprint(fmt, ap); va_end(ap); } /*****************************************************************************/ void out_list ( char *str /* process ranges in this string */ ) { int start, stop; /* end points */ /* * * Called to get the processing ranges that were specified by using the -o option. * The range syntax should be identical to the one used in nroff and troff. * */ while ( *str && nolist < sizeof(olist) - 2 ) { start = stop = str_convert(&str, 0); if ( *str == '-' && *str++ ) stop = str_convert(&str, 9999); if ( start > stop ) error(FATAL, "illegal range %d-%d", start, stop); olist[nolist++] = start; olist[nolist++] = stop; if ( *str != '\0' ) str++; } /* End while */ olist[nolist] = 0; } /* End of out_list */ /*****************************************************************************/ int in_olist ( int num /* should we print this page? */ ) { size_t i; /* just a loop index */ /* * * Returns ON if num represents a page that we're supposed to print. If no ranges * were selected nolist will be 0 and we'll print everything. * */ if ( nolist == 0 ) /* everything's included */ return(ON); for ( i = 0; i < nolist; i += 2 ) if ( num >= olist[i] && num <= olist[i+1] ) return(ON); return(OFF); } /* End of in_olist */ /*****************************************************************************/ int cat ( const char *file, /* copy this file to out */ FILE *out ) { int fd_in; /* for the input */ int fd_out; /* and output files */ char buf[512]; /* buffer for reads and writes */ int count; /* number of bytes we just read */ /* * * Copies *file to stdout - mostly for the prologue. Returns FALSE if there was a * problem and TRUE otherwise. * */ fflush(out); if ( (fd_in = open(file, O_RDONLY)) == -1 ) return(FALSE); fd_out = fileno(out); while ( (count = read(fd_in, buf, sizeof(buf))) > 0 ) write(fd_out, buf, count); close(fd_in); return(TRUE); } /* End of cat */ /*****************************************************************************/ int str_convert ( char **str, /* get next number from this string */ int err /* value returned on error */ ) { int i; /* just a loop index */ int c; /* * * Gets the next integer from **str and returns its value to the caller. If **str * isn't an integer err is returned. *str is updated after each digit is processed. * */ if ( ! isdigit(c = **str) ) /* something's wrong */ return(err); for ( i = 0; isdigit(c = **str); *str += 1 ) i = 10 * i + c - '0'; return(i); } /* End of str_convert */ /*****************************************************************************/ void interrupt( int sig __unused) /* signal that we caught */ { /* * * Called when we get a signal that we're supposed to catch. * */ if ( temp_file != NULL ) unlink(temp_file); exit(1); } /* End of interrupt */ /*****************************************************************************/ char * tempname(const char *sfx) { size_t l = strlen(TEMPDIR) + strlen(sfx) + 10; char *pat = malloc(l); snprintf(pat, l, "%s/%sXXXXXX", TEMPDIR, sfx); if (close(mkstemp(pat)) < 0) return NULL; return pat; } /*****************************************************************************/ - -#if defined (__GLIBC__) && defined (_IO_getc_unlocked) -#undef getc -#define getc(f) _IO_getc_unlocked(f) -#endif #define LSIZE 512 int psskip(size_t n, FILE *fp) { return fseek(fp, n, SEEK_CUR); } char *psgetline(char **line, size_t *linesize, size_t *llen, FILE *fp) { int c; size_t n = 0; int nl = 0; if (*line == NULL || *linesize < LSIZE + n + 1) *line = realloc(*line, *linesize = LSIZE + n + 1); for (;;) { if (n >= *linesize - LSIZE / 2) *line = realloc(*line, *linesize += LSIZE); c = getc(fp); if (c != EOF) { if (nl && c != '\n') { ungetc(c, fp); break; } (*line)[n++] = c; (*line)[n] = '\0'; if (c == '\n') break; if (c == '\r') nl = 1; } else { if (n > 0) break; else return NULL; } } if (llen) *llen = n; return *line; } /*****************************************************************************/ int sget(char *buf, size_t size, FILE *fp) { int c; size_t n = 0; do c = getc(fp); while (spacechar(c)); if (c != EOF) do { if (n+1 < size) buf[n++] = c; c = getc(fp); } while (c != EOF && !spacechar(c)); ungetc(c, fp); buf[n] = 0; return n > 1 ? 1 : c == EOF ? EOF : 0; } Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/ps_include.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/ps_include.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/ps_include.c (revision 307812) @@ -1,361 +1,362 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "ps_include.c 1.5 05/06/08 SMI" SVr4.0 1.3 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)ps_include.c 1.10 (gritter) 10/15/06 */ /* * * Picture inclusion code for PostScript printers. * */ #include #include #include #include #include "gen.h" #include "ext.h" #include "path.h" #include "asciitype.h" +#include "global.h" #define var(x) fprintf(fout, "/%s %g def\n", #x, x) #define has(word) _has(buf, word) #define grab(n) ((Section *)(nglobal \ ? realloc((char *)global, n*sizeof(Section)) \ : calloc(n, sizeof(Section)))) static char *buf; static size_t bufsize; typedef struct {long start, end;} Section; static void copy(FILE *, FILE *, Section *); static char *_has(char *, const char *); static void addfonts(char *); /*****************************************************************************/ void ps_include( const char *name, /* file name */ FILE *fin, FILE *fout, /* input and output files */ int page_no, /* physical page number from *fin */ int whiteout, /* erase picture area */ int outline, /* draw a box around it and */ int scaleboth, /* scale both dimensions - if not zero */ double cx, double cy, /* center of the picture and */ double sx, double sy, /* its size - in current coordinates */ double ax, double ay, /* left-right, up-down adjustment */ double rot /* rotation - in clockwise degrees */ ) { static int gotinclude; int foundpage = 0; /* found the page when non zero */ int nglobal = 0; /* number of global defs so far */ int maxglobal = 0; /* and the number we've got room for */ Section prolog, page, trailer; /* prologue, page, and trailer offsets */ Section *global = 0; /* offsets for all global definitions */ double llx, lly; /* lower left and */ double urx, ury; /* upper right corners - default coords */ double w = whiteout != 0; /* mostly for the var() macro */ double o = outline != 0; double s = scaleboth != 0; int i; /* loop index */ int lno = 0; int epsf = 0; int hires = 0; int state = 0; int indoc = 0; char *bp, *cp; enum { NORMAL, DOCUMENTFONTS, DOCUMENTNEEDEDRESOURCES, } cont = NORMAL; /* * * Reads a PostScript file (*fin), and uses structuring comments to locate the * prologue, trailer, global definitions, and the requested page. After the whole * file is scanned, the special ps_include PostScript definitions are copied to * *fout, followed by the prologue, global definitions, the requested page, and * the trailer. Before returning the initial environment (saved in PS_head) is * restored. * * By default we assume the picture is 8.5 by 11 inches, but the BoundingBox * comment, if found, takes precedence. * */ if (gotinclude == 0 && access(PSINCLUDEFILE, 04) == 0) { doglobal(PSINCLUDEFILE); gotinclude++; } llx = lly = 0; /* default BoundingBox - 8.5x11 inches */ urx = 72 * 8.5; ury = 72 * 11.0; /* section boundaries and bounding box */ prolog.start = prolog.end = 0; page.start = page.end = 0; trailer.start = 0; fseek(fin, 0L, SEEK_SET); while ( psgetline(&buf, &bufsize, NULL, fin) != NULL ) { if (++lno == 1 && strncmp(buf, "%!PS-", 5) == 0) { for (bp = buf; !spacechar(*bp&0377); bp++); while (*bp && *bp != '\n' && *bp != '\r' && spacechar(*bp&0377)) bp++; if (strncmp(bp, "EPSF-", 5) == 0) epsf++; } if (state == 0 && (*buf == '\n' || has("%%EndComments") || buf[0] != '%' || buf[1] == ' ' || buf[1] == '\t' || buf[1] == '\r' || buf[1] == '\n')) { state = 1; continue; } if (buf[0] != '%' || buf[1] != '%') continue; if (state != 1 && (bp = has("%%+")) != NULL) { switch (cont) { case DOCUMENTFONTS: addfonts(bp); break; case DOCUMENTNEEDEDRESOURCES: goto needres; } continue; } else cont = NORMAL; if (has("%%Page: ")) { if (!foundpage) page.start = ftell(fin); sscanf(buf, "%*s %*s %d", &i); if (i == page_no) foundpage = 1; else if (foundpage && page.end <= page.start) page.end = ftell(fin); } else if (has("%%EndPage: ")) { sscanf(buf, "%*s %*s %d", &i); if (i == page_no) { foundpage = 1; page.end = ftell(fin); } if (!foundpage) page.start = ftell(fin); } else if (state != 1 && !indoc && has("%%BoundingBox:") && !hires) { sscanf(buf, "%%%%BoundingBox: %lf %lf %lf %lf", &llx, &lly, &urx, &ury); if (epsf) epsf++; } else if (state != 1 && !indoc && has("%%HiResBoundingBox:")) { sscanf(buf, "%%%%HiResBoundingBox: %lf %lf %lf %lf", &llx, &lly, &urx, &ury); hires++; if (epsf) epsf++; } else if (has("%%LanguageLevel:")) { int n; sscanf(buf, "%%%%LanguageLevel: %d", &n); - LanguageLevel = MAX(LanguageLevel, n); + LanguageLevel = max(LanguageLevel, n); } else if ((bp = has("%%DocumentNeededFonts:")) != NULL || (bp = has("%%DocumentFonts:")) != NULL) { cont = DOCUMENTFONTS; addfonts(bp); } else if ((bp = has("%%DocumentNeededResources:")) != NULL) { needres: if ((cp = _has(bp, "font"))) addfonts(cp); else { for (cp = bp; *cp && *cp != '\n' && *cp != '\r'; cp++); *cp = '\0'; needresource("%s", bp); } cont = DOCUMENTNEEDEDRESOURCES; } else if (indoc == 0 && (has("%%EndProlog") || has("%%EndSetup") || has("%%EndDocumentSetup"))) prolog.end = page.start = ftell(fin); else if (indoc == 0 && has("%%EOF")) break; else if (state == 1 && indoc == 0 && has("%%Trailer")) { trailer.start = ftell(fin); state = 2; } else if (state == 1 && has("%%BeginDocument:")) indoc++; else if (state == 1 && indoc > 0 && has("%%EndDocument")) indoc--; else if (state == 1 && (cp = has("%%BeginBinary:")) != NULL) { if ((i = strtol(cp, &cp, 10)) > 0) psskip(i, fin); } else if (state == 1 && (cp = has("%%BeginData:")) != NULL) { if ((i = strtol(cp, &cp, 10)) > 0) { while (*cp == ' ' || *cp == '\t') cp++; while (*cp && *cp != ' ' && *cp != '\t') cp++; while (*cp == ' ' || *cp == '\t') cp++; if (strncmp(cp, "Bytes", 5) == 0) psskip(i, fin); else if (strncmp(cp, "Lines", 5) == 0) { while (i-- && psgetline(&buf, &bufsize, NULL, fin) != NULL); } } } else if (has("%%BeginGlobal")) { if (page.end <= page.start) { if (nglobal >= maxglobal) { maxglobal += 20; global = grab(maxglobal); } global[nglobal].start = ftell(fin); } } else if (has("%%EndGlobal")) if (page.end <= page.start) global[nglobal++].end = ftell(fin); } fseek(fin, 0L, SEEK_END); if (trailer.start == 0) trailer.start = ftell(fin); trailer.end = ftell(fin); if (page.end <= page.start) page.end = trailer.start; /* fprintf(stderr, "prolog=(%d,%d)\n", prolog.start, prolog.end); fprintf(stderr, "page=(%d,%d)\n", page.start, page.end); for(i = 0; i < nglobal; i++) fprintf(stderr, "global[%d]=(%d,%d)\n", i, global[i].start, global[i].end); fprintf(stderr, "trailer=(%d,%d)\n", trailer.start, trailer.end); */ /* all output here */ fprintf(fout, "_ps_include_head\n"); var(llx); var(lly); var(urx); var(ury); var(w); var(o); var(s); var(cx); var(cy); var(sx); var(sy); var(ax); var(ay); var(rot); fprintf(fout, "_ps_include_setup\n"); if (epsf >= 2) { size_t len; rewind(fin); fprintf(fout, "%%%%BeginDocument: %s\n", name); while (psgetline(&buf, &bufsize, &len, fin) != NULL) { if (has("%%BeginPreview:")) { while (psgetline(&buf, &bufsize, &len, fin) != NULL && !has("%%EndPreview")); continue; } fwrite(buf, 1, len, fout); } fprintf(fout, "%%%%EndDocument\n"); } else { copy(fin, fout, &prolog); for(i = 0; i < nglobal; i++) copy(fin, fout, &global[i]); copy(fin, fout, &page); copy(fin, fout, &trailer); } fprintf(fout, "_ps_include_tail\n"); if(nglobal) free(global); } static void copy(FILE *fin, FILE *fout, Section *s) { size_t len; if (s->end <= s->start) return; fseek(fin, s->start, SEEK_SET); while (ftell(fin) < s->end && psgetline(&buf, &bufsize, &len, fin) != NULL) { if (buf[0] == '%') putc(' ', fout); fwrite(buf, 1, len, fout); } } static char * _has(char *buffer, const char *word) { int n; n = strlen(word); if (strncmp(buffer, word, n) != 0) return NULL; if (buffer[n] == ' ' || buffer[n] == '\t' || buffer[n] == '\r' || buffer[n] == '\n' || buffer[n] == 0) { while (buffer[n] == ' ' || buffer[n] == '\t') n++; return &buffer[n]; } return NULL; } static void addfonts(char *line) { char *lp = line, c; do { while (*lp == ' ' || *lp == '\t') lp++; line = lp; while (*lp && *lp != ' ' && *lp != '\t' && *lp != '\n' && *lp != '\r') lp++; c = *lp; *lp = '\0'; if (*line && strcmp(line, "(atend)")) documentfont(line); *lp = c; } while (c && c != '\n' && c != '\r'); } Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/request.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/request.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/request.c (revision 307812) @@ -1,182 +1,182 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "request.c 1.5 05/06/08 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)request.c 1.3 (gritter) 8/9/05 */ /* * * Things used to handle special requests (eg. manual feed) globally or on a per * page basis. Requests are passed through to the translator using the -R option. * The argument to -R can be "request", "request:page", or "request:page:file". * If page is omitted (as in the first form) or set to 0 request will be applied * to the global environment. In all other cases it applies only to the selected * page. If a file is given, page must be supplied, and the lookup is in that file * rather than *requestfile. * */ #include #include #include #include "gen.h" /* general purpose definitions */ #include "request.h" /* a few special definitions */ #include "path.h" /* for the default request file */ static Request request[MAXREQUEST]; /* next page or global request */ static int nextreq = 0; /* goes in request[nextreq] */ static const char *requestfile = REQUESTFILE; /* default lookup file */ /*****************************************************************************/ void saverequest ( char *want /* grab code for this stuff */ ) { char *page; /* and save it for this page */ /* * * Save the request until we get to appropriate page - don't even bother with * the lookup right now. Format of *want string is "request", "request:page", or * "request:page:file", and we assume we can change the string here as needed. * If page is omitted or given as 0 the request will be done globally. If *want * includes a file, request and page must also be given, and in that case *file * will be used for the lookup. * */ if ( nextreq < MAXREQUEST ) { request[nextreq].want = strtok(want, ": "); if ( (page = strtok(NULL, ": ")) == NULL ) request[nextreq].page = 0; else request[nextreq].page = atoi(page); if ( (request[nextreq].file = strtok(NULL, ": ")) == NULL ) request[nextreq].file = requestfile; nextreq++; } else error(NON_FATAL, "too many requests - ignoring %s", want); } /* End of saverequest */ /*****************************************************************************/ void writerequest( int page, /* write everything for this page */ FILE *fp_out /* to this file */ ) { int i; /* loop index */ /* * * Writes out all the requests that have been saved for page. Page 0 refers to * the global environment and is done during initial setup. * */ for ( i = 0; i < nextreq; i++ ) if ( request[i].page == page ) dumprequest(request[i].want, request[i].file, fp_out); } /* End of writerequest */ /*****************************************************************************/ void dumprequest( char *want, /* look for this string */ - char *file, /* in this file */ + const char *file, /* in this file */ FILE *fp_out /* and write the value out here */ ) { char buf[100]; /* line buffer for reading *file */ FILE *fp_in; /* * * Looks for *want in the request file and if it's found the associated value * is copied to the output file. Keywords (ie. the *want strings) begin an @ in * the first column of file, while the values (ie. the stuff that's copied to * the output file) starts on the next line and extends to the next keyword or * to the end of file. * */ if ( (fp_in = fopen(file, "r")) != NULL ) { while ( fgets(buf, sizeof(buf), fp_in) != NULL ) if ( buf[0] == '@' && strncmp(want, &buf[1], strlen(want)) == 0 ) while ( fgets(buf, sizeof(buf), fp_in) != NULL ) { if ( buf[0] == '#' || buf[0] == '%' ) continue; else if ( buf[0] != '@' ) fprintf(fp_out, "%s", buf); else break; } fclose(fp_in); } /* End if */ } /* End of dumprequest */ /*****************************************************************************/ Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/request.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/request.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/request.h (revision 307812) @@ -1,58 +1,58 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "request.h 1.5 05/06/08 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)request.h 1.3 (gritter) 8/9/05 */ /* * * Things used to handle special PostScript requests (like manual feed) globally * or on a per page basis. All the translators I've supplied accept the -R option * that can be used to insert special PostScript code before the global setup is * done, or at the start of named pages. The argument to the -R option is a string * that can be "request", "request:page", or "request:page:file". If page isn't * given (as in the first form) or if it's 0 in the last two, the request applies * to the global environment, otherwise request holds only for the named page. * If a file name is given a page number must be supplied, and in that case the * request will be looked up in that file. * */ #define MAXREQUEST 30 typedef struct { char *want; int page; - char *file; + const char *file; } Request; Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/fontmap.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/fontmap.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/fontmap.c (revision 307812) @@ -1,158 +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 #include #include #include #include #include #include #include #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; static 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) { +const char * +mapft(const 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); } Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/fontmap.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/fontmap.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/fontmap.h (revision 307812) @@ -1,2 +1,2 @@ void rdftmap(char *); -char *mapft(char *); +const char *mapft(const char *); Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/otf.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/otf.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/otf.c (revision 307812) @@ -1,3608 +1,3608 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)otf.c 1.68 (gritter) 3/17/10 */ #include #include #include #include #include #include #include #include #include #include #include #include #include "dev.h" #include "afm.h" #ifndef __unused #define __unused __attribute__((unused)) #endif extern struct dev dev; extern char *chname; extern short *chtab; extern int nchtab; extern void errprint(const char *, ...); extern void verrprint(const char *, va_list); static jmp_buf breakpoint; static char *contents; static size_t size; static unsigned short numTables; static int ttf; static const char *filename; unsigned short unitsPerEm; static short xMin, yMin, xMax, yMax; static short indexToLocFormat; static struct afmtab *a; static int nc; static int fsType; static int WeightClass; static int isFixedPitch; static int minMemType42; static int maxMemType42; static int numGlyphs; static char *PostScript_name; static char *Copyright; static char *Notice; static struct table_directory { char tag[4]; unsigned long checkSum; unsigned long offset; unsigned long length; } *table_directories; static int pos_CFF; static int pos_head; static int pos_hhea; static int pos_loca; static int pos_prep; static int pos_fpgm; static int pos_vhea; static int pos_glyf; static int pos_cvt; static int pos_maxp; static int pos_vmtx; static int pos_hmtx; static int pos_OS_2; static int pos_GSUB; static int pos_GPOS; static int pos_post; static int pos_kern; static int pos_name; static int pos_cmap; static struct table { const char *name; int *pos; int in_sfnts; uint32_t checksum; } tables[] = { { "CFF ", &pos_CFF, 0, 0 }, { "cmap", &pos_cmap, 0, 0 }, { "cvt ", &pos_cvt, 1, 0 }, { "fpgm", &pos_fpgm, 1, 0 }, { "GPOS", &pos_GPOS, 0, 0 }, { "GSUB", &pos_GSUB, 0, 0 }, { "head", &pos_head, 2, 0 }, { "hhea", &pos_hhea, 1, 0 }, { "hmtx", &pos_hmtx, 1, 0 }, { "kern", &pos_kern, 0, 0 }, { "loca", &pos_loca, 1, 0 }, { "maxp", &pos_maxp, 1, 0 }, { "name", &pos_name, 0, 0 }, { "OS/2", &pos_OS_2, 0, 0 }, { "post", &pos_post, 0, 0 }, { "prep", &pos_prep, 1, 0 }, { "vhea", &pos_vhea, 1, 0 }, { "vmtx", &pos_vmtx, 1, 0 }, { "glyf", &pos_glyf, 3, 0 }, /* holds glyph data */ { NULL, NULL, 0, 0 } }; static unsigned short *gid2sid; struct INDEX { unsigned short count; int offSize; int *offset; char *data; }; static struct CFF { struct INDEX *Name; struct INDEX *Top_DICT; struct INDEX *String; struct INDEX *Global_Subr; struct INDEX *CharStrings; int Charset; int baseoffset; } CFF; static const int ExpertCharset[] = { 0, 1, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 158, 155, 163, 319, 320, 321, 322, 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378 }; static const int ExpertSubsetCharset[] = { 0, 1, 231, 232, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, 251, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, 269, 270, 272, 300, 301, 302, 305, 314, 315, 158, 155, 163, 320, 321, 322, 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346 }; static const char *const StandardStrings[] = { ".notdef", /* 0 */ "space", /* 1 */ "exclam", /* 2 */ "quotedbl", /* 3 */ "numbersign", /* 4 */ "dollar", /* 5 */ "percent", /* 6 */ "ampersand", /* 7 */ "quoteright", /* 8 */ "parenleft", /* 9 */ "parenright", /* 10 */ "asterisk", /* 11 */ "plus", /* 12 */ "comma", /* 13 */ "hyphen", /* 14 */ "period", /* 15 */ "slash", /* 16 */ "zero", /* 17 */ "one", /* 18 */ "two", /* 19 */ "three", /* 20 */ "four", /* 21 */ "five", /* 22 */ "six", /* 23 */ "seven", /* 24 */ "eight", /* 25 */ "nine", /* 26 */ "colon", /* 27 */ "semicolon", /* 28 */ "less", /* 29 */ "equal", /* 30 */ "greater", /* 31 */ "question", /* 32 */ "at", /* 33 */ "A", /* 34 */ "B", /* 35 */ "C", /* 36 */ "D", /* 37 */ "E", /* 38 */ "F", /* 39 */ "G", /* 40 */ "H", /* 41 */ "I", /* 42 */ "J", /* 43 */ "K", /* 44 */ "L", /* 45 */ "M", /* 46 */ "N", /* 47 */ "O", /* 48 */ "P", /* 49 */ "Q", /* 50 */ "R", /* 51 */ "S", /* 52 */ "T", /* 53 */ "U", /* 54 */ "V", /* 55 */ "W", /* 56 */ "X", /* 57 */ "Y", /* 58 */ "Z", /* 59 */ "bracketleft", /* 60 */ "backslash", /* 61 */ "bracketright", /* 62 */ "asciicircum", /* 63 */ "underscore", /* 64 */ "quoteleft", /* 65 */ "a", /* 66 */ "b", /* 67 */ "c", /* 68 */ "d", /* 69 */ "e", /* 70 */ "f", /* 71 */ "g", /* 72 */ "h", /* 73 */ "i", /* 74 */ "j", /* 75 */ "k", /* 76 */ "l", /* 77 */ "m", /* 78 */ "n", /* 79 */ "o", /* 80 */ "p", /* 81 */ "q", /* 82 */ "r", /* 83 */ "s", /* 84 */ "t", /* 85 */ "u", /* 86 */ "v", /* 87 */ "w", /* 88 */ "x", /* 89 */ "y", /* 90 */ "z", /* 91 */ "braceleft", /* 92 */ "bar", /* 93 */ "braceright", /* 94 */ "asciitilde", /* 95 */ "exclamdown", /* 96 */ "cent", /* 97 */ "sterling", /* 98 */ "fraction", /* 99 */ "yen", /* 100 */ "florin", /* 101 */ "section", /* 102 */ "currency", /* 103 */ "quotesingle", /* 104 */ "quotedblleft", /* 105 */ "guillemotleft", /* 106 */ "guilsinglleft", /* 107 */ "guilsinglright", /* 108 */ "fi", /* 109 */ "fl", /* 110 */ "endash", /* 111 */ "dagger", /* 112 */ "daggerdbl", /* 113 */ "periodcentered", /* 114 */ "paragraph", /* 115 */ "bullet", /* 116 */ "quotesinglbase", /* 117 */ "quotedblbase", /* 118 */ "quotedblright", /* 119 */ "guillemotright", /* 120 */ "ellipsis", /* 121 */ "perthousand", /* 122 */ "questiondown", /* 123 */ "grave", /* 124 */ "acute", /* 125 */ "circumflex", /* 126 */ "tilde", /* 127 */ "macron", /* 128 */ "breve", /* 129 */ "dotaccent", /* 130 */ "dieresis", /* 131 */ "ring", /* 132 */ "cedilla", /* 133 */ "hungarumlaut", /* 134 */ "ogonek", /* 135 */ "caron", /* 136 */ "emdash", /* 137 */ "AE", /* 138 */ "ordfeminine", /* 139 */ "Lslash", /* 140 */ "Oslash", /* 141 */ "OE", /* 142 */ "ordmasculine", /* 143 */ "ae", /* 144 */ "dotlessi", /* 145 */ "lslash", /* 146 */ "oslash", /* 147 */ "oe", /* 148 */ "germandbls", /* 149 */ "onesuperior", /* 150 */ "logicalnot", /* 151 */ "mu", /* 152 */ "trademark", /* 153 */ "Eth", /* 154 */ "onehalf", /* 155 */ "plusminus", /* 156 */ "Thorn", /* 157 */ "onequarter", /* 158 */ "divide", /* 159 */ "brokenbar", /* 160 */ "degree", /* 161 */ "thorn", /* 162 */ "threequarters", /* 163 */ "twosuperior", /* 164 */ "registered", /* 165 */ "minus", /* 166 */ "eth", /* 167 */ "multiply", /* 168 */ "threesuperior", /* 169 */ "copyright", /* 170 */ "Aacute", /* 171 */ "Acircumflex", /* 172 */ "Adieresis", /* 173 */ "Agrave", /* 174 */ "Aring", /* 175 */ "Atilde", /* 176 */ "Ccedilla", /* 177 */ "Eacute", /* 178 */ "Ecircumflex", /* 179 */ "Edieresis", /* 180 */ "Egrave", /* 181 */ "Iacute", /* 182 */ "Icircumflex", /* 183 */ "Idieresis", /* 184 */ "Igrave", /* 185 */ "Ntilde", /* 186 */ "Oacute", /* 187 */ "Ocircumflex", /* 188 */ "Odieresis", /* 189 */ "Ograve", /* 190 */ "Otilde", /* 191 */ "Scaron", /* 192 */ "Uacute", /* 193 */ "Ucircumflex", /* 194 */ "Udieresis", /* 195 */ "Ugrave", /* 196 */ "Yacute", /* 197 */ "Ydieresis", /* 198 */ "Zcaron", /* 199 */ "aacute", /* 200 */ "acircumflex", /* 201 */ "adieresis", /* 202 */ "agrave", /* 203 */ "aring", /* 204 */ "atilde", /* 205 */ "ccedilla", /* 206 */ "eacute", /* 207 */ "ecircumflex", /* 208 */ "edieresis", /* 209 */ "egrave", /* 210 */ "iacute", /* 211 */ "icircumflex", /* 212 */ "idieresis", /* 213 */ "igrave", /* 214 */ "ntilde", /* 215 */ "oacute", /* 216 */ "ocircumflex", /* 217 */ "odieresis", /* 218 */ "ograve", /* 219 */ "otilde", /* 220 */ "scaron", /* 221 */ "uacute", /* 222 */ "ucircumflex", /* 223 */ "udieresis", /* 224 */ "ugrave", /* 225 */ "yacute", /* 226 */ "ydieresis", /* 227 */ "zcaron", /* 228 */ "exclamsmall", /* 229 */ "Hungarumlautsmall", /* 230 */ "dollaroldstyle", /* 231 */ "dollarsuperior", /* 232 */ "ampersandsmall", /* 233 */ "Acutesmall", /* 234 */ "parenleftsuperior", /* 235 */ "parenrightsuperior", /* 236 */ "twodotenleader", /* 237 */ "onedotenleader", /* 238 */ "zerooldstyle", /* 239 */ "oneoldstyle", /* 240 */ "twooldstyle", /* 241 */ "threeoldstyle", /* 242 */ "fouroldstyle", /* 243 */ "fiveoldstyle", /* 244 */ "sixoldstyle", /* 245 */ "sevenoldstyle", /* 246 */ "eightoldstyle", /* 247 */ "nineoldstyle", /* 248 */ "commasuperior", /* 249 */ "threequartersemdash", /* 250 */ "periodsuperior", /* 251 */ "questionsmall", /* 252 */ "asuperior", /* 253 */ "bsuperior", /* 254 */ "centsuperior", /* 255 */ "dsuperior", /* 256 */ "esuperior", /* 257 */ "isuperior", /* 258 */ "lsuperior", /* 259 */ "msuperior", /* 260 */ "nsuperior", /* 261 */ "osuperior", /* 262 */ "rsuperior", /* 263 */ "ssuperior", /* 264 */ "tsuperior", /* 265 */ "ff", /* 266 */ "ffi", /* 267 */ "ffl", /* 268 */ "parenleftinferior", /* 269 */ "parenrightinferior", /* 270 */ "Circumflexsmall", /* 271 */ "hyphensuperior", /* 272 */ "Gravesmall", /* 273 */ "Asmall", /* 274 */ "Bsmall", /* 275 */ "Csmall", /* 276 */ "Dsmall", /* 277 */ "Esmall", /* 278 */ "Fsmall", /* 279 */ "Gsmall", /* 280 */ "Hsmall", /* 281 */ "Ismall", /* 282 */ "Jsmall", /* 283 */ "Ksmall", /* 284 */ "Lsmall", /* 285 */ "Msmall", /* 286 */ "Nsmall", /* 287 */ "Osmall", /* 288 */ "Psmall", /* 289 */ "Qsmall", /* 290 */ "Rsmall", /* 291 */ "Ssmall", /* 292 */ "Tsmall", /* 293 */ "Usmall", /* 294 */ "Vsmall", /* 295 */ "Wsmall", /* 296 */ "Xsmall", /* 297 */ "Ysmall", /* 298 */ "Zsmall", /* 299 */ "colonmonetary", /* 300 */ "onefitted", /* 301 */ "rupiah", /* 302 */ "Tildesmall", /* 303 */ "exclamdownsmall", /* 304 */ "centoldstyle", /* 305 */ "Lslashsmall", /* 306 */ "Scaronsmall", /* 307 */ "Zcaronsmall", /* 308 */ "Dieresissmall", /* 309 */ "Brevesmall", /* 310 */ "Caronsmall", /* 311 */ "Dotaccentsmall", /* 312 */ "Macronsmall", /* 313 */ "figuredash", /* 314 */ "hypheninferior", /* 315 */ "Ogoneksmall", /* 316 */ "Ringsmall", /* 317 */ "Cedillasmall", /* 318 */ "questiondownsmall", /* 319 */ "oneeighth", /* 320 */ "threeeighths", /* 321 */ "fiveeighths", /* 322 */ "seveneighths", /* 323 */ "onethird", /* 324 */ "twothirds", /* 325 */ "zerosuperior", /* 326 */ "foursuperior", /* 327 */ "fivesuperior", /* 328 */ "sixsuperior", /* 329 */ "sevensuperior", /* 330 */ "eightsuperior", /* 331 */ "ninesuperior", /* 332 */ "zeroinferior", /* 333 */ "oneinferior", /* 334 */ "twoinferior", /* 335 */ "threeinferior", /* 336 */ "fourinferior", /* 337 */ "fiveinferior", /* 338 */ "sixinferior", /* 339 */ "seveninferior", /* 340 */ "eightinferior", /* 341 */ "nineinferior", /* 342 */ "centinferior", /* 343 */ "dollarinferior", /* 344 */ "periodinferior", /* 345 */ "commainferior", /* 346 */ "Agravesmall", /* 347 */ "Aacutesmall", /* 348 */ "Acircumflexsmall", /* 349 */ "Atildesmall", /* 350 */ "Adieresissmall", /* 351 */ "Aringsmall", /* 352 */ "AEsmall", /* 353 */ "Ccedillasmall", /* 354 */ "Egravesmall", /* 355 */ "Eacutesmall", /* 356 */ "Ecircumflexsmall", /* 357 */ "Edieresissmall", /* 358 */ "Igravesmall", /* 359 */ "Iacutesmall", /* 360 */ "Icircumflexsmall", /* 361 */ "Idieresissmall", /* 362 */ "Ethsmall", /* 363 */ "Ntildesmall", /* 364 */ "Ogravesmall", /* 365 */ "Oacutesmall", /* 366 */ "Ocircumflexsmall", /* 367 */ "Otildesmall", /* 368 */ "Odieresissmall", /* 369 */ "OEsmall", /* 370 */ "Oslashsmall", /* 371 */ "Ugravesmall", /* 372 */ "Uacutesmall", /* 373 */ "Ucircumflexsmall", /* 374 */ "Udieresissmall", /* 375 */ "Yacutesmall", /* 376 */ "Thornsmall", /* 377 */ "Ydieresissmall", /* 378 */ "001.000", /* 379 */ "001.001", /* 380 */ "001.002", /* 381 */ "001.003", /* 382 */ "Black", /* 383 */ "Bold", /* 384 */ "Book", /* 385 */ "Light", /* 386 */ "Medium", /* 387 */ "Regular", /* 388 */ "Roman", /* 389 */ "Semibold" /* 390 */ }; static const int nStdStrings = 391; static const char *const MacintoshStrings[] = { ".notdef", /* 0 */ ".null", /* 1 */ "nonmarkingreturn", /* 2 */ "space", /* 3 */ "exclam", /* 4 */ "quotedbl", /* 5 */ "numbersign", /* 6 */ "dollar", /* 7 */ "percent", /* 8 */ "ampersand", /* 9 */ "quotesingle", /* 10 */ "parenleft", /* 11 */ "parenright", /* 12 */ "asterisk", /* 13 */ "plus", /* 14 */ "comma", /* 15 */ "hyphen", /* 16 */ "period", /* 17 */ "slash", /* 18 */ "zero", /* 19 */ "one", /* 20 */ "two", /* 21 */ "three", /* 22 */ "four", /* 23 */ "five", /* 24 */ "six", /* 25 */ "seven", /* 26 */ "eight", /* 27 */ "nine", /* 28 */ "colon", /* 29 */ "semicolon", /* 30 */ "less", /* 31 */ "equal", /* 32 */ "greater", /* 33 */ "question", /* 34 */ "at", /* 35 */ "A", /* 36 */ "B", /* 37 */ "C", /* 38 */ "D", /* 39 */ "E", /* 40 */ "F", /* 41 */ "G", /* 42 */ "H", /* 43 */ "I", /* 44 */ "J", /* 45 */ "K", /* 46 */ "L", /* 47 */ "M", /* 48 */ "N", /* 49 */ "O", /* 50 */ "P", /* 51 */ "Q", /* 52 */ "R", /* 53 */ "S", /* 54 */ "T", /* 55 */ "U", /* 56 */ "V", /* 57 */ "W", /* 58 */ "X", /* 59 */ "Y", /* 60 */ "Z", /* 61 */ "bracketleft", /* 62 */ "backslash", /* 63 */ "bracketright", /* 64 */ "asciicircum", /* 65 */ "underscore", /* 66 */ "grave", /* 67 */ "a", /* 68 */ "b", /* 69 */ "c", /* 70 */ "d", /* 71 */ "e", /* 72 */ "f", /* 73 */ "g", /* 74 */ "h", /* 75 */ "i", /* 76 */ "j", /* 77 */ "k", /* 78 */ "l", /* 79 */ "m", /* 80 */ "n", /* 81 */ "o", /* 82 */ "p", /* 83 */ "q", /* 84 */ "r", /* 85 */ "s", /* 86 */ "t", /* 87 */ "u", /* 88 */ "v", /* 89 */ "w", /* 90 */ "x", /* 91 */ "y", /* 92 */ "z", /* 93 */ "braceleft", /* 94 */ "bar", /* 95 */ "braceright", /* 96 */ "asciitilde", /* 97 */ "Adieresis", /* 98 */ "Aring", /* 99 */ "Ccedilla", /* 100 */ "Eacute", /* 101 */ "Ntilde", /* 102 */ "Odieresis", /* 103 */ "Udieresis", /* 104 */ "aacute", /* 105 */ "agrave", /* 106 */ "acircumflex", /* 107 */ "adieresis", /* 108 */ "atilde", /* 109 */ "aring", /* 110 */ "ccedilla", /* 111 */ "eacute", /* 112 */ "egrave", /* 113 */ "ecircumflex", /* 114 */ "edieresis", /* 115 */ "iacute", /* 116 */ "igrave", /* 117 */ "icircumflex", /* 118 */ "idieresis", /* 119 */ "ntilde", /* 120 */ "oacute", /* 121 */ "ograve", /* 122 */ "ocircumflex", /* 123 */ "odieresis", /* 124 */ "otilde", /* 125 */ "uacute", /* 126 */ "ugrave", /* 127 */ "ucircumflex", /* 128 */ "udieresis", /* 129 */ "dagger", /* 130 */ "degree", /* 131 */ "cent", /* 132 */ "sterling", /* 133 */ "section", /* 134 */ "bullet", /* 135 */ "paragraph", /* 136 */ "germandbls", /* 137 */ "registered", /* 138 */ "copyright", /* 139 */ "trademark", /* 140 */ "acute", /* 141 */ "dieresis", /* 142 */ "notequal", /* 143 */ "AE", /* 144 */ "Oslash", /* 145 */ "infinity", /* 146 */ "plusminus", /* 147 */ "lessequal", /* 148 */ "greaterequal", /* 149 */ "yen", /* 150 */ "mu", /* 151 */ "partialdiff", /* 152 */ "summation", /* 153 */ "product", /* 154 */ "pi", /* 155 */ "integral", /* 156 */ "ordfeminine", /* 157 */ "ordmasculine", /* 158 */ "Omega", /* 159 */ "ae", /* 160 */ "oslash", /* 161 */ "questiondown", /* 162 */ "exclamdown", /* 163 */ "logicalnot", /* 164 */ "radical", /* 165 */ "florin", /* 166 */ "approxequal", /* 167 */ "Delta", /* 168 */ "guillemotleft", /* 169 */ "guillemotright", /* 170 */ "ellipsis", /* 171 */ "nonbreakingspace", /* 172 */ "Agrave", /* 173 */ "Atilde", /* 174 */ "Otilde", /* 175 */ "OE", /* 176 */ "oe", /* 177 */ "endash", /* 178 */ "emdash", /* 179 */ "quotedblleft", /* 180 */ "quotedblright", /* 181 */ "quoteleft", /* 182 */ "quoteright", /* 183 */ "divide", /* 184 */ "lozenge", /* 185 */ "ydieresis", /* 186 */ "Ydieresis", /* 187 */ "fraction", /* 188 */ "currency", /* 189 */ "guilsinglleft", /* 190 */ "guilsinglright", /* 191 */ "fi", /* 192 */ "fl", /* 193 */ "daggerdbl", /* 194 */ "periodcentered", /* 195 */ "quotesinglbase", /* 196 */ "quotedblbase", /* 197 */ "perthousand", /* 198 */ "Acircumflex", /* 199 */ "Ecircumflex", /* 200 */ "Aacute", /* 201 */ "Edieresis", /* 202 */ "Egrave", /* 203 */ "Iacute", /* 204 */ "Icircumflex", /* 205 */ "Idieresis", /* 206 */ "Igrave", /* 207 */ "Oacute", /* 208 */ "Ocircumflex", /* 209 */ "apple", /* 210 */ "Ograve", /* 211 */ "Uacute", /* 212 */ "Ucircumflex", /* 213 */ "Ugrave", /* 214 */ "dotlessi", /* 215 */ "circumflex", /* 216 */ "tilde", /* 217 */ "macron", /* 218 */ "breve", /* 219 */ "dotaccent", /* 220 */ "ring", /* 221 */ "cedilla", /* 222 */ "hungarumlaut", /* 223 */ "ogonek", /* 224 */ "caron", /* 225 */ "Lslash", /* 226 */ "lslash", /* 227 */ "Scaron", /* 228 */ "scaron", /* 229 */ "Zcaron", /* 230 */ "zcaron", /* 231 */ "brokenbar", /* 232 */ "Eth", /* 233 */ "eth", /* 234 */ "Yacute", /* 235 */ "yacute", /* 236 */ "Thorn", /* 237 */ "thorn", /* 238 */ "minus", /* 239 */ "multiply", /* 240 */ "onesuperior", /* 241 */ "twosuperior", /* 242 */ "threesuperior", /* 243 */ "onehalf", /* 244 */ "onequarter", /* 245 */ "threequarters", /* 246 */ "franc", /* 247 */ "Gbreve", /* 248 */ "gbreve", /* 249 */ "Idotaccent", /* 250 */ "Scedilla", /* 251 */ "scedilla", /* 252 */ "Cacute", /* 253 */ "cacute", /* 254 */ "Ccaron", /* 255 */ "ccaron", /* 256 */ "dcroat" /* 257 */ }; static const int nMacintoshStrings = 258; static const struct WGL { int u; const char *s; } WGL[] = { /* WGL4 */ { 0x0000, ".notdef" }, { 0x0020, "space" }, { 0x0021, "exclam" }, { 0x0022, "quotedbl" }, { 0x0023, "numbersign" }, { 0x0024, "dollar" }, { 0x0025, "percent" }, { 0x0026, "ampersand" }, { 0x0027, "quotesingle" }, { 0x0028, "parenleft" }, { 0x0029, "parenright" }, { 0x002a, "asterisk" }, { 0x002b, "plus" }, { 0x002c, "comma" }, { 0x002d, "hyphen" }, { 0x002e, "period" }, { 0x002f, "slash" }, { 0x0030, "zero" }, { 0x0031, "one" }, { 0x0032, "two" }, { 0x0033, "three" }, { 0x0034, "four" }, { 0x0035, "five" }, { 0x0036, "six" }, { 0x0037, "seven" }, { 0x0038, "eight" }, { 0x0039, "nine" }, { 0x003a, "colon" }, { 0x003b, "semicolon" }, { 0x003c, "less" }, { 0x003d, "equal" }, { 0x003e, "greater" }, { 0x003f, "question" }, { 0x0040, "at" }, { 0x0041, "A" }, { 0x0042, "B" }, { 0x0043, "C" }, { 0x0044, "D" }, { 0x0045, "E" }, { 0x0046, "F" }, { 0x0047, "G" }, { 0x0048, "H" }, { 0x0049, "I" }, { 0x004a, "J" }, { 0x004b, "K" }, { 0x004c, "L" }, { 0x004d, "M" }, { 0x004e, "N" }, { 0x004f, "O" }, { 0x0050, "P" }, { 0x0051, "Q" }, { 0x0052, "R" }, { 0x0053, "S" }, { 0x0054, "T" }, { 0x0055, "U" }, { 0x0056, "V" }, { 0x0057, "W" }, { 0x0058, "X" }, { 0x0059, "Y" }, { 0x005a, "Z" }, { 0x005b, "bracketleft" }, { 0x005c, "backslash" }, { 0x005d, "bracketright" }, { 0x005e, "asciicircum" }, { 0x005f, "underscore" }, { 0x0060, "grave" }, { 0x0061, "a" }, { 0x0062, "b" }, { 0x0063, "c" }, { 0x0064, "d" }, { 0x0065, "e" }, { 0x0066, "f" }, { 0x0067, "g" }, { 0x0068, "h" }, { 0x0069, "i" }, { 0x006a, "j" }, { 0x006b, "k" }, { 0x006c, "l" }, { 0x006d, "m" }, { 0x006e, "n" }, { 0x006f, "o" }, { 0x0070, "p" }, { 0x0071, "q" }, { 0x0072, "r" }, { 0x0073, "s" }, { 0x0074, "t" }, { 0x0075, "u" }, { 0x0076, "v" }, { 0x0077, "w" }, { 0x0078, "x" }, { 0x0079, "y" }, { 0x007a, "z" }, { 0x007b, "braceleft" }, { 0x007c, "bar" }, { 0x007d, "braceright" }, { 0x007e, "asciitilde" }, { 0x00a1, "exclamdown" }, { 0x00a2, "cent" }, { 0x00a3, "sterling" }, { 0x00a4, "currency" }, { 0x00a5, "yen" }, { 0x00a6, "brokenbar" }, { 0x00a7, "section" }, { 0x00a8, "dieresis" }, { 0x00a9, "copyright" }, { 0x00aa, "ordfeminine" }, { 0x00ab, "guillemotleft" }, { 0x00ac, "logicalnot" }, { 0x00ae, "registered" }, { 0x00af, "macron" }, { 0x00b0, "degree" }, { 0x00b1, "plusminus" }, { 0x00b2, "twosuperior" }, { 0x00b3, "threesuperior" }, { 0x00b4, "acute" }, { 0x00b5, "mu" }, { 0x00b6, "paragraph" }, { 0x00b7, "periodcentered" }, { 0x00b8, "cedilla" }, { 0x00b9, "onesuperior" }, { 0x00ba, "ordmasculine" }, { 0x00bb, "guillemotright" }, { 0x00bc, "onequarter" }, { 0x00bd, "onehalf" }, { 0x00be, "threequarters" }, { 0x00bf, "questiondown" }, { 0x00c0, "Agrave" }, { 0x00c1, "Aacute" }, { 0x00c2, "Acircumflex" }, { 0x00c3, "Atilde" }, { 0x00c4, "Adieresis" }, { 0x00c5, "Aring" }, { 0x00c6, "AE" }, { 0x00c7, "Ccedilla" }, { 0x00c8, "Egrave" }, { 0x00c9, "Eacute" }, { 0x00ca, "Ecircumflex" }, { 0x00cb, "Edieresis" }, { 0x00cc, "Igrave" }, { 0x00cd, "Iacute" }, { 0x00ce, "Icircumflex" }, { 0x00cf, "Idieresis" }, { 0x00d0, "Eth" }, { 0x00d1, "Ntilde" }, { 0x00d2, "Ograve" }, { 0x00d3, "Oacute" }, { 0x00d4, "Ocircumflex" }, { 0x00d5, "Otilde" }, { 0x00d6, "Odieresis" }, { 0x00d7, "multiply" }, { 0x00d8, "Oslash" }, { 0x00d9, "Ugrave" }, { 0x00da, "Uacute" }, { 0x00db, "Ucircumflex" }, { 0x00dc, "Udieresis" }, { 0x00dd, "Yacute" }, { 0x00de, "Thorn" }, { 0x00df, "germandbls" }, { 0x00e0, "agrave" }, { 0x00e1, "aacute" }, { 0x00e2, "acircumflex" }, { 0x00e3, "atilde" }, { 0x00e4, "adieresis" }, { 0x00e5, "aring" }, { 0x00e6, "ae" }, { 0x00e7, "ccedilla" }, { 0x00e8, "egrave" }, { 0x00e9, "eacute" }, { 0x00ea, "ecircumflex" }, { 0x00eb, "edieresis" }, { 0x00ec, "igrave" }, { 0x00ed, "iacute" }, { 0x00ee, "icircumflex" }, { 0x00ef, "idieresis" }, { 0x00f0, "eth" }, { 0x00f1, "ntilde" }, { 0x00f2, "ograve" }, { 0x00f3, "oacute" }, { 0x00f4, "ocircumflex" }, { 0x00f5, "otilde" }, { 0x00f6, "odieresis" }, { 0x00f7, "divide" }, { 0x00f8, "oslash" }, { 0x00f9, "ugrave" }, { 0x00fa, "uacute" }, { 0x00fb, "ucircumflex" }, { 0x00fc, "udieresis" }, { 0x00fd, "yacute" }, { 0x00fe, "thorn" }, { 0x00ff, "ydieresis" }, { 0x0100, "Amacron" }, { 0x0101, "amacron" }, { 0x0102, "Abreve" }, { 0x0103, "abreve" }, { 0x0104, "Aogonek" }, { 0x0105, "aogonek" }, { 0x0106, "Cacute" }, { 0x0107, "cacute" }, { 0x0108, "Ccircumflex" }, { 0x0109, "ccircumflex" }, { 0x010a, "Cdotaccent" }, { 0x010b, "cdotaccent" }, { 0x010c, "Ccaron" }, { 0x010d, "ccaron" }, { 0x010e, "Dcaron" }, { 0x010f, "dcaron" }, { 0x0110, "Dcroat" }, { 0x0111, "dcroat" }, { 0x0112, "Emacron" }, { 0x0113, "emacron" }, { 0x0114, "Ebreve" }, { 0x0115, "ebreve" }, { 0x0116, "Edotaccent" }, { 0x0117, "edotaccent" }, { 0x0118, "Eogonek" }, { 0x0119, "eogonek" }, { 0x011a, "Ecaron" }, { 0x011b, "ecaron" }, { 0x011c, "Gcircumflex" }, { 0x011d, "gcircumflex" }, { 0x011e, "Gbreve" }, { 0x011f, "gbreve" }, { 0x0120, "Gdotaccent" }, { 0x0121, "gdotaccent" }, { 0x0122, "Gcommaaccent" }, { 0x0123, "gcommaaccent" }, { 0x0124, "Hcircumflex" }, { 0x0125, "hcircumflex" }, { 0x0126, "Hbar" }, { 0x0127, "hbar" }, { 0x0128, "Itilde" }, { 0x0129, "itilde" }, { 0x012a, "Imacron" }, { 0x012b, "imacron" }, { 0x012c, "Ibreve" }, { 0x012d, "ibreve" }, { 0x012e, "Iogonek" }, { 0x012f, "iogonek" }, { 0x0130, "Idotaccent" }, { 0x0131, "dotlessi" }, { 0x0132, "IJ" }, { 0x0133, "ij" }, { 0x0134, "Jcircumflex" }, { 0x0135, "jcircumflex" }, { 0x0136, "Kcommaaccent" }, { 0x0137, "kcommaaccent" }, { 0x0138, "kgreenlandic" }, { 0x0139, "Lacute" }, { 0x013a, "lacute" }, { 0x013b, "Lcommaaccent" }, { 0x013c, "lcommaaccent" }, { 0x013d, "Lcaron" }, { 0x013e, "lcaron" }, { 0x013f, "Ldot" }, { 0x0140, "ldot" }, { 0x0141, "Lslash" }, { 0x0142, "lslash" }, { 0x0143, "Nacute" }, { 0x0144, "nacute" }, { 0x0145, "Ncommaaccent" }, { 0x0146, "ncommaaccent" }, { 0x0147, "Ncaron" }, { 0x0148, "ncaron" }, { 0x0149, "napostrophe" }, { 0x014a, "Eng" }, { 0x014b, "eng" }, { 0x014c, "Omacron" }, { 0x014d, "omacron" }, { 0x014e, "Obreve" }, { 0x014f, "obreve" }, { 0x0150, "Ohungarumlaut" }, { 0x0151, "ohungarumlaut" }, { 0x0152, "OE" }, { 0x0153, "oe" }, { 0x0154, "Racute" }, { 0x0155, "racute" }, { 0x0156, "Rcommaaccent" }, { 0x0157, "rcommaaccent" }, { 0x0158, "Rcaron" }, { 0x0159, "rcaron" }, { 0x015a, "Sacute" }, { 0x015b, "sacute" }, { 0x015c, "Scircumflex" }, { 0x015d, "scircumflex" }, { 0x015e, "Scedilla" }, { 0x015f, "scedilla" }, { 0x0160, "Scaron" }, { 0x0161, "scaron" }, { 0x0164, "Tcaron" }, { 0x0165, "tcaron" }, { 0x0166, "Tbar" }, { 0x0167, "tbar" }, { 0x0168, "Utilde" }, { 0x0169, "utilde" }, { 0x016a, "Umacron" }, { 0x016b, "umacron" }, { 0x016c, "Ubreve" }, { 0x016d, "ubreve" }, { 0x016e, "Uring" }, { 0x016f, "uring" }, { 0x0170, "Uhungarumlaut" }, { 0x0171, "uhungarumlaut" }, { 0x0172, "Uogonek" }, { 0x0173, "uogonek" }, { 0x0174, "Wcircumflex" }, { 0x0175, "wcircumflex" }, { 0x0176, "Ycircumflex" }, { 0x0177, "ycircumflex" }, { 0x0178, "Ydieresis" }, { 0x0179, "Zacute" }, { 0x017a, "zacute" }, { 0x017b, "Zdotaccent" }, { 0x017c, "zdotaccent" }, { 0x017d, "Zcaron" }, { 0x017e, "zcaron" }, { 0x017f, "longs" }, { 0x0192, "florin" }, { 0x01fa, "Aringacute" }, { 0x01fb, "aringacute" }, { 0x01fc, "AEacute" }, { 0x01fd, "aeacute" }, { 0x01fe, "Oslashacute" }, { 0x01ff, "oslashacute" }, { 0x02c6, "circumflex" }, { 0x02c7, "caron" }, { 0x02d8, "breve" }, { 0x02d9, "dotaccent" }, { 0x02da, "ring" }, { 0x02db, "ogonek" }, { 0x02dc, "tilde" }, { 0x02dd, "hungarumlaut" }, { 0x0384, "tonos" }, { 0x0385, "dieresistonos" }, { 0x0386, "Alphatonos" }, { 0x0387, "anoteleia" }, { 0x0388, "Epsilontonos" }, { 0x0389, "Etatonos" }, { 0x038a, "Iotatonos" }, { 0x038c, "Omicrontonos" }, { 0x038e, "Upsilontonos" }, { 0x038f, "Omegatonos" }, { 0x0390, "iotadieresistonos" }, { 0x0391, "Alpha" }, { 0x0392, "Beta" }, { 0x0393, "Gamma" }, { 0x0395, "Epsilon" }, { 0x0396, "Zeta" }, { 0x0397, "Eta" }, { 0x0398, "Theta" }, { 0x0399, "Iota" }, { 0x039a, "Kappa" }, { 0x039b, "Lambda" }, { 0x039c, "Mu" }, { 0x039d, "Nu" }, { 0x039e, "Xi" }, { 0x039f, "Omicron" }, { 0x03a0, "Pi" }, { 0x03a1, "Rho" }, { 0x03a3, "Sigma" }, { 0x03a4, "Tau" }, { 0x03a5, "Upsilon" }, { 0x03a6, "Phi" }, { 0x03a7, "Chi" }, { 0x03a8, "Psi" }, { 0x03aa, "Iotadieresis" }, { 0x03ab, "Upsilondieresis" }, { 0x03ac, "alphatonos" }, { 0x03ad, "epsilontonos" }, { 0x03ae, "etatonos" }, { 0x03af, "iotatonos" }, { 0x03b0, "upsilondieresistonos" }, { 0x03b1, "alpha" }, { 0x03b2, "beta" }, { 0x03b3, "gamma" }, { 0x03b4, "delta" }, { 0x03b5, "epsilon" }, { 0x03b6, "zeta" }, { 0x03b7, "eta" }, { 0x03b8, "theta" }, { 0x03b9, "iota" }, { 0x03ba, "kappa" }, { 0x03bb, "lambda" }, { 0x03bd, "nu" }, { 0x03be, "xi" }, { 0x03bf, "omicron" }, { 0x03c0, "pi" }, { 0x03c1, "rho" }, { 0x03c2, "sigma1" }, { 0x03c3, "sigma" }, { 0x03c4, "tau" }, { 0x03c5, "upsilon" }, { 0x03c6, "phi" }, { 0x03c7, "chi" }, { 0x03c8, "psi" }, { 0x03c9, "omega" }, { 0x03ca, "iotadieresis" }, { 0x03cb, "upsilondieresis" }, { 0x03cc, "omicrontonos" }, { 0x03cd, "upsilontonos" }, { 0x03ce, "omegatonos" }, { 0x0401, "afii10023" }, { 0x0402, "afii10051" }, { 0x0403, "afii10052" }, { 0x0404, "afii10053" }, { 0x0405, "afii10054" }, { 0x0406, "afii10055" }, { 0x0407, "afii10056" }, { 0x0408, "afii10057" }, { 0x0409, "afii10058" }, { 0x040a, "afii10059" }, { 0x040b, "afii10060" }, { 0x040c, "afii10061" }, { 0x040e, "afii10062" }, { 0x040f, "afii10145" }, { 0x0410, "afii10017" }, { 0x0411, "afii10018" }, { 0x0412, "afii10019" }, { 0x0413, "afii10020" }, { 0x0414, "afii10021" }, { 0x0415, "afii10022" }, { 0x0416, "afii10024" }, { 0x0417, "afii10025" }, { 0x0418, "afii10026" }, { 0x0419, "afii10027" }, { 0x041a, "afii10028" }, { 0x041b, "afii10029" }, { 0x041c, "afii10030" }, { 0x041d, "afii10031" }, { 0x041e, "afii10032" }, { 0x041f, "afii10033" }, { 0x0420, "afii10034" }, { 0x0421, "afii10035" }, { 0x0422, "afii10036" }, { 0x0423, "afii10037" }, { 0x0424, "afii10038" }, { 0x0425, "afii10039" }, { 0x0426, "afii10040" }, { 0x0427, "afii10041" }, { 0x0428, "afii10042" }, { 0x0429, "afii10043" }, { 0x042a, "afii10044" }, { 0x042b, "afii10045" }, { 0x042c, "afii10046" }, { 0x042d, "afii10047" }, { 0x042e, "afii10048" }, { 0x042f, "afii10049" }, { 0x0430, "afii10065" }, { 0x0431, "afii10066" }, { 0x0432, "afii10067" }, { 0x0433, "afii10068" }, { 0x0434, "afii10069" }, { 0x0435, "afii10070" }, { 0x0436, "afii10072" }, { 0x0437, "afii10073" }, { 0x0438, "afii10074" }, { 0x0439, "afii10075" }, { 0x043a, "afii10076" }, { 0x043b, "afii10077" }, { 0x043c, "afii10078" }, { 0x043d, "afii10079" }, { 0x043e, "afii10080" }, { 0x043f, "afii10081" }, { 0x0440, "afii10082" }, { 0x0441, "afii10083" }, { 0x0442, "afii10084" }, { 0x0443, "afii10085" }, { 0x0444, "afii10086" }, { 0x0445, "afii10087" }, { 0x0446, "afii10088" }, { 0x0447, "afii10089" }, { 0x0448, "afii10090" }, { 0x0449, "afii10091" }, { 0x044a, "afii10092" }, { 0x044b, "afii10093" }, { 0x044c, "afii10094" }, { 0x044d, "afii10095" }, { 0x044e, "afii10096" }, { 0x044f, "afii10097" }, { 0x0451, "afii10071" }, { 0x0452, "afii10099" }, { 0x0453, "afii10100" }, { 0x0454, "afii10101" }, { 0x0455, "afii10102" }, { 0x0456, "afii10103" }, { 0x0457, "afii10104" }, { 0x0458, "afii10105" }, { 0x0459, "afii10106" }, { 0x045a, "afii10107" }, { 0x045b, "afii10108" }, { 0x045c, "afii10109" }, { 0x045e, "afii10110" }, { 0x045f, "afii10193" }, { 0x0490, "afii10050" }, { 0x0491, "afii10098" }, { 0x1e80, "Wgrave" }, { 0x1e81, "wgrave" }, { 0x1e82, "Wacute" }, { 0x1e83, "wacute" }, { 0x1e84, "Wdieresis" }, { 0x1e85, "wdieresis" }, { 0x1ef2, "Ygrave" }, { 0x1ef3, "ygrave" }, { 0x2013, "endash" }, { 0x2014, "emdash" }, { 0x2015, "afii00208" }, { 0x2017, "underscoredbl" }, { 0x2018, "quoteleft" }, { 0x2019, "quoteright" }, { 0x201a, "quotesinglbase" }, { 0x201b, "quotereversed" }, { 0x201c, "quotedblleft" }, { 0x201d, "quotedblright" }, { 0x201e, "quotedblbase" }, { 0x2020, "dagger" }, { 0x2021, "daggerdbl" }, { 0x2022, "bullet" }, { 0x2026, "ellipsis" }, { 0x2030, "perthousand" }, { 0x2032, "minute" }, { 0x2033, "second" }, { 0x2039, "guilsinglleft" }, { 0x203a, "guilsinglright" }, { 0x203c, "exclamdbl" }, { 0x203e, "uni203E" }, { 0x2044, "fraction" }, { 0x207f, "nsuperior" }, { 0x20a3, "franc" }, { 0x20a4, "lira" }, { 0x20a7, "peseta" }, { 0x20ac, "Euro" }, { 0x2105, "afii61248" }, { 0x2113, "afii61289" }, { 0x2116, "afii61352" }, { 0x2122, "trademark" }, { 0x2126, "Omega" }, { 0x212e, "estimated" }, { 0x215b, "oneeighth" }, { 0x215c, "threeeighths" }, { 0x215d, "fiveeighths" }, { 0x215e, "seveneighths" }, { 0x2190, "arrowleft" }, { 0x2191, "arrowup" }, { 0x2192, "arrowright" }, { 0x2193, "arrowdown" }, { 0x2194, "arrowboth" }, { 0x2195, "arrowupdn" }, { 0x21a8, "arrowupdnbse" }, { 0x2202, "partialdiff" }, { 0x2206, "Delta" }, { 0x220f, "product" }, { 0x2211, "summation" }, { 0x2212, "minus" }, { 0x221a, "radical" }, { 0x221e, "infinity" }, { 0x221f, "orthogonal" }, { 0x2229, "intersection" }, { 0x222b, "integral" }, { 0x2248, "approxequal" }, { 0x2260, "notequal" }, { 0x2261, "equivalence" }, { 0x2264, "lessequal" }, { 0x2265, "greaterequal" }, { 0x2302, "house" }, { 0x2310, "revlogicalnot" }, { 0x2320, "integraltp" }, { 0x2321, "integralbt" }, { 0x2500, "SF100000" }, { 0x2502, "SF110000" }, { 0x250c, "SF010000" }, { 0x2510, "SF030000" }, { 0x2514, "SF020000" }, { 0x2518, "SF040000" }, { 0x251c, "SF080000" }, { 0x2524, "SF090000" }, { 0x252c, "SF060000" }, { 0x2534, "SF070000" }, { 0x253c, "SF050000" }, { 0x2550, "SF430000" }, { 0x2551, "SF240000" }, { 0x2552, "SF510000" }, { 0x2553, "SF520000" }, { 0x2554, "SF390000" }, { 0x2555, "SF220000" }, { 0x2556, "SF210000" }, { 0x2557, "SF250000" }, { 0x2558, "SF500000" }, { 0x2559, "SF490000" }, { 0x255a, "SF380000" }, { 0x255b, "SF280000" }, { 0x255c, "SF270000" }, { 0x255d, "SF260000" }, { 0x255e, "SF360000" }, { 0x255f, "SF370000" }, { 0x2560, "SF420000" }, { 0x2561, "SF190000" }, { 0x2562, "SF200000" }, { 0x2563, "SF230000" }, { 0x2564, "SF470000" }, { 0x2565, "SF480000" }, { 0x2566, "SF410000" }, { 0x2567, "SF450000" }, { 0x2568, "SF460000" }, { 0x2569, "SF400000" }, { 0x256a, "SF540000" }, { 0x256b, "SF530000" }, { 0x256c, "SF440000" }, { 0x2580, "upblock" }, { 0x2584, "dnblock" }, { 0x2588, "block" }, { 0x258c, "lfblock" }, { 0x2590, "rtblock" }, { 0x2591, "ltshade" }, { 0x2592, "shade" }, { 0x2593, "dkshade" }, { 0x25a0, "filledbox" }, { 0x25a1, "H22073" }, { 0x25aa, "H18543" }, { 0x25ab, "H18551" }, { 0x25ac, "filledrect" }, { 0x25b2, "triagup" }, { 0x25ba, "triagrt" }, { 0x25bc, "triagdn" }, { 0x25c4, "triaglf" }, { 0x25ca, "lozenge" }, { 0x25cb, "circle" }, { 0x25cf, "H18533" }, { 0x25d8, "invbullet" }, { 0x25d9, "invcircle" }, { 0x25e6, "openbullet" }, { 0x263a, "smileface" }, { 0x263b, "invsmileface" }, { 0x263c, "sun" }, { 0x2640, "female" }, { 0x2642, "male" }, { 0x2660, "spade" }, { 0x2663, "club" }, { 0x2665, "heart" }, { 0x2666, "diamond" }, { 0x266a, "musicalnote" }, { 0x266b, "musicalnotedbl" }, { 0xfb01, "fi" }, { 0xfb02, "fl" }, { -1, NULL } }; static int nWGL = 642; static char **ExtraStrings; static char *ExtraStringSpace; static int ExtraStringSpacePos; static int nExtraStrings; static char * getSID(int n) { if (ttf == 3) { /*EMPTY*/; } else if (ttf == 2) { if (n >= 0 && n < nWGL) return (char *)WGL[n].s; n -= nWGL; } else if (ttf == 1) { if (n >= 0 && n < nMacintoshStrings) return (char *)MacintoshStrings[n]; n -= nMacintoshStrings; } else { if (n >= 0 && n < nStdStrings) return (char *)StandardStrings[n]; n -= nStdStrings; } if (n < nExtraStrings) return ExtraStrings[n]; return NULL; } static void error(const char *fmt, ...) { char buf[4096]; va_list ap; int n; n = snprintf(buf, sizeof buf, "%s: ", filename); va_start(ap, fmt); vsnprintf(&buf[n], sizeof buf - n, fmt, ap); errprint("%s", buf); va_end(ap); longjmp(breakpoint, 1); } #define _pbe16(cp) ((uint16_t)((cp)[1]&0377) + ((uint16_t)((cp)[0]&0377) << 8)) static uint32_t pbe16(const char *cp) { return (uint16_t)(cp[1]&0377) + ((uint16_t)(cp[0]&0377) << 8); } static uint32_t pbe24(const char *cp) { return (uint32_t)(cp[3]&0377) + ((uint32_t)(cp[2]&0377) << 8) + ((uint32_t)(cp[1]&0377) << 16); } static uint32_t pbe32(const char *cp) { return (uint32_t)(cp[3]&0377) + ((uint32_t)(cp[2]&0377) << 8) + ((uint32_t)(cp[1]&0377) << 16) + ((uint32_t)(cp[0]&0377) << 24); } static uint32_t pbeXX(const char *cp, int n) { switch (n) { default: error("invalid number size %d", n); case 1: return *cp&0377; case 2: return _pbe16(cp); case 3: return pbe24(cp); case 4: return pbe32(cp); } } static double cffoper(long *op) { int b0; int n = 0; double v = 0; b0 = contents[*op]&0377; if (b0 >= 32 && b0 <= 246) { n = 1; v = b0 - 139; } else if (b0 >= 247 && b0 <= 250) { n = 2; v = (b0 - 247) * 256 + (contents[*op+1]&0377) + 108; } else if (b0 >= 251 && b0 <= 254) { n = 2; v = -(b0 - 251) * 256 - (contents[*op+1]&0377) - 108; } else if (b0 == 28) { n = 3; v = (int16_t)((contents[*op+1]&0377)<<8 | (contents[*op+2]&0377)); } else if (b0 == 29) { n = 5; v = (int32_t)pbe32(&contents[*op+1]); } else if (b0 == 30) { char buf[100], *xp; int c, i = 0, s = 0; n = 1; for (;;) { if (i == sizeof buf - 2) error("floating point operand too long"); c = (contents[*op+n]&0377) >> (s ? 8 : 0) & 0xf; if (c >= 0 && c <= 9) buf[i++] = c + '0'; else if (c == 0xa) buf[i++] = '.'; else if (c == 0xb) buf[i++] = 'E'; else if (c == 0xc) { buf[i++] = 'E'; buf[i++] = '-'; } else if (c == 0xd) error("reserved nibble d in floating point " "operand"); else if (c == 0xe) buf[i++] = '-'; else if (c == 0xf) { buf[i++] = 0; if (s == 0) n++; break; } if ((s = !s) == 0) n++; } v = strtod(buf, &xp); if (*xp != 0) error("invalid floating point operand <%s>", buf); } else error("invalid operand b0 range %d", b0); *op += n; return v; } static void get_offset_table(void) { char buf[12]; if (size < 12) error("no offset table"); memcpy(buf, contents, 12); if (pbe32(buf) == 0x00010000 || memcmp(buf, "true", 4) == 0) { ttf = 1; } else if (memcmp(buf, "OTTO", 4) == 0) { ttf = 0; } else error("unknown font type"); numTables = pbe16(&buf[4]); } static void get_table_directories(void) { int i, j, o; char buf[16]; free(table_directories); table_directories = calloc(numTables, sizeof *table_directories); o = 12; for (i = 0; tables[i].pos; i++) *tables[i].pos = -1; for (i = 0; i < numTables; i++) { if (o + 16 >= size) error("cannot get %dth table directory", i); memcpy(buf, &contents[o], 16); for (j = 0; tables[j].name; j++) if (memcmp(buf, tables[j].name, 4) == 0) { *tables[j].pos = i; break; } o += 16; memcpy(table_directories[i].tag, buf, 4); table_directories[i].checkSum = pbe32(&buf[4]); table_directories[i].offset = pbe32(&buf[8]); table_directories[i].length = pbe32(&buf[12]); if (table_directories[i].offset + table_directories[i].length > size) error("invalid table directory, " "size for entry %4.4s too large", table_directories[i].tag); } } static void free_INDEX(struct INDEX *ip) { if (ip) { free(ip->offset); free(ip); } } static struct INDEX * -get_INDEX(long *op) +get_INDEX(unsigned long *op) { struct INDEX *ip; int i; if (*op + 3 >= size) error("no index at position %ld", *op); ip = calloc(1, sizeof *ip); ip->count = pbe16(&contents[*op]); *op += 2; if (ip->count != 0) { ip->offSize = contents[(*op)++] & 0377; ip->offset = calloc(ip->count+1, sizeof *ip->offset); for (i = 0; i < ip->count+1; i++) { if (*op + ip->offSize >= size) { free_INDEX(ip); error("no index offset at position %ld", *op); } ip->offset[i] = pbeXX(&contents[*op], ip->offSize); *op += ip->offSize; } ip->data = &contents[*op]; for (i = 0; i < ip->count+1; i++) ip->offset[i] += *op - 1; *op = ip->offset[ip->count]; } return ip; } static void get_bb(int gid, int B[4]) { int k, o; if (pos_loca < 0 || pos_glyf < 0) return; o = table_directories[pos_loca].offset; k = indexToLocFormat ? pbe32(&contents[o+4*gid]) : pbe16(&contents[o+2*gid]) * 2; o = table_directories[pos_glyf].offset; B[0] = (int16_t)pbe16(&contents[o+k+2]); B[1] = (int16_t)pbe16(&contents[o+k+4]); B[2] = (int16_t)pbe16(&contents[o+k+6]); B[3] = (int16_t)pbe16(&contents[o+k+8]); } static void onechar(int gid, int sid) { long o; int w, tp; char *N; int *b = NULL, B[4] = { 0, 0, 0, 0}; if ((gid == 0 && sid != 0) || (sid == 0 && gid != 0)) return; /* require .notdef to be GID 0 */ if (gid >= nc) return; if (pos_hmtx < 0) error("no hmtx table"); if (table_directories[pos_hmtx].length < 4) error("empty hmtx table"); o = table_directories[pos_hmtx].offset; if (isFixedPitch) w = pbe16(&contents[o]); else { if (table_directories[pos_hmtx].length < 4 * (gid+1)) return; /* just ignore this glyph */ w = pbe16(&contents[o + 4 * gid]); } if (sid != 0 && gid2sid[gid] != 0) return; if (a) { if ((N = getSID(sid)) != NULL) { a->nspace += strlen(N) + 1; tp = afmmapname(N, a->spec); } else tp = 0; if (ttf) get_bb(gid, b = B); afmaddchar(a, gid, tp, 0, w, b, N, a->spec, gid); } gid2sid[gid] = sid; } static int get_CFF_Top_DICT_Entry(int e) { long o; int d = 0; if (CFF.Top_DICT == NULL || CFF.Top_DICT->offset == NULL) error("no Top DICT INDEX"); o = CFF.Top_DICT->offset[0]; while (o < CFF.Top_DICT->offset[1] && contents[o] != e) { if (contents[o] < 0 || contents[o] > 27) d = cffoper(&o); else { d = 0; if (contents[o] == 12) o++; o++; } } return d; } static void get_CFF_Charset(void) { int d = 0; int gid, i, j, first, nLeft; d = get_CFF_Top_DICT_Entry(15); if (d == 0) { for (i = 0; i < nc && i <= 228; i++) onechar(i, i); } else if (d == 1) { for (i = 0; i < nc && i <= 166; i++) onechar(i, ExpertCharset[i]); } else if (d == 2) { for (i = 0; i < nc && i <= 87; i++) onechar(i, ExpertSubsetCharset[i]); } else if (d > 2) { d = CFF.Charset = d + CFF.baseoffset; onechar(0, 0); gid = 1; switch (contents[d++]) { case 0: for (i = 1; i < nc; i++) { j = pbe16(&contents[d]); d += 2; onechar(gid++, j); } break; case 1: i = nc - 1; while (i > 0) { first = pbe16(&contents[d]); d += 2; nLeft = contents[d++] & 0377; for (j = 0; j <= nLeft && gid < nc; j++) onechar(gid++, first + j); i -= nLeft + 1; } break; default: error("unknown Charset table format %d", contents[d-1]); case 2: i = nc - 1; while (i > 0) { first = pbe16(&contents[d]); d += 2; nLeft = pbe16(&contents[d]); d += 2; for (j = 0; j <= nLeft && gid < nc; j++) onechar(gid++, first + j); i -= nLeft + 1; } } } else error("invalid Charset offset"); } static void build_ExtraStrings(void) { int c, i; char *sp; if (CFF.String == NULL || CFF.String->count == 0) return; ExtraStrings = calloc(CFF.String->count, sizeof *ExtraStrings); sp = ExtraStringSpace = malloc(CFF.String->count + CFF.String->offset[CFF.String->count]); for (c = 0; c < CFF.String->count; c++) { ExtraStrings[c] = sp; for (i = CFF.String->offset[c]; i < CFF.String->offset[c+1]; i++) *sp++ = contents[i]; *sp++ = 0; } nExtraStrings = c; } static void otfalloc(int _nc) { nc = _nc; gid2sid = calloc(nc, sizeof *gid2sid); if (a) { afmalloc(a, nc); a->gid2tr = calloc(nc, sizeof *a->gid2tr); } } static void get_CFF(void) { size_t o; char buf[4]; if (pos_CFF < 0) error("no CFF table"); CFF.baseoffset = o = table_directories[pos_CFF].offset; if (o + 4 >= size) error("no CFF header"); memcpy(buf, &contents[o], 4); o += 4; if (buf[0] != 1) error("can only handle CFF major version 1"); CFF.Name = get_INDEX(&o); CFF.Top_DICT = get_INDEX(&o); CFF.String = get_INDEX(&o); build_ExtraStrings(); CFF.Global_Subr = get_INDEX(&o); o = get_CFF_Top_DICT_Entry(17); o += CFF.baseoffset; CFF.CharStrings = get_INDEX(&o); if (CFF.Name->count != 1) error("cannot handle CFF data with more than one font"); a->fontname = malloc(CFF.Name->offset[1] - CFF.Name->offset[0] + 1); memcpy(a->fontname, &contents[CFF.Name->offset[0]], CFF.Name->offset[1] - CFF.Name->offset[0]); a->fontname[CFF.Name->offset[1] - CFF.Name->offset[0]] = 0; #ifdef DUMP print(SHOW_NAME, "name %s", a->fontname); #endif if (CFF.CharStrings == NULL || CFF.CharStrings->count == 0) error("no characters in font"); otfalloc(CFF.CharStrings->count); get_CFF_Charset(); afmremap(a); } /*ARGSUSED*/ static void get_ttf_post_1_0(int o __unused) { int i; otfalloc(numGlyphs); for (i = 0; i < numGlyphs; i++) onechar(i, i); } static void get_ttf_post_2_0(int o) { size_t numberOfGlyphs; size_t numberNewGlyphs; size_t i, j, n; char *cp, *sp; numberOfGlyphs = pbe16(&contents[o+32]); if (34+2*numberOfGlyphs > table_directories[pos_post].length) error("numberOfGlyphs value in post table too large"); otfalloc(numberOfGlyphs); numberNewGlyphs = 0; for (i = 0; i < numberOfGlyphs; i++) { n = pbe16(&contents[o+34+2*i]); if (n >= 258) { n -= 258; if (n >= numberNewGlyphs) numberNewGlyphs = n + 1; } } ExtraStrings = calloc(numberNewGlyphs, sizeof *ExtraStrings); sp = ExtraStringSpace = malloc(table_directories[pos_post].length - 34 - 2*numberOfGlyphs); cp = &contents[o+34+2*numberOfGlyphs]; for (i = 0; i < numberNewGlyphs; i++) { if (cp >= &contents[o + table_directories[pos_post].length]) break; ExtraStrings[i] = sp; n = *cp++ & 0377; if (&cp[n] > &contents[o + table_directories[pos_post].length]) break; for (j = 0; j < n; j++) *sp++ = *cp++; *sp++ = 0; } nExtraStrings = i; for (i = 0; i < numberOfGlyphs; i++) { n = pbe16(&contents[o+34+2*i]); onechar(i, n); } } static void get_ttf_post_2_5(int o) { size_t numberOfGlyphs, i; int offset; numberOfGlyphs = pbe16(&contents[o+32]); if (34+numberOfGlyphs > table_directories[pos_post].length) error("numberOfGlyphs value in post table too large"); otfalloc(numberOfGlyphs); for (i = 0; i < numberOfGlyphs; i++) { offset = ((signed char *)contents)[o+34+i]; onechar(i, i + offset); } } static void unichar(int gid, int c) { int i; char *sp; for (i = 0; WGL[i].s; i++) if (WGL[i].u == c) { onechar(gid, i); return; } if (ExtraStrings == NULL) ExtraStrings = calloc(nc, sizeof *ExtraStrings); if (ExtraStringSpace == NULL) ExtraStringSpace = malloc(nc * 12); sp = &ExtraStringSpace[ExtraStringSpacePos]; ExtraStrings[nExtraStrings] = sp; ExtraStringSpacePos += snprintf(sp, 10, "uni%04X", c) + 1; onechar(gid, nWGL + nExtraStrings++); } #if !defined (DPOST) && !defined (DUMP) #include "unimap.h" static void addunimap(int gid, int c) { struct unimap ***up, *u, *ut; int x, y; if (c != 0 && (c&~0xffff) == 0) { if (a->unimap == NULL) a->unimap = calloc(256, sizeof *up); up = a->unimap; x = c >> 8; y = c & 0377; if (up[x] == NULL) up[x] = calloc(256, sizeof **up); u = calloc(1, sizeof *u); u->u.code = gid; if (up[x][y] != NULL) { for (ut = up[x][y]; ut->next; ut = ut->next); ut->next = u; } else up[x][y] = u; } } #endif /* !DPOST && !DUMP */ #if defined(DPOST) || defined(DUMP) #define __actual_use __unused #else #define __actual_use #endif static void addunitab(int c __actual_use, int u __actual_use) { #if !defined (DPOST) && !defined (DUMP) if (c >= a->nunitab) { a->unitab = realloc(a->unitab, (c+1) * sizeof *a->unitab); memset(&a->unitab[a->nunitab], 0, (c+1-a->nunitab) * sizeof *a->unitab); a->nunitab = c+1; } a->unitab[c] = u; addunimap(c, u); #endif } static char *got_gid; static void got_mapping(int c, int gid, int addchar) { if (gid < nc) { if (addchar) { if (!got_gid[gid]) { unichar(gid, c); got_gid[gid] = 1; } } else { addunitab(a->gid2tr[gid].ch1, c); addunitab(a->gid2tr[gid].ch2, c); } } } static int get_ms_unicode_cmap4(int o, int addchar) { /* int length; */ int segCount; int endCount; int startCount; int idDelta; int idRangeOffset; /* int glyphIdArray; */ int c, e, i, d, r, s, gid; size_t x; /* length = */ pbe16(&contents[o+2]); segCount = pbe16(&contents[o+6]) / 2; endCount = o + 14; startCount = endCount + 2*segCount + 2; idDelta = startCount + 2*segCount; idRangeOffset = idDelta + 2*segCount; /* glyphIdArray = idRangeOffset + 2*segCount; */ for (i = 0; i < segCount; i++) { s = pbe16(&contents[startCount+2*i]); e = pbe16(&contents[endCount+2*i]); d = pbe16(&contents[idDelta+2*i]); r = pbe16(&contents[idRangeOffset+2*i]); for (c = s; c <= e; c++) { if (r) { x = r + 2*(c - s) + idRangeOffset+2*i; if (x+1 >= table_directories[pos_cmap].offset + table_directories[pos_cmap].length) continue; gid = pbe16(&contents[x]); if (gid != 0) gid += d; } else gid = c + d; gid &= 0xffff; if (gid != 0) got_mapping(c, gid, addchar); } } return 1; } static int get_ms_unicode_cmap12(int o, int addchar) { /* int length; */ int nGroups; int startCharCode; int endCharCode; int startGlyphID; int c, i, gid; /* length = */ pbe32(&contents[o+4]); nGroups = pbe32(&contents[o+12]); o += 16; for (i = 0; i < nGroups; i++) { startCharCode = pbe32(&contents[o]); endCharCode = pbe32(&contents[o+4]); startGlyphID = pbe32(&contents[o+8]); for (c = startCharCode, gid = startGlyphID; c <= endCharCode; c++, gid++) got_mapping(c, gid, addchar); o += 12; } return 1; } static int get_ms_unicode_cmap(int o, int addchar) { int format; format = pbe16(&contents[o]); switch (format) { case 4: return get_ms_unicode_cmap4(o, addchar); case 12: return get_ms_unicode_cmap12(o, addchar); default: return 0; } } static int get_cmap(int addchar) { size_t nTables, i; int platformID; int encodingID; int offset; int o; int want_tbl; int gotit = 0; if (pos_cmap < 0) { if (addchar) error("no cmap table"); return gotit; } o = table_directories[pos_cmap].offset; if (pbe16(&contents[o]) != 0) { if (addchar) error("can only handle version 0 cmap tables"); return gotit; } nTables = pbe16(&contents[o+2]); if (4 + 8*nTables > table_directories[pos_cmap].length) { if (addchar) error("cmap table too small for values inside"); return gotit; } if (addchar) otfalloc(numGlyphs); want_tbl = -1; for (i = 0; i < nTables; i++) { platformID = pbe16(&contents[o+4+8*i]); encodingID = pbe16(&contents[o+4+8*i+2]); if ((platformID == 3 && encodingID == 10) || (want_tbl < 0 && ((platformID == 3 && (encodingID == 0 || encodingID == 1)) || platformID == 0))) want_tbl = i; } if (want_tbl >= 0) { offset = pbe32(&contents[o+4+8*want_tbl+4]); gotit |= get_ms_unicode_cmap(o + offset, addchar); } return gotit; } static void get_ttf_post_3_0(int o __unused) { int i, n; int gotit; char *sp; size_t l; ttf = 2; got_gid = calloc(numGlyphs, sizeof *got_gid); gotit = get_cmap(1); if (gotit <= 0) { ttf = 3; ExtraStrings = calloc(numGlyphs, sizeof *ExtraStrings); l = n = 12 * numGlyphs; sp = ExtraStringSpace = malloc(l); n_strcpy(sp, ".notdef", l); ExtraStrings[0] = sp; sp += 8; nExtraStrings = 1; onechar(0, 0); for (i = 1; i < numGlyphs; i++) { ExtraStrings[i] = sp; sp += snprintf(sp, n - (sp - ExtraStringSpace), "index0x%02X", i) + 1; if (sp >= &ExtraStringSpace[n]) sp = &ExtraStringSpace[n]; nExtraStrings++; onechar(i, i); } } else { n = numGlyphs * 12; if (ExtraStrings == NULL) ExtraStrings = calloc(numGlyphs, sizeof *ExtraStrings); if (ExtraStringSpace == NULL) ExtraStringSpace = malloc(n); sp = &ExtraStringSpace[ExtraStringSpacePos]; for (i = 0; i < numGlyphs; i++) if (got_gid[i] == 0) { ExtraStrings[nExtraStrings] = sp; sp += snprintf(sp, n - (sp - ExtraStringSpace), "index0x%02X", i) + 1; if (sp >= &ExtraStringSpace[n]) sp = &ExtraStringSpace[n]; onechar(i, nWGL + nExtraStrings++); } } free(got_gid); got_gid = NULL; } static void ttfname(void) { if (a) { if (PostScript_name && strchr(PostScript_name, ' ') == NULL) a->fontname = strdup(PostScript_name); else { const char *base = a->Font.namefont[0] ? a->Font.namefont : a->base; size_t l = strlen(base) + 5; a->fontname = malloc(l); n_strcpy(a->fontname, base, l); n_strcat(a->fontname, ".TTF", l); } #ifdef DUMP print(SHOW_NAME, "name %s", a->fontname); #endif } } static void get_ttf(void) { long o; int Version; if (pos_post < 0) error("no post table"); o = table_directories[pos_post].offset; switch (Version = pbe32(&contents[o])) { case 0x00010000: ttfname(); get_ttf_post_1_0(o); break; case 0x00020000: ttfname(); get_ttf_post_2_0(o); break; case 0x00025000: ttfname(); get_ttf_post_2_5(o); break; case 0x00030000: ttfname(); get_ttf_post_3_0(o); break; default: error("cannot handle TrueType fonts with " "version %d.%d post table", Version>>16, (Version&0xffff) >> 12); } if (a) afmremap(a); } static void get_head(void) { long o; if (pos_head < 0) error("no head table"); o = table_directories[pos_head].offset; if (pbe32(&contents[o]) != 0x00010000) error("can only handle version 1.0 head tables"); unitsPerEm = pbe16(&contents[o + 18]); xMin = (int16_t)pbe16(&contents[o + 36]); yMin = (int16_t)pbe16(&contents[o + 38]); xMax = (int16_t)pbe16(&contents[o + 40]); yMax = (int16_t)pbe16(&contents[o + 42]); indexToLocFormat = pbe16(&contents[o + 50]); } static void get_post(void) { long o; isFixedPitch = 0; minMemType42 = maxMemType42 = -1; if (pos_post < 0) return; o = table_directories[pos_post].offset; if (pbe32(&contents[o]) > 0x00030000) return; if (table_directories[pos_post].length >= 16) isFixedPitch = pbe32(&contents[o+12]); if (a) a->isFixedPitch = isFixedPitch; if (table_directories[pos_post].length >= 20) minMemType42 = pbe32(&contents[o+16]); if (table_directories[pos_post].length >= 24) maxMemType42 = pbe32(&contents[o+20]); } static void get_maxp(void) { if (pos_maxp < 0) error("no maxp table"); numGlyphs = pbe16(&contents[table_directories[pos_maxp].offset+4]); } static char * build_string(int o, int length, int ucs) { char *string, *sp; int i; int ch; sp = string = malloc(3*length + 1); for (i = 0; i < length; i++) { if (ucs) { ch = pbe16(&contents[o+i]); i++; } else ch = contents[o+i]&0377; if ((ch & 0200) == 0) { switch (ch) { case '\\': case '(': case ')': *sp++ = '\\'; /*FALLTHRU*/ default: *sp++ = ch; } } else if (ch == 169) { /* * 169 happens to be COPYRIGHT SIGN in both MacRoman and * Unicode. */ *sp++ = '('; *sp++ = 'c'; *sp++ = ')'; } } *sp = 0; return string; } static void get_name(void) { char **sp; long o; int count; int stringOffset; int i; int platformID; int encodingID; int languageID; int nameID; int length; int offset; if (pos_name < 0) return; o = table_directories[pos_name].offset; if (pbe16(&contents[o]) != 0) return; count = pbe16(&contents[o+2]); stringOffset = o + pbe16(&contents[o+4]); for (i = 0; i < count; i++) { platformID = pbe16(&contents[o+6+12*i]); encodingID = pbe16(&contents[o+6+12*i+2]); languageID = pbe16(&contents[o+6+12*i+4]); nameID = pbe16(&contents[o+6+12*i+6]); length = pbe16(&contents[o+6+12*i+8]); offset = pbe16(&contents[o+6+12*i+10]); switch (nameID) { case 0: sp = &Copyright; break; case 6: sp = &PostScript_name; break; case 7: sp = &Notice; break; default: sp = NULL; } if (sp != NULL && *sp == NULL) { if (platformID == 1 && encodingID == 0 && languageID == 0) *sp = build_string(stringOffset+offset, length, 0); else if (platformID == 3 && languageID == 0x409) *sp = build_string(stringOffset+offset, length, 1); } } } static void get_OS_2(void) { long o; if (pos_OS_2 < 0) goto dfl; o = table_directories[pos_OS_2].offset; if (pbe16(&contents[o]) > 0x0003) goto dfl; if (table_directories[pos_OS_2].length >= 6) WeightClass = pbe16(&contents[o+4]); else WeightClass = -1; if (table_directories[pos_OS_2].length >= 10) fsType = pbe16(&contents[o+8]); else fsType = -1; if (table_directories[pos_OS_2].length >= 72) { if (a) { a->ascender = _unitconv((int16_t)pbe16(&contents[o + 68])); a->descender = _unitconv((int16_t)pbe16(&contents[o + 70])); } } if (table_directories[pos_OS_2].length >= 92) { if (a) { a->xheight = _unitconv(pbe16(&contents[o + 88])); a->capheight = _unitconv(pbe16(&contents[o + 90])); } } else { dfl: if (a) { a->xheight = 500; a->capheight = 700; } } } static char * GID2SID(int gid) { if (gid < 0 || gid >= nc) return NULL; return getSID(gid2sid[gid]); } int fprintenc(FILE *fd, const char *enc) { const char *cp; for (cp = enc; *cp && !isspace(*cp); cp++); if (*cp) { return fprintf(fd, "(%s) cvn", enc); } else { return fprintf(fd, "/%s", enc); } } #ifndef DPOST static int ScriptList; static int FeatureList; static int LookupList; struct cov { int offset; int CoverageFormat; int RangeCount; int GlyphCount; int cnt; int gid; }; static struct cov * open_cov(int o) { struct cov *cp; cp = calloc(1, sizeof *cp); cp->offset = o; switch (cp->CoverageFormat = pbe16(&contents[o])) { default: free(cp); return NULL; case 1: cp->GlyphCount = pbe16(&contents[o+2]); return cp; case 2: cp->RangeCount = pbe16(&contents[o+2]); cp->gid = -1; return cp; } } static int get_cov(struct cov *cp) { int Start, End; switch (cp->CoverageFormat) { default: return -1; case 1: if (cp->cnt < cp->GlyphCount) return pbe16(&contents[cp->offset+4+2*cp->cnt++]); return -1; case 2: while (cp->cnt < cp->RangeCount) { Start = pbe16(&contents[cp->offset+4+6*cp->cnt]); End = pbe16(&contents[cp->offset+4+6*cp->cnt+2]); if (cp->gid > End) { cp->gid = -1; cp->cnt++; continue; } if (cp->gid < Start) cp->gid = Start; return cp->gid++; } return -1; } } static void free_cov(struct cov *cp) { free(cp); } struct class { int offset; int ClassFormat; int StartGlyph; int GlyphCount; int ClassRangeCount; int cnt; int gid; }; static struct class * open_class(int o) { struct class *cp; cp = calloc(1, sizeof *cp); cp->offset = o; switch (cp->ClassFormat = pbe16(&contents[o])) { default: free(cp); return NULL; case 1: cp->StartGlyph = pbe16(&contents[o+2]); cp->GlyphCount = pbe16(&contents[o+4]); return cp; case 2: cp->ClassRangeCount = pbe16(&contents[o+2]); cp->gid = -1; return cp; } } static inline void get_class(struct class *cp, int *gp, int *vp) { int Start, End; switch (cp->ClassFormat) { case 1: if (cp->cnt < cp->GlyphCount) { *gp = cp->StartGlyph + cp->cnt; *vp = _pbe16(&contents[cp->offset+6+2*cp->cnt]); cp->cnt++; return; } goto dfl; case 2: while (cp->cnt < cp->ClassRangeCount) { Start = _pbe16(&contents[cp->offset+4+6*cp->cnt]); End = _pbe16(&contents[cp->offset+4+6*cp->cnt+2]); if (cp->gid > End) { cp->gid = -1; cp->cnt++; continue; } if (cp->gid < Start) cp->gid = Start; *gp = cp->gid++; *vp = _pbe16(&contents[cp->offset+4+6*cp->cnt+4]); return; } /*FALLTHRU*/ default: dfl: *gp = -1; *vp = -1; return; } } static void free_class(struct class *cp) { free(cp); } static int get_value_size(int ValueFormat1, int ValueFormat2) { int i, sz = 0; for (i = 0; i < 16; i++) if (ValueFormat1 & (1<= nc ? NULL : nametable[gid]) static inline void kernpair(int first, int second, int x) { struct namecache *np1, *np2; if (x == 0 || (x = _unitconv(x)) == 0) return; np1 = GID2name(first); np2 = GID2name(second); if (np1 == NULL || np2 == NULL) return; if (np1->fival[0] != NOCODE && np2->fival[0] != NOCODE) afmaddkernpair(a, np1->fival[0], np2->fival[0], x); if (np1->fival[0] != NOCODE && np2->fival[1] != NOCODE) afmaddkernpair(a, np1->fival[0], np2->fival[1], x); if (np1->fival[1] != NOCODE && np2->fival[0] != NOCODE) afmaddkernpair(a, np1->fival[1], np2->fival[0], x); if (np1->fival[1] != NOCODE && np2->fival[1] != NOCODE) afmaddkernpair(a, np1->fival[1], np2->fival[1], x); } static void kernfinish(void) { free(nametable); } #endif /* !DUMP */ static void get_PairValueRecord(int first, int ValueFormat1, int ValueFormat2, int o) { int second; int x; second = _pbe16(&contents[o]); x = get_x_adj(ValueFormat1, o+2); kernpair(first, second, x); } static void get_PairSet(int first, int ValueFormat1, int ValueFormat2, int o) { int PairValueCount; int i; int sz; PairValueCount = _pbe16(&contents[o]); sz = get_value_size(ValueFormat1, ValueFormat2); for (i = 0; i < PairValueCount; i++) get_PairValueRecord(first, ValueFormat1, ValueFormat2, o+2+(2+sz)*i); } static void get_PairPosFormat1(int o) { struct cov *cp; int Coverage; int ValueFormat1, ValueFormat2; int PairSetCount; int first; int i; Coverage = o + pbe16(&contents[o+2]); if ((cp = open_cov(Coverage)) == NULL) return; ValueFormat1 = pbe16(&contents[o+4]); ValueFormat2 = pbe16(&contents[o+6]); PairSetCount = pbe16(&contents[o+8]); for (i = 0; i < PairSetCount && (first = get_cov(cp)) >= 0; i++) get_PairSet(first, ValueFormat1, ValueFormat2, o + pbe16(&contents[o+10+2*i])); free_cov(cp); } static void get_PairPosFormat2(int o) { struct class *c1, *c2; int ValueFormat1, ValueFormat2; int ClassDef1, ClassDef2; int Class1Count, Class2Count; int g, *g2 = NULL; int v, *v2 = NULL; int sz; int i, n, a; int x; ValueFormat1 = pbe16(&contents[o+4]); ValueFormat2 = pbe16(&contents[o+6]); ClassDef1 = o + pbe16(&contents[o+8]); ClassDef2 = o + pbe16(&contents[o+10]); Class1Count = pbe16(&contents[o+12]); Class2Count = pbe16(&contents[o+14]); sz = get_value_size(ValueFormat1, ValueFormat2); if ((c1 = open_class(ClassDef1)) != NULL) { if ((c2 = open_class(ClassDef2)) != NULL) { n = a = 0; while (get_class(c2, &g, &v), g >= 0) { if (v < 0 || v >= Class2Count) continue; if (n >= a) { a = a ? 2*a : 128; g2 = realloc(g2, a * sizeof *g2); v2 = realloc(v2, a * sizeof *v2); } g2[n] = g; v2[n] = v; n++; } while (get_class(c1, &g, &v), g >= 0) { if (v < 0 || v >= Class1Count) continue; for (i = 0; i < n; i++) { x = get_x_adj(ValueFormat1, o + 16 + v*Class2Count*sz + v2[i]*sz); kernpair(g, g2[i], x); } } free_class(c2); } free_class(c1); } free(g2); free(v2); } static void get_GPOS_kern1(int _t, int o, const char *_name) { int PosFormat; got_kern = 1; switch (PosFormat = pbe16(&contents[o])) { case 1: get_PairPosFormat1(o); break; } } static void get_GPOS_kern2(int _t, int o, const char *_name) { int PosFormat; got_kern = 1; switch (PosFormat = pbe16(&contents[o])) { case 2: get_PairPosFormat2(o); break; } } static void get_Ligature(int first, int o) { int LigGlyph; int CompCount; int Component[16]; int i; char *gn; LigGlyph = pbe16(&contents[o]); CompCount = pbe16(&contents[o+2]); for (i = 0; i < CompCount - 1 && i < sizeof Component / sizeof *Component - 1; i++) { Component[i] = pbe16(&contents[o+4+2*i]); } Component[i] = -1; gn = GID2SID(first); if (gn && gn[0] == 'f' && gn[1] == 0 && CompCount > 1) { gn = GID2SID(Component[0]); if (gn && gn[0] && gn[1] == 0) switch (gn[0]) { case 'f': if (CompCount == 2) { gn = GID2SID(LigGlyph); if (gn && (strcmp(gn, "ff") == 0 || strcmp(gn, "f_f") == 0)) a->Font.ligfont |= LFF; } else if (CompCount == 3) { gn = GID2SID(Component[1]); if (gn[0] && gn[1] == 0) switch (gn[0]) { case 'i': gn = GID2SID(LigGlyph); if (gn && (strcmp(gn, "ffi") == 0 || strcmp(gn, "f_f_i") == 0)) a->Font.ligfont |= LFFI; break; case 'l': gn = GID2SID(LigGlyph); if (gn && (strcmp(gn, "ffl") == 0 || strcmp(gn, "f_f_l") == 0)) a->Font.ligfont |= LFFL; break; } } break; case 'i': if (CompCount == 2) { gn = GID2SID(LigGlyph); if (gn && (strcmp(gn, "fi") == 0 || strcmp(gn, "f_i") == 0)) a->Font.ligfont |= LFI; } break; case 'l': if (CompCount == 2) { gn = GID2SID(LigGlyph); if (gn && (strcmp(gn, "fl") == 0 || strcmp(gn, "f_l") == 0)) a->Font.ligfont |= LFL; } break; } } } static void get_LigatureSet(int first, int o) { int LigatureCount; int i; LigatureCount = pbe16(&contents[o]); for (i = 0; i < LigatureCount; i++) get_Ligature(first, o + pbe16(&contents[o+2+2*i])); } static void get_LigatureSubstFormat1(int _t, int o, const char *_name) { struct cov *cp; int Coverage; int LigSetCount; int i; int first; if (pbe16(&contents[o]) != 1) return; Coverage = o + pbe16(&contents[o+2]); if ((cp = open_cov(Coverage)) == NULL) return; LigSetCount = pbe16(&contents[o+4]); for (i = 0; i < LigSetCount && (first = get_cov(cp)) >= 0; i++) get_LigatureSet(first, o + pbe16(&contents[o+6+2*i])); free_cov(cp); } static struct feature * add_feature(const char *name) { int i; char *np; if (a->features == NULL) a->features = calloc(1, sizeof *a->features); for (i = 0; a->features[i]; i++) if (strcmp(a->features[i]->name, name) == 0) return a->features[i]; a->features = realloc(a->features, (i+2) * sizeof *a->features); a->features[i] = calloc(1, sizeof **a->features); a->features[i]->name = strdup(name); for (np = a->features[i]->name; *np; np++) if (*np == ' ') { *np = 0; break; } a->features[i+1] = NULL; return a->features[i]; } static void add_substitution_pair1(struct feature *fp, int ch1, int ch2) { fp->pairs = realloc(fp->pairs, (fp->npairs+1) * sizeof *fp->pairs); fp->pairs[fp->npairs].ch1 = ch1; fp->pairs[fp->npairs].ch2 = ch2; fp->npairs++; } static void add_substitution_pair(struct feature *fp, int ch1, int ch2) { if (ch1 && ch2) { #ifdef DUMP print(SHOW_SUBSTITUTIONS, "feature %s substitution %s %s", fp->name, GID2SID(ch1), GID2SID(ch2)); #endif if (a->gid2tr[ch1].ch1) { if (a->gid2tr[ch2].ch1) add_substitution_pair1(fp, a->gid2tr[ch1].ch1, a->gid2tr[ch2].ch1); if (a->gid2tr[ch2].ch2) add_substitution_pair1(fp, a->gid2tr[ch1].ch1, a->gid2tr[ch2].ch2); } if (a->gid2tr[ch1].ch2) { if (a->gid2tr[ch2].ch1) add_substitution_pair1(fp, a->gid2tr[ch1].ch2, a->gid2tr[ch2].ch1); if (a->gid2tr[ch2].ch2) add_substitution_pair1(fp, a->gid2tr[ch1].ch2, a->gid2tr[ch2].ch2); } } } static void get_SingleSubstitutionFormat1(int o, const char *name) { struct feature *fp; struct cov *cp; int c, d; int Coverage; int DeltaGlyphID; if (pbe16(&contents[o]) != 1) return; Coverage = o + pbe16(&contents[o+2]); if ((cp = open_cov(Coverage)) == NULL) return; DeltaGlyphID = pbe16(&contents[o+4]); fp = add_feature(name); while ((c = get_cov(cp)) >= 0) if ((d = c + DeltaGlyphID) < nc) add_substitution_pair(fp, c, d); free_cov(cp); } static void get_SingleSubstitutionFormat2(int o, const char *name) { struct feature *fp; struct cov *cp; int Coverage; int GlyphCount; int c, i; if (pbe16(&contents[o]) != 2) return; Coverage = o + pbe16(&contents[o+2]); if ((cp = open_cov(Coverage)) == NULL) return; GlyphCount = pbe16(&contents[o+4]); fp = add_feature(name); for (i = 0; i < GlyphCount && (c = get_cov(cp)) >= 0; i++) add_substitution_pair(fp, c, pbe16(&contents[o+6+2*i])); free_cov(cp); } static void get_substitutions(int type, int o, const char *name) { int format; format = pbe16(&contents[o]); switch (type) { case 1: switch (format) { case 1: get_SingleSubstitutionFormat1(o, name); break; case 2: get_SingleSubstitutionFormat2(o, name); break; } } } static void get_lookup(int o, int type, const char *name, void (*func)(int, int, const char *)) { int i, j, t, x, y; int LookupCount; int SubTableCount; LookupCount = pbe16(&contents[o+2]); for (i = 0; i < LookupCount; i++) { x = pbe16(&contents[o+4+2*i]); y = pbe16(&contents[LookupList+2+2*x]); if ((t = pbe16(&contents[LookupList+y])) == type || type < 0) { SubTableCount = pbe16(&contents[LookupList+y+4]); for (j = 0; j < SubTableCount; j++) func(t, LookupList+y + pbe16(&contents[LookupList+y+6+2*j]), name); } } } static void get_LangSys(int o, const char *name, int type, void (*func)(int, int, const char *)) { char nb[5]; int i, x; int FeatureCount; int ReqFeatureIndex; ReqFeatureIndex = pbe16(&contents[o+2]); FeatureCount = pbe16(&contents[o+4]); if (ReqFeatureIndex != 0xFFFF) FeatureCount += ReqFeatureIndex; for (i = 0; i < FeatureCount; i++) { x = pbe16(&contents[o+6+2*i]); if (name == NULL || memcmp(&contents[FeatureList+2+6*x], name, 4) == 0) { memcpy(nb, &contents[FeatureList+2+6*x], 4); nb[4] = 0; get_lookup(FeatureList + pbe16(&contents[FeatureList+2+6*x+4]), type, nb, func); } } } static void get_feature(int table, const char *name, int type, void (*func)(int, int, const char *)) { long o; int i; int DefaultLangSys; int ScriptCount; int Script; if (table < 0) return; o = table_directories[table].offset; if (pbe32(&contents[o]) != 0x00010000) return; ScriptList = o + pbe16(&contents[o+4]); FeatureList = o + pbe16(&contents[o+6]); LookupList = o + pbe16(&contents[o+8]); ScriptCount = pbe16(&contents[ScriptList]); for (i = 0; i < ScriptCount; i++) if (memcmp(&contents[ScriptList+2+6*i], "DFLT", 4) == 0 || memcmp(&contents[ScriptList+2+6*i], "latn", 4) == 0) { Script = ScriptList + pbe16(&contents[ScriptList+2+6*i+4]); DefaultLangSys = Script + pbe16(&contents[Script]); get_LangSys(DefaultLangSys, name, type, func); } } static void get_kern_subtable(int o) { int length; int coverage; int nPairs; int i; int left, right, value; if (pbe16(&contents[o]) != 0) return; length = pbe16(&contents[o+2]); coverage = pbe16(&contents[o+4]); if ((coverage&1) != 1 || /* check: horizontal data */ (coverage&2) != 0 || /* . . . kerning values */ (coverage&4) != 0 || /* . . . not perpendicular */ ((coverage&0xff00) != 0)) /* . . . format 0 */ return; got_kern = 1; nPairs = pbe16(&contents[o+6]); for (i = 0; i < nPairs; i++) { if (o + 14 + 6 * (i+1) > o + length) break; left = pbe16(&contents[o+14+6*i]); right = pbe16(&contents[o+14+6*i+2]); value = (int16_t)pbe16(&contents[o+14+6*i+4]); kernpair(left, right, value); } } static void get_kern(void) { long o; int nTables; int i, length; if (pos_kern < 0) return; o = table_directories[pos_kern].offset; if (pbe16(&contents[o]) != 0) return; nTables = pbe16(&contents[o+2]); o += 4; for (i = 0; i < nTables; i++) { if (o + 6 > table_directories[pos_kern].offset + table_directories[pos_kern].length) return; length = pbe16(&contents[o+2]); if (o + length > table_directories[pos_kern].offset + table_directories[pos_kern].length) return; get_kern_subtable(o); o += length; } } #endif /* !DPOST */ #ifdef DPOST static void checkembed(void) { /* * Do not check the embedding bits under the assumption that the * resulting PostScript file is sent to a printer. This follows * Adobe's "Font Embedding Guidelines for Adobe Third-party * Developers", 5/16/05, p. 8. * * It is the responsibility of a following distiller command or * the like to check the fsType bit then. * if (fsType != -1 && (fsType&0x030e) == 0x0002 || fsType & 0x0200) error("embedding not allowed"); */ } int otfcff(const char *path, char *_contents, size_t _size, size_t *offset, size_t *length) { int ok = 0; (void) &ok; a = NULL; filename = path; contents = _contents; size = _size; if (setjmp(breakpoint) == 0) { get_offset_table(); get_table_directories(); get_OS_2(); if (pos_CFF < 0) error("no CFF table"); checkembed(); *offset = table_directories[pos_CFF].offset; *length = table_directories[pos_CFF].length; } else ok = -1; return ok; } static uint32_t CalcTableChecksum(uint32_t sum, const char *cp, int length) { while (length > 0) { sum += pbe32(cp); cp += 4; length -= 4; } return sum; } static void sfnts1(struct table *tp, int *offset, uint32_t *ccs, FILE *fp __unused) { int o, length; o = table_directories[*tp->pos].offset; length = table_directories[*tp->pos].length; if (tp->in_sfnts == 2) /* head table */ memset(&contents[o+8], 0, 4); /* checkSumAdjustment */ tp->checksum = CalcTableChecksum(0, &contents[o], length); *ccs = CalcTableChecksum(*ccs, tp->name, 4); *ccs += tp->checksum; *ccs += *offset; *ccs += length; *offset += length; } static void sfnts1a(struct table *tp, int *offset, uint32_t *ccs, FILE *fp) { int o, length, m; o = table_directories[*tp->pos].offset; length = table_directories[*tp->pos].length; if (tp->in_sfnts == 2) { *ccs -= 0xB1B0AFBA; contents[o+8] = (*ccs&0xff000000) >> 24; contents[o+9] = (*ccs&0x00ff0000) >> 16; contents[o+10] = (*ccs&0x0000ff00) >> 8; contents[o+11] = (*ccs&0x000000ff); } fprintf(fp, "%08X%08X%08X%08X", pbe32(tp->name), (unsigned int)tp->checksum, *offset, length); if ((m = length % 4) != 0) length += 4 - m; *offset += length; } static int start_of_next_glyph(int *start, int offset) { int i = *start; int last = INT_MAX; int cur; int o; int tms = 0; if (pos_loca < 0) error("no loca table"); o = table_directories[pos_loca].offset; for (;;) { if (i >= numGlyphs) { i = 0; if (tms++ == 4) return -1; } cur = indexToLocFormat ? pbe32(&contents[o + 4*i]) : pbe16(&contents[o + 2*i]) * 2; if (offset > last && offset < cur) { *start = i; return cur; } if (cur < last) last = cur; i++; } } static void sfnts2(struct table *tp, FILE *fp) { const char hex[] = "0123456789ABCDEF"; int i, o, length, next = -1; int start = 0; o = table_directories[*tp->pos].offset; length = table_directories[*tp->pos].length; putc('<', fp); for (i = 0; i < length; i++) { if (i && i % 36 == 0) putc('\n', fp); if (i && i % 60000 == 0 && tp->in_sfnts == 3) { /* split string at start of next glyph */ next = start_of_next_glyph(&start, i); } if (i == next) fprintf(fp, "00><"); if (i && i % 65534 == 0 && tp->in_sfnts != 3) fprintf(fp, "00>\n<"); putc(hex[(contents[o+i]&0360)>>4], fp); putc(hex[contents[o+i]&017], fp); } while (i++ % 4) fprintf(fp, "00"); fprintf(fp, "00>\n"); } static void build_sfnts(FILE *fp) { int i, o, n; unsigned short nTables; unsigned short searchRange; unsigned short entrySelector; unsigned short rangeShift; uint32_t ccs; nTables = 0; for (i = 0; tables[i].name; i++) if (tables[i].in_sfnts && *tables[i].pos >= 0) nTables++; entrySelector = 0; for (searchRange = 1; searchRange*2 < nTables; searchRange *= 2) entrySelector++; searchRange *= 16; rangeShift = nTables * 16 - searchRange; fprintf(fp, "<%08X%04hX%04hX%04hX%04hX\n", 0x00010000, nTables, searchRange, entrySelector, rangeShift); ccs = 0x00010000 + (nTables<<16) + searchRange + (entrySelector<<16) + rangeShift; o = 12 + nTables * 16; for (i = 0; tables[i].name; i++) if (tables[i].in_sfnts && *tables[i].pos >= 0) sfnts1(&tables[i], &o, &ccs, fp); o = 12 + nTables * 16; n = 0; for (i = 0; tables[i].name; i++) { if (tables[i].in_sfnts && *tables[i].pos >= 0) { if (n++) putc('\n', fp); sfnts1a(&tables[i], &o, &ccs, fp); } } fprintf(fp, "00>\n"); for (i = 0; tables[i].name; i++) if (tables[i].in_sfnts && *tables[i].pos >= 0) sfnts2(&tables[i], fp); } int otft42(char *font, char *path, char *_contents, size_t _size, FILE *fp) { const char *cp; int ok = 0; int i; (void) &ok; a = NULL; filename = path; contents = _contents; size = _size; if (setjmp(breakpoint) == 0) { get_offset_table(); get_table_directories(); get_head(); get_OS_2(); get_post(); get_maxp(); get_name(); if (ttf == 0) error("not a TrueType font file"); checkembed(); get_ttf(); if (minMemType42 >= 0 && maxMemType42 >= 0 && (minMemType42 || maxMemType42)) fprintf(fp, "%%%%VMUsage: %d %d\n", minMemType42, maxMemType42); fprintf(fp, "11 dict begin\n"); fprintf(fp, "/FontType 42 def\n"); fprintf(fp, "/FontMatrix [1 0 0 1 0 0] def\n"); fprintf(fp, "/FontName /%s def\n", font); fprintf(fp, "/FontBBox [%d %d %d %d] def\n", xMin * 1000 / unitsPerEm, yMin * 1000 / unitsPerEm, xMax * 1000 / unitsPerEm, yMax * 1000 / unitsPerEm); fprintf(fp, "/PaintType 0 def\n"); fprintf(fp, "/Encoding StandardEncoding def\n"); if (fsType != -1 || Notice || Copyright || WeightClass) { fprintf(fp, "/FontInfo 4 dict dup begin\n"); if (fsType != -1) fprintf(fp, "/FSType %d def\n", fsType); if (Notice) fprintf(fp, "/Notice (%s) readonly def\n", Notice); if (Copyright) fprintf(fp, "/Copyright (%s) readonly def\n", Copyright); if (WeightClass) { if (WeightClass <= 350) cp = "Light"; else if (WeightClass <= 550) cp = "Medium"; else if (WeightClass <= 750) cp = "Bold"; else if (WeightClass <= 850) cp = "Ultra"; else cp = "Heavy"; fprintf(fp, "/Weight (%s) readonly def\n", cp); } fprintf(fp, "end readonly def\n"); } fprintf(fp, "/CharStrings %d dict dup begin\n", nc); for (i = 0; i < nc; i++) { if ((cp = GID2SID(i)) != NULL && (i == 0 || strcmp(cp, ".notdef"))) { fprintenc(fp, cp); fprintf(fp, " %d def\n", i); } else fprintf(fp, "/index0x%02X %d def\n", i, i); } fprintf(fp, "end readonly def\n"); fprintf(fp, "/sfnts["); build_sfnts(fp); fprintf(fp, "]def\n"); fprintf(fp, "FontName currentdict end definefont pop\n"); } else ok = -1; free(PostScript_name); PostScript_name = 0; free(Copyright); Copyright = 0; free(Notice); Notice = 0; free(ExtraStringSpace); ExtraStringSpace = NULL; ExtraStringSpacePos = 0; free(ExtraStrings); ExtraStrings = NULL; nExtraStrings = 0; return ok; } #endif /* DPOST */ int otfget(struct afmtab *_a, char *_contents, size_t _size) { int ok = 0; (void) &ok; a = _a; filename = a->path; contents = _contents; size = _size; if (setjmp(breakpoint) == 0) { get_offset_table(); get_table_directories(); get_head(); get_OS_2(); get_post(); if (ttf == 0) { a->type = TYPE_OTF; get_CFF(); } else { a->type = TYPE_TTF; get_maxp(); get_name(); get_ttf(); } #ifndef DPOST kerninit(); get_feature(pos_GSUB, "liga", 4, get_LigatureSubstFormat1); get_feature(pos_GPOS, "kern", 2, get_GPOS_kern1); get_feature(pos_GPOS, "kern", 2, get_GPOS_kern2); get_feature(pos_GSUB, NULL, -1, get_substitutions); if (ttf && got_kern == 0) get_kern(); kernfinish(); get_cmap(0); #endif /* !DPOST */ a->Font.nwfont = a->nchars > 255 ? 255 : a->nchars; } else ok = -1; free(PostScript_name); PostScript_name = 0; free(Copyright); Copyright = 0; free(Notice); Notice = 0; free_INDEX(CFF.Name); CFF.Name = 0; free_INDEX(CFF.Top_DICT); CFF.Top_DICT = 0; free_INDEX(CFF.String); CFF.String = 0; free_INDEX(CFF.Global_Subr); CFF.Global_Subr = 0; free_INDEX(CFF.CharStrings); CFF.CharStrings = 0; free(ExtraStringSpace); ExtraStringSpace = NULL; ExtraStringSpacePos = 0; free(ExtraStrings); ExtraStrings = NULL; nExtraStrings = 0; free(a->gid2tr); a->gid2tr = NULL; return ok; } Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/otfdump.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/otfdump.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/otfdump.c (revision 307812) @@ -1,216 +1,213 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)otfdump.c 1.15 (gritter) 3/16/06 */ static enum show { SHOW_CHARS = 001, SHOW_KERNPAIRS = 002, SHOW_SUBSTITUTIONS = 004, SHOW_NAME = 010 } show; #include static void print(enum show, const char *, ...); #define DUMP #include +#include #include "otf.c" #include "afm.c" -#include "dpost.d/getopt.c" #include static const char *progname; struct dev dev; char *chname; short *chtab; int nchtab; static int prname; static void print(enum show s, const char *fmt, ...) { va_list ap; if (show & s) { if (prname) printf("%s: ", filename); va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); putchar('\n'); } } void verrprint(const char *s, va_list ap) { fprintf(stderr, "%s: ", progname); vfprintf(stderr, s, ap); putc('\n', stderr); } void errprint(const char *s, ...) { va_list ap; va_start(ap, s); verrprint(s, ap); va_end(ap); } static void devinit(void) { dev.res = 72000; dev.hor = dev.vert = 1; dev.unitwidth = 1; dev.afmfonts = 1; } static void usage(void) { errprint("usage: %s [-ckns] font ...", progname); exit(2); } static int dump(const char *name) { struct afmtab A; struct stat st; FILE *fp; char *cp; - size_t l; if ((fp = fopen(filename = name, "r")) == NULL) { errprint("%s: cannot open", filename); return 1; } memset(&A, 0, sizeof A); a = &A; a->file = a->path = (char *)filename; - l = strlen(filename) + 1; - a->base = malloc(l); - n_strcpy(a->base, filename, l); + a->base = strdup(filename); a->base = basename(a->base); if ((cp = strrchr(a->base, '.')) != NULL) *cp = '\0'; if (fstat(fileno(fp), &st) < 0) { errprint("%s: cannot stat", filename); return 1; } size = st.st_size; contents = malloc(size); if (fread(contents, 1, size, fp) != size) { errprint("%s: cannot read", filename); return 1; } fclose(fp); return otfget(a, contents, size) != 0; } int main(int argc, char **argv) { int i, e = 0; progname = basename(argv[0]); devinit(); while ((i = getopt(argc, argv, "ckns")) != EOF) { switch (i) { case 'c': show |= SHOW_CHARS; break; case 'k': show |= SHOW_KERNPAIRS; break; case 'n': show |= SHOW_NAME; break; case 's': show |= SHOW_SUBSTITUTIONS; break; default: usage(); } } if (show == 0) show = 0xFFFFFFFF; if (argc < optind + 1) usage(); prname = argc > optind + 1; for (i = optind; i < argc; i++) e |= dump(argv[i]); return e; } void afmaddchar(struct afmtab *a, int C, int tp, int cl, int WX, int B[4], char *N, enum spec s, int gid) { if (N) print(SHOW_CHARS, "char %s width %d", N, _unitconv(WX)); } void afmalloc(struct afmtab *a, int n) { } void afmaddkernpair(struct afmtab *a, int ch1, int ch2, int k) { } static void kernpair(int first, int second, int x) { char *s1, *s2; if (x) { s1 = GID2SID(first); s2 = GID2SID(second); if (s1 && s2) print(SHOW_KERNPAIRS, "kernpair %s %s width %d", s1, s2, _unitconv(x)); } } static void kerninit(void) { } static void kernfinish(void) { } Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/pt.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/pt.h (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/pt.h (revision 307812) @@ -1,96 +1,96 @@ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)pt.h 1.54 (gritter) 8/19/08 */ /* t6.c */ extern int width(register tchar); extern void zapwcache(int); extern int getcw(register int); extern int abscw(int); extern int onfont(tchar); extern int getascender(void); extern int getdescender(void); extern int kernadjust(tchar, tchar); extern void xbits(register tchar, int); extern tchar setch(int); extern tchar setabs(void); extern int findft(register int, int); extern void caseps(void); extern void casps1(register int); extern int findps(register int); extern void mchbits(void); extern void setps(void); extern tchar setht(void); extern tchar setslant(void); extern void caseft(void); extern void setfont(int); extern void setwd(void); extern tchar vmot(void); extern tchar hmot(void); extern tchar mot(void); extern tchar sethl(int); extern tchar makem(register int); extern tchar getlg(tchar); extern int strlg(int, int *, int); extern void caselg(void); extern void caseflig(int); extern void casefdeferlig(void); extern void casefp(int); extern void casefps(void); extern int setfp(int, int, char *); extern int nextfp(void); extern void casecs(void); extern void casebd(void); extern void casevs(void); extern void casess(int); extern void caseminss(void); extern void caseletadj(void); extern void casefspacewidth(void); extern void casespacewidth(void); extern tchar xlss(void); extern void casetrack(void); extern void casefallback(void); extern void casehidechar(void); extern void casefzoom(void); extern double getfzoom(void); extern void casekern(void); extern void casefkern(void); extern void casepapersize(void); extern void casemediasize(void); extern void casetrimat(void); extern void casebleedat(void); extern void casecropat(void); extern void caselhang(void); extern void caserhang(void); extern void casekernpair(void); extern void casekernafter(void); extern void casekernbefore(void); extern void caseftr(void); extern void casefeature(void); extern int un2tr(int, int *); extern int tr2un(tchar, int); extern tchar setuc0(int); extern tchar setanchor(void); extern tchar setlink(void); extern tchar setulink(void); extern int pts2u(int); extern double u2pts(int); /* t10.c */ extern void ptinit(void); extern void specnames(void); extern int findch(register const char *); extern void ptout(register tchar); extern tchar *ptout0(tchar *, tchar *); extern void ptps(void); extern void ptfont(void); -extern void ptfpcmd(int, char *, char *, int); +extern void ptfpcmd(int, const char *, char *, int); extern void ptlead(void); extern void ptesc(void); extern void newpage(int); extern void ptsupplyfont(char *, char *); extern void ptlocale(const char *); extern void pttrailer(void); extern void ptstop(void); extern void dostop(void); Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/t10.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/t10.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/t10.c (revision 307812) @@ -1,1139 +1,1140 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1989 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "t10.c 1.11 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)t10.c 1.98 (gritter) 8/19/08 */ /* * Changes Copyright (c) 2014 Carsten Kunze (carsten.kunze at arcor.de) */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ +#include #include #include "tdef.h" #include #include #include #include #ifdef EUC #include #endif #include "ext.h" #include "dev.h" #include "afm.h" #include "pt.h" #include "troff.h" #include "unimap.h" #include "fontmap.h" /* * troff10.c * * typesetter interface */ int vpos = 0; /* absolute vertical position on page */ int hpos = 0; /* ditto horizontal */ int initbdtab[NFONT+1]; short *chtab; char *chname; int **fontab; char **kerntab; unsigned short **fitab; unsigned short **codetab; int Inch; int Hor; int Vert; int Unitwidth; int nfonts; static int nsizes; int nchtab; int lettrack; float horscale; static float mzoom; static int mtrack; static float mhorscale; /* these characters are used as various signals or values * in miscellaneous places. * values are set in specnames in t10.c */ int c_hyphen; int c_emdash; int c_endash; int c_rule; int c_minus; int c_fi; int c_fl; int c_ff; int c_ffi; int c_ffl; int c_acute; int c_grave; int c_under; int c_rooten; int c_boxrule; int c_lefthand; int c_dagger; struct dev dev; struct Font **fontbase; int Nfont; static int okern(tchar *, tchar *, int); static void pthorscale(int); static void pttrack(int); static void ptanchor(int); static void ptlink(int); static void ptulink(int); static void ptyon(int); static void ptchar(int, int); static void pnc(int, struct afmtab *); void growfonts(int n) { int i, j; fontbase = realloc(fontbase, n * sizeof *fontbase); memset(&fontbase[Nfont], 0, (n - Nfont) * sizeof *fontbase); fontab = realloc(fontab, n * sizeof *fontab); memset(&fontab[Nfont], 0, (n - Nfont) * sizeof *fontab); kerntab = realloc(kerntab, n * sizeof *kerntab); memset(&kerntab[Nfont], 0, (n - Nfont) * sizeof *kerntab); codetab = realloc(codetab, n * sizeof *codetab); memset(&codetab[Nfont], 0, (n - Nfont) * sizeof *codetab); fitab = realloc(fitab, n * sizeof *fitab); memset(&fitab[Nfont], 0, (n - Nfont) * sizeof *fitab); fontlab = realloc(fontlab, n * sizeof *fontlab); memset(&fontlab[Nfont], 0, (n - Nfont) * sizeof *fontlab); cstab = realloc(cstab, n * sizeof *cstab); memset(&cstab[Nfont], 0, (n - Nfont) * sizeof *cstab); ccstab = realloc(ccstab, n * sizeof *ccstab); memset(&ccstab[Nfont], 0, (n - Nfont) * sizeof *ccstab); bdtab = realloc(bdtab, n * sizeof *bdtab); memset(&bdtab[Nfont], 0, (n - Nfont) * sizeof *bdtab); tracktab = realloc(tracktab, n * sizeof *tracktab); memset(&tracktab[Nfont], 0, (n - Nfont) * sizeof *tracktab); fallbacktab = realloc(fallbacktab, n * sizeof *fallbacktab); memset(&fallbacktab[Nfont], 0, (n - Nfont) * sizeof *fallbacktab); zoomtab = realloc(zoomtab, n * sizeof *zoomtab); memset(&zoomtab[Nfont], 0, (n - Nfont) * sizeof *zoomtab); lhangtab = realloc(lhangtab, n * sizeof *lhangtab); memset(&lhangtab[Nfont], 0, (n - Nfont) * sizeof *lhangtab); rhangtab = realloc(rhangtab, n * sizeof *rhangtab); memset(&rhangtab[Nfont], 0, (n - Nfont) * sizeof *rhangtab); kernafter = realloc(kernafter, n * sizeof *kernafter); memset(&kernafter[Nfont], 0, (n - Nfont) * sizeof *kernafter); kernbefore = realloc(kernbefore, n * sizeof *kernbefore); memset(&kernbefore[Nfont], 0, (n - Nfont) * sizeof *kernbefore); ftrtab = realloc(ftrtab, n * sizeof *ftrtab); for (i = Nfont; i < n; i++) { ftrtab[i] = malloc(NCHARS * sizeof **ftrtab); for (j = 0; j < NCHARS; j++) ftrtab[i][j] = j; } lgtab = realloc(lgtab, n * sizeof *lgtab); memset(&lgtab[Nfont], 0, (n - Nfont) * sizeof *lgtab); lgrevtab = realloc(lgrevtab, n * sizeof *lgrevtab); memset(&lgrevtab[Nfont], 0, (n - Nfont) * sizeof *lgrevtab); Nfont = n; } void ptinit(void) { int i, nw; char *filebase, *p, *ap, *descp; char *p2; size_t l; size_t l2; if (!strcmp(devname, "html")) html = 1; growfonts(NFONT+1); memcpy(bdtab, initbdtab, max((NFONT+1) * sizeof *bdtab, sizeof initbdtab)); uninit(); /* open table for device, * read in resolution, size info, font info, etc. * and set params */ l = strlen(termtab) + strlen(devname) + 10; l2 = l + 3; p = malloc(l); p2 = malloc(l2); n_strcpy(p, termtab, l); termtab = p; n_strcat(termtab, "/dev", l); n_strcat(termtab, devname, l); n_strcpy(p2, termtab, l2); n_strcat(p2, "/FONTMAP", l2); rdftmap(p2); free(p2); n_strcat(termtab, "/DESC", l); /* makes "..../devXXX/DESC" */ if ((descp = readdesc(termtab)) == NULL) done3(1); memcpy(&dev, descp, sizeof dev); Inch = dev.res; Hor = dev.hor; Vert = dev.vert; Unitwidth = dev.unitwidth; nfonts = dev.nfonts; nsizes = dev.nsizes; nchtab = dev.nchtab; if (nchtab >= NCHARS - 128) { errprint("too many special characters in file %s", termtab); done3(1); } filebase = malloc(dev.filesize + 3*EXTRAFONT); /* enough room for whole file */ memcpy(filebase, &descp[sizeof dev], dev.filesize); /* all at once */ free(descp); pstab = (int *) filebase; for (i = 0; pstab[i]; i++) pstab[i] = pts2u(pstab[i]); chtab = (short *)(pstab + nsizes + 1); chname = (char *) (chtab + dev.nchtab); p = chname + dev.lchname; specnames(); /* install names like "hyphen", etc. */ for (i = 1; i <= nfonts; i++) { fontbase[i] = (struct Font *) p; nw = *p & BYTEMASK; /* 1st thing is width count */ fontlab[i] = PAIR(fontbase[i]->namefont[0], fontbase[i]->namefont[1]); /* for now, still 2 char names */ if (smnt == 0 && fontbase[i]->specfont == 1) smnt = i; /* first special font */ p += sizeof(struct Font); /* that's what's on the beginning */ if ((ap = strstr(fontbase[i]->namefont, ".afm")) != NULL) { *ap = 0; if (ap == &fontbase[i]->namefont[1]) fontlab[i] &= BYTEMASK; loadafm(i, fontlab[i], fontbase[i]->namefont, NULL, 1, SPEC_NONE); } else { makefont(i, p, p + nw, p + 2 * nw, p + 3 * nw, nw); } p += 3 * nw + dev.nchtab + 128 - 32; } fontbase[0] = (struct Font *) p; /* the last shall be first */ memset(fontbase[0], 0, sizeof *fontbase[0]); nw = EXTRAFONT - dev.nchtab - (128-32) - sizeof (struct Font); fontbase[0]->nwfont = nw; makefont(0, p, p + nw, p + 2 * nw, p + 3 * nw, nw); /* there are a lot of things that used to be constant * that now require code to be executed. */ sps = SPS; ses = SES; for (i = 0; i < 16; i++) tabtab[i] = DTAB * (i + 1); pl = 11 * INCH; po = PO; spacesz = SS; sesspsz = SSS; lss = lss1 = VS; ll = ll1 = lt = lt1 = LL; apts = pts2u(apts); apts1 = pts2u(apts1); pts = pts2u(pts); pts1 = pts2u(pts1); ics = ICS; for (i = 0; i <= nfonts; i++) setlig(i, fontbase[i]->ligfont); kern = xflag; if (ascii) return; - fdprintf(ptid, "x T %s\n", devname); - fdprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert); - fdprintf(ptid, "x init\n"); /* do initialization for particular device */ + dprintf(ptid, "x T %s\n", devname); + dprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert); + dprintf(ptid, "x init\n"); /* do initialization for particular device */ /* for (i = 1; i <= nfonts; i++) - fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont); - fdprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth); - fdprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n", + dprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont); + dprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth); + dprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n", dev.nchtab, dev.lchname, dev.nchtab+128-32); - fdprintf(ptid, "x xxx sizes:\nx xxx "); + dprintf(ptid, "x xxx sizes:\nx xxx "); for (i = 0; i < nsizes; i++) - fdprintf(ptid, " %d", pstab[i]); - fdprintf(ptid, "\nx xxx chars:\nx xxx "); + dprintf(ptid, " %d", pstab[i]); + dprintf(ptid, "\nx xxx chars:\nx xxx "); for (i = 0; i < dev.nchtab; i++) - fdprintf(ptid, " %s", &chname[chtab[i]]); - fdprintf(ptid, "\nx xxx\n"); + dprintf(ptid, " %s", &chname[chtab[i]]); + dprintf(ptid, "\nx xxx\n"); */ #ifdef EUC ptlocale(setlocale(LC_CTYPE, NULL)); #endif /* EUC */ free(termtab); } void specnames(void) { static struct { int *n; const char *v; } spnames[] = { { &c_hyphen , "hy" }, { &c_emdash , "em" }, { &c_endash , "en" }, { &c_rule , "ru" }, { &c_minus , "\\-"}, { &c_fi , "fi" }, { &c_fl , "fl" }, { &c_ff , "ff" }, { &c_ffi , "Fi" }, { &c_ffl , "Fl" }, { &c_acute , "aa" }, { &c_grave , "ga" }, { &c_under , "ul" }, { &c_rooten , "rn" }, { &c_boxrule , "br" }, { &c_lefthand, "lh" }, { &c_dagger , "dg" }, { 0 , 0 } }; static int twice; int i; if (twice++) return; for (i = 0; spnames[i].n; i++) *spnames[i].n = findch(spnames[i].v); } int findch(register const char *s) /* find char s in chname */ { register int i; for (i = 0; i < nchtab; i++) if (strcmp(s, &chname[chtab[i]]) == 0) return(i + 128); return(0); } void ptout(register tchar i) { register int dv; register tchar *k; int temp, a, b; if (isadjspc(i)) return; if (olinep >= &oline[olinesz]) { olinesz += 100; k = realloc(oline, olinesz * sizeof *oline); olinep = (tchar *)((char *)olinep + ((char *)k-(char *)oline)); oline = k; } if (cbits(i) != '\n') { *olinep++ = i; return; } if (olinep == oline) { lead += lss; return; } hpos = po; /* ??? */ esc = 0; /* ??? */ ptesc(); /* the problem is to get back to the left end of the line */ dv = 0; for (k = oline; k < olinep; k++) { if (ismot(*k) && isvmot(*k)) { temp = absmot(*k); if (isnmot(*k)) temp = -temp; dv += temp; } } if (dv) { vflag++; *olinep++ = makem(-dv); vflag = 0; } b = dip->blss + lss; lead += dip->blss + lss; dip->blss = 0; if (linkout) linkhp = hpos; for (k = oline; k < olinep; ) k = ptout0(k, olinep); /* now passing a pointer! */ olinep = oline; lead += dip->alss; a = dip->alss; dip->alss = 0; if (linkout) ptlink(linkout); /* - fdprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos); + dprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos); */ - fdprintf(ptid, "n%d %d\n", b, a); /* be nice to chuck */ + dprintf(ptid, "n%d %d\n", b, a); /* be nice to chuck */ } tchar * ptout0(tchar *pi, tchar *pend) { struct afmtab *a; register int j; register int k, w = 0; int z, dx, dy, dx2, dy2, n, c; register tchar i; int outsize; /* size of object being printed */ double f; int tfont; outsize = 1; /* default */ i = *pi; k = cbits(i); if (k == FILLER) return(pi+outsize); if (ismot(i)) { j = absmot(i); if (isnmot(i)) j = -j; if (isvmot(i)) lead += j; else esc += j; return(pi+outsize); } if (k == XON) { if (xfont != mfont) ptfont(); if (xpts != mpts || zoomtab[xfont] != mzoom) ptps(); if (lead) ptlead(); if (esc) ptesc(); - fdprintf(ptid, "x X "); + dprintf(ptid, "x X "); /* * not guaranteed of finding a XOFF if a word overflow * error occured, so also bound this loop by olinep */ pi++; while( cbits(*pi) != XOFF && pi < olinep ) outascii(*pi++); oput('\n'); if ( cbits(*pi) == XOFF ) pi++; return pi; } ; if (k == CHARHT) { if (xflag) { xfont = fbits(i); if (xfont != mfont) ptfont(); } if (xpts != mpts || zoomtab[xfont] != mzoom) ptps(); j = f = u2pts(sbits(i)); if (j != f && xflag && dev.anysize) - fdprintf(ptid, "x H -23 %g\n", f); + dprintf(ptid, "x H -23 %g\n", f); else - fdprintf(ptid, "x H %d\n", j); + dprintf(ptid, "x H %d\n", j); return(pi+outsize); } if (k == SLANT) { if (xflag) { xfont = fbits(i); if (xfont != mfont) ptfont(); } - fdprintf(ptid, "x S %d\n", (int)sbits(i)-180); + dprintf(ptid, "x S %d\n", (int)sbits(i)-180); return(pi+outsize); } if (k == WORDSP) { oput('w'); return(pi+outsize); } if (k == FONTPOS) { n = i >> 22; ptfpcmd(0, macname(n), NULL, 0); return(pi+outsize); } if (k == XFUNC) { switch (fbits(i)) { case ANCHOR: ptanchor(sbits(i)); return(pi+outsize); case LINKON: linkout = sbits(i); linkhp = hpos + esc; if (html) ptlink(sbits(i)); return(pi+outsize); case LINKOFF: ptlink(html ? 0 : sbits(i)); linkout = 0; return(pi+outsize); case ULINKON: linkout = sbits(i); linkhp = hpos + esc; if (html) ptulink(sbits(i)); return(pi+outsize); case ULINKOFF: ptulink(html ? 0 : sbits(i)); linkout = 0; return(pi+outsize); case INDENT: if (linkout) linkhp += sbits(i); return(pi+outsize); case LETSP: lettrack = sbits(i); return(pi+outsize); case NLETSP: lettrack = -sbits(i); return(pi+outsize); case LETSH: horscale = 1 + (double)sbits(i) / LAFACT; return(pi+outsize); case NLETSH: horscale = 1 - (double)sbits(i) / LAFACT; return(pi+outsize); case YON: if (&pi[outsize] >= pend) return(pi+outsize); ptyon(fetchrq(&pi[outsize])); return(pi+outsize+1); case CHAR: ptchar(sbits(i), iszbit(i) != 0); if (!iszbit(i)) esc += okern(pi, pend, outsize); return(pi+outsize); default: return(pi+outsize); } } if (sfbits(i) == oldbits) { xfont = pfont; xpts = ppts; } else xbits(i, 2); if (k < 040 && k != DRAWFCN) return(pi+outsize); if (k >= 32) { if (html && k >= NCHARS) w = getcw(0); else if (widcache[k-32].fontpts == xfont + (xpts<<8) && !setwdf && kern == 0 && horscale == 0) { w = widcache[k-32].width; lasttrack = widcache[k-32].track; bd = 0; cs = 0; } else { tfont = xfont; w = getcw(k-32); if (tfont != xfont) k = ftrans(xfont, k); } } if (xfont != mfont) ptfont(); if (xpts != mpts || zoomtab[xfont] != mzoom) ptps(); if (lead) ptlead(); if (lettrack || lasttrack || mtrack) pttrack(0); if (horscale || mhorscale) pthorscale(0); w += okern(pi, pend, outsize); if (afmtab && (j = (fontbase[xfont]->afmpos) - 1) >= 0) a = afmtab[j]; else a = NULL; j = z = 0; if (k != DRAWFCN) { if (cs && !fmtchar) { if (bd) w += (bd - 1) * HOR; j = (cs - w) / 2; w = cs - j; if (bd) w -= (bd - 1) * HOR; } if (iszbit(i)) { if (cs && !fmtchar) w = -j; else w = 0; z = 1; } } esc += j; /* put out the real character here */ if (k == DRAWFCN) { if (esc) ptesc(); dx = absmot(pi[3]); if (isnmot(pi[3])) dx = -dx; dy = absmot(pi[4]); if (isnmot(pi[4])) dy = -dy; switch ((c=cbits(pi[1]))) { case DRAWCIRCLE: /* circle */ case DRAWCIRCLEFI: - fdprintf(ptid, "D%c %d\n", c, dx); /* dx is diameter */ + dprintf(ptid, "D%c %d\n", c, dx); /* dx is diameter */ w = 0; hpos += dx; break; case DRAWELLIPSE: case DRAWELLIPSEFI: - fdprintf(ptid, "D%c %d %d\n", c, dx, dy); + dprintf(ptid, "D%c %d %d\n", c, dx, dy); w = 0; hpos += dx; break; case DRAWLINE: /* line */ k = cbits(pi[2]); - fdprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy); + dprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy); if (k < 128) - fdprintf(ptid, "%c\n", k); + dprintf(ptid, "%c\n", k); else - fdprintf(ptid, "%s\n", &chname[chtab[k - 128]]); + dprintf(ptid, "%s\n", &chname[chtab[k - 128]]); w = 0; hpos += dx; vpos += dy; break; case DRAWARC: /* arc */ dx2 = absmot(pi[5]); if (isnmot(pi[5])) dx2 = -dx2; dy2 = absmot(pi[6]); if (isnmot(pi[6])) dy2 = -dy2; - fdprintf(ptid, "D%c %d %d %d %d\n", DRAWARC, + dprintf(ptid, "D%c %d %d %d %d\n", DRAWARC, dx, dy, dx2, dy2); w = 0; hpos += dx + dx2; vpos += dy + dy2; break; case DRAWSPLINE: /* spline */ default: /* something else; copy it like spline */ - fdprintf(ptid, "D%c %d %d", (int)cbits(pi[1]), dx, dy); + dprintf(ptid, "D%c %d %d", (int)cbits(pi[1]), dx, dy); w = 0; hpos += dx; vpos += dy; if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) { /* it was somehow defective */ - fdprintf(ptid, "\n"); + dprintf(ptid, "\n"); break; } for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) { dx = absmot(pi[n]); if (isnmot(pi[n])) dx = -dx; dy = absmot(pi[n+1]); if (isnmot(pi[n+1])) dy = -dy; - fdprintf(ptid, " %d %d", dx, dy); + dprintf(ptid, " %d %d", dx, dy); hpos += dx; vpos += dy; } - fdprintf(ptid, "\n"); + dprintf(ptid, "\n"); break; } for (n = 3; cbits(pi[n]) != DRAWFCN; n++) ; outsize = n + 1; } else if (k < 128) { /* try to go faster and compress output */ /* by printing nnc for small positive motion followed by c */ /* kludgery; have to make sure set all the vars too */ if (esc > 0 && esc < 100) { oput(esc / 10 + '0'); oput(esc % 10 + '0'); oput(k); hpos += esc; esc = 0; } else { if (esc) ptesc(); oput('c'); oput(k); oput('\n'); } } else { if (esc) ptesc(); pnc(k, a); } if (bd && !fmtchar) { bd -= HOR; if (esc += bd) ptesc(); if (k < 128) { - fdprintf(ptid, "c%c\n", k); + dprintf(ptid, "c%c\n", k); } else pnc(k, a); if (z) esc -= bd; } esc += w; lettrack = 0; horscale = 0; return(pi+outsize); } static void pnc(int k, struct afmtab *a) { int j; if (k >= nchtab + 128) { if (a && (j = a->fitab[k-nchtab-128-32]) < a->nchars && a->nametab[j] != NULL) { - fdprintf(ptid, "CPS%s\n", a->nametab[j]); + dprintf(ptid, "CPS%s\n", a->nametab[j]); } else { - fdprintf(ptid, "N%d\n", + dprintf(ptid, "N%d\n", k - (html ? 0 : (nchtab + 128)) ); } } else { - fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); + dprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); } } static int okern(tchar *pi, tchar *pend, int outsize) { int j; for (j = outsize; &pi[j] < pend; j++) if (cbits(pi[j]) != XFUNC || (fbits(pi[j]) != LETSP && fbits(pi[j]) != NLETSP && fbits(pi[j]) != LETSH && fbits(pi[j]) != NLETSH)) break; if (&pi[j] < pend) return getkw(pi[0], pi[j]); else return 0; } static void pthorscale(int always) { if (horscale || mhorscale) { if (always || mhorscale != horscale) - fdprintf(ptid, "x X HorScale %g\n", + dprintf(ptid, "x X HorScale %g\n", horscale ? horscale : 1.0); mhorscale = horscale; } else mhorscale = 0; } static void pttrack(int always) { if (xflag && (lasttrack || lettrack || mtrack)) { if (always || mtrack != (lasttrack + lettrack)) - fdprintf(ptid, "x X Track %d\n", lasttrack + lettrack); + dprintf(ptid, "x X Track %d\n", lasttrack + lettrack); mtrack = lasttrack + lettrack; } else mtrack = 0; } void ptps(void) { register int i, j, k; double s, z; int found; i = xpts; for (j = 0; i > (k = pstab[j]); j++) if (!k) { k = pstab[--j]; break; } found = k == i; if (dev.anysize && xflag) k = i; s = u2pts(k); if ((z = zoomtab[xfont]) != 0 && dev.anysize && xflag) s *= z; if (dev.anysize && xflag && (!found || (z != 0 && z != 1))) - fdprintf(ptid, "s-23 %g\n", s); + dprintf(ptid, "s-23 %g\n", s); else - fdprintf(ptid, "s%d\n", (int)s); /* really should put out string rep of size */ + dprintf(ptid, "s%d\n", (int)s); /* really should put out string rep of size */ mpts = i; mzoom = z; pttrack(0); pthorscale(0); } void ptfont(void) { mfont = xfont; - fdprintf(ptid, "f%d\n", xfont); + dprintf(ptid, "f%d\n", xfont); mtrack = 0; pttrack(1); pthorscale(1); } void -ptfpcmd(int f, char *s, char *path, int flags) +ptfpcmd(int f, const char *s, char *path, int flags) { if (ascii) return; - fdprintf(ptid, "x font %d %s", f, s); + dprintf(ptid, "x font %d %s", f, s); if (path) { - fdprintf(ptid, " %s", path); + dprintf(ptid, " %s", path); if (flags) - fdprintf(ptid, " %d", flags); + dprintf(ptid, " %d", flags); } - fdprintf(ptid, "\n"); + dprintf(ptid, "\n"); ptfont(); /* make sure that it gets noticed */ } void ptlead(void) { vpos += lead; if (!ascii) - fdprintf(ptid, "V%d\n", vpos); + dprintf(ptid, "V%d\n", vpos); lead = 0; } void ptesc(void) { hpos += esc; if (esc > 0) { oput('h'); if (esc>=10 && esc<100) { oput(esc/10 + '0'); oput(esc%10 + '0'); } else - fdprintf(ptid, "%d", esc); + dprintf(ptid, "%d", esc); } else - fdprintf(ptid, "H%d\n", hpos); + dprintf(ptid, "H%d\n", hpos); esc = 0; } void ptsupplyfont(char *fontname, char *file) { if (ascii) return; - fdprintf(ptid, "x X SupplyFont %s %s\n", fontname, file); + dprintf(ptid, "x X SupplyFont %s %s\n", fontname, file); } void ptpapersize(void) { if (ascii || mediasize.flag == 0) return; - fdprintf(ptid, "x X PaperSize %d %d %d\n", + dprintf(ptid, "x X PaperSize %d %d %d\n", mediasize.val[2], mediasize.val[3], mediasize.flag&2?1:0); } static void cut1(const char *name, struct box *bp) { if (bp->flag) - fdprintf(ptid, "x X %s %d %d %d %d\n", name, + dprintf(ptid, "x X %s %d %d %d %d\n", name, bp->val[0], bp->val[1], bp->val[2], bp->val[3]); } void ptcut(void) { if (ascii) return; cut1("TrimAt", &trimat); cut1("BleedAt", &bleedat); cut1("CropAt", &cropat); } void ptlocale(const char *cp) { static char *lp; if (cp != NULL) { size_t l; free(lp); l = strlen(cp) + 1; lp = malloc(l); n_strcpy(lp, cp, l); } if (ascii || realpage == 0 || lp == NULL || dev.lc_ctype == 0) return; - fdprintf(ptid, "x X LC_CTYPE %s\n", lp); + dprintf(ptid, "x X LC_CTYPE %s\n", lp); } static void ptanchor(int n) { struct ref *rp; if (ascii) return; for (rp = anchors; rp; rp = rp->next) if (rp->cnt == n) { if (html) { - fdprintf(ptid, "x X Anchor %s\n", rp->name); + dprintf(ptid, "x X Anchor %s\n", rp->name); } else { - fdprintf(ptid, "x X Anchor %d,%d %s\n", + dprintf(ptid, "x X Anchor %d,%d %s\n", vpos + lead - lss, hpos + esc, rp->name); } break; } } static void _ptlink(int n, struct ref *rstart, const char *type) { struct ref *rp; if (ascii) return; if (html && !n) { - fdprintf(ptid, "x X %s\n", type); + dprintf(ptid, "x X %s\n", type); return; } for (rp = rstart; rp; rp = rp->next) if (rp->cnt == n) { if (html) - fdprintf(ptid, "x X %s %s\n", type, rp->name); + dprintf(ptid, "x X %s %s\n", type, rp->name); else - fdprintf(ptid, "x X %s %d,%d,%d,%d %s\n", + dprintf(ptid, "x X %s %d,%d,%d,%d %s\n", type, linkhp, vpos + pts2u(1), hpos + esc, vpos - pts * 8 / 10, rp->name); break; } } static void ptlink(int n) { _ptlink(n, links, "Link"); } static void ptulink(int n) { _ptlink(n, ulinks, "ULink"); } static void ptyon(int i) { struct contab *cp; tchar c; int k, nl; filep savip; if ((cp = findmx(i)) == NULL || !cp->mx) { nosuch(i); return; } if (xfont != mfont) ptfont(); if (xpts != mpts || zoomtab[xfont] != mzoom) ptps(); if (lead) ptlead(); if (esc) ptesc(); - fdprintf(ptid, "x X "); + dprintf(ptid, "x X "); savip = ip; ip = (filep)cp->mx; app = 1; k = -1; nl = 0; while ((c = rbf()) != 0) { if ((k = cbits(c)) != '\n') { while (nl--) oputs("\n+"); nl = 0; outascii(c); } else nl++; } while (nl-- > 1) oputs("\n+"); oput('\n'); app = 0; ip = savip; } static void ptchar1(struct charout *cp, int z) { filep savip; tchar i, *k, *savoline, *savolinep; size_t savolinesz; int savhpos, savvpos, savlettrack; savoline = oline; savolinep = olinep; savolinesz = olinesz; olinep = oline = NULL; olinesz = 0; savlettrack = lettrack; lettrack = 0; savhpos = hpos + esc; savvpos = vpos + lead; savip = ip; ip = cp->op; app++; fmtchar++; while ((i = rbf()) != 0 && cbits(i) != '\n' && cbits(i) != FLSS) pchar(i); for (k = oline; k < olinep; ) k = ptout0(k, olinep); fmtchar--; app--; ip = savip; free(oline); oline = savoline; olinep = savolinep; olinesz = savolinesz; lettrack = savlettrack; esc = savhpos - hpos; if (!z) esc += cs ? cs : cp->width + lettrack; lead = savvpos - vpos; } static void ptchar(int n, int z) { struct charout *cp = &charout[n]; int savbd; ptchar1(cp, z); if (bd) { bd -= HOR; if (esc += bd) ptesc(); savbd = bd; bd = 0; ptchar1(cp, z); bd = savbd; if (iszbit(cp->ch)) esc -= bd; } lettrack = 0; } void newpage(int n) /* called at end of each output page (we hope) */ { int i; realpage++; ptlead(); vpos = 0; if (ascii) return; - fdprintf(ptid, "p%d\n", n); /* new page */ + dprintf(ptid, "p%d\n", n); /* new page */ for (i = 0; i <= nfonts; i++) { if (fontbase[i] == NULL) continue; if (afmtab && fontbase[i]->afmpos) { struct afmtab *a = afmtab[(fontbase[i]->afmpos)-1]; if (a->encpath == NULL) a->encpath = afmencodepath(a->path); - fdprintf(ptid, "x font %d %s %s %d\n", i, + dprintf(ptid, "x font %d %s %s %d\n", i, macname(fontlab[i]), a->encpath, (int)a->spec); if (a->supply) ptsupplyfont(a->fontname, a->supply); } else if (fontbase[i]->namefont[0]) - fdprintf(ptid, "x font %d %s\n", i, macname(fontlab[i])); + dprintf(ptid, "x font %d %s\n", i, macname(fontlab[i])); } ptps(); ptfont(); ptpapersize(); ptcut(); ptlocale(NULL); } void pttrailer(void) { - fdprintf(ptid, "x trailer\n"); + dprintf(ptid, "x trailer\n"); } void ptstop(void) { - fdprintf(ptid, "x stop\n"); + dprintf(ptid, "x stop\n"); } void dostop(void) { if (ascii) return; ptlead(); vpos = 0; - /* fdprintf(ptid, "x xxx end of page\n");*/ + /* dprintf(ptid, "x xxx end of page\n");*/ if (!nofeed) pttrailer(); ptlead(); - fdprintf(ptid, "x pause\n"); + dprintf(ptid, "x pause\n"); flusho(); mpts = mfont = 0; ptesc(); esc = po; hpos = vpos = 0; /* probably in wrong place */ } Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/t6.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/t6.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/t6.c (revision 307812) @@ -1,3037 +1,3030 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* from OpenSolaris "t6.c 1.9 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)t6.c 1.194 (gritter) 2/7/10 */ /* * Changes Copyright (c) 2014 Carsten Kunze */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ /* * t6.c * * width functions, sizes and fonts */ #include #include #include #include #include #include "tdef.h" #include "dev.h" #include #include #include #include #include "ext.h" #include "afm.h" #include "pt.h" #include "troff.h" #include "fontmap.h" /* fitab[f][c] is 0 if c is not on font f */ /* if it's non-zero, c is in fontab[f] at position * fitab[f][c]. */ int *fontlab; int *pstab; int *cstab; int *ccstab; int **fallbacktab; float *zoomtab; int *bdtab; int **lhangtab; int **rhangtab; int **kernafter; int **kernbefore; int **ftrtab; struct lgtab **lgtab; int ***lgrevtab; struct tracktab *tracktab; static int sbold = 0; int kern = 0; struct box mediasize, bleedat, trimat, cropat; int psmaxcode; struct ref *anchors, *links, *ulinks; static int _minflg; int lastrst; int lastrsb; static int spacewidth; static void kernsingle(int **); static int _ps2cc(const char *name, int create); int width(register tchar j) { register int i, k; _minflg = minflg; minflg = minspc = 0; lasttrack = 0; rawwidth = 0; lastrst = lastrsb = 0; if (isadjspc(j)) return(0); if (j & (ZBIT|MOT)) { if (iszbit(j)) return(0); if (isvmot(j)) return(0); k = absmot(j); if (isnmot(j)) k = -k; return(k); } i = cbits(j); if (html && i >= NCHARS) i = ' '; if (i < ' ') { if (i == '\b') return(-widthp); if (i == PRESC) i = eschar; else if (iscontrol(i)) return(0); else if (isxfunc(j, CHAR)) { k = charout[sbits(j)].width + lettrack; lastrst = charout[sbits(j)].height; lastrsb = -charout[sbits(j)].depth; goto set; } } else if (i == ' ' && issentsp(j)) { _minflg = 0; return(ses); } if (i==ohc) return(0); if (!xflag || !isdi(j)) { if (i == STRETCH) setcbits(j, ' '); i = trtab[i]; i = ftrans(fbits(j), i); } if (i < 32) return(0); lasttrack = 0; if (sfbits(j) == oldbits) { xfont = pfont; xpts = ppts; } else xbits(j, 0); if (widcache[i-32].fontpts == xfont + (xpts<<8) && (i > 32 || widcache[i-32].evid == evname) && !setwdf && !_minflg && !horscale) { rawwidth = widcache[i-32].width - widcache[i-32].track; k = widcache[i-32].width + lettrack; lastrst = widcache[i-32].rst; lastrsb = widcache[i-32].rsb; lasttrack = widcache[i-32].track; } else { if (_minflg && i == 32 && cbits(j) != 32) _minflg = 0; k = getcw(i-32); if (i == 32 && _minflg && !cs) { _minflg = 0; minspc = getcw(0) - k; } _minflg = 0; set: if (bd && !fmtchar) k += (bd - 1) * HOR; if (cs && !fmtchar) k = cs; } widthp = k; return(k); } /* * clear width cache-- s means just space */ void zapwcache(int s) { register int i; if (s) { widcache[0].fontpts = 0; return; } for (i=0; i= nchtab + 128-32) { if (afmtab && fontbase[xfont]->afmpos - 1 >= 0) { cd = nchtab + 128; i -= cd; } else { j = abscw(i + 32 - (nchtab+128)); goto g0; } } if (i == 0) { /* a blank */ if (_minflg) { j = minspsz; nocache = 1; } else j = spacesz; if (fontbase[xfont]->cspacewidth >= 0) k = fontbase[xfont]->cspacewidth; else if (spacewidth || gflag) k = fontbase[xfont]->spacewidth; else k = fontab[xfont][0]; k = (k * j + 6) / 12; lastrst = lastrsb = 0; /* this nonsense because .ss cmd uses 1/36 em as its units */ /* and default is 12 */ goto g1; } if ((j = fitab[xfont][i]) == 0) { /* it's not on current font */ int ii, jj, _t; /* search through search list of xfont * to see what font it ought to be on. * first searches explicit fallbacks, then * searches S, then remaining fonts in wraparound order. */ nocache = 1; if (fallbacktab[xfont]) { for (jj = 0; fallbacktab[xfont][jj] != 0; jj++) { if ((ii = findft(fallbacktab[xfont][jj],0)) < 0) continue; _t = ftrans(ii, i + 32) - 32; j = fitab[ii][_t]; if (j != 0) { xfont = ii; goto found; } } } if (smnt) { for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) { if (fontbase[ii] == NULL) continue; _t = ftrans(ii, i + 32) - 32; j = fitab[ii][_t]; if (j != 0) { /* * troff traditionally relies on the * device postprocessor to find the * appropriate character since it * searches the fonts in the same * order. This does not work with the * new requests anymore, so change * the font explicitly. */ if (xflag) xfont = ii; found: p = fontab[ii]; k = *(p + j); if (afmtab && (_t=fontbase[ii]->afmpos-1)>=0) { a = afmtab[_t]; if (a->bbtab[j]) { lastrst = a->bbtab[j][3]; lastrsb = a->bbtab[j][1]; } else { lastrst = a->ascender; lastrsb = a->descender; } } if (xfont == sbold) bd = bdtab[ii]; if (setwdf) numtab[CT].val |= kerntab[ii][j]; goto g1; } } } k = fontab[xfont][0]; /* leave a space-size space */ lastrst = lastrsb = 0; goto g1; } g0: p = fontab[xfont]; if (setwdf) numtab[CT].val |= kerntab[xfont][j]; if (afmtab && (t = fontbase[xfont]->afmpos-1) >= 0) { a = afmtab[t]; if (a->bbtab[j]) { lastrst = a->bbtab[j][3]; lastrsb = a->bbtab[j][1]; } else { /* * Avoid zero values by all means. In many use * cases, endless loops will result unless values * are non-zero. */ lastrst = a->ascender; lastrsb = a->descender; } } k = *(p + j); if (dev.anysize == 0 || xflag == 0 || (z = zoomtab[xfont]) == 0) z = 1; g1: zv = z; if (horscale) { z *= horscale; nocache = 1; } if (!bd) bd = bdtab[ofont]; if ((cs = cstab[ofont])) { nocache = 1; if ((ccs = ccstab[ofont])) x = pts2u(ccs); else x = xpts; cs = (cs * EMPTS(x)) / 36; } k = (k * z * u2pts(xpts) + (Unitwidth / 2)) / Unitwidth; lastrst = (lastrst * zv * u2pts(xpts) + (Unitwidth / 2)) / Unitwidth; lastrsb = (lastrsb * zv * u2pts(xpts) + (Unitwidth / 2)) / Unitwidth; rawwidth = k; s = xpts; lasttrack = 0; if (s <= tracktab[ofont].s1 && tracktab[ofont].n1) lasttrack = tracktab[ofont].n1; else if (s >= tracktab[ofont].s2 && tracktab[ofont].n2) lasttrack = tracktab[ofont].n2; else if (s > tracktab[ofont].s1 && s < tracktab[ofont].s2) { int r; r = (s * tracktab[ofont].n2 - s * tracktab[ofont].n1 + tracktab[ofont].s2 * tracktab[ofont].n1 - tracktab[ofont].s1 * tracktab[ofont].n2) / (tracktab[ofont].s2 - tracktab[ofont].s1); if (r != 0) lasttrack = r; } k += lasttrack + lettrack; i += cd; if (nocache|bd) widcache[i].fontpts = 0; else { widcache[i].fontpts = xfont + (xpts<<8); widcache[i].width = k - lettrack; widcache[i].rst = lastrst; widcache[i].rsb = lastrsb; widcache[i].track = lasttrack; widcache[i].evid = evname; } return(k); /* Unitwidth is Units/Point, where * Units is the fundamental digitization * of the character set widths, and * Point is the number of goobies in a point * e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6 * In effect, it's the size at which the widths * translate directly into units. */ } int abscw(int n) /* return index of abs char n in fontab[], etc. */ { register int i, ncf; ncf = fontbase[xfont]->nwfont & BYTEMASK; for (i = 0; i < ncf; i++) if (codetab[xfont][i] == n) return i; return 0; } int onfont(tchar c) { int k = cbits(c); int f = fbits(c); if (k <= ' ') return 1; k -= 32; if (k >= nchtab + 128-32) { if (afmtab && fontbase[f]->afmpos - 1 >= 0) k -= nchtab + 128; else return abscw(k + 32 - (nchtab+128)) != 0; } return fitab[f][k] != 0; } static int fvert2pts(int f, int s, int k) { double z; if (k != 0) { k = (k * u2pts(s) + (Unitwidth / 2)) / Unitwidth; if (dev.anysize && xflag && (z = zoomtab[f]) != 0) k *= z; } return k; } int getascender(void) { struct afmtab *a; int n; if ((n = fontbase[font]->afmpos - 1) >= 0) { a = afmtab[n]; return fvert2pts(font, pts, a->ascender); } else return 0; } int getdescender(void) { struct afmtab *a; int n; if ((n = fontbase[font]->afmpos - 1) >= 0) { a = afmtab[n]; return fvert2pts(font, pts, a->descender); } else return 0; } int kernadjust(tchar c, tchar e) { lastkern = 0; if (!kern || ismot(c) || ismot(e) || html) return 0; if (!isdi(c)) { c = trtab[cbits(c)] | (c & SFMASK); c = ftrans(fbits(c), cbits(c)) | (c & SFMASK); } if (!isdi(e)) { e = trtab[cbits(e)] | (e & SFMASK); e = ftrans(fbits(e), cbits(e)) | (e & SFMASK); } return getkw(c, e); } #define kprime 1021 #define khash(c, d) (((2654435769U * (c) * (d) >> 16)&0x7fffffff) % kprime) static struct knode { struct knode *next; tchar c; tchar d; int n; } **ktable; static void kadd(tchar c, tchar e, int n) { struct knode *kn; int h; if (ktable == NULL) ktable = calloc(kprime, sizeof *ktable); h = khash(c, e); kn = calloc(1, sizeof *kn); kn->c = c; kn->d = e; kn->n = n; kn->next = ktable[h]; ktable[h] = kn; } static void kzap(int f) { struct knode *kp; int i; if (ktable == NULL) return; for (i = 0; i < kprime; i++) for (kp = ktable[i]; kp; kp = kp->next) if (fbits(kp->c) == f || fbits(kp->d) == f) kp->n = INT_MAX; } static tchar findchar(tchar c) { int f, i; f = fbits(c); c = cbits(c); i = c - 32; if (c != ' ' && i > 0 && i < nchtab + 128 - 32 && fitab[f][i] == 0) { int ii, jj; if (fallbacktab[f]) { for (jj = 0; fallbacktab[f][jj] != 0; jj++) { if ((ii = findft(fallbacktab[f][jj], 0)) < 0) continue; if (fitab[ii][i] != 0) { f = ii; goto found; } } } if (smnt) { for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) { if (fontbase[ii] == NULL) continue; if (fitab[ii][i] != 0) { f = ii; goto found; } } } return 0; } found: setfbits(c, f); return c; } static struct knode * klook(tchar c, tchar e) { struct knode *kp; int h; c = findchar(c); e = findchar(e); h = khash(c, e); for (kp = ktable[h]; kp; kp = kp->next) if (kp->c == c && kp->d == e) break; return kp && kp->n != INT_MAX ? kp : NULL; } int getkw(tchar c, tchar e) { struct knode *kp; struct afmtab *a; int f, g, i, j, k, n, s, I, J; double z; if (isxfunc(c, CHAR)) c = charout[sbits(c)].ch; if (isxfunc(e, CHAR)) e = charout[sbits(e)].ch; lastkern = 0; if (!kern || iszbit(c) || iszbit(e) || ismot(c) || ismot(e)) return 0; if (sbits(c) != sbits(e)) return 0; f = fbits(c); g = fbits(e); if ((s = sbits(c)) == 0) { s = xpts; if (f == 0) f = xfont; } i = cbits(c); j = cbits(e); if (i == SLANT || j == SLANT || i == XFUNC || j == XFUNC || cstab[f]) return 0; k = 0; if (i >= 32 && j >= 32) { if (ktable != NULL && (kp = klook(c, e)) != NULL) k = kp->n; else if ((n = (fontbase[f]->afmpos)-1) >= 0 && n == (fontbase[g]->afmpos)-1 && fontbase[f]->kernfont >= 0) { a = afmtab[n]; I = i - 32; J = j - 32; if (I >= nchtab + 128) I -= nchtab + 128; if (J >= nchtab + 128) J -= nchtab + 128; k = afmgetkern(a, I, J); if (abs(k) < fontbase[f]->kernfont) k = 0; } if (j>32 && kernafter != NULL && kernafter[fbits(c)] != NULL) k += kernafter[fbits(c)][i]; if (i>32 && kernbefore != NULL && kernbefore[fbits(e)] != NULL) k += kernbefore[fbits(e)][j]; } if (k != 0) { k = (k * u2pts(s) + (Unitwidth / 2)) / Unitwidth; if (dev.anysize && xflag && (z = zoomtab[f]) != 0) k *= z; } lastkern = k; return k; } void xbits(register tchar i, int bitf) { register int k; xfont = fbits(i); k = sbits(i); if (k) { xpts = dev.anysize && xflag ? k : pstab[--k]; oldbits = sfbits(i); pfont = xfont; ppts = xpts; return; } switch (bitf) { case 0: xfont = font; xpts = pts; break; case 1: xfont = pfont; xpts = ppts; break; case 2: xfont = mfont; xpts = mpts; } } static tchar postchar1(const char *temp, int f) { struct namecache *np; struct afmtab *a; int i; if (afmtab && (i = (fontbase[f]->afmpos) - 1) >= 0) { a = afmtab[i]; np = afmnamelook(a, temp); if (np->afpos != 0) { if (np->fival[0] != NOCODE && fitab[f][np->fival[0]]) return np->fival[0] + 32 + nchtab + 128; else if (np->fival[1] != NOCODE && fitab[f][np->fival[1]]) return np->fival[1] + 32 + nchtab + 128; else return 0; } } return(0); } static tchar postchar(const char *temp, int *fp) { int i, j; tchar c; *fp = font; if ((c = postchar1(temp, *fp)) != 0) return c; if (fallbacktab[font]) { for (j = 0; fallbacktab[font][j] != 0; j++) { if ((i = findft(fallbacktab[font][j], 0)) < 0) continue; if ((c = postchar1(temp, i)) != 0 && fchartab[c] == 0) { *fp = i; return c; } } } if (smnt) { for (i=smnt, j=0; j < nfonts; j++, i=i % nfonts + 1) { if (fontbase[i] == NULL) continue; if ((c = postchar1(temp, i)) != 0 && fchartab[c] == 0) { *fp = i; return c; } } } return 0; } static const struct amap { const char *alias; const char *trname; } amap[] = { { "lq", "``" }, { "rq", "''" }, { NULL, NULL } }; tchar setch(int delim) { register int j; char temp[NC]; tchar c, e[2] = {0, 0}; int f; size_t n; const struct amap *ap; n = 0; if (delim == 'C') e[0] = getach(); do { c = getach(); if (c == 0 && n < 2) return(0); if (n >= sizeof temp) { temp[n-1] = 0; break; } if ((delim == '[' && c == ']') || (delim == 'C' && c == e[0])) { temp[n] = 0; break; } temp[n++] = c; if (delim == '(' && n == 2) { temp[n] = 0; break; } } while (c); for (ap = amap; ap->alias; ap++) if (!strcmp(ap->alias, temp)) { size_t l; const char *s = ap->trname; if ((l = strlen(s) + 1) > NC) { fprintf(stderr, "%s %i: strlen(%s)+1 > %d\n", __FILE__, __LINE__, s, NC); break; } memcpy(temp, s, l); break; } if (delim == '[' && c != ']') { nodelim(']'); return ' '; } if (delim == 'C' && c != e[0]) { nodelim(e[0]); return ' '; } c = 0; if (delim == '[' || delim == 'C') { size_t l = strlen(temp); if (gemu) { if (l == 5 && *temp == 'u' && isxdigit((unsigned)temp[1]) && isxdigit((unsigned)temp[2]) && isxdigit((unsigned)temp[3]) && isxdigit((unsigned)temp[4])) { n = strtol(temp + 1, NULL, 16); if (n) c = setuc0(n); } else if ((l == 6 || (l == 7 && isdigit((unsigned)temp[6]))) && isdigit((unsigned)temp[5]) && isdigit((unsigned)temp[4]) && !strncmp(temp, "char", 4)) { int i = atoi(temp + 4); if (i <= 127) c = i + nchtab + 128; } } if (!c && (c = postchar(temp, &f))) { c |= chbits & ~FMASK; setfbits(c, f); } } if (c == 0) for (j = 0; j < nchtab; j++) if (strcmp(&chname[chtab[j]], temp) == 0) { c = (j + 128) | chbits; break; } if (c == 0 && delim == '(') if ((c = postchar(temp, &f)) != 0) { c |= chbits & ~FMASK; setfbits(c, f); } if (c == 0 && (c = _ps2cc(temp, 0)) != 0) { c += nchtab + 128 + 32 + 128 - 32 + nchtab; if (chartab[c] == NULL) c = 0; } if (c == 0 && warn & WARN_CHAR) errprint("missing glyph \\%c%s%s%s%s", delim, e, temp, e, delim == '[' ? "]" : ""); if (c == 0 && !tryglf) c = ' '; return c; } tchar setabs(void) /* set absolute char from \C'...' */ { int n; getch(); n = 0; n = inumb(&n); getch(); if (nonumb || n + nchtab + 128 >= NCHARS) return 0; return n + nchtab + 128; } int findft(register int i, int required) { register int k; int nk; - char *mn, *mp; + const char *mn; + char *mp; if ((k = i - '0') >= 0 && k <= nfonts && k < smnt && fontbase[k]) return(k); for (k = 0; k > nfonts || fontlab[k] != i; k++) if (k > nfonts) { mn = macname(i); nk = k; if ((k = strtol(mn, &mp, 10)) >= 0 && *mp == 0 && mp > mn && k <= nfonts && fontbase[k]) break; if (setfp(nk, i, NULL) == -1) return -1; else { fontlab[nk] = i; return nk; } if (required && warn & WARN_FONT) errprint("%s: no such font", mn); return(-1); } return(k); } void caseps(void) { register int i; if (skip(0)) i = apts1; else { if (xflag == 0) { noscale++; apts = u2pts(apts); } else { dfact = INCH; dfactd = 72; res = VERT; } i = inumb(&apts); if (xflag == 0) { noscale--; i = pts2u(i); apts = pts2u(apts); } if (nonumb) return; } casps1(i); } void casps1(register int i) { /* * in olden times, it used to ignore changes to 0 or negative. * this is meant to allow the requested size to be anything, * in particular so eqn can generate lots of \s-3's and still * get back by matching \s+3's. if (i <= 0) return; */ apts1 = apts; apts = i; pts1 = pts; pts = findps(i); mchbits(); } int findps(register int i) { register int j, k; if (dev.anysize && xflag) { if (i <= 0) i = pstab[0]; return i; } for (j=k=0 ; pstab[j] != 0 ; j++) if (abs(pstab[j]-i) < abs(pstab[k]-i)) k = j; return(pstab[k]); } void mchbits(void) { register int i, j, k; i = pts; if (dev.anysize && xflag) j = i - 1; else for (j = 0; i > (k = pstab[j]); j++) if (!k) { k = pstab[--j]; break; } chbits = 0; setsbits(chbits, ++j); setfbits(chbits, font); zapwcache(1); if (minspsz) { k = spacesz; spacesz = minspsz; minsps = width(' ' | chbits); spacesz = k; zapwcache(1); } if (letspsz) { k = spacesz; spacesz = letspsz; letsps = width(' ' | chbits); spacesz = k; zapwcache(1); } k = spacesz; spacesz = sesspsz; ses = width(' ' | chbits); spacesz = k; zapwcache(1); sps = width(' ' | chbits); zapwcache(1); } void setps(void) { tchar c; register int i, j = 0; int k; i = cbits(c = getch()); if (ismot(c) && xflag) return; if (ischar(i) && isdigit(i)) { /* \sd or \sdd */ i -= '0'; if (i == 0) /* \s0 */ j = apts1; else if (i <= 3 && ischar(j = cbits(ch = getch())) && isdigit(j)) { /* \sdd */ j = 10 * i + j - '0'; ch = 0; j = pts2u(j); } else /* \sd */ j = pts2u(i); } else if (i == '(') { /* \s(dd */ j = cbits(getch()) - '0'; j = 10 * j + cbits(getch()) - '0'; if (j == 0) /* \s(00 */ j = apts1; else j = pts2u(j); } else if (i == '+' || i == '-') { /* \s+, \s- */ j = cbits(c = getch()); if (ischar(j) && isdigit(j)) { /* \s+d, \s-d */ j -= '0'; j = pts2u(j); } else if (j == '(') { /* \s+(dd, \s-(dd */ j = cbits(getch()) - '0'; j = 10 * j + cbits(getch()) - '0'; j = pts2u(j); } else if (xflag) { /* \s+[dd], */ k = j == '[' ? ']' : j; /* \s-'dd' */ setcbits(c, k); dfact = INCH; dfactd = 72; res = HOR; j = hatoi(); res = dfactd = dfact = 1; if (nonumb) return; if (!issame(getch(), c)) nodelim(k); } if (i == '-') j = -j; j += apts; } else if (xflag) { /* \s'+dd', \s[dd] */ if (i == '[') { i = ']'; setcbits(c, i); } dfact = INCH; dfactd = 72; res = HOR; j = inumb2(&apts, &k); if (nonumb) return; if (j == 0 && k == 0) j = apts1; if (!issame(getch(), c)) nodelim(i); } casps1(j); } tchar setht(void) /* set character height from \H'...' */ { int n; tchar c; getch(); dfact = INCH; dfactd = 72; res = VERT; n = inumb(&apts); getch(); if (n == 0 || nonumb) n = apts; /* does this work? */ c = CHARHT; c |= ZBIT; setfbits(c, font); setsbits(c, n); return(c); } tchar setslant(void) /* set slant from \S'...' */ { int n; tchar c; getch(); n = 0; n = inumb(&n); getch(); if (nonumb) n = 0; c = SLANT; c |= ZBIT; setfbits(c, font); setsbits(c, n+180); return(c); } void caseft(void) { skip(0); setfont(1); } void setfont(int a) { register int i, j; if (a) i = getrq(3); else i = getsn(1); if (!i || i == 'P') { j = font1; goto s0; } if (/* i == 'S' || */ i == '0') return; if ((j = findft(i, 0)) == -1) if ((j = setfp(0, i, 0)) == -1) { /* try to put it in position 0 */ if (xflag) { font1 = font; } return; } s0: font1 = font; font = j; mchbits(); } void setwd(void) { register int base, wid; register tchar i; tchar delim, lasti = 0; int emsz, k; int savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1; int savlgf; int rst = 0, rsb = 0; int n; base = numtab[SB].val = numtab[ST].val = wid = numtab[CT].val = 0; if (ismot(i = getch())) return; delim = i; argdelim = delim; n = noschr; noschr = 0; savhp = numtab[HP].val; numtab[HP].val = 0; savapts = apts; savapts1 = apts1; savfont = font; savfont1 = font1; savpts = pts; savpts1 = pts1; savlgf = lgf; lgf = 0; setwdf++; while (i = getch(), !issame(i, delim) && !nlflg) { k = width(i); k += kernadjust(lasti, i); lasti = i; wid += k; numtab[HP].val += k; if (!ismot(i)) { emsz = POINT * u2pts(xpts); } else if (isvmot(i)) { k = absmot(i); if (isnmot(i)) k = -k; base -= k; emsz = 0; } else continue; if (base < numtab[SB].val) numtab[SB].val = base; if ((k = base + emsz) > numtab[ST].val) numtab[ST].val = k; if (lastrst > rst) rst = lastrst; if (lastrsb < rsb) rsb = lastrsb; } if (!issame(i, delim)) nodelim(delim); argdelim = 0; noschr = n; setn1(wid, 0, (tchar) 0); prwatchn(&numtab[CT]); prwatchn(&numtab[SB]); prwatchn(&numtab[ST]); setnr("rst", rst, 0); setnr("rsb", rsb, 0); numtab[HP].val = savhp; apts = savapts; apts1 = savapts1; font = savfont; font1 = savfont1; pts = savpts; pts1 = savpts1; lgf = savlgf; mchbits(); setwdf = 0; } tchar vmot(void) { dfact = lss; vflag++; return(mot()); } tchar hmot(void) { dfact = EM; return(mot()); } tchar mot(void) { register int j, n; register tchar i; tchar c, delim; j = HOR; delim = getch(); /*eat delim*/ if ((n = hatoi())) { if (vflag) j = VERT; i = makem(quant(n, j)); } else i = 0; c = getch(); if (!issame(c, delim)) nodelim(delim); vflag = 0; dfact = 1; return(i); } tchar sethl(int k) { register int j; tchar i; j = EM / 2; if (k == 'u') j = -j; else if (k == 'r') j = -2 * j; vflag++; i = makem(j); vflag = 0; return(i); } tchar makem(register int i) { register tchar j; if ((j = i) < 0) j = -j; j = sabsmot(j) | MOT; if (i < 0) j |= NMOT; if (vflag) j |= VMOT; return(j); } tchar getlg(tchar i) { tchar j, k, pb[NC]; struct lgtab *lp; int c, f; size_t n, lgn; f = fbits(i); if (lgtab[f] == NULL) /* font lacks ligatures */ return(i); c = cbits(i); lp = &lgtab[f][c]; if (lp->from != c || (lp = lp->link) == NULL) return(i); k = i; n = 1; lgn = lg == 2 ? 2 : 1000; for (;;) { j = getch0(); if (n < sizeof pb) pb[n-1] = j; c = cbits(j); while (lp != NULL && lp->from != c) lp = lp->next; if (lp == NULL || lp->to == 0) { pbbuf[pbp++] = j; return(k); } if (lp->to == -1) { /* fdeferlig request */ pb[n < sizeof pb ? n : sizeof pb - 1] = 0; pushback(pb); return(i); } k = (i & SFMASK) | lp->to | AUTOLIG; if (lp->link == NULL || ++n > lgn) return(k); lp = lp->link; } } int strlg(int f, int *tp, int n) { struct lgtab *lp; int i; if (n == 1) return tp[0]; if (lgtab[f] == NULL) return 0; lp = &lgtab[f][tp[0]]; if (lp->from != tp[0]) return 0; for (i = 1; i < n; i++) { if ((lp = lp->link) == NULL) return 0; while (lp != NULL && lp->from != tp[i]) lp = lp->next; if (lp == NULL || lp->to == 0) return 0; } return lp->to > 0 ? lp->to : 0; } void caselg(void) { lg = 1; if (skip(0)) return; lg = hatoi(); } static void addlig(int f, tchar *from, int to) { int i, j; struct lgtab *lp; if (from[0] == 0 || from[1] == 0) { if (warn & WARN_FONT) errprint("short ligature has no effect"); return; } if (lgtab[f] == NULL) lgtab[f] = calloc(NCHARS, sizeof **lgtab); i = cbits(from[0]); gchtab[i] |= LGBIT; lp = &lgtab[f][i]; lp->from = i; j = 1; for (;;) { i = cbits(from[j]); if (lp->link == NULL) { if (from[j+1] != 0) { if (warn & WARN_FONT) errprint("ligature step missing"); return; } lp->link = calloc(1, sizeof *lp->link); lp = lp->link; lp->from = i; lp->to = to; break; } lp = lp->link; if (++j >= 4) { if (warn & WARN_FONT) errprint("ignoring ligature of length >4"); return; } while (lp->from != i && lp->next) lp = lp->next; if (lp->from != i) { if (from[j] != 0) { if (warn & WARN_FONT) errprint("ligature step missing"); return; } lp->next = calloc(1, sizeof *lp->next); lp = lp->next; lp->from = i; } if (from[j] == 0) { lp->to = to; break; } } if (to >= 0) { if (lgrevtab[f] == NULL) lgrevtab[f] = calloc(NCHARS, sizeof **lgrevtab); lgrevtab[f][to] = malloc((j+2) * sizeof ***lgrevtab); j = 0; while ((lgrevtab[f][to][j] = cbits(from[j]))) j++; } /* * If the font still contains the charlib substitutes for ff, * Fi, and Fl, hide them. The ".flig" request is intended for * use in combination with expert fonts only. */ if ((to == LIG_FF || (cbits(from[0]) == 'f' && cbits(from[1]) == 'f' && cbits(from[2]) == 0)) && fitab[f][LIG_FF-32] != NOCODE) if (codetab[f][fitab[f][LIG_FF-32]] < 32) fitab[f][LIG_FF-32] = 0; if ((to == LIG_FFI || (cbits(from[0]) == 'f' && cbits(from[1]) == 'f' && cbits(from[2]) == 'i' && cbits(from[3]) == 0)) && fitab[f][LIG_FFI-32] != NOCODE) if (codetab[f][fitab[f][LIG_FFI-32]] < 32) fitab[f][LIG_FFI-32] = 0; if ((to == LIG_FFL || (cbits(from[0]) == 'f' && cbits(from[1]) == 'f' && cbits(from[2]) == 'l' && cbits(from[3]) == 0)) && fitab[f][LIG_FFL-32] != NOCODE) if (codetab[f][fitab[f][LIG_FFL-32]] < 32) fitab[f][LIG_FFL-32] = 0; } static void dellig(int f, tchar *from) { struct lgtab *lp, *lq; int i, j; if (from[0] == 0 || from[1] == 0) return; if (lgtab[f] == NULL) return; i = cbits(from[0]); lp = lq = &lgtab[f][i]; j = 1; for (;;) { i = cbits(from[j]); if (lp->link == NULL) break; lq = lp; lp = lp->link; while (lp->from != i && lp->next) { lq = lp; lp = lp->next; } if (lp->from != i) break; if (from[++j] == 0) { if (lq->link == lp) lq->link = lp->next; else if (lq->next == lp) lq->next = lp->next; if (lp->link) if (warn & WARN_FONT) errprint("deleted ligature cuts chain"); free(lgrevtab[f][lp->to]); lgrevtab[f][lp->to] = NULL; free(lp); break; } } } void setlig(int f, int j) { tchar from[4], to; free(lgrevtab[f]); lgrevtab[f] = NULL; free(lgtab[f]); lgtab[f] = NULL; from[0] = 'f'; from[2] = from[3] = 0; from[1] = 'f'; to = LIG_FF; if (j & LFF) addlig(f, from, to); from[1] = 'i'; to = LIG_FI; if (j & LFI) addlig(f, from, to); from[1] = 'l'; to = LIG_FL; if (j & LFL) addlig(f, from, to); from[1] = 'f'; from[2] = 'i'; to = LIG_FFI; if (j & LFFI) addlig(f, from, to); from[2] = 'l'; to = LIG_FFL; if (j & LFFL) addlig(f, from, to); } static int getflig(int f, int mode) { int delete, allnum; tchar from[NC], to; int c; size_t i, j; char number[NC]; if (skip(0)) return 0; switch (cbits(c = getch())) { case '-': c = getch(); delete = 1; break; case '+': c = getch(); /*FALLTHRU*/ default: delete = 0; break; case 0: return 0; } allnum = 1; for (i = 0; i < sizeof from - 2; i++) { from[i] = c; j = cbits(c); if (c == 0 || ismot(c) || j == ' ' || j == '\n') { from[i] = 0; ch = j; break; } if (j < '0' || j > '9') allnum = 0; c = getch(); } if (mode == 0 && allnum == 1) { /* backwards compatibility */ if (skip(0) == 0) goto new; for (j = 0; j <= i+1; j++) number[j] = cbits(from[j]); j = strtol(number, NULL, 10); setlig(f, j); return 0; } if (delete == 0) { if (mode >= 0) { if (skip(1)) return 0; new: to = cbits(getch()); } else to = -1; addlig(f, from, to); } else dellig(f, from); return 1; } void caseflig(int defer) { int i, j; lgf++; if (skip(1)) return; i = getrq(2); if ((j = findft(i, 1)) < 0) return; i = 0; while (getflig(j, defer ? -1 : i++) != 0); } void casefdeferlig(void) { caseflig(1); } void casefp(int spec) { register int i, j; char *file, *supply; lgf++; skip(0); if ((i = xflag ? hatoi() : cbits(getch()) - '0') < 0 || i > 255) bad: errprint("fp: bad font position %d", i); else if (skip(0) || !(j = getrq(3))) errprint("fp: no font name"); else { if (skip(0) || !getname()) { if (i == 0) goto bad; setfp(i, j, 0); } else { /* 3rd argument = filename */ - size_t l; - l = strlen(nextf) + 1; - file = malloc(l); - n_strcpy(file, nextf, l); + file = strdup(nextf); if (!skip(0) && getname()) { - l = strlen(nextf) + 1; - supply = malloc(l); - n_strcpy(supply, nextf, l); + supply = strdup(nextf); } else supply = NULL; if (loadafm(i?i:-1, j, file, supply, 0, spec) == 0) { if (i == 0) { if (warn & WARN_FONT) errprint("fp: cannot mount %s", file); } else setfp(i, j, file); } free(file); free(supply); } } } void casefps(void) { const struct { enum spec spec; const char *name; } tab[] = { { SPEC_MATH, "math" }, { SPEC_GREEK, "greek" }, { SPEC_PUNCT, "punct" }, { SPEC_LARGE, "large" }, { SPEC_S1, "S1" }, { SPEC_S, "S" }, { SPEC_NONE, NULL } }; char name[NC]; int c = 0; size_t i; enum spec s = SPEC_NONE; if (skip(1)) return; do { for (i = 0; i < sizeof name - 2; i++) { if ((c = getach()) == 0 || c == ':' || c == ',') break; name[i] = c; } name[i] = 0; for (i = 0; tab[i].name; i++) if (strcmp(tab[i].name, name) == 0) { s |= tab[i].spec; break; } if (tab[i].name == NULL) errprint("fps: unknown special set %s", name); } while (c); casefp(s); } int setfp(int pos, int f, char *truename) /* mount font f at position pos[0...nfonts] */ { - char longname[4096], *shortname, *ap; + char longname[4096], *ap; + const char *shortname; char *fpout; int i, nw; zapwcache(0); if (truename) shortname = truename; else shortname = macname(f); shortname = mapft(shortname); snprintf(longname, sizeof longname, "%s/dev%s/%s", fontfile, devname, shortname); if ((fpout = readfont(longname, &dev, warn & WARN_FONT)) == NULL) return(-1); if (pos >= Nfont) growfonts(pos+1); if (pos > nfonts) nfonts = pos; fontbase[pos] = (struct Font *)fpout; if ((ap = strstr(fontbase[pos]->namefont, ".afm")) != NULL) { *ap = 0; if (ap == &fontbase[pos]->namefont[1]) f &= BYTEMASK; loadafm(pos, f, fontbase[pos]->namefont, NULL, 1, SPEC_NONE); free(fpout); } else { nw = fontbase[pos]->nwfont & BYTEMASK; makefont(pos, &((char *)fontbase[pos])[sizeof(struct Font)], &((char *)fontbase[pos])[sizeof(struct Font) + nw], &((char *)fontbase[pos])[sizeof(struct Font) + 2*nw], &((char *)fontbase[pos])[sizeof(struct Font) + 3*nw], nw); setlig(pos, fontbase[pos]->ligfont); } if (pos == smnt) { smnt = 0; sbold = 0; } if ((fontlab[pos] = f) == 'S') smnt = pos; bdtab[pos] = cstab[pos] = ccstab[pos] = 0; zoomtab[pos] = 0; fallbacktab[pos] = NULL; free(lhangtab[pos]); lhangtab[pos] = NULL; free(rhangtab[pos]); rhangtab[pos] = NULL; memset(&tracktab[pos], 0, sizeof tracktab[pos]); for (i = 0; i < NCHARS; i++) ftrtab[pos][i] = i; kzap(pos); /* if there is a directory, no place to store its name. */ /* if position isn't zero, no place to store its value. */ /* only time a FONTPOS is pushed back is if it's a */ /* standard font on position 0 (i.e., mounted implicitly. */ /* there's a bug here: if there are several input lines */ /* that look like .ft XX in short successtion, the output */ /* will all be in the last one because the "x font ..." */ /* comes out too soon. pushing back FONTPOS doesn't work */ /* with .ft commands because input is flushed after .xx cmds */ if (realpage && ap == NULL) ptfpcmd(pos, shortname, NULL, 0); if (pos == 0) ch = (tchar) FONTPOS | (tchar) f << 22; return(pos); } int nextfp(void) { int i; for (i = 1; i <= nfonts; i++) if (fontbase[i] == NULL) return i; if (i <= 255) return i; return 0; } void casecs(void) { register int i, j; noscale++; if (skip(1)) goto rtn; if (!(i = getrq(2))) goto rtn; if ((i = findft(i, 1)) < 0) goto rtn; skip(0); cstab[i] = hatoi(); skip(0); j = hatoi(); if (nonumb) ccstab[i] = 0; else ccstab[i] = findps(j); rtn: zapwcache(0); noscale = 0; } void casebd(void) { register int i, j = 0, k; zapwcache(0); k = 0; bd0: if (skip(1) || !(i = getrq(2)) || (j = findft(i, 1)) == -1) { if (k) goto bd1; else return; } if (j == smnt) { k = smnt; goto bd0; } if (k) { sbold = j; j = k; } bd1: skip(0); noscale++; bdtab[j] = hatoi(); noscale = 0; } void casevs(void) { register int i; skip(0); vflag++; dfact = INCH; /* default scaling is points! */ dfactd = 72; res = VERT; i = inumb(&lss); if (nonumb) i = lss1; if (xflag && i < 0) { if (warn & WARN_RANGE) errprint("negative vertical spacing ignored"); i = lss1; } if (i < VERT) i = VERT; lss1 = lss; lss = i; } void casess(int flg) { register int i, j; noscale++; if (skip(flg == 0)) minsps = minspsz = 0; else if ((i = hatoi()) != 0 && !nonumb) { if (xflag && flg == 0 && !skip(0)) { j = hatoi(); if (!nonumb) { sesspsz = j & 0177; spacesz = sesspsz; zapwcache(1); ses = width(' ' | chbits); } } if (flg) { j = spacesz; minspsz = i & 0177; spacesz = minspsz; zapwcache(1); minsps = width(' ' | chbits); spacesz = j; zapwcache(0); sps = width(' ' | chbits); } else { spacesz = i & 0177; zapwcache(0); sps = width(' ' | chbits); if (minspsz > spacesz) minsps = minspsz = 0; } } noscale = 0; } void caseminss(void) { casess(1); } void caseletadj(void) { int s, n, x, l, h; dfact = LAFACT / 100; if (skip(0) || (n = hatoi()) == 0) { letspsz = 0; letsps = 0; lspmin = 0; lspmax = 0; lshmin = 0; lshmax = 0; goto ret; } if (skip(1)) goto ret; dfact = LAFACT / 100; l = hatoi(); if (skip(1)) goto ret; noscale++; s = hatoi(); noscale--; if (skip(1)) goto ret; dfact = LAFACT / 100; x = hatoi(); if (skip(1)) goto ret; dfact = LAFACT / 100; h = hatoi(); letspsz = s; lspmin = LAFACT - n; lspmax = x - LAFACT; lshmin = LAFACT - l; lshmax = h - LAFACT; s = spacesz; spacesz = letspsz; zapwcache(1); letsps = width(' ' | chbits); spacesz = s; zapwcache(1); sps = width(' ' | chbits); zapwcache(1); ret: dfact = 1; } void casefspacewidth(void) { int f, n, i; lgf++; if (skip(1)) return; i = getrq(2); if ((f = findft(i, 1)) < 0) return; if (skip(0)) { fontbase[f]->cspacewidth = -1; fontab[f][0] = fontbase[f]->spacewidth; } else { noscale++; n = hatoi(); noscale--; unitsPerEm = 1000; if (n >= 0) fontbase[f]->cspacewidth = fontab[f][0] = _unitconv(n); else if (warn & WARN_RANGE) errprint("ignoring negative space width %d", n); } zapwcache(1); } void casespacewidth(void) { noscale++; spacewidth = skip(0) || hatoi(); noscale--; } tchar xlss(void) { /* stores \x'...' into * two successive tchars. * the first contains HX, the second the value, * encoded as a vertical motion. * decoding is done in n2.c by pchar(). */ int i; getch(); dfact = lss; i = quant(hatoi(), VERT); dfact = 1; getch(); if (i >= 0) pbbuf[pbp++] = MOT | VMOT | sabsmot(i); else pbbuf[pbp++] = MOT | VMOT | NMOT | sabsmot(-i); return(HX); } struct afmtab **afmtab; int nafm; static char * onefont(char *prefix, char *file, char *type) { char *path, *fp, *tp; size_t l; l = strlen(prefix) + strlen(file) + 2; path = malloc(l); n_strcpy(path, prefix, l); n_strcat(path, "/", l); n_strcat(path, file, l); if (type) { for (fp = file; *fp; fp++); for (tp = type; *tp; tp++); while (tp >= type && fp >= file && *fp-- == *tp--); if (tp >= type) { l = strlen(path) + strlen(type) + 2; tp = malloc(l); n_strcpy(tp, path, l); n_strcat(tp, ".", l); n_strcat(tp, type, l); free(path); path = tp; } } return path; } static char * getfontpath(char *file, char *type) { char *path, *troffonts, *tp, *tq, c; size_t l; if ((troffonts = getenv("TROFFONTS")) != NULL) { - l = strlen(troffonts) + 1; - tp = malloc(l); - n_strcpy(tp, troffonts, l); + tp = strdup(troffonts); troffonts = tp; do { for (tq = tp; *tq && *tq != ':'; tq++); c = *tq; *tq = 0; path = onefont(tp, file, type); if (access(path, 0) == 0) { free(troffonts); return path; } free(path); tp = &tq[1]; } while (c); free(troffonts); } l = strlen(fontfile) + strlen(devname) + 10; tp = malloc(l); snprintf(tp, l, "%s/dev%s", fontfile, devname); path = onefont(tp, file, type); free(tp); return path; } static void checkenminus(int f) { /* * A fix for a very special case: If the font supplies punctuation * characters but is not S1, only one of \- and \(en is present * since the PostScript character "endash" is mapped to both of * them. */ enum spec spec; int i; if (afmtab == NULL || (i = fontbase[f]->afmpos - 1) < 0) return; if (c_endash == 0 || c_minus == 0) specnames(); spec = afmtab[i]->spec; if ((spec&(SPEC_PUNCT|SPEC_S1)) == SPEC_PUNCT) { if (fitab[f][c_endash-32] == 0 && ftrtab[f][c_minus-32]) ftrtab[f][c_endash] = c_minus; else if (fitab[f][c_endash-32] && ftrtab[f][c_minus-32] != 0) ftrtab[f][c_minus] = c_endash; } } int loadafm(int nf, int rq, char *file, char *supply, int required, enum spec spec) { struct stat st; int fd; char *path, *contents; struct afmtab *a; int i, have = 0; struct namecache *np; size_t l; zapwcache(0); if (nf < 0) nf = nextfp(); path = getfontpath(file, "afm"); if (access(path, 0) < 0) { path = getfontpath(file, "otf"); if (access(path, 0) < 0) path = getfontpath(file, "ttf"); } if (dev.allpunct) spec |= SPEC_PUNCT; a = calloc(1, sizeof *a); for (i = 0; i < nafm; i++) if (strcmp(afmtab[i]->path, path) == 0 && afmtab[i]->spec == spec) { *a = *afmtab[i]; have = 1; break; } a->path = path; - l = strlen(file) + 1; - a->file = malloc(l); - n_strcpy(a->file, file, l); + a->file = strdup(file); a->spec = spec; a->rq = rq; a->Font.namefont[0] = rq&0377; a->Font.namefont[1] = (rq>>8)&0377; snprintf(a->Font.intname, sizeof(a->Font.intname), "%d", nf); if (have) goto done; if ((fd = open(path, O_RDONLY)) < 0) { if (required) errprint("Can't open %s", path); free(a->file); free(a); free(path); return 0; } if (fstat(fd, &st) < 0) { errprint("Can't stat %s", path); free(a->file); free(a); free(path); return -1; } contents = malloc(st.st_size + 1); if (read(fd, contents, st.st_size) != st.st_size) { errprint("Can't read %s", path); free(a->file); free(a); free(path); free(contents); return -1; } contents[st.st_size] = 0; close(fd); if (afmget(a, contents, st.st_size) < 0) { free(path); free(contents); return -1; } free(contents); morechars(a->nchars+32+1+128-32+nchtab+32+nchtab+128+psmaxcode+1); done: afmtab = realloc(afmtab, (nafm+1) * sizeof *afmtab); afmtab[nafm] = a; if (nf >= Nfont) growfonts(nf+1); a->Font.afmpos = nafm+1; if ((np = afmnamelook(a, "space")) != NULL) a->Font.spacewidth = a->fontab[np->afpos]; else a->Font.spacewidth = a->fontab[0]; a->Font.cspacewidth = -1; fontbase[nf] = &afmtab[nafm]->Font; fontlab[nf] = rq; free(fontab[nf]); free(kerntab[nf]); free(codetab[nf]); free(fitab[nf]); fontab[nf] = malloc(a->nchars * sizeof *fontab[nf]); kerntab[nf] = malloc(a->nchars * sizeof *kerntab[nf]); codetab[nf] = malloc(a->nchars * sizeof *codetab[nf]); fitab[nf] = calloc(NCHARS, sizeof *fitab[nf]); memcpy(fontab[nf], a->fontab, a->nchars * sizeof *fontab[nf]); memcpy(kerntab[nf], a->kerntab, a->nchars * sizeof *kerntab[nf]); memcpy(codetab[nf], a->codetab, a->nchars * sizeof *codetab[nf]); memcpy(fitab[nf], a->fitab, a->fichars * sizeof *fitab[nf]); bdtab[nf] = cstab[nf] = ccstab[nf] = 0; zoomtab[nf] = 0; fallbacktab[nf] = NULL; free(lhangtab[nf]); lhangtab[nf] = NULL; free(rhangtab[nf]); rhangtab[nf] = NULL; memset(&tracktab[nf], 0, sizeof tracktab[nf]); setlig(nf, a->Font.ligfont); for (i = 0; i < NCHARS; i++) ftrtab[nf][i] = i; kzap(nf); nafm++; if (nf > nfonts) nfonts = nf; if (supply) { char *data; if (strcmp(supply, "pfb") == 0 || strcmp(supply, "pfa") == 0 || strcmp(supply, "t42") == 0 || strcmp(supply, "otf") == 0 || strcmp(supply, "ttf") == 0) data = getfontpath(file, supply); else data = getfontpath(supply, NULL); a->supply = afmencodepath(data); free(data); if (realpage) ptsupplyfont(a->fontname, a->supply); } checkenminus(nf); if (realpage) ptfpcmd(nf, macname(fontlab[nf]), a->path, (int)a->spec); return 1; } static int tracknum(void) { skip(1); dfact = INCH; dfactd = 72; res = VERT; return inumb(NULL); } void casetrack(void) { int i, j, s1, n1, s2, n2; if (skip(1)) return; i = getrq(2); if ((j = findft(i, 1)) < 0) return; s1 = tracknum(); if (!nonumb) { n1 = tracknum(); if (!nonumb) { s2 = tracknum(); if (!nonumb) { n2 = tracknum(); if (!nonumb) { tracktab[j].s1 = s1; tracktab[j].n1 = n1; tracktab[j].s2 = s2; tracktab[j].n2 = n2; zapwcache(0); } } } } } void casefallback(void) { int *fb = NULL; int i, j, n = 0; if (skip(1)) return; i = getrq(2); if ((j = findft(i, 1)) < 0) return; do { skip(0); i = getrq(2); fb = realloc(fb, (n+2) * sizeof *fb); fb[n++] = i; } while (i); fallbacktab[j] = fb; } void casehidechar(void) { int savfont = font, savfont1 = font1; int i, j; tchar k; if (skip(1)) return; i = getrq(2); if ((j = findft(i, 1)) < 0) return; font = font1 = j; mchbits(); while ((i = cbits(k = getch())) != '\n') { if (fbits(k) != j || ismot(k) || i == ' ') continue; if (i >= nchtab + 128-32 && afmtab && fontbase[j]->afmpos - 1 >= 0) i -= nchtab + 128; fitab[j][i - 32] = 0; } font = savfont; font1 = savfont1; mchbits(); zapwcache(0); } void casefzoom(void) { int i, j; float f; if (skip(1)) return; i = getrq(2); if ((j = findft(i, 1)) < 0) return; skip(1); f = atof(); if (!nonumb && f >= 0) { zoomtab[j] = f; zapwcache(0); if (realpage && j == xfont && !ascii) ptps(); } } double getfzoom(void) { return zoomtab[font]; } void casekern(void) { kern = skip(0) || hatoi() ? 1 : 0; } void casefkern(void) { int f, i, j; lgf++; if (skip(1)) return; i = getrq(2); if ((f = findft(i, 1)) < 0) return; if (skip(0)) fontbase[f]->kernfont = 0; else { j = hatoi(); if (!nonumb) fontbase[f]->kernfont = j ? j : -1; } } static void setpapersize(int setmedia) { const struct { const char *name; int width; int heigth; } papersizes[] = { { "executive", 518, 756 }, { "letter", 612, 792 }, { "legal", 612, 992 }, { "ledger", 1224, 792 }, { "tabloid", 792, 1224 }, { "a0", 2384, 3370 }, { "a1", 1684, 2384 }, { "a2", 1191, 1684 }, { "a3", 842, 1191 }, { "a4", 595, 842 }, { "a5", 420, 595 }, { "a6", 298, 420 }, { "a7", 210, 298 }, { "a8", 147, 210 }, { "a9", 105, 147 }, { "a10", 74, 105 }, { "b0", 2835, 4008 }, { "b1", 2004, 2835 }, { "b2", 1417, 2004 }, { "b3", 1000, 1417 }, { "b4", 709, 1000 }, { "b5", 499, 709 }, { "b6", 354, 499 }, { "b7", 249, 354 }, { "b8", 176, 249 }, { "b9", 125, 176 }, { "b10", 87, 125 }, { "c0", 2599, 3677 }, { "c1", 1837, 2599 }, { "c2", 1298, 1837 }, { "c3", 918, 1298 }, { "c4", 649, 918 }, { "c5", 459, 649 }, { "c6", 323, 459 }, { "c7", 230, 323 }, { "c8", 162, 230 }, { NULL, 0, 0 } }; int c; int x = 0, y = 0; size_t n; char buf[NC]; lgf++; if (skip(1)) return; c = cbits(ch); if (isdigit(c) || c == '(') { x = hatoi(); if (!nonumb) { skip(1); y = hatoi(); } if (nonumb || x == 0 || y == 0) return; } else { n = 0; do { c = getach(); if (n+1 < sizeof buf) buf[n++] = c; } while (c); buf[n] = 0; for (n = 0; papersizes[n].name != NULL; n++) if (strcmp(buf, papersizes[n].name) == 0) { x = papersizes[n].width * INCH / 72; y = papersizes[n].heigth * INCH / 72; break; } if (x == 0 || y == 0) { errprint("Unknown paper size %s", buf); return; } } pl = defaultpl = y; if (numtab[NL].val > pl) { numtab[NL].val = pl; prwatchn(&numtab[NL]); } po = x > 6 * PO ? PO : x / 8; ll = ll1 = lt = lt1 = x - 2 * po; setnel(); mediasize.val[2] = x; mediasize.val[3] = y; mediasize.flag |= 1; if (setmedia) mediasize.flag |= 2; if (realpage) ptpapersize(); } void casepapersize(void) { setpapersize(0); } void casemediasize(void) { setpapersize(1); } static void cutat(struct box *bp) { int c[4], i; for (i = 0; i < 4; i++) { if (skip(1)) return; dfact = INCH; dfactd = 72; c[i] = inumb(NULL); if (nonumb) return; } for (i = 0; i < 4; i++) bp->val[i] = c[i]; bp->flag |= 1; if (realpage) ptcut(); } void casetrimat(void) { cutat(&trimat); } void casebleedat(void) { cutat(&bleedat); } void casecropat(void) { cutat(&cropat); } void caselhang(void) { kernsingle(lhangtab); } void caserhang(void) { kernsingle(rhangtab); } void casekernpair(void) { int savfont = font, savfont1 = font1; int f, g, i, j, n; tchar c, e, *cp = NULL, *dp = NULL; int a = 0, b = 0; lgf++; if (skip(1)) return; i = getrq(2); if ((f = findft(i, 1)) < 0) return; font = font1 = f; mchbits(); if (skip(1)) goto done; while ((j = cbits(c = getch())) > ' ' || j == UNPAD) { if (fbits(c) != f) { if (warn & WARN_CHAR) errprint("glyph %C not in font %s", c, macname(i)); continue; } cp = realloc(cp, ++a * sizeof *cp); cp[a-1] = c; } if (a == 0 || skip(1)) goto done; i = getrq(2); if ((g = findft(i, 1)) < 0) goto done; font = font1 = g; mchbits(); if (skip(1)) goto done; while ((j = cbits(c = getch())) > ' ' || j == UNPAD) { if (fbits(c) != g) { if (warn & WARN_CHAR) errprint("glyph %C not in font %s", c, macname(i)); continue; } dp = realloc(dp, ++b * sizeof *dp); dp[b-1] = c; } if (b == 0 || skip(1)) goto done; noscale++; n = hatoi(); noscale--; unitsPerEm = 1000; n = _unitconv(n); for (i = 0; i < a; i++) for (j = 0; j < b; j++) { if ((c = cbits(cp[i])) == 0) continue; if (c == UNPAD) c = ' '; setfbits(c, f); if ((e = cbits(dp[j])) == 0) continue; if (e == UNPAD) e = ' '; setfbits(e, g); kadd(c, e, n); } done: free(cp); free(dp); font = savfont; font1 = savfont1; mchbits(); } static void kernsingle(int **tp) { int savfont = font, savfont1 = font1; int f, i, j, n; int twice = 0; tchar c, *cp = NULL; int a; lgf++; if (skip(1)) return; i = getrq(2); if ((f = findft(i, 1)) < 0) return; font = font1 = f; mchbits(); while (!skip(twice++ == 0)) { a = 0; while ((j = cbits(c = getch())) > ' ') { if (fbits(c) != f) { if (warn & WARN_CHAR) errprint("glyph %C not in font %s", c, macname(i)); continue; } cp = realloc(cp, ++a * sizeof *cp); cp[a-1] = c; } if (skip(1)) break; noscale++; n = hatoi(); noscale--; if (tp[f] == NULL) tp[f] = calloc(NCHARS, sizeof *tp); unitsPerEm = 1000; n = _unitconv(n); for (j = 0; j < a; j++) tp[f][cbits(cp[j])] = n; } free(cp); font = savfont; font1 = savfont1; mchbits(); } void casekernafter(void) { kernsingle(kernafter); } void casekernbefore(void) { kernsingle(kernbefore); } void caseftr(void) { int savfont = font, savfont1 = font1; int f, i, j; tchar k; lgf++; if (skip(1)) return; i = getrq(2); if ((f = findft(i, 1)) < 0) return; font = font1 = f; mchbits(); if (skip(1)) goto done; while ((i = cbits(k=getch())) != '\n') { if (ismot(k)) goto done; if (ismot(k = getch())) goto done; if ((j = cbits(k)) == '\n') j = ' '; ftrtab[f][i] = j; } done: checkenminus(f); font = savfont; font1 = savfont1; mchbits(); } static int getfeature(struct afmtab *a, int f) { char name[NC]; int ch1, ch2, c, j, minus; size_t i; struct feature *fp; if (skip(0)) return 0; switch (c = getach()) { case '-': c = getach(); minus = 1; break; case '+': c = getach(); /*FALLTHRU*/ default: minus = 0; break; case 0: return 0; } for (i = 0; i < sizeof name - 2; i++) { name[i] = c; if ((c = getach()) == 0) break; } name[i+1] = 0; for (i = 0; (fp = a->features[i]); i++) if (strcmp(fp->name, name) == 0) { for (j = 0; j < fp->npairs; j++) { ch1 = fp->pairs[j].ch1; ch2 = fp->pairs[j].ch2; if (minus) { if (ftrtab[f][ch1] == ch2) ftrtab[f][ch1] = ch1; } else { ftrtab[f][ch1] = ch2; } } break; } if (fp == NULL) errprint("no feature named %s in font %s", name, a->fontname); return 1; } void casefeature(void) { struct afmtab *a; int f, i, j; lgf++; if (skip(1)) return; i = getrq(2); if ((f = findft(i, 1)) < 0) return; if ((j = (fontbase[f]->afmpos) - 1) < 0 || ((a = afmtab[j])->type != TYPE_OTF && a->type != TYPE_TTF)) { errprint("font %s is not an OpenType font", macname(i)); return; } if (a->features == NULL) { errprint("font %s has no OpenType features", a->fontname); return; } while (getfeature(a, f) != 0); } #include "unimap.h" static int ufmap(int c, int f, int *fp) { struct unimap *up, ***um; struct afmtab *a; int i; if ((c&~0xffff) == 0 && (i = (fontbase[f]->afmpos) - 1) >= 0 && (um = (a = afmtab[i])->unimap) != NULL && um[c>>8] != NULL && (up = um[c>>8][c&0377]) != NULL) { *fp = f; return up->u.code; } return 0; } int un2tr(int c, int *fp) { extern char ifilt[]; struct unimap *um, *up; int i, j; switch (c) { case 0x00A0: *fp = font; return UNPAD; case 0x00AD: *fp = font; return ohc; case 0x2002: return makem((int)(EM)/2); case 0x2003: return makem((int)EM); case 0x2004: return makem((int)EM/3); case 0x2005: return makem((int)EM/4); case 0x2006: return makem((int)EM/6); case 0x2007: return makem(width('0' | chbits)); case 0x2008: return makem(width('.' | chbits)); case 0x2009: return makem((int)EM/6); case 0x200A: return makem((int)EM/12); case 0x2010: *fp = font; return '-'; case 0x2027: *fp = font; return OHC | BLBIT; case 0x2060: *fp = font; return FILLER; default: if ((i = ufmap(c, font, fp)) != 0) return i; if ((c&~0xffff) == 0 && unimap[c>>8] != NULL && (um = unimap[c>>8][c&0377]) != NULL) { up = um; do if ((j = postchar1(up->u.psc, font)) != 0) { *fp = font; return j; } while ((up = up->next) != NULL); up = um; do if ((j = postchar(up->u.psc, fp)) != 0) return j; while ((up = up->next) != NULL); up = um; do if ((j = _ps2cc(up->u.psc, 0)) != 0) { j += nchtab + 128 + 32 + 128 - 32 + nchtab; if (chartab[j] != NULL) return j; } while ((up = up->next) != NULL); } if (fallbacktab[font]) for (j = 0; fallbacktab[font][j] != 0; j++) { if ((i = findft(fallbacktab[font][j], 0)) < 0) continue; if ((i = ufmap(c, i, fp)) != 0) return i; } if (smnt) for (i = smnt, j=0; j < nfonts; j++, i = i % nfonts + 1) { if (fontbase[i] == NULL) continue; if ((i = ufmap(c, i, fp)) != 0) return i; } *fp = font; if ((c < 040 && c == ifilt[c]) || (c >= 040 && c < 0177)) return c; else if ((c & ~0177) == 0) { illseq(c, NULL, 0); return 0; } else if (defcf && (c & ~0xffff) == 0) { char buf[20]; snprintf(buf, sizeof(buf), "[uni%04X]", c); cpushback(buf); unadd(c, NULL); return WORDSP; } else if (html) { return c; } else { if (warn & WARN_CHAR) errprint("no glyph available for %U", c); return tryglf ? 0 : ' '; } } } int tr2un(tchar i, int f) { struct afmtab *a; int c, n; if (i < 32) return -1; else if (i < 128) return i; if ((n = (fontbase[f]->afmpos) - 1) >= 0) { a = afmtab[n]; if (a->unitab && i < a->nunitab && a->unitab[i]) return a->unitab[i]; if (i - 32 >= nchtab + 128) i -= nchtab + 128; if ((n = a->fitab[i - 32]) < a->nchars && a->nametab[n] != NULL) for (c = 0; rawunimap[c].psc; c++) if (strcmp(rawunimap[c].psc, a->nametab[n])==0) return rawunimap[c].code; } return -1; } tchar setuc0(int n) { int f; tchar c; if ((c = un2tr(n, &f)) != 0 && !ismot(c)) { c |= chbits & ~FMASK; setfbits(c, f); } return c; } static char * getref(void) { int a = 0, i, c, delim; char *np = NULL; if ((delim = getach()) != 0) { for (i = 0; ; i++) { if (i + 1 >= a) np = realloc(np, a += 32); if ((c = getach()) == 0) { if (cbits(ch) == ' ') { ch = 0; c = ' '; } else { nodelim(delim); break; } } if (c == delim) break; np[i] = c; } np[i] = 0; } return np; } tchar setanchor(void) { static int cnt; struct ref *rp; char *np; if ((np = getref()) != NULL) { rp = calloc(1, sizeof *rp); rp->cnt = ++cnt; rp->name = np; rp->next = anchors; anchors = rp; return mkxfunc(ANCHOR, cnt); } else return mkxfunc(ANCHOR, 0); } static tchar _setlink(struct ref **rstart, int oncode, int offcode, int *cnt) { struct ref *rp; char *np; int _sv; _sv = linkin; if ((linkin = !linkin)) { if ((np = getref()) != NULL) { rp = calloc(1, sizeof *rp); rp->cnt = ++*cnt; rp->name = np; rp->next = *rstart; *rstart = rp; linkin = *cnt; return mkxfunc(oncode, *cnt); } else { linkin = -1; return mkxfunc(oncode, 0); } } else return mkxfunc(offcode, _sv > 0 ? _sv : 0); } tchar setlink(void) { static int cnt; return _setlink(&links, LINKON, LINKOFF, &cnt); } tchar setulink(void) { static int cnt; return _setlink(&ulinks, ULINKON, ULINKOFF, &cnt); } int pts2u(int p) { return p * INCH / 72; } double u2pts(int u) { return u * 72.0 / INCH; } #define psnprime 1021 static struct psnnode { struct psnnode *next; const char *name; int code; } **psntable; static int _ps2cc(const char *name, int create) { struct psnnode *pp; unsigned h; if (psntable == NULL) psntable = calloc(psnprime, sizeof *psntable); h = pjw(name) % psnprime; for (pp = psntable[h]; pp; pp = pp->next) if (strcmp(name, pp->name) == 0) return pp->code; if (create == 0) return 0; pp = calloc(1, sizeof *pp); pp->name = strdup(name); pp->next = psntable[h]; psntable[h] = pp; return pp->code = ++psmaxcode; } int ps2cc(const char *name) { return _ps2cc(name, 1); } Index: projects/doctools/contrib/heirloom-doctools/vgrind/vfontedpr.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/vgrind/vfontedpr.c (revision 307811) +++ projects/doctools/contrib/heirloom-doctools/vgrind/vfontedpr.c (revision 307812) @@ -1,901 +1,897 @@ /* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ /* from OpenSolaris "vfontedpr.c 1.17 93/06/03 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)vfontedpr.c 1.4 (gritter) 10/22/05 */ #include #include #include #include #include #include #include #include #ifdef EUC #include #endif - -#if defined (__GLIBC__) && defined (_IO_getc_unlocked) -#undef getc -#define getc(f) _IO_getc_unlocked(f) -#endif +#include "global.h" #define boolean int #define TRUE 1 #define FALSE 0 #define NIL 0 #define STANDARD 0 #define ALTERNATE 1 /* * Vfontedpr. * * Dave Presotto 1/12/81 (adapted from an earlier version by Bill Joy) * */ #define STRLEN 10 /* length of strings introducing things */ #define PNAMELEN 40 /* length of a function/procedure name */ #define PSMAX 20 /* size of procedure name stacking */ /* regular expression routines */ /* regexp.c */ /*char *expmatch(); match a string to an expression */ char *expmatch(register char *, register char *, register char *); /*char *STRNCMP(); a different kind of strncmp */ int STRNCMP(register char *, register char *, register int); /*char *convexp(); convert expression to internal form */ char *convexp(char *); /* * The state variables */ static boolean incomm; /* in a comment of the primary type */ static boolean instr; /* in a string constant */ static boolean inchr; /* in a string constant */ static boolean nokeyw = FALSE; /* no keywords being flagged */ static boolean doindex = FALSE;/* form an index */ static boolean twocol = FALSE; /* in two-column mode */ static boolean filter = FALSE; /* act as a filter (like eqn) */ static boolean pass = FALSE; /* when acting as a filter, pass indicates * whether we are currently processing * input. */ static boolean prccont; /* continue last procedure */ static int comtype; /* type of comment */ static int margin; static int psptr; /* the stack index of the current procedure */ static char pstack[PSMAX][PNAMELEN+1]; /* the procedure name stack */ static int plstack[PSMAX]; /* the procedure nesting level stack */ static int blklevel; /* current nesting level */ static int prclevel; /* nesting level at which procedure definitions may be found, -1 if none currently valid (meaningful only if l_prclevel is true) */ static char *defsfile = LIBDIR "/vgrindefs"; /* name of language definitions file */ static char pname[BUFSIZ+1]; /* * The language specific globals */ static char *language = "c";/* the language indicator */ static char *l_keywds[BUFSIZ/2]; /* keyword table address */ static char *l_prcbeg; /* regular expr for procedure begin */ static char *l_combeg; /* string introducing a comment */ static char *l_comend; /* string ending a comment */ static char *l_acmbeg; /* string introducing a comment */ static char *l_acmend; /* string ending a comment */ static char *l_blkbeg; /* string begining of a block */ static char *l_blkend; /* string ending a block */ static char *l_strbeg; /* delimiter for string constant */ static char *l_strend; /* delimiter for string constant */ static char *l_chrbeg; /* delimiter for character constant */ static char *l_chrend; /* delimiter for character constant */ static char *l_prcenable; /* re indicating that procedure definitions can be found in the next lexical level -- kludge for lisp-like languages that use something like (defun (proc ...) (proc ...) ) to define procedures */ static char l_escape; /* character used to escape characters */ static boolean l_toplex; /* procedures only defined at top lex level */ static boolean l_prclevel; /* procedure definitions valid only within the nesting level indicated by the px (l_prcenable) capability */ /* * for the benefit of die-hards who aren't convinced that tabs * occur every eight columns */ static short tabsize = 8; static int mb_cur_max; /* * global variables also used by expmatch */ boolean escaped; /* if last character was an escape */ char *Start; /* start of the current string */ boolean l_onecase; /* upper and lower case are equivalent */ char *l_idchars; /* characters legal in identifiers in addition to letters and digits (default "_") */ extern int STRNCMP(register char *, register char *, register int); extern char *convexp(char *); extern char *expmatch(register char *, register char *, register char *); extern int tgetent(char *, char *, char *); extern int tgetnum(char *); extern int tgetflag(char *); extern char *tgetstr(char *, char **); static void putScp(char *); static void putKcp(char *, char *, int); static int tabs(char *, char *); static int width(register char *, register char *); static void putcp(register int); static int isproc(char *); static int iskw(register char *); static char *fgetline(char **, size_t *, size_t *, FILE *); /* * The code below emits troff macros and directives that consume part of the * troff macro and register space. See tmac.vgrind for an enumeration of * these macros and registers. */ int main(int argc, char **argv) { FILE *in; char *fname; struct stat stbuf; char *buf = NULL; size_t size = 0; char idbuf[256]; /* enough for all 8 bit chars */ char strings[2 * BUFSIZ]; char defs[2 * BUFSIZ]; int needbp = 0; int i; char *cp; setlocale(LC_CTYPE, ""); mb_cur_max = MB_CUR_MAX; buf = malloc(size = BUFSIZ); /* * Dump the name by which we were invoked. */ argc--, argv++; /* * Process arguments. For the sake of compatibility with older versions * of the program, the syntax accepted below is very idiosyncratic. Some * options require space between the option and its argument; others * disallow it. No options may be bundled together. * * Actually, there is one incompatibility. Files and options formerly * could be arbitrarily intermixed, but this is no longer allowed. (This * possiblity was never documented.) */ while (argc > 0 && *argv[0] == '-') { switch (*(cp = argv[0] + 1)) { case '\0': /* - */ /* Take input from stdin. */ /* * This option implies the end of the flag arguments. Leave the * "-" in place for the file processing code to see. */ goto flagsdone; case '2': /* -2 */ /* Enter two column mode. */ twocol = 1; printf("'nr =2 1\n"); break; case 'd': /* -d */ /* Specify the language description file. */ defsfile = argv[1]; argc--, argv++; break; case 'f': /* -f */ /* Act as a filter like eqn. */ filter = 1; /* * Slide remaining arguments down one position and postpend "-", * to force reading from stdin. */ for (i = 0; i < argc - 1; i++) argv[i] = argv[i + 1]; argv[argc - 1] = "-"; continue; case 'h': /* -h [header] */ /* Specify header string. */ if (argc == 1) { printf("'ds =H\n"); break; } printf("'ds =H %s\n", argv[1]); argc--, argv++; break; case 'l': /* -l */ /* Specify the language. */ language = cp + 1; break; case 'n': /* -n */ /* Indicate no keywords. */ nokeyw = 1; break; case 's': /* -s */ /* Specify the font size. */ i = 0; cp++; while (*cp) i = i * 10 + (*cp++ - '0'); printf("'nr vP %d\n", i); break; case 't': /* -t */ /* Specify a nondefault tab size. */ tabsize = 4; break; case 'x': /* -x */ /* Build an index. */ doindex = 1; /* This option implies "-n" as well; turn it on. */ argv[0] = "-n"; continue; } /* Advance to next argument. */ argc--, argv++; } flagsdone: /* * Get the language definition from the defs file. */ i = tgetent (defs, language, defsfile); if (i == 0) { fprintf (stderr, "no entry for language %s\n", language); exit (0); } else if (i < 0) { fprintf (stderr, "cannot find vgrindefs file %s\n", defsfile); exit (0); } cp = strings; if (tgetstr ("kw", &cp) == NIL) nokeyw = TRUE; else { char **cpp; cpp = l_keywds; cp = strings; while (*cp) { while (*cp == ' ' || *cp =='\t') *cp++ = '\0'; if (*cp) *cpp++ = cp; while (*cp != ' ' && *cp != '\t' && *cp) cp++; } *cpp = NIL; } cp = buf; l_prcbeg = convexp (tgetstr ("pb", &cp)); cp = buf; l_combeg = convexp (tgetstr ("cb", &cp)); cp = buf; l_comend = convexp (tgetstr ("ce", &cp)); cp = buf; l_acmbeg = convexp (tgetstr ("ab", &cp)); cp = buf; l_acmend = convexp (tgetstr ("ae", &cp)); cp = buf; l_strbeg = convexp (tgetstr ("sb", &cp)); cp = buf; l_strend = convexp (tgetstr ("se", &cp)); cp = buf; l_blkbeg = convexp (tgetstr ("bb", &cp)); cp = buf; l_blkend = convexp (tgetstr ("be", &cp)); cp = buf; l_chrbeg = convexp (tgetstr ("lb", &cp)); cp = buf; l_chrend = convexp (tgetstr ("le", &cp)); cp = buf; l_prcenable = convexp (tgetstr ("px", &cp)); cp = idbuf; l_idchars = tgetstr ("id", &cp); /* Set default, for compatibility with old version */ if (l_idchars == NIL) l_idchars = "_"; l_escape = '\\'; l_onecase = tgetflag ("oc"); l_toplex = tgetflag ("tl"); l_prclevel = tgetflag ("pl"); /* * Emit a call to the initialization macro. If not in filter mode, emit a * call to the vS macro, so that tmac.vgrind can uniformly assume that all * program input is bracketed with vS-vE pairs. */ printf("'vI\n"); if (!filter) printf("'vS\n"); if (doindex) { /* * XXX: Hard-wired spacing information. This should probably turn * into the emission of a macro invocation, so that tmac.vgrind * can make up its own mind about what spacing is appropriate. */ if (twocol) printf("'ta 2.5i 2.75i 4.0iR\n'in .25i\n"); else printf("'ta 4i 4.25i 5.5iR\n'in .5i\n"); } while (argc > 0) { if (strcmp(argv[0], "-") == 0) { /* Embed an instance of the original stdin. */ in = fdopen(fileno(stdin), "r"); fname = ""; } else { /* Open the file for input. */ if ((in = fopen(argv[0], "r")) == NULL) { perror(argv[0]); exit(1); } fname = argv[0]; } argc--, argv++; /* * Reinitialize for the current file. */ incomm = FALSE; instr = FALSE; inchr = FALSE; escaped = FALSE; blklevel = 0; prclevel = -1; for (psptr=0; psptr= 0)) printf("'FC %s\n", pstack[psptr]); #ifdef DEBUG printf ("com %o str %o chr %o ptr %d\n", incomm, instr, inchr, psptr); #endif margin = 0; } needbp = 1; fclose(in); } /* Close off the vS-vE pair. */ if (!filter) printf("'vE\n"); exit(0); /* NOTREACHED */ } #define isidchr(c) (isalnum(c) || ((c) != NIL && strchr(l_idchars, (c)) != NIL)) static void putScp(char *os) { register char *s = os; /* pointer to unmatched string */ char dummy[BUFSIZ]; /* dummy to be used by expmatch */ char *comptr; /* end of a comment delimiter */ char *acmptr; /* end of a comment delimiter */ char *strptr; /* end of a string delimiter */ char *chrptr; /* end of a character const delimiter */ char *blksptr; /* end of a lexical block start */ char *blkeptr; /* end of a lexical block end */ Start = os; /* remember the start for expmatch */ escaped = FALSE; if (nokeyw || incomm || instr) goto skip; if (isproc(s)) { printf("'FN %s\n", pname); if (psptr < PSMAX-1) { ++psptr; strncpy (pstack[psptr], pname, PNAMELEN); pstack[psptr][PNAMELEN] = '\0'; plstack[psptr] = blklevel; } } /* * if l_prclevel is set, check to see whether this lexical level * is one immediately below which procedure definitions are allowed. */ if (l_prclevel && !incomm && !instr && !inchr) { if (expmatch (s, l_prcenable, dummy) != NIL) prclevel = blklevel + 1; } skip: do { /* check for string, comment, blockstart, etc */ if (!incomm && !instr && !inchr) { blkeptr = expmatch (s, l_blkend, dummy); blksptr = expmatch (s, l_blkbeg, dummy); comptr = expmatch (s, l_combeg, dummy); acmptr = expmatch (s, l_acmbeg, dummy); strptr = expmatch (s, l_strbeg, dummy); chrptr = expmatch (s, l_chrbeg, dummy); /* start of a comment? */ if (comptr != NIL) if ((comptr < strptr || strptr == NIL) && (comptr < acmptr || acmptr == NIL) && (comptr < chrptr || chrptr == NIL) && (comptr < blksptr || blksptr == NIL) && (comptr < blkeptr || blkeptr == NIL)) { putKcp (s, comptr-1, FALSE); s = comptr; incomm = TRUE; comtype = STANDARD; if (s != os) printf ("\\c"); printf ("\\c\n'+C\n"); continue; } /* start of a comment? */ if (acmptr != NIL) if ((acmptr < strptr || strptr == NIL) && (acmptr < chrptr || chrptr == NIL) && (acmptr < blksptr || blksptr == NIL) && (acmptr < blkeptr || blkeptr == NIL)) { putKcp (s, acmptr-1, FALSE); s = acmptr; incomm = TRUE; comtype = ALTERNATE; if (s != os) printf ("\\c"); printf ("\\c\n'+C\n"); continue; } /* start of a string? */ if (strptr != NIL) if ((strptr < chrptr || chrptr == NIL) && (strptr < blksptr || blksptr == NIL) && (strptr < blkeptr || blkeptr == NIL)) { putKcp (s, strptr-1, FALSE); s = strptr; instr = TRUE; continue; } /* start of a character string? */ if (chrptr != NIL) if ((chrptr < blksptr || blksptr == NIL) && (chrptr < blkeptr || blkeptr == NIL)) { putKcp (s, chrptr-1, FALSE); s = chrptr; inchr = TRUE; continue; } /* end of a lexical block */ if (blkeptr != NIL) { if (blkeptr < blksptr || blksptr == NIL) { /* reset prclevel if necessary */ if (l_prclevel && prclevel == blklevel) prclevel = -1; putKcp (s, blkeptr - 1, FALSE); s = blkeptr; blklevel--; if (psptr >= 0 && plstack[psptr] >= blklevel) { /* end of current procedure */ if (s != os) printf ("\\c"); printf ("\\c\n'-F\n"); blklevel = plstack[psptr]; /* see if we should print the last proc name */ if (--psptr >= 0) prccont = TRUE; else psptr = -1; } continue; } } /* start of a lexical block */ if (blksptr != NIL) { putKcp (s, blksptr - 1, FALSE); s = blksptr; blklevel++; continue; } /* check for end of comment */ } else if (incomm) { comptr = expmatch (s, l_comend, dummy); acmptr = expmatch (s, l_acmend, dummy); if (((comtype == STANDARD) && (comptr != NIL)) || ((comtype == ALTERNATE) && (acmptr != NIL))) { if (comtype == STANDARD) { putKcp (s, comptr-1, TRUE); s = comptr; } else { putKcp (s, acmptr-1, TRUE); s = acmptr; } incomm = FALSE; printf("\\c\n'-C\n"); continue; } else { putKcp (s, s + strlen(s) -1, TRUE); s = s + strlen(s); continue; } /* check for end of string */ } else if (instr) { if ((strptr = expmatch (s, l_strend, dummy)) != NIL) { putKcp (s, strptr-1, TRUE); s = strptr; instr = FALSE; continue; } else { putKcp (s, s+strlen(s)-1, TRUE); s = s + strlen(s); continue; } /* check for end of character string */ } else if (inchr) { if ((chrptr = expmatch (s, l_chrend, dummy)) != NIL) { putKcp (s, chrptr-1, TRUE); s = chrptr; inchr = FALSE; continue; } else { putKcp (s, s+strlen(s)-1, TRUE); s = s + strlen(s); continue; } } /* print out the line */ putKcp (s, s + strlen(s) -1, FALSE); s = s + strlen(s); } while (*s); } static void putKcp ( char *start, /* start of string to write */ char *end, /* end of string to write */ boolean force /* true if we should force nokeyw */ ) { int i; int xfld = 0; while (start <= end) { if (doindex) { if (*start == ' ' || *start == '\t') { if (xfld == 0) printf(""); printf("\t"); xfld = 1; while (*start == ' ' || *start == '\t') start++; continue; } } /* take care of nice tab stops */ if (*start == '\t') { while (*start == '\t') start++; i = tabs(Start, start) - margin / tabsize; printf ("\\h'|%dn'", i * (tabsize == 4 ? 5 : 10) + 1 - margin % tabsize); continue; } if (!nokeyw && !force) if ( (*start == '#' || isidchr((int)*start)) && (start == Start || !isidchr((int)start[-1])) ) { i = iskw(start); if (i > 0) { printf("\\*(+K"); do putcp(*start++); while (--i > 0); printf("\\*(-K"); continue; } } putcp (*start++); } } static int tabs(char *s, char *os) { return (width(s, os) / tabsize); } static int width(register char *s, register char *os) { register int i = 0; unsigned char c; int n; while (s < os) { if (*s == '\t') { i = (i + tabsize) &~ (tabsize-1); s++; continue; } c = *(unsigned char *)s; if (c < ' ') i += 2, s++; #ifdef EUC else if (c >= 0200) { wchar_t wc; if ((n = mbtowc(&wc, s, mb_cur_max)) > 0) { s += n; if ((n = wcwidth(wc)) > 0) i += n; } else s++; } #endif /* EUC */ else i++, s++; } return (i); } static void putcp(register int c) { switch(c) { case 0: break; case '\f': break; case '{': printf("\\*(+K{\\*(-K"); break; case '}': printf("\\*(+K}\\*(-K"); break; case '\\': printf("\\e"); break; case '_': printf("\\*_"); break; case '-': printf("\\*-"); break; /* * The following two cases deal with the accent characters. * If they're part of a comment, we assume that they're part * of running text and hand them to troff as regular quote * characters. Otherwise, we assume they're being used as * special characters (e.g., string delimiters) and arrange * for troff to render them as accents. This is an imperfect * heuristic that produces slightly better appearance than the * former behavior of unconditionally rendering the characters * as accents. (See bug 1040343.) */ case '`': if (incomm) printf("`"); else printf("\\`"); break; case '\'': if (incomm) printf("'"); else printf("\\'"); break; case '.': printf("\\&."); break; /* * The following two cases contain special hacking * to make C-style comments line up. The tests aren't * really adequate; they lead to grotesqueries such * as italicized multiplication and division operators. * However, the obvious test (!incomm) doesn't work, * because incomm isn't set until after we've put out * the comment-begin characters. The real problem is * that expmatch() doesn't give us enough information. */ case '*': if (instr || inchr) printf("*"); else printf("\\f2*\\fP"); break; case '/': if (instr || inchr) printf("/"); else printf("\\f2\\h'\\w' 'u-\\w'/'u'/\\fP"); break; default: if (c < 040) putchar('^'), c |= '@'; case '\t': case '\n': putchar(c); } } /* * look for a process beginning on this line */ static boolean isproc(char *s) { pname[0] = '\0'; if (l_prclevel ? (prclevel == blklevel) : (!l_toplex || blklevel == 0)) if (expmatch (s, l_prcbeg, pname) != NIL) { return (TRUE); } return (FALSE); } /* * iskw - check to see if the next word is a keyword * Return its length if it is or 0 if it isn't. */ static int iskw(register char *s) { register char **ss = l_keywds; register int i = 1; register char *cp = s; /* Get token length. */ while (++cp, isidchr((int)*cp)) i++; while ((cp = *ss++)) { if (!STRNCMP(s,cp,i) && !isidchr((int)cp[i])) return (i); } return (0); } #define LSIZE 128 static char * fgetline(char **line, size_t *linesize, size_t *llen, FILE *fp) { int c; size_t n = 0; if (*line == NULL || *linesize < LSIZE + n + 1) *line = realloc(*line, *linesize = LSIZE + n + 1); for (;;) { if (n >= *linesize - LSIZE / 2) *line = realloc(*line, *linesize += LSIZE); c = getc(fp); if (c != EOF) { (*line)[n++] = c; (*line)[n] = '\0'; if (c == '\n') break; } else { if (n > 0) break; else return NULL; } } if (llen) *llen = n; return *line; } Index: projects/doctools/contrib/heirloom-doctools =================================================================== --- projects/doctools/contrib/heirloom-doctools (revision 307811) +++ projects/doctools/contrib/heirloom-doctools (revision 307812) Property changes on: projects/doctools/contrib/heirloom-doctools ___________________________________________________________________ Added: svn:mergeinfo ## -0,0 +0,42 ## Merged /user/ngie/release-pkg-fix-tests/contrib/heirloom-doctools:r298865-299093 Merged /projects/release-arm-redux/contrib/heirloom-doctools:r278203,278595-278597,278610,280643-280650,280652,280655,282539-282546,282548,282553-282557,282564,282566,282570,282573,282587-282593,282596-282607,282615-282616,282624-282629,282631,282633,282635-282640,282642,282647-282648,282653-282654,282656-282657,282659,282662-282667,282682,282691 Merged /projects/clang350-import/contrib/heirloom-doctools:r274961-275126,275128-275133,275135-276476 Merged /vendor/device-tree/dist/contrib/heirloom-doctools:r303380 Merged /vendor/resolver/dist/contrib/heirloom-doctools:r1540-186085 Merged /projects/clang370-import/contrib/heirloom-doctools:r287506-288928 Merged /projects/quota64/contrib/heirloom-doctools:r184125-207707 Merged /projects/elftoolchain/contrib/heirloom-doctools:r260687-261245 Merged /projects/ipfw/contrib/heirloom-doctools:r267383-272837 Merged /user/ngie/make_check/contrib/heirloom-doctools:r291879-295379 Merged /user/ngie/socket-tests/contrib/heirloom-doctools:r293882-293885,294103,294117,294119-294120,294245-294247,294488,294555,294643-294644 Merged /projects/mpsutil/contrib/heirloom-doctools:r286179-290100 Merged /head/contrib/heirloom-doctools:r306791-307810 Merged /user/ngie/more-tests2/contrib/heirloom-doctools:r288935-289179,289223-289224,289226-289227,289230,289236,289325,289437,289440,289478,289484-289486,290904,290921 Merged /projects/netbsd-tests-update-12/contrib/heirloom-doctools:r303985-305318 Merged /projects/vnet/contrib/heirloom-doctools:r295220 Merged /projects/release-embedded/contrib/heirloom-doctools:r262314,262504,262510-262511,262580,262660,262662,262700,262713,262774,262786-262788,262790-262792,262798,262802,262808 Merged /projects/release-pkg/contrib/heirloom-doctools:r274131-298104 Merged /projects/clang-sparc64/contrib/heirloom-doctools:r262258-262612 Merged /user/ngie/bsnmp_cleanup/contrib/heirloom-doctools:r295193 Merged /projects/largeSMP/contrib/heirloom-doctools:r221273-222812,222815-223757 Merged /user/ngie/bug203673/contrib/heirloom-doctools:r289470-289489 Merged /projects/head_mfi/contrib/heirloom-doctools:r233621 Merged /user/delphij/zfs-arc-rebase/contrib/heirloom-doctools:r281754 Merged /projects/collation/contrib/heirloom-doctools:r286424-290491 Merged /projects/lldb-r201577/contrib/heirloom-doctools:r262185-262527 Merged /projects/release-arm64/contrib/heirloom-doctools:r281786,281788,281792 Merged /projects/bsnmp-improved-ipv6-support/contrib/heirloom-doctools:r301868 Merged /projects/clang360-import/contrib/heirloom-doctools:r277327-280030 Merged /projects/elftoolchain-update-r3130/contrib/heirloom-doctools:r276164,276167,276170-276172 Merged /projects/clang380-import/contrib/heirloom-doctools:r292913-296412 Merged /projects/pms/contrib/heirloom-doctools:r285199-285661 Merged /projects/multi-fibv6/head/contrib/heirloom-doctools:r230929-231848 Merged /projects/random_number_generator/contrib/heirloom-doctools:r254613-256243 Merged /projects/zfsd/head/contrib/heirloom-doctools:r266519,269993 Merged /vendor/heirloom-doctools/dist:r306859-307811 Merged /projects/contrib-netbsd-update-12/contrib/heirloom-doctools:r303899-303984 Merged /user/ngie/more-tests/contrib/heirloom-doctools:r281427-281428,281430,281432,281450,281460,281464-281465,281485,281489-281491,281515,281519,281589,281593-281597,281619,284388,288316,288321-288327,288422,288476,288478-288481,288483,288578,288650-288651,288655-288656,288659-288661,288663,288673-288676,288680,288828,288930-288932 Merged /projects/pf/head/contrib/heirloom-doctools:r263908 Merged /projects/cxl_iscsi/contrib/heirloom-doctools:r291227-291228,292618 Merged /projects/clang-trunk/contrib/heirloom-doctools:r283596-287505 Merged /projects/building-blocks/contrib/heirloom-doctools:r275142-275143,275198,275297,275306-275307,275309,275311,275556,275558,275600,277445,277670,277673