Index: projects/doctools/contrib/heirloom-doctools/checknr/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/checknr/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/checknr/Makefile.mk (revision 307924) @@ -1,21 +1,21 @@ OBJ = checknr.o FLAGS = $(DEFINES) -I../include .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: checknr checknr: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o checknr + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJ) $(LIBS) -o checknr install: $(INSTALL) -c checknr $(ROOT)$(BINDIR)/checknr $(STRIP) $(ROOT)$(BINDIR)/checknr $(INSTALL) -c -m 644 checknr.1 $(ROOT)$(MANDIR)/man1/checknr.1 clean: rm -f $(OBJ) checknr core log *~ mrproper: clean Index: projects/doctools/contrib/heirloom-doctools/col/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/col/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/col/Makefile.mk (revision 307924) @@ -1,22 +1,22 @@ BIN = col OBJ = col.o FLAGS = $(DEFINES) -I../include all: $(BIN) $(BIN): $(OBJ) - $(CC) ${CFLAGS} $(LDFLAGS) $(OBJ) -o $(BIN) + $(CC) ${_CFLAGS} $(_LDFLAGS) $(OBJ) -o $(BIN) install: $(INSTALL) -c $(BIN) $(ROOT)$(BINDIR)/$(BIN) $(STRIP) $(ROOT)$(BINDIR)/$(BIN) clean: rm -f $(OBJ) $(BIN) core log *~ mrproper: clean .c.o: - ${CC} ${CFLAGS} ${CPPFLAGS} $(FLAGS) -c $< + ${CC} ${_CFLAGS} $(FLAGS) -c $< Index: projects/doctools/contrib/heirloom-doctools/configure =================================================================== --- projects/doctools/contrib/heirloom-doctools/configure (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/configure (revision 307924) @@ -1,235 +1,236 @@ #!/bin/sh # Copyright (c) 2016, Carsten Kunze # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. usage () { echo "Usage: $0 [-s]" echo " -s Silence output" exit $1 } SFLAG= MAKE= DEFS= LIB_LEX= LIB_CURSES= cat /dev/null > compat.h while [ $# -gt 0 ]; do case $1 in -s) SFLAG=1;; *) echo "$0: $1: Unknown option" >&2 usage 1;; esac shift done check_for () { [ -e $LOG ] && echo >>$LOG A="Checking for $1 ... " echo "$A" >>$LOG [ -z "$SFLAG" ] && printf "$A" } compile () { rm -f ${TMPNAM}.o $TMPNAM $OUT $ERR $MAKE -f $OUTMK $TMPNAM > $OUT 2> $ERR RESULT=$? cat $OUT $ERR >> $LOG if [ $RESULT -eq 0 ]; then true; else false; fi } test_result () { RESULT=$? RESULT_TEXT=${1:-0} # 1: omit "no", 2: say nothing if [ $RESULT -eq 0 ]; then echo success >>$LOG [ -z "$SFLAG" -a $RESULT_TEXT -lt 2 ] && \ echo "yes$PASS_TEXT" PASS_TEXT= [ -e $TMPC ] && rm -f $TMPC true else [ -z "$SFLAG" -a $RESULT_TEXT -lt 1 ] && echo no if [ -e $TMPC ]; then echo "Failed program:" >>$LOG pr -n -t $TMPC >>$LOG rm -f $TMPC fi false fi } gen_mk () { [ $# -eq 0 ] && rm -f $OUTMK [ -n "$LEX" ] && echo "LEX=$LEX" >> $OUTMK [ -n "$FLOAT_STORE" ] && echo "FLOAT_STORE=$FLOAT_STORE" >> $OUTMK [ -n "$DEFS" ] && echo "DEFINES=$DEFS" >> $OUTMK [ -n "$INCDIR_CURSES" ] && echo "INCDIR_CURSES=$INCDIR_CURSES" >> $OUTMK [ -n "$RPATH_CURSES" ] && echo "RPATH_CURSES=$RPATH_CURSES" >> $OUTMK [ -n "$LIBDIR_CURSES" ] && echo "LIBDIR_CURSES=$LIBDIR_CURSES" \ >> $OUTMK [ -n "$LIB_CURSES" ] && echo "LIB_CURSES=$LIB_CURSES" >> $OUTMK [ -n "$LIB_AVLBST" ] && echo "LIB_AVLBST=$LIB_AVLBST" >> $OUTMK [ -n "$LIB_LEX" ] && echo "LIB_LEX=$LIB_LEX" >> $OUTMK [ -n "$__CDBG" ] && echo "__CDBG=$__CDBG" >> $OUTMK - [ -n "$__SAN" ] && echo "__SAN=$__SAN" >> $OUTMK + [ -n "$__CLDBG" ] && echo "__CLDBG=$__CLDBG" >> $OUTMK cat $INMK >> $OUTMK || exit 1 } check_make () { check_for "make(1)" cat <$TMPMK all: true EOT make -f $TMPMK >> $LOG 2>&1 test_result && { MAKE=make return } echo "Failed makefile:" >>$LOG pr -n -t $TMPMK >>$LOG check_for "bmake(1)" cat <$TMPMK all: true EOT bmake -f $TMPMK >> $LOG 2>&1 test_result && MAKE=bmake } check_lex () { check_for '$(LEX)' cat <$TMPL %% %% int main() { return 0; } int yywrap(void) { return 0; } EOT compile test_result && return check_for 'flex(1)' LEX=flex gen_mk compile test_result && return check_for 'lex(1)' LEX=lex gen_mk compile test_result && return } check_strlcpy () { check_for "strlcpy(3)" cat <$TMPC #include int main(int argc, char **argv) { char a[10]; (void)argc; strlcpy(a, *argv, sizeof a); return 0; } EOT compile if test_result; then DEFS="$DEFS -DHAVE_STRLCPY" else H=compat.h grep -q '' $H 2>/dev/null || cat <>$H #include EOT cat <>$H size_t strlcpy(char *, const char *, size_t); EOT fi } check_strlcat () { check_for "strlcat(3)" cat <$TMPC #include int main(int argc, char **argv) { char a[10]; (void)argc; *a = 0; strlcat(a, *argv, sizeof a); return 0; } EOT compile if test_result; then DEFS="$DEFS -DHAVE_STRLCAT" else H=compat.h grep -q '' $H 2>/dev/null || cat <>$H #include EOT cat <>$H size_t strlcat(char *, const char *, size_t); EOT fi } check_wcslcpy () { check_for "wcslcpy(3)" cat <$TMPC #include #include int main() { wchar_t a, b; a = getwchar(); wcslcpy(&b, &a, 1); return 0; } EOT compile test_result && DEFS="$DEFS -DHAVE_WCSLCPY" } [ ! -s compat.h ] && rm compat.h OUTMK=cfg.mk INMK=mk.config CFG=config TMPNAM=.$CFG TMPMK=${TMPNAM}.mk TMPC=${TMPNAM}.c TMPL=${TMPNAM}.l OUT=${TMPNAM}.out ERR=${TMPNAM}.err LOG=${CFG}.log rm -f $LOG gen_mk check_make +#check_Sanitizer check_lex check_strlcpy check_strlcat check_wcslcpy gen_mk cat version.mk >> $OUTMK || exit 1 rm -f $TMPNAM* Index: projects/doctools/contrib/heirloom-doctools/eqn/checkeq.d/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/checkeq.d/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/eqn/checkeq.d/Makefile.mk (revision 307924) @@ -1,23 +1,23 @@ VPATH=.. OBJ = checkeq.o FLAGS = .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: checkeq checkeq: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o checkeq + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJ) $(LIBS) -o checkeq install: $(INSTALL) -c checkeq $(ROOT)$(BINDIR)/checkeq $(STRIP) $(ROOT)$(BINDIR)/checkeq rm -f $(ROOT)$(MANDIR)/man1/checkeq.1 ln -s eqn.1 $(ROOT)$(MANDIR)/man1/checkeq.1 clean: rm -f $(OBJ) checkeq core log *~ mrproper: clean Index: projects/doctools/contrib/heirloom-doctools/eqn/e.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/e.h (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/eqn/e.h (revision 307924) @@ -1,182 +1,178 @@ /* 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" #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); 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 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/eqn.d/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/eqn.d/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/eqn/eqn.d/Makefile.mk (revision 307924) @@ -1,56 +1,56 @@ VPATH=.. OBJ = diacrit.o e.o eqnbox.o font.o fromto.o funny.o glob.o integral.o \ io.o lex.o lookup.o mark.o matrix.o move.o over.o paren.o pile.o \ shift.o size.o sqrt.o text.o version.o FLAGS = -I. -I.. -I../../include $(DEFINES) .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: eqn eqn: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o eqn + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJ) $(LIBS) -o eqn e.c: e.y $(YACC) -d ../e.y sed -f ../yyval.sed $@ y.tab.h: e.c install: test -d $(ROOT)$(BINDIR) || mkdir -p $(ROOT)$(BINDIR) $(INSTALL) -c eqn $(ROOT)$(BINDIR)/eqn $(STRIP) $(ROOT)$(BINDIR)/eqn test -d $(ROOT)$(MANDIR)/man1 || mkdir -p $(ROOT)$(MANDIR)/man1 test -d $(ROOT)$(MANDIR)/man7 || mkdir -p $(ROOT)$(MANDIR)/man7 $(INSTALL) -c -m 644 eqn.1 $(ROOT)$(MANDIR)/man1/eqn.1 $(INSTALL) -c -m 644 eqnchar.7 $(ROOT)$(MANDIR)/man7/eqnchar.7 clean: rm -f $(OBJ) eqn e.c y.tab.* core log *~ mrproper: clean diacrit.o: ../diacrit.c ../e.h y.tab.h eqnbox.o: ../eqnbox.c ../e.h font.o: ../font.c ../e.h fromto.o: ../fromto.c ../e.h funny.o: ../funny.c ../e.h y.tab.h glob.o: ../glob.c ../e.h integral.o: ../integral.c ../e.h y.tab.h io.o: ../io.c ../e.h lex.o: ../lex.c ../e.h y.tab.h lookup.o: ../lookup.c ../e.h y.tab.h mark.o: ../mark.c ../e.h matrix.o: ../matrix.c ../e.h move.o: ../move.c ../e.h y.tab.h over.o: ../over.c ../e.h paren.o: ../paren.c ../e.h pile.o: ../pile.c ../e.h shift.o: ../shift.c ../e.h y.tab.h size.o: ../size.c ../e.h sqrt.o: ../sqrt.c ../e.h text.o: ../text.c ../e.h y.tab.h e.o: e.c ../e.h Index: projects/doctools/contrib/heirloom-doctools/eqn/eqnchar.d/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/eqnchar.d/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/eqn/eqnchar.d/Makefile.mk (revision 307924) @@ -1,28 +1,28 @@ FILES = ascii eqnchar greek iso utf-8 .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(EUC) -c $< + $(CC) $(_CFLAGS) $(EUC) -c $< all: $(FILES) utf-8: genutf8 -./genutf8 >utf-8 genutf8: genutf8.o - -$(CC) $(CFLAGS) $(LDFLAGS) genutf8.o $(LIBS) -o genutf8 + -$(CC) $(_CFLAGS) $(_LDFLAGS) genutf8.o $(LIBS) -o genutf8 genutf8.o: genutf8.c - -$(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(EUC) -c genutf8.c + -$(CC) $(_CFLAGS) $(EUC) -c genutf8.c install: all test -d $(ROOT)$(PUBDIR) || mkdir -p $(ROOT)$(PUBDIR) for i in $(FILES); \ do \ test -s $$i || continue; \ $(INSTALL) -c -m 644 $$i $(ROOT)$(PUBDIR)/$$i || exit; \ done clean: rm -f utf-8 genutf8 genutf8.o core log *~ mrproper: clean Index: projects/doctools/contrib/heirloom-doctools/eqn/lex.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/lex.c (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/eqn/lex.c (revision 307924) @@ -1,307 +1,308 @@ /* 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 const char *str) { 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; + extern tbl *keytbl[], *deftbl[]; 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/eqn/neqn.d/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/neqn.d/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/eqn/neqn.d/Makefile.mk (revision 307924) @@ -1,53 +1,53 @@ VPATH=.. OBJ = diacrit.o e.o eqnbox.o font.o fromto.o funny.o glob.o integral.o \ io.o lex.o lookup.o mark.o matrix.o move.o over.o paren.o pile.o \ shift.o size.o sqrt.o text.o version.o FLAGS = -I. -I.. -I../../include -DNEQN $(DEFINES) .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: neqn neqn: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o neqn + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJ) $(LIBS) -o neqn e.c: e.y $(YACC) -d ../e.y sed -f ../yyval.sed $@ y.tab.h: e.c install: $(INSTALL) -c neqn $(ROOT)$(BINDIR)/neqn $(STRIP) $(ROOT)$(BINDIR)/neqn rm -f $(ROOT)$(MANDIR)/man1/neqn.1 ln -s eqn.1 $(ROOT)$(MANDIR)/man1/neqn.1 clean: rm -f $(OBJ) neqn e.c y.tab.* core log *~ mrproper: clean diacrit.o: ../diacrit.c ../e.h y.tab.h eqnbox.o: ../eqnbox.c ../e.h font.o: ../font.c ../e.h fromto.o: ../fromto.c ../e.h funny.o: ../funny.c ../e.h y.tab.h glob.o: ../glob.c ../e.h integral.o: ../integral.c ../e.h y.tab.h io.o: ../io.c ../e.h lex.o: ../lex.c ../e.h y.tab.h lookup.o: ../lookup.c ../e.h y.tab.h mark.o: ../mark.c ../e.h matrix.o: ../matrix.c ../e.h move.o: ../move.c ../e.h y.tab.h over.o: ../over.c ../e.h paren.o: ../paren.c ../e.h pile.o: ../pile.c ../e.h shift.o: ../shift.c ../e.h y.tab.h size.o: ../size.c ../e.h sqrt.o: ../sqrt.c ../e.h text.o: ../text.c ../e.h y.tab.h e.o: e.c ../e.h Index: projects/doctools/contrib/heirloom-doctools/eqn/text.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/eqn/text.c (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/eqn/text.c (revision 307924) @@ -1,233 +1,234 @@ /* 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 "text.c 1.6 05/06/02 SMI" SVr4.0 1.1 */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)text.c 1.8 (gritter) 1/13/08 */ /* * Changes Copyright (c) 2014 Carsten Kunze (carsten.kunze at arcor.de) */ #include "e.h" #include "y.tab.h" extern YYSTYPE yyval; static int csp; static int psp; #define CSSIZE 400 static char cs[420]; static int lf, rf; /* temporary spots for left and right fonts */ void text(int t,char *p1) { int c; const char *p; tbl *tp; + extern tbl *restbl; yyval.token = oalloc(); ebase[yyval.token] = 0; #ifndef NEQN eht[yyval.token] = VERT(EM(1.0, EFFPS(ps))); /* ht in machine units */ #else /* NEQN */ eht[yyval.token] = VERT(2); /* 2 half-spaces */ #endif /* NEQN */ lfont[yyval.token] = rfont[yyval.token] = ROM; if (t == QTEXT) p = p1; else if ( t == SPACE ) p = "\\ "; else if ( t == THIN ) p = "\\|"; else if ( t == TAB ) p = "\\t"; else if ((tp = lookup(&restbl, p1, NULL)) != NULL) p = tp->defn; else { lf = rf = 0; for (csp=psp=0; (c=p1[psp++])!='\0';) { rf = trans(c, p1); if (lf == 0) lf = rf; /* save first */ if (csp>CSSIZE) error(FATAL, "converted token %.25s... too long" ,p1); } cs[csp] = '\0'; p = cs; lfont[yyval.token] = lf; rfont[yyval.token] = rf; } #ifndef NEQN if(dbg)printf(".\t%dtext: S%d <- %s; b=%g,h=%g,lf=%c,rf=%c\n", t, yyval.token, p, ebase[yyval.token], eht[yyval.token], lfont[yyval.token], rfont[yyval.token]); #else /* NEQN */ if(dbg)printf(".\t%dtext: S%d <- %s; b=%d,h=%d,lf=%c,rf=%c\n", t, yyval.token, p, ebase[yyval.token], eht[yyval.token], lfont[yyval.token], rfont[yyval.token]); #endif /* NEQN */ printf(".ds %d \"%s\n", yyval.token, p); } int trans(int c,char *p1) { int f; int half = 0; f = ROM; switch( c) { case ')': half = 1; /*FALLTHRU*/ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ':': case ';': case '!': case '%': case '(': case '[': case ']': if (rf == ITAL) shim(half); roman(c); break; case ',': roman(c); shim(0); break; case '.': if (rf == ROM) roman(c); else cs[csp++] = c; f = rf; break; case '|': if (rf == ITAL) shim(0); shim(0); roman(c); shim(0); break; case '=': if (rf == ITAL) shim(0); name4('e','q'); f |= OP; break; case '+': if (rf == ITAL) shim(0); name4('p', 'l'); f |= OP; break; case '>': case '<': if (rf == ITAL) shim(0); if (p1[psp]=='=') { /* look ahead for == <= >= */ name4(c,'='); psp++; } else { cs[csp++] = c; } f |= OP; break; case '-': if (rf == ITAL) shim(0); if (p1[psp]=='>') { name4('-','>'); psp++; } else { name4('m','i'); } f |= OP; break; case '/': if (rf == ITAL) shim(0); name4('s','l'); f |= OP; break; case '~': case ' ': shim(0); shim(0); break; case '^': shim(0); break; case '\\': /* troff - pass 2 or 3 more chars */ if (rf == ITAL) shim(0); cs[csp++] = c; cs[csp++] = c = p1[psp++]; cs[csp++] = p1[psp++]; if (c=='(') cs[csp++] = p1[psp++]; if (c=='*' && cs[csp-1] == '(') { cs[csp++] = p1[psp++]; cs[csp++] = p1[psp++]; } else if (c == '[' || (c == '*' && cs[csp-1] == '[')) { do cs[csp++] = p1[psp++]; while (p1[psp-1] != ' ' && p1[psp-1] != '\t' && p1[psp-1] != '\n' && p1[psp-1] != ']'); if (cs[csp-1] != ']') { csp--; psp--; } } break; case '\'': cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = rf==ITAL ? ITAL : ROM; name4('f','m'); cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'P'; f = rf==ITAL ? ITAL : ROM; break; case 'f': if (ft == ITAL) { cs[csp++] = '\\'; cs[csp++] = '^'; cs[csp++] = 'f'; cs[csp++] = '\\'; cs[csp++] = '|'; /* trying | instead of ^ */ f = ITAL; } else cs[csp++] = 'f'; break; case 'j': if (ft == ITAL) { cs[csp++] = '\\'; cs[csp++] = '^'; cs[csp++] = 'j'; f = ITAL; } else cs[csp++] = 'j'; break; default: cs[csp++] = c; f = ft==ITAL ? ITAL : ROM; break; } return(f); } void shim(int small) { cs[csp++] = '\\'; cs[csp++] = small ? '^' : '|'; } void roman(int c) { cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = ROM; cs[csp++] = c; cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'P'; } void name4(int c1,int c2) { cs[csp++] = '\\'; cs[csp++] = '('; cs[csp++] = c1; cs[csp++] = c2; } Index: projects/doctools/contrib/heirloom-doctools/grap/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/grap/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/grap/Makefile.mk (revision 307924) @@ -1,41 +1,41 @@ OBJ = coord.o for.o frame.o grap.o grapl.o input.o label.o main.o misc.o \ plot.o print.o ticks.o version.o FLAGS = -DLIBDIR='"$(LIBDIR)"' $(DEFINES) -I../include YFLAGS = -d .c.o: - $(CC) $(CFLAGS) $(WARN) $(FLAGS) $(CPPFLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: grap.c grapl.c grap grap: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -lm -o grap + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJ) $(LIBS) -lm -o grap y.tab.h: grap.c install: $(INSTALL) -c grap $(ROOT)$(BINDIR)/grap $(STRIP) $(ROOT)$(BINDIR)/grap test -d $(ROOT)$(LIBDIR) || mkdir -p $(ROOT)$(LIBDIR) $(INSTALL) -c -m 644 grap.defines $(ROOT)$(LIBDIR)/grap.defines $(INSTALL) -c -m 644 grap.1 $(ROOT)$(MANDIR)/man1/grap.1 clean: rm -f $(OBJ) grapl.c grap.c y.tab.h grap core log *~ mrproper: clean coord.o: coord.c grap.h y.tab.h for.o: for.c grap.h y.tab.h frame.o: frame.c grap.h y.tab.h grap.o: grap.c grap.h grapl.o: grapl.c grap.h y.tab.h input.o: input.c grap.h y.tab.h label.o: label.c grap.h y.tab.h main.o: main.c grap.h y.tab.h misc.o: misc.c grap.h y.tab.h plot.o: plot.c grap.h y.tab.h print.o: print.c grap.h y.tab.h ticks.o: ticks.c grap.h y.tab.h Index: projects/doctools/contrib/heirloom-doctools/mk.config =================================================================== --- projects/doctools/contrib/heirloom-doctools/mk.config (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/mk.config (revision 307924) @@ -1,114 +1,109 @@ # # A BSD-compatible install command. # INSTALL=install # # Packaging prefix. # PREFIX=/usr/local # # Where to place binaries. # BINDIR=$(PREFIX)/ucb # # Where to place libraries. # LIBDIR=$(PREFIX)/ucblib # # Where to place ASCII charts and the like. # PUBDIR=$(PREFIX)/pub # # Where to place manual pages. # MANDIR=$(PREFIX)/share/heirloom-doctools/man # # Where to place the troff macro packages. # MACDIR=$(LIBDIR)/doctools/tmac # # Where to place the troff font files. # FNTDIR=$(LIBDIR)/doctools/font # # Where to place PostScript helper files. # PSTDIR=$(FNTDIR)/devpost/postscript # # Where to place the nroff terminal description files. # TABDIR=$(LIBDIR)/doctools/nterm # # Where to place troff hyphenation files. # HYPDIR=$(LIBDIR)/doctools/hyphen # # Where to place files belonging to the "refer" utility. # REFDIR=$(LIBDIR)/reftools # # Define this if you want troff and nroff to be able to process # locale-specific (8-bit) characters. It requires appropriate support # from the C library, so it does not work e.g. with diet libc. # EUC=-DEUC # # Binaries are stripped with this command after installation. # STRIP=strip # # The C compiler. # #CC= # # The C++ compiler. # #CXX= # # Compiler flags. # -#CFLAGS= +_CFLAGS=$(CFLAGS) $(_CPPFLAGS) $(__CDBG) $(__CLDBG) # # C preprocessor flags. # # Use -D_GNU_SOURCE for Linux with GNU libc. # Use -D_INCLUDE__STDC_A1_SOURCE for HP-UX. # -CPPFLAGS=-D_GNU_SOURCE +_CPPFLAGS=$(CPPFLAGS) -D_GNU_SOURCE # -# Warning flags for the compiler. -# -#WARN= - -# # Linker flags. # -#LDFLAGS= +_LDFLAGS=$(LDFLAGS) $(__CLDBG) # # Additional libraries to link with. # #LIBS= # # A Bourne-compatible shell. # SHELL=/bin/sh Index: projects/doctools/contrib/heirloom-doctools/mpm/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/mpm/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/mpm/Makefile.mk (revision 307924) @@ -1,30 +1,30 @@ OBJ = misc.o page.o queue.o range.o slug.o version.o FLAGS = $(EUC) $(DEFINES) -I../include .c.o: - $(CC) $(CFLAGS) $(WARN) $(FLAGS) $(CPPFLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< .cc.o: - $(CXX) $(CFLAGS) $(WARN) $(FLAGS) $(CPPFLAGS) -c $< + $(CXX) $(_CFLAGS) $(FLAGS) -c $< all: pm pm: $(OBJ) - $(CXX) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -lm -o pm + $(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/pic/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/pic/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/pic/Makefile.mk (revision 307924) @@ -1,44 +1,44 @@ OBJ = arcgen.o blockgen.o boxgen.o circgen.o for.o input.o linegen.o \ main.o misc.o movegen.o picl.o picy.o pltroff.o print.o symtab.o \ textgen.o version.o FLAGS = $(DEFINES) -I../include YFLAGS = -d .c.o: - $(CC) $(CFLAGS) $(WARN) $(FLAGS) $(CPPFLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: picy.c picl.c pic pic: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -lm -o pic + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJ) $(LIBS) -lm -o pic y.tab.h: picy.c install: $(INSTALL) -c pic $(ROOT)$(BINDIR)/pic $(STRIP) $(ROOT)$(BINDIR)/pic test -d $(ROOT)$(MANDIR)/man1 || mkdir -p $(ROOT)$(MANDIR)/man1 $(INSTALL) -c -m 644 pic.1 $(ROOT)$(MANDIR)/man1/pic.1 clean: rm -f $(OBJ) picl.c picy.c y.tab.h pic core log *~ mrproper: clean arcgen.o: arcgen.c pic.h y.tab.h blockgen.o: blockgen.c pic.h y.tab.h boxgen.o: boxgen.c pic.h y.tab.h circgen.o: circgen.c pic.h y.tab.h for.o: for.c pic.h y.tab.h input.o: input.c pic.h y.tab.h linegen.o: linegen.c pic.h y.tab.h main.o: main.c pic.h y.tab.h misc.o: misc.c pic.h y.tab.h movegen.o: movegen.c pic.h y.tab.h picy.o: picy.c pic.h pltroff.o: pltroff.c pic.h print.o: print.c pic.h y.tab.h symtab.o: symtab.c pic.h y.tab.h textgen.o: textgen.c pic.h y.tab.h Index: projects/doctools/contrib/heirloom-doctools/picpack/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/picpack/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/picpack/Makefile.mk (revision 307924) @@ -1,21 +1,21 @@ OBJ = picpack.o FLAGS = -I../troff/troff.d/dpost.d .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: picpack picpack: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o picpack + $(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 307923) +++ projects/doctools/contrib/heirloom-doctools/picpack/picpack.c (revision 307924) @@ -1,608 +1,609 @@ /* * 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 *); /*****************************************************************************/ 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 ( 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 */ + /* 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 307923) +++ projects/doctools/contrib/heirloom-doctools/ptx/Makefile.mk (revision 307924) @@ -1,23 +1,23 @@ OBJ = ptx.o FLAGS = -DLIBDIR='"$(LIBDIR)"' $(EUC) -I../include .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: ptx ptx: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o ptx + $(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/refer/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/refer/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/refer/Makefile.mk (revision 307924) @@ -1,132 +1,132 @@ ROBJ = glue1.o refer1.o refer2.o refer4.o refer5.o refer6.o mkey3.o \ refer7.o refer8.o hunt2.o hunt3.o deliv2.o hunt5.o hunt6.o \ hunt8.o glue3.o hunt7.o hunt9.o glue2.o glue4.o glue5.o refer0.o \ shell.o version.o AOBJ = addbib.o version.o LOBJ = lookbib.o version.o SOBJ = sortbib.o version.o MOBJ = mkey1.o mkey2.o mkey3.o deliv2.o version.o IOBJ = inv1.o inv2.o inv3.o inv5.o inv6.o deliv2.o version.o HOBJ = hunt1.o hunt2.o hunt3.o hunt5.o hunt6.o hunt7.o glue5.o refer3.o \ hunt9.o shell.o deliv2.o hunt8.o glue4.o tick.o version.o FLAGS = -DMACDIR='"$(MACDIR)"' -DREFDIR='"$(REFDIR)"' $(EUC) $(DEFINES) \ -I../include .c.o: - $(CC) $(CFLAGS) $(WARN) $(FLAGS) $(CPPFLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: refer addbib lookbib sortbib roffbib indxbib mkey inv hunt papers/runinv cd papers && PATH=..:$$PATH sh runinv refer: $(ROBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(ROBJ) $(LIBS) -o $@ + $(CC) $(_CFLAGS) $(_LDFLAGS) $(ROBJ) $(LIBS) -o $@ addbib: $(AOBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(AOBJ) $(LIBS) -o $@ + $(CC) $(_CFLAGS) $(_LDFLAGS) $(AOBJ) $(LIBS) -o $@ lookbib: $(LOBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(LOBJ) $(LIBS) -o $@ + $(CC) $(_CFLAGS) $(_LDFLAGS) $(LOBJ) $(LIBS) -o $@ sortbib: $(SOBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(SOBJ) $(LIBS) -o $@ + $(CC) $(_CFLAGS) $(_LDFLAGS) $(SOBJ) $(LIBS) -o $@ mkey: $(MOBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(MOBJ) $(LIBS) -o $@ + $(CC) $(_CFLAGS) $(_LDFLAGS) $(MOBJ) $(LIBS) -o $@ inv: $(IOBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(IOBJ) $(LIBS) -o $@ + $(CC) $(_CFLAGS) $(_LDFLAGS) $(IOBJ) $(LIBS) -o $@ hunt: $(HOBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(HOBJ) $(LIBS) -o $@ + $(CC) $(_CFLAGS) $(_LDFLAGS) $(HOBJ) $(LIBS) -o $@ indxbib: indxbib.sh rm -f $@ echo '#!$(SHELL)' >$@ 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 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 *~ \ 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/soelim/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/soelim/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/soelim/Makefile.mk (revision 307924) @@ -1,21 +1,21 @@ OBJ = soelim.o FLAGS = .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: soelim soelim: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o soelim + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJ) $(LIBS) -o soelim install: $(INSTALL) -c soelim $(ROOT)$(BINDIR)/soelim $(STRIP) $(ROOT)$(BINDIR)/soelim $(INSTALL) -c -m 644 soelim.1 $(ROOT)$(MANDIR)/man1/soelim.1 clean: rm -f $(OBJ) soelim core log *~ mrproper: clean Index: projects/doctools/contrib/heirloom-doctools/tbl/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/tbl/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/tbl/Makefile.mk (revision 307924) @@ -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)"' -I../include .c.o: - $(CC) $(CFLAGS) $(WARN) $(FLAGS) $(CPPFLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: tbl tbl: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o tbl + $(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/troff/ext.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/ext.h (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/ext.h (revision 307924) @@ -1,596 +1,602 @@ /* * 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 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); +#undef min +#undef max +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/libhnj/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/libhnj/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/libhnj/Makefile.mk (revision 307924) @@ -1,22 +1,22 @@ -FLAGS = -Wall -Wunused-parameter -Wmissing-prototypes +FLAGS = .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< OBJ = hnjalloc.o hyphen.o all: libhnj.a test libhnj.a: $(OBJ) $(AR) crs $@ $(OBJ) test: test.o libhnj.a - $(CC) $(CFLAGS) $(LDFLAGS) test.o -L. -lhnj -o test + $(CC) $(_CFLAGS) $(_LDFLAGS) test.o -L. -lhnj -o test install: clean: rm -f $(OBJ) test test.o core log *~ mrproper: clean rm -f libhnj.a Index: projects/doctools/contrib/heirloom-doctools/troff/n1.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/n1.c (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/n1.c (revision 307924) @@ -1,2307 +1,2491 @@ /* * 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; 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)]); } /* returns pointer to \0 that ends the string */ /* VARARGS2 */ char *roff_sprintf(char *str, size_t size, const char *fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vsnprintf(str, size, fmt, ap); va_end(ap); return (str + ret); } 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; 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]); 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]); 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]); 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 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/n2.c (revision 307924) @@ -1,512 +1,511 @@ /* * 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)) - dprintf(ptid, "%lc", j); + fdprintf(ptid, "%lc", j); else #endif /* EUC */ - dprintf(ptid, "%c", j); + fdprintf(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/n5.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/n5.c (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/n5.c (revision 307924) @@ -1,2517 +1,2535 @@ /* * 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/nroff.d/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/nroff.d/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/nroff.d/Makefile.mk (revision 307924) @@ -1,49 +1,49 @@ VPATH=.. LIBHNJ = ../libhnj BST = ../../stuff/bst OBJ = n10.o n6.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 \ version.o draw.o $(BST)/bst.o FLAGS = -DNROFF -DUSG $(EUC) -I. -I.. -I../../include -DMACDIR='"$(MACDIR)"' \ -DFNTDIR='"$(FNTDIR)"' -DTABDIR='"$(TABDIR)"' -DHYPDIR='"$(HYPDIR)"' \ -DSHELL='"$(SHELL)"' -DRELEASE='"$(RELEASE)"' $(DEFINES) \ - -I$(BST) -Wmissing-prototypes + -I$(BST) .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: nroff nroff: $(OBJ) $(LIBHNJ)/libhnj.a - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -L$(LIBHNJ) -lhnj $(LIBS) -o nroff + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJ) -L$(LIBHNJ) -lhnj $(LIBS) -o nroff install: $(INSTALL) -c nroff $(ROOT)$(BINDIR)/nroff $(STRIP) $(ROOT)$(BINDIR)/nroff $(INSTALL) -c -m 644 nroff.1 $(ROOT)$(MANDIR)/man1/nroff.1 clean: rm -f $(OBJ) nroff core log *~ mrproper: clean draw.o: ../tdef.h ../ext.h n10.o: n10.c ../tdef.h ../ext.h tw.h pt.h n6.o: n6.c ../tdef.h tw.h pt.h ../ext.h hytab.o: ../hytab.c malloc.o: ../malloc.c ../mallint.h n1.o: ../n1.c ../tdef.h ../ext.h ./pt.h tw.h n2.o: ../n2.c ../tdef.h ./pt.h ../ext.h tw.h n3.o: ../n3.c ../tdef.h ./pt.h ../ext.h tw.h n4.o: ../n4.c ../tdef.h ./pt.h ../ext.h tw.h n5.o: ../n5.c ../tdef.h ./pt.h ../ext.h tw.h n7.o: ../n7.c ../tdef.h ./pt.h ../ext.h tw.h n8.o: ../n8.c ../tdef.h ../ext.h ./pt.h n9.o: ../n9.c ../tdef.h ./pt.h ../ext.h tw.h ni.o: ../ni.c ../tdef.h ./pt.h ./ext.h nii.o: ../nii.c ../tdef.h ./pt.h ../ext.h tw.h suftab.o: ../suftab.c version.o: ../version.c Index: projects/doctools/contrib/heirloom-doctools/troff/nroff.d/pt.h =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/nroff.d/pt.h (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/nroff.d/pt.h (revision 307924) @@ -1,86 +1,85 @@ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)pt.h 1.43 (gritter) 8/19/08 */ /* n10.c */ extern void ptinit(void); extern char *skipstr(char *); extern char *getstr(char *, char *); extern char *getint(char *, int *); extern void specnames(void); extern int findch(register const char *); extern void twdone(void); -extern void ptout(tchar); extern void ptout1(void); extern char *plot(char *); extern void move(void); extern void ptlead(void); extern void dostop(void); extern void newpage(int); extern void pttrailer(void); /* n6.c */ extern int width(register tchar); extern tchar setch(int); extern tchar setabs(void); extern int tr2un(tchar, int); extern int findft(register int, int); extern void caseps(void); 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(int); extern tchar getlg(tchar); extern void caselg(void); extern void caseflig(void); extern void casefp(void); extern void casefps(void); extern void casecs(void); extern void casebd(void); extern void casevs(void); extern void casess(void); extern tchar xlss(void); extern tchar setuc0(int); extern tchar setanchor(void); extern tchar setlink(void); extern tchar setulink(void); extern void casedummy(void); #define casetrack casedummy #define casefallback casedummy #define casehidechar casedummy #define casefzoom casedummy #define casekern casedummy #define casepapersize casedummy #define casemediasize casedummy #define caselhang casedummy #define caserhang casedummy #define casekernpair casedummy #define casekernbefore casedummy #define casekernafter casedummy #define caseftr casedummy #define casefeature casedummy #define casetrimat casedummy #define casebleedat casedummy #define casecropat casedummy #define casefspacewidth casedummy #define casespacewidth casedummy #define casefdeferlig casedummy #define casefkern casedummy #define caseminss casedummy #define caseletadj casedummy #define kernadjust(a, b) 0 #define u2pts(i) (i) #define getascender() 0 #define getdescender() 0 #define getfzoom() 0 Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/Makefile.mk (revision 307924) @@ -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 $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: troff ta otfdump troff: $(OBJ) $(LIBHNJ)/libhnj.a - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -L$(LIBHNJ) -lhnj $(LIBS) -o troff + $(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 $@ + $(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 $@ + $(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 dev.h fontmap.o: fontmap.h Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/Makefile.mk (revision 307924) @@ -1,48 +1,48 @@ 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 $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: daps makedev fonts HM.out daps: $(OBJ) - $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -lm -o daps + $(CC) $(_LDFLAGS) $(OBJ) $(LIBS) -lm -o daps makedev: makedev.o - $(CC) $(LDFLAGS) makedev.o $(LIBS) -o makedev + $(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/devaps/daps.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/daps.c (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/devaps/daps.c (revision 307924) @@ -1,2999 +1,2995 @@ /* * 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 "daps.c 1.6 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)daps.c 1.8 (gritter) 7/9/06 */ /* * 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. */ -#ifndef __unused -#define __unused __attribute__((unused)) -#endif - char *xxxvers = "troff.d/devaps/daps.c 1.2"; /**************************************************************************** * * * This is the post-processor for the APS-5 phototypesetter. The * * language that is accepted by this program is produced by the new device * * independent troff, and consists of the following statements, * * * * * * sn set the point size to n * * fn set the typesetter font to the one in position n * * cx output the ASCII character x * * Cxyz output the code for the special character xyz. This * * command is 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 from current position * * vn go n units vertically from current position * * nnc move right nn units, then print the character c. This * * command expects exactly two digits followed by the * * character c. * * w paddable word space - no action needed * * nb a end of line ( information only - no action needed ) * * pn begin page n * * Dt ...\n draw operation 't': * * * * Dl x y line from here to x,y * * Dc d circle of diameter d, left side here * * De x y ellipse of axes x,y, left side here * * Da u v x y arc * * D~ x y x y wiggly line by x,y then x,y * * * * x ... \n device control functions: * * * * x i initialize the typesetter * * x T s name of device is s * * x r n h v resolution is n units per inch. h is * * min horizontal motion, v is min vert. * * motion in machine units. * * x p pause - can restart the typesetter * * x s stop - done forever * * x t generate trailer - no-op for the APS * * x f n s load font position n with tables for * * font s. Referring to font n now means * * font s. * * x H n set character height to n * * x S n set character slant to n * * * * Subcommands like i are often spelled out as "init" * * * * To get the post-processor running properly on your system, you may * * have to make one or more of changes: * * * * Choose the appropriate description of your typesetter. These * * values include the type of lens and the maximum master range * * for your fonts. The values that you will need to adjust are * * macros and defined constants located at the start of the * * daps.h file. * * * * Make sure the variable 'typesetter' is properly initialized * * to the APS-5 typesetter file on your system. If you are not * * going to have daps directly drive the typesetter, you may * * want to set it to the null file, and/or initialize 'tf' to * * be stdout. (file daps.g) * * * * Make sure that the accounting file pathname 'tracct' is the * * the accounting file that you want. If no accounting is to be * * done then initialize it to the null string. (file daps.g) * * * * Check to make sure that 'fontdir' is the directory that * * contains the devaps directory where your font tables are * * located. (file daps.g) * * * * If there are no characters on your font disk that need any * * adjustment in their vertical placement, then make sure that * * the conditional compilation flag ADJUST is undefined. I would * * recommend that you start this way to see what your font disk * * really looks like. (file daps.h) * * * * * ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "aps.h" /* APS-5 opcode definitions */ #include "dev.h" /* font and dev structure declarations */ #include "daps.h" /* constant and macro definitions */ #include "daps.g" /* global variable definitions */ /*****************************************************************************/ int main (int argc, char *argv[]) { /******************************************************************** * * * This is the main program for the APS-5 post-processor. It * * is responsible for calling the sequence of routines that are * * needed to translate troff's new typesetter independent output * * language into a form that will be understood by the APS-5 * * phototypesetter. * * * ********************************************************************/ fp_debug = stderr; fp_error = stderr; fp_acct = stderr; tf = stdout; get_options(argc, argv); /* process the option list */ if ( tf != stdout ) /* need to open the file */ out_file(); init_signals(); /* set up signal handling */ acct_file(); /* open the accounting file */ process_input(argc, argv); /* translate the input files */ account(); /* make sure we charge this guy */ done(); /* finish up this job and reset the APS */ /*NOTREACHED*/ return 0; } /* End of main */ /****************************************************************************/ void get_options (int argc, char *argv[]) { int save; /* used to adjust arg_index */ int v_step = 0; /* vertical step in -V option */ int ch; int i, sharpsign = 0; extern char *optarg; extern int optind; /******************************************************************** * * * This is the routine that processes the command line option * * list. The macro SET_ARGS uses the global variable arg_index to * * properly initialize the local argc and argv values, while the * * macro COUNT_ARGS adjusts the value of arg_index to account for * * the number of arguments that were just processed. * * * * The options that are currently available in this driver * * are, * * * * -f dir - use dir as the font directory * * -F dir - same * * * * -t - use standard output * * * * -r - report the number of pages * * * * -A - do accounting even if there is no real * * accounting file. If tracct is NULL then * * the accounting information is written * * to stderr. This is the way things are * * done on our APS. * * * * -b - report whether typesetter is busy or * * not. Nothing is printed. * * * * -w - wait until typesetter is available, * * then procees the job. * * * * -o[str] - process only this list of pages. The * * list may contain single pages or page * * ranges, where the latter consists of * * a pair of pages separated by -. * * * * -s[num] - stop processing every num pages, and * * HALT the typesetter. * * * * -v[num] - use num as the maximum vertical step * * size up or down the page. The argument * * num is interpreted as 10ths of a point. * * * * -h[str] - use str as the string to be printed * * in the header. * * * * -H[str] - use str as the pathname of the file * * whose first line contains the string * * to be printed in the header. * * * * -d[str] - toggle the debug flags for each number * * contained in the string str. If str * * contains the character '*' then all of * * the debug flags will be toggled. * * * * -D[str] - dump all of the debug information into * * file str. If this option is not used * * then the debugging stuff is written to * * stderr. * * * * -L[str] - use the file str as the log file for * * all error messages. If this option is * * not used then all error messages will * * be written to stderr. * * * * -I - ignore all FATAL errors. This option is * * only to be used for debugging - it may * * cause a core file to be written. * * * ********************************************************************/ SET_ARGS(save); /* MACRO - adjust internal argc and argv */ while ((ch = getopt(argc, argv, "f:F:trAbwo:s:h:H:d:D:L:Iv:c:#")) != EOF) { /*read options list*/ switch ( ch ) { /* check option */ case 'f': /* font directory */ case 'F': fontdir = optarg; break; case 't': /* use standard output */ tf = stdout; break; case 'r': /* print page report */ report = YES; break; case 'A': /* do accounting! */ if ( privelege == ON ) x_stat |= DO_ACCT; break; case 'b': /* check if busy or not */ busyflag = ON; break; case 'w': /* wait til APS is free */ waitflag = ON; break; case 'o': /* process page list */ outlist(optarg); break; case 's': /* stop every spage(s) */ spage = atoi(optarg); if ( spage <= 0 ) /* illegal page number */ spage = 9999; break; case 'h': /* banner is in argument */ banner = optarg; print_banner = YES; break; case 'H': /* banner is in file */ ban_file(optarg); print_banner = YES; break; case 'd': /* selective debug */ debug_select(optarg); break; case 'D': /* set up debug file */ debug_file(optarg); break; case 'L': /* set up log file */ log_file(optarg); break; case 'I': /* ignore fatal errors */ if ( privelege == ON ) ignore = YES; break; case 'v': /* set max vertical step */ v_step = atoi(optarg); if ( v_step != 0 ) vert_step = ( v_step > 0 ) ? v_step : -v_step; if ( vert_step > MAX_INT ) /* its too big */ vert_step = MAX_INT; break; case 'c': /* set beam cutoff */ if ( (cutoff = atof(optarg)) <= 0 ) cutoff = CUTOFF; break; case '#': sharpsign = 1; break; default: /* didn't find it */ error(NON_FATAL, "illegal option %c", argv[1][1]); break; } /* End of switch */ } /* End while */ argc -= optind - 1; COUNT_ARGS(save); /* MACRO - adjust arg_index */ if (sharpsign == 1) { fprintf(stderr, "report = %d, x_stat = %o\n", report, x_stat); fprintf(stderr, "busyflag = %d, waitflag = %d, ignore = %d\n", busyflag, waitflag, ignore); fprintf(stderr, "fontdir = %s, spage = %d, banner = %s\n", fontdir, spage, banner); fprintf(stderr, "v_step = %d, cutoff = %g\n", v_step, cutoff); for (i=0; i 0 ) { /* rest of the args are input files */ if ( strcmp(*++argv, "-") == 0 ) /* use standard input */ fp_in = stdin; else if ( (fp_in = fopen(*argv, "r")) == NULL ) { error(FATAL, "can't open input file %s", *argv); continue; /* in case we ignore this error */ } /* End else */ conv(fp_in); /* translate the file */ if ( fp_in != stdin ) /* probably don't need it anymore */ fclose(fp_in); } /* End of while */ } /* End else */ COUNT_ARGS(save); /* MACRO - adjust arg_index */ } /* End of process_input */ /****************************************************************************/ void init_signals (void) { /******************************************************************** * * * This routine is called by main to set up the appropriate * * handling of external signals for the post-processor. As * * currently written interrupts, quits and hangups are all either * * ignored or processed by the routine wrap_up(). * * * ********************************************************************/ signal(SIGFPE, float_err); /* catch floating point errors */ if ( signal(SIGINT, wrap_up) == SIG_IGN ) { /* ignoring interrupts */ signal(SIGINT, SIG_IGN); /* so reset SIGINT */ signal(SIGQUIT, SIG_IGN); /* and ignore the rest */ signal(SIGHUP, SIG_IGN); } else { /* wrap_up() handles them */ signal(SIGQUIT, wrap_up); signal(SIGHUP, wrap_up); } /* End if */ } /* End of init_signals */ /*****************************************************************************/ void debug_select ( char *str /* string of debug flags */ ) { int index; /* single debug flag to toggle */ int i; /* for loop index */ /******************************************************************** * * * This routine is called by main() when it finds the -d * * option. The parameter str is a pointer to a string of comma * * separated tokens from the command line that specify which of * * the debug flags is to be toggled. As currently implemented the * * tokens in str may consist of numbers, which specify the actual * * flag to be toggled, or the character '*', which stands for all * * of the available debug flags. * * * ********************************************************************/ while ( *str ) { if ( isdigit(*str) ) { /* have a single debug flag */ STR_CONVERT(str, index); /* MACRO - get the debug flag */ if ( index >= 0 && index < MAX_DEBUG ) TOGGLE(debug[index]); /* MACRO - toggle it */ } else if ( *str == '*' ) /* toggle all the debug flags */ for ( i = 0; i < MAX_DEBUG; i++ ) TOGGLE(debug[i]); /* MACRO */ if ( *str != '\0' ) str++; /* skip the comma */ } /* End while */ } /* End of debug_select */ /*****************************************************************************/ void debug_file ( char *str /* debug file pathname */ ) { /******************************************************************** * * * This routine is called by get_options() when it finds the * * -D option in the command line. The parameter str is a pointer * * to the pathname of the file to be used for all of the debugging * * output. If the -D option is not specified then by default all * * the debug output is written to stderr. * * * ********************************************************************/ if ( (fp_debug = fopen(str, "w")) == NULL ) { fp_debug = stderr; error(NON_FATAL, "can't open debug file %s", str); } /* End if */ } /* End of debug_file */ /*****************************************************************************/ void log_file ( char *str /* log file pathname */ ) { /******************************************************************** * * * This routine is called to open the log file for the APS-5 * * post-processor. The pathname of the file is passed in the * * parameter str when this routine is called from get_options(). * * If the log file isn't specified then the post-processor will * * write all of it's error messages to stderr. * * * ********************************************************************/ if ( (fp_error = fopen(str, "a")) == NULL ) { fp_error = stderr; error(FATAL, "can't open log file %s", str); } /* End if */ } /* End of log_file */ /*****************************************************************************/ void acct_file (void) { /******************************************************************** * * * This routine is called to open the accounting file whose * * pathname is pointed to by the variable tracct. If there is no * * pathname in tracct then nothing is done in this routine, while * * if we are unable to open the accounting file then an error * * message is printed out and we quit. * * * ********************************************************************/ if ( *tracct ) { /* we have an accnt file pathname */ if ( (fp_acct = fopen(tracct, "a")) == NULL ) { /* so open it */ fp_acct = stderr; /* couldn't open accounting file */ x_stat |= NO_ACCTFILE; /* indicate this in the exit status */ error(FATAL, "unable to open accounting file"); exit(x_stat); /* in case we ignore this error */ } /* End if */ x_stat |= DO_ACCT; /* accounting needs to be done */ } /* End if */ } /* End of acct_file */ /*****************************************************************************/ void ban_file ( char *str /* banner file pathname */ ) { FILE *fp_ban; /* banner file descriptor */ /******************************************************************** * * * This routine is called from get_options() to read the * * banner string from the first line of the file whose pathname is * * contained in the string str. * * * ********************************************************************/ if ( (fp_ban = fopen(str, "r")) == NULL ) { error(NON_FATAL, "can't open the banner file %s", str); return; } /* End if */ GET_LINE(fp_ban, ban_buf); /* MACRO - banner is first line only */ banner = ban_buf; /* t_banner() prints string *banner */ fclose(fp_ban); /* shouldn't need this file again */ } /* End of ban_file */ /*****************************************************************************/ void out_file (void) { /******************************************************************** * * * This routine is called from the main program to open the * * file pointed to by typesetter. * * * ********************************************************************/ do { tf = fopen(typesetter, "w"); /* typesetter output file */ if ( busyflag == ON ) { /* report status and then exit */ printf(tf == NULL ? "Busy.\n" : "Available.\n"); exit(0); } /* End if */ if ( tf == NULL ) { /* didn't open on last try */ if ( waitflag == OFF ) { /* he doesn't want to wait */ error(NON_FATAL, "can't open typesetter"); exit(NO_OUTFILE); } /* End if */ else sleep(60); /* try again later */ } /* End if */ } while ( tf == NULL ); } /* End of out_file */ /*****************************************************************************/ void outlist ( char *str /* string of pages to process */ ) { int start, stop; /* page range end points */ int i; /* loop index - debug only */ /******************************************************************** * * * This routine is called when the -o option is read in * * the command line. The parameter str points to a list of page * * numbers to be processed. This list consists single pages or * * page ranges, separated by commas. A page range is specified by * * separating two page numbers by the character '-'. In this case * * all pages in this closed interval will be processed by daps. * * * ********************************************************************/ while ( *str && nolist < MAX_OUTLIST - 2 ) { start = 0; if ( isdigit(*str) ) /* page number should begin here */ STR_CONVERT(str,start); /* MACRO - get left end point */ else start = -9999; /* use lowest possible page */ stop = start; /* in case it is a single page */ if ( *str == '-' ) { /* have a page range */ str++; /* so skip the minus sign */ if ( isdigit(*str) ) /* page number begins here */ STR_CONVERT(str,stop); /* MACRO - get right end point */ else stop = 9999; /* use largest possible page */ } /* End if */ if ( start > stop ) error(FATAL,"illegal range %d-%d",start,stop); olist[nolist++] = start; /* save the page range */ olist[nolist++] = stop; if ( *str != '\0' ) str++; /* skip the comma */ } /* End while */ olist[nolist] = 0; /* terminate the page list */ if ( *str ) /* too many pages for olist array */ error(NON_FATAL, "skipped pages %s", str); if ( debug[1] ) /* dump the olist[] array */ for ( i = 0; i < nolist; i += 2 ) fprintf(fp_debug,"%3d %3d\n", olist[i], olist[i+1]); } /* End of outlist */ /*****************************************************************************/ void error ( int kind, /* kind of error ie. FATAL or NON_FATAL */ char *str, /* pointer to message to be printed */ ... ) { /******************************************************************** * * * This routine is called when the post-processor has found * * an internal error. The parameter kind has the value FATAL or * * NON_FATAL, and accordingly determines whether processing will * * continue or not. The parameter str is a pointer to the error * * message that is to be printed. All the remaining parameters * * are the arguments that may be referenced in the control string * * str. * * * * The global variable ignore is initialized to NO in the * * file daps.globals, and can be set to YES by using the -I option * * in the command line. This will allow the post-processor to * * continue after a normally FATAL error has been encountered. * * This is only a debugging feature and should not generally be * * used. * * * ********************************************************************/ va_list ap; fprintf(fp_error, "daps: "); if ( (kind == NON_FATAL) && (line_number > 0) ) fprintf(fp_error, "warning - "); va_start(ap, str); vfprintf(fp_error, str, ap); va_end(ap); if ( line_number > 0 ) fprintf(fp_error, " ( line = %ld )", line_number); fprintf(fp_error, "\n"); if ( ignore == YES && privelege == ON ) return; if ( kind == FATAL ) /* can't ignore this error */ wrap_up(0); /* so quit */ } /* End of error */ /*****************************************************************************/ int done (void) { /******************************************************************** * * * This routine is called to do the final processing for the * * current job. If there is to be any accounting for this job we * * need to be sure that the account function is called first * * because there is nothing more we can do when we get here. * * * ********************************************************************/ if ( tf == NULL ) /* Nowhere to write */ exit(x_stat | NO_OUTFILE); /* so set the bit in x_stat and quit */ t_reset('s'); /* get APS ready for the next job */ exit(x_stat); /* quit with status x_stat */ } /* End of done */ /*****************************************************************************/ void float_err ( - int sig __unused /* signal number - not used */ + int sig /* signal number - not used */ ) { /******************************************************************** * * * Called when a floating point error has been detected. * * Needed because we want to make sure we exit gracefully if a * * users job would normally dump a core file. * * * ********************************************************************/ error(FATAL, "floating point exception"); } /* End of float_err */ /*****************************************************************************/ void wrap_up ( - int sig __unused /* signal number - not used */ + int sig /* signal number - not used */ ) { /******************************************************************** * * * This routine is called to make sure that all the necessary * * stuff is done when the driver finishes its job because of some * * external signal or because it encountered a FATAL syntax error. * * * ********************************************************************/ account(); /* keep some kind of record for this job */ done(); /* get the APS ready for next job */ } /* End of wrap_up */ /*****************************************************************************/ void conv( register FILE *fp /* input file descriptor */ ) { register int ch; /* first character of the command */ int c; /* used only as a character */ int n; /* general purpose integer variable */ char str[100], buf[300]; /* buffers for fscanf and fgets */ /******************************************************************** * * * This is the main interpreter for the post-processor. It is * * called from routine process_input with the single parameter * * fp, which is the file descriptor for the current input file. * * * * The global variable line_number is used to keep track of * * the current line in the input file fp. Its value is adjusted * * in both conv() and devcntrl() and it is used in the routine * * error() when error messages are written to the file fp_error. * * * * The bits in the global variable x_stat are used to keep * * track of the progress of the post-processor, and when the * * program exits it will return x_stat as its termination status. * * * * * * NOTE - In order to improve the speed of this routine we may * * want to declare more register variables. When we do this we * * need to be sure that the macros that are being used will accept * * register variables as arguments. For example if a macro takes * * the address of one of its arguments, then we can't assign this * * variable to a register. * * * ********************************************************************/ x_stat |= FILE_STARTED; /* indicate this in x_stat */ line_number = 1; /* line in current input file */ while ( (ch = getc(fp) ) != EOF ) { switch ( ch ) { /* ch determines the command */ case 'w': /* don't do anything for these */ case ' ': case 0: break; case '\n': /* just increment line_number */ line_number++; break; case '0': /* two motion digits and a char */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': GET_DIG(fp, c); /* MACRO - get the second digit */ hmot((ch - '0') * 10 + c - '0'); /* Be careful - we need to fall through here */ case 'c': /* single ASCII character */ GET_CHAR(fp, c); /* MACRO - read the character */ put1(c); /* output c's APS-5 code */ break; case 'h': /* relative horizontal motion */ case 'H': /* absolute horizontal motion */ case 'v': /* relative vertical motion */ case 'V': /* absolute vertical motion */ case 's': /* set point size */ case 'p': /* start a new page */ GET_INT(fp, n); /* MACRO - first get an integer */ switch( ch ) { /* and then process the command */ case 'h': hmot(n); break; case 'H': hgoto(n); break; case 'v': vmot(n); break; case 'V': vgoto(n); break; case 's': setsize(t_size(n)); break; case 'p': t_page(n); break; } /* End switch */ break; case 'C': /* process special char string */ case 'f': /* set font */ GET_STR(fp, str); /* MACRO - first get a string */ if ( ch == 'C' ) put1s(str); else setfont(t_font(str)); break; case 'x': /* device control function */ devcntrl(fp); break; case 'D': /* drawing operation */ case 't': /* text string upto newline */ GET_LINE(fp, buf); /* MACRO - get rest of the line */ if ( ch == 'D' ) drawfunct(buf, fp); else t_text(buf); line_number++; /* finished with this line */ break; case 'n': /* end of line */ case '#': /* comment */ SKIP_LINE(fp,c); /* MACRO - skip rest of this line */ if ( ch == 'n' ) t_newline(); line_number++; break; default: /* illegal command - quit */ error(FATAL,"unknown input character 0%o %c", ch, ch); break; /* in case we ignore this error */ } /* End switch */ } /* End while */ x_stat &= ~FILE_STARTED; /* turn off FILE_STARTED bit in x_stat */ } /* End of conv */ /*****************************************************************************/ void drawfunct( char buf[], /* drawing command */ - FILE *fp __unused + FILE *fp ) { int n1, n2, n3, n4; /* values are set in the MACROS */ /******************************************************************** * * * This routine interprets the drawing functions that are * * provided by troff. The array buf[] has been filled in by the * * function conv(), and it contains the drawing command line from * * the input file. * * * ********************************************************************/ switch ( buf[0] ) { /* process the command */ case 'l': /* draw a line */ SCAN2(buf+1, n1, n2); /* MACRO - get two integers */ drawline(n1, n2, "."); break; case 'c': /* draw a circle */ SCAN1(buf+1, n1); /* MACRO - get one integer */ drawcirc(n1); break; case 'e': /* draw an ellipse */ SCAN2(buf+1, n1, n2); /* MACRO - get two integers */ drawellip(n1, n2); break; case 'a': /* draw an arc */ SCAN4(buf+1,n1,n2,n3,n4); /* MACRO - get four integers */ drawarc(n1, n2, n3, n4); break; case '~': /* draw spline curve */ drawwig(buf+1); break; #ifdef PLOT case 'p': /* plot these points */ plot_points(buf+1, fp); break; #endif default: /* don't understand the command */ error(FATAL, "unknown drawing function %s", buf); break; /* in case we ignore this error */ } /* End switch */ } /* End of drawfunct */ /*****************************************************************************/ void devcntrl( FILE *fp /* input file descriptor */ ) { int c; /* character used in SKIP_LINE */ int n; /* integer used in GET_INT */ char str[20]; /* used to hold different strings */ char file[50]; /* load from this font file - maybe */ char buf[4096]; /* buffer used in GET_LINE etc. */ /******************************************************************** * * * This is the interpreter for the device control language * * that is produced by the new troff. The parameter fp is the file * * descriptor for the current input file. * * * ********************************************************************/ GET_STR(fp, str); /* read command from input file */ switch ( str[0] ) { /* str[0] determines the command */ case 'i': /* initialize the device */ fileinit(); /* read data from DESC.out */ t_init(); /* initialize the typesetter */ if ( print_banner == YES ) /* print the job's banner */ t_banner(); break; case 'T': /* set device name */ GET_STR(fp, devname); /* MACRO - get device string */ if ( strcmp(devname, "aps") != SAME_STR ) error(FATAL, "illegal typesetter %s", devname); break; case 't': /* trailer - do nothing on APS-5 */ break; case 'p': /* pause - we can restart */ case 's': /* stop - done with this job */ t_reset(str[0]); /* reset the typesetter */ break; case 'r': /* set resolution */ GET_INT(fp, res); /* MACRO - get one integer */ hcutoff = cutoff * res; /* beam cutoff in device units */ break; case 'f': /* load a font */ GET_INT(fp, n); /* MACRO - put font number in n */ GET_STR(fp, str); /* MACRO - put font name in str */ GET_LINE(fp, buf); /* MACRO - use this filename */ ungetc('\n', fp); /* put '\n' back for SKIP_LINE */ file[0] = 0; /* in case there is no file name */ SCAN_STR(buf, file); /* MACRO - may have a file name */ loadfont(n, str, file); break; case 'H': /* set character height */ GET_INT(fp, n); /* MACRO - read vertical point size */ t_charht(t_size(n)); break; case 'S': /* set character slant */ GET_INT(fp, n); /* MACRO - read APS slant angle */ t_slant(n); /* set the APS slant to n */ last_req_slant = n; /* and remember this angle */ break; case 'X': GET_STR(fp, buf); if (strcmp(buf, "LC_CTYPE") == 0) break; /*FALLTHRU*/ default: /* don't understand the command */ error(FATAL, "unknown device command %c", str[0]); break; /* in case we ignore this error */ } /* End switch */ SKIP_LINE(fp, c); /* finished with this line */ line_number++; } /* End of devcntrl */ /*****************************************************************************/ void t_init (void) { int i; /* for loop variable */ /******************************************************************** * * * This routine is called from devcntrl() when the command * * x init is read. It produces the instructions that initialize * * the APS, and then it sets up the picture drawing variables * * drawdot and drawsize. * * * * * * NOTE - the opcode STRTJOB is defined to be octal 272 in the * * file aps.h, although on our APS-5 typesetter it is one of the * * reserved but not implemented opcodes. * * * ********************************************************************/ PUTC(STRTJOB, tf); /* MACRO - output STRTJOB opcode */ putint(1); /* dummy argument for STRTJOB? */ PUTC(STRTPG, tf); /* MACRO - start page 0 */ putint(0); hpos = vpos = 0; /* initialize page coordinates */ for ( i = 0; i < nchtab; i++ ) /* find drawing character index */ if ( strcmp(&chname[chtab[i]], "l.") == SAME_STR ) break; if ( i < nchtab ) { /* found it in the table */ drawdot = i + 128; /* so use these values for drawing */ drawsize = 1; } else { /* didn't find it - use default */ drawdot = '.'; drawsize = 3; } /* End if */ } /* End of t_init */ /*****************************************************************************/ void t_banner (void) { int i; /* while loop counter */ char *bp; /* temp pointer to banner string */ /******************************************************************** * * * This routine is called from devcntrl() when the device * * initialization command is read. It is responsible for printing * * the job's header. This includes checking and then writing out * * the string pointed to by banner. The user may set this string * * by using either the -h or the -H options on the command line. * * * ********************************************************************/ output = ON; /* ON for routine put1() etc. */ bp = banner; /* point to start of banner string */ i = 0; /* characters looked at so far */ while ( *bp ) /* check at most BAN_LENGTH chars */ if ( *bp++ < ' ' || ++i > BAN_LENGTH ) /* unprintable or too long */ *(--bp) = '\0'; /* so last char is as far as we go */ setsize(t_size(BAN_SIZE)); /* use font 1 and point size BAN_SIZE */ vmot(VSPACE0); /* space down for banner cut marks */ t_text(cut_marks); /* print first set of cut marks */ hmot(HSPACE0); /* space right for more cut marks */ t_text(cut_marks); /* print second set of cut marks */ vmot(VSPACE1); /* skip this far before banner */ hgoto(HSPACE1); /* indent */ t_text(ban_sep); /* start of banner */ vmot(VSPACE2); /* space down for banner string */ hgoto(HSPACE2); /* indent */ t_text(banner); /* print the user's banner */ vmot(VSPACE3); /* skip down for next separator */ hgoto(HSPACE3); /* indent */ t_text(ban_sep); /* print the second separator */ vmot(VSPACE4); /* skip down for banner cut marks */ hgoto(HSPACE4); /* position for first cut marks */ t_text(cut_marks); /* print first set of cut marks */ hmot(HSPACE0); /* skip right for second cut marks */ t_text(cut_marks); /* print second set */ hpos = vpos = 0; /* reset these guys again */ cur_vpos = max_vpos = 0; /* user doesn't own the banner */ print_banner = NO; /* don't print it again */ output = OFF; /* output is controlled in t_page() */ } /* End of t_banner */ /*****************************************************************************/ void t_page (int n) { int i; /* for loop index */ /******************************************************************** * * * This routine is called from conv() to do the work that is * * necessary when we begin a new page. The STRTPG command to the * * APS-5 invokes the RESET command which sets the font to 0000, * * the master range to 1, and sets the oblique mode to normal and * * the oblique angle to 14 degrees. To reset the font and range * * properly we call setsize(), while if we were in oblique mode * * the variable aps_slant will be non-zero and so in this case * * we call routine t_slant() with aps_slant as the parameter. * * * ********************************************************************/ if ( output == ON && ++scount >= spage ) { /* reached stop page */ t_reset('p'); /* so reset the APS and then HALT */ scount = 0; /* and start counting over again */ } /* End if */ vpos = 0; /* we are at the top of new page */ output = ON; /* enable output in put1() etc. */ last_slant = POS_SLANT; /* this will be the stored angle */ PUTC(STRTPG, tf); /* MACRO - start page n */ putint(n); ++pageno; /* update user's page number */ setsize(size); /* reset both the font and size */ if ( aps_slant ) /* then the APS was in oblique mode */ t_slant(aps_slant); /* so go back to previous slant */ if ( nolist == 0 ) return; /* no -o option, so print every page */ output = OFF; /* otherwise -o option was specified */ for ( i = 0; i < nolist; i += 2 ) /* so check page pairs in olist[] */ if ( n >= olist[i] && n <= olist[i+1] ) { output = ON; /* enable output for this page */ break; } /* End if */ } /* End of t_page */ /*****************************************************************************/ void t_newline (void) { /******************************************************************** * * * This routine is called from conv() when it has read the * * start new line command. This command has the form "n a b" where * * a and b are integers that we can safely ignore for the APS-5. * * * ********************************************************************/ hpos = 0; /* return to left margin */ } /* End of t_newline */ /*****************************************************************************/ int t_size ( int n /* convert this point size */ ) { int i; /* for loop index */ /******************************************************************** * * * This routine is called to convert the point size n to an * * internal size, which is defined as one plus the index of the * * least upper bound for n in the array pstab[]. If n is larger * * than all the entries in pstab[] then nsizes is returned. * * * * * * NOTE - this routine expects the entries in pstab[] to be in * * increasing numerical order, but it doesn't require this list to * * be terminated by a 0 point size entry. * * * ********************************************************************/ if ( n >= pstab[nsizes-1] ) /* greater than all entries */ return(nsizes); /* so use largest internal size */ for ( i = 0; n > pstab[i]; i++ ) /* otherwise find the LUB for n */ ; return(i+1); /* internal size is i+1 */ } /* End of t_size */ /*****************************************************************************/ void t_charht ( int n /* set height to this internal size */ ) { int max; /* max internal size for current range */ /******************************************************************** * * * This routine is called by devcntrl() to set the height of * * the characters that are being printed to the internal size * * specified by the parameter n. If the requested size is too * * large for the current range then an error message is written * * and the requested size is set to the maximum allowed in the * * current range. Since the APS-5 apparently allows us to decrease * * the height as far as we want, no lower limit checks are made on * * the requested size. The global variable range is set by the * * routine setfont() to the current master range that is being * * used. * * * ********************************************************************/ if ( range < 1 || range > MAX_RANGE ) { /* something is wrong here */ error(FATAL, "illegal master range %d", range); return; /* in case this error is ignored */ } /* End if */ max = upper_limit(range); /* internal upper limit for range */ if ( n > max ) { /* requested size is too big */ error(NON_FATAL, "size %d too large for range %d", pstab[n-1], range); n = max; /* reset n to largest allowed size */ } /* End if */ PUTC(VSIZE, tf); /* MACRO - set character height */ putint(10 * pstab[n-1]); /* vertical size - in decipoints */ } /* End of t_charht */ /*****************************************************************************/ int upper_limit ( int n /* find upper limit for this range */ ) { int bsize; /* master range base size */ int max; /* maximum point size for range n */ int max_internal; /* maximum internal size for range n */ /******************************************************************** * * * This routine is called by t_charht() and possibly others to * * find the maximum internal size that is allowed for master range * * n. The value returned to the caller is the largest internal * * size that is allowed in this range. * * * ********************************************************************/ bsize = BASE_SIZE(n); /* base size for master range n */ max = bsize; /* max point size if n > 3 */ if ( n <= 3 ) /* can scale these ranges up */ max = SCALE_UP(bsize); /* to this limit on our APS-5 */ max_internal = t_size(max); /* first try at max internal size */ if ( pstab[max_internal -1] > max ) /* take next lower internal size */ max_internal--; return(max_internal); } /* End of upper_limit */ /*****************************************************************************/ void t_slant ( int n /* set the APS slant to this value */ ) { /******************************************************************** * * * Called to set the slant angle to the value of the parameter * * n. On the APS-5 we can only set positive or negative 14 degree * * slants, even though in TROFF any slant angle can be requested. * * The global variable last_slant is the value of the last angle * * that was stored in the APS-5 using either the SETOBLIQUE or * * STRTPG commands, while aps_slant is the last angle we set in * * this routine. * * * * Originally we only set the oblique angle if last_slant * * was not equal to n. This really didn't work too well, because * * appaerntly the APS-5 resets the oblique angle to +14 degrees * * when it returns to normal mode. * * * ********************************************************************/ if ( n != 0 ) { /* need to slant type being set */ n = ( n > 0 ) ? POS_SLANT /* use +14 degree slant */ : NEG_SLANT; /* otherwise slant at -14 degrees */ PUTC(SETOBLIQUE, tf); /* MACRO - store new angle n */ putint(10 * n); /* APS expects 10 times the angle */ last_slant = n; /* remember this stored angle */ PUTC(XOBLIQUE, tf); /* MACRO - execute oblique mode */ } /* End if */ else PUTC(XNORMAL, tf); /* MACRO - otherwise use normal mode */ aps_slant = n; /* angle that type is being set at */ } /* End of t_slant */ /*****************************************************************************/ int t_font ( char *str /* convert this string to font number */ ) { int n; /* integer value for number in str */ /******************************************************************** * * * This routine is called from conv() to convert the ASCII * * string *str to an integer that represents a legal font number. * * If the resulting number is outside the allowed range for fonts * * on this typesetter then an error message is printed out and * * the program is aborted. * * * ********************************************************************/ n = atoi(str); /* font number */ if ( n < 0 || n > nfonts ) { /* illegal font - abort */ error(FATAL, "illegal font number %d", n); n = font; /* in case we don't quit on an error */ } /* End if */ return(n); /* legal value so return it */ } /* End of t_font */ /*****************************************************************************/ void t_text ( char *str /* typeset this string of characters */ ) { int ch; /* internal character variable */ char buf[4]; /* buffer used for special chars */ /******************************************************************** * * * This routine is called by conv() to process the text string * * that is in the array str. Characters are read from str and * * written to the output file until the end of the string is * * reached. * * * * After the character has been put in the output file the * * current horizontal position is adjusted by a call to hmot() * * using the global variable lastw as the parameter. lastw is set * * in put1() and represents the width of the last character that * * was printed. * * * ********************************************************************/ if ( debug[2] ) fprintf(fp_debug,"input string = %s\n", str); if ( output == OFF ) return; /* not doing output on this page */ while ( (ch = *str++) != '\n' && ch != '\0' ) { if ( ch == '\\' ) { /* this is a special char sequence */ switch ( ch = *str++ ) { /* so check the next character */ case '(': /* special troff character sequence */ buf[0] = *str++; buf[1] = *str++; buf[2] = '\0'; put1s(buf); break; case '\\': /* backslash character */ case 'e': put1('\\'); break; default: /* illegal character sequence */ error(FATAL,"illegal character sequence \\%c", ch); break; } /* End switch */ } else put1(ch); /* otherwise it is a simple character */ hmot(lastw); /* beam has moved right lastw units */ if ( debug[3] ) fprintf(fp_debug,"char = %c width = %d\n", ch, lastw); } /* End while */ } /* End of t_text */ /*****************************************************************************/ void t_reset ( int ch /* pause or stop */ ) { int n; /* for loop variable */ long dist; /* distance to end of job */ int opcode; /* ENDJOB or HALT */ /******************************************************************** * * * This routine is called to produce the typesetter commands * * that are required at the end of a job. If the parameter ch has * * the value 's' then we have reached the end of the current job * * and so we output the ENDJOB opcode, otherwise ch should be * * equal to 'p', and so we produce the HALT command. This enables * * the operator to restart the current job by pressing the PROCEED * * button on the front panel, while if he hits the INITIAL button * * the current job will be terminated. * * * * If we have finished this job, but we are not currently at * * position max_vpos, we step the job forward to this position so * * that the next job begins on unexposed paper. * * * ********************************************************************/ output = ON; /* probably not needed here? */ if ( ((dist = max_vpos - cur_vpos) > 0) && (ch == 's') ) { dist += (pstab[nsizes-1] / 2) * 10; /* try to get whole last line */ while ( dist > 0 ) { /* go to the end of the job */ vmot(dist > MAX_INT ? MAX_INT : dist); dist -= (dist > MAX_INT) ? MAX_INT : dist; } /* End while */ } /* End if */ PUTC(STRTPG, tf); /* MACRO - output STRTPG opcode */ putint(9000+pageno); /* can't possibly be a page number */ for ( n = 0; n < 10; n++ ) /* flush out APS internal buffer */ PUTC(APSNOOP, tf); /* MACRO - put out a few no-op's */ opcode = ( ch == 'p' ) ? HALT /* may want to restart this job */ : ENDJOB; /* done with this guy */ PUTC(opcode, tf); /* MACRO - stop */ fflush(tf); /* flush any buffered output */ } /* End of t_reset */ /*****************************************************************************/ void hflush (void) { /******************************************************************** * * * This routine is called in put1() and t_push() to make sure * * that the two variables hpos and htrue aren't too different. If * * they differ by more than the constant SLOP then a tab is set * * and then executed to position the beam properly. * * * * The variable hpos is the current horizontal position as * * determined by troff, while htrue is the horizontal position as * * calculated by the post-processor. * * * ********************************************************************/ if ( output == OFF ) return; /* not doing output for this page */ if ( abs(hpos - htrue) > SLOP ) { /* positions are too different */ PUTC(SETTAB, tf); /* MACRO - so set a tab */ putint(hpos); /* to the current value of hpos */ PUTC(XTAB, tf); /* MACRO - then execute the tab */ htrue = hpos; /* the positions are the same now */ } /* End if */ } /* End of hflush */ /*****************************************************************************/ void hmot ( int n /* move this far from here */ ) { /******************************************************************** * * * This routine is called from conv() to handle a relative * * horizontal motion of n units. If n is positive then we move to * * the right on the current line. If the final horizontal position * * hpos is negative then something has gone wrong and so we print * * out an error message and if we return from error() we set hpos * * to 0. * * * ********************************************************************/ if ( (hpos += n ) < 0 || hpos > hcutoff ) { /* bad beam position */ error(FATAL, "illegal horizontal position %d", hpos); hpos = 0; /* in case we ignore this error */ } /* End if */ } /* End of hmot */ /*****************************************************************************/ void hgoto ( int n /* move to this horizontal position */ ) { /******************************************************************** * * * This routine is called by conv() to set the absolute * * horizontal position of the beam to the position n, where n * * must be a positive integer. * * * ********************************************************************/ if ( (hpos = n) < 0 || hpos > hcutoff ) { /* bad beam position */ error(FATAL, "illegal horizontal position %d", hpos); hpos = 0; /* in case we ignore this error */ } /* End if */ } /* End of hgoto */ /*****************************************************************************/ void vgoto ( int n /* final absolute vert position */ ) { /******************************************************************** * * * This routine is called from conv() to position the beam at * * the absolute vertical position n. The unit used in all of the * * APS absolute spacing commands is 1/10 of a point. * * * * * * NOTE - it is important to check that a job doesn't try to * * write on a previous job by using the vertical spacing commands. * * Currently this check is made in the routine vmot(). * * * ********************************************************************/ vmot(n - vpos); /* move n-vpos units from here */ } /* End of vgoto */ /*****************************************************************************/ void vmot ( int n /* move n units vertically from here */ ) { int sign; /* sign of the requested motion */ int dist; /* distance left to move */ /******************************************************************** * * * This routine is called to move the vertical position of the * * beam n units from the current position. The global variable * * cur_vpos is the typesetter's current vertical position as * * measured from the start of the job. If the user has requested * * a relative vertical motion that would make cur_vpos negative * * we print an error message and then abort. The variable max_vpos * * is the maximum vertical position that this job has reached. It * * is used to calculate the amount of paper that has been used. * * * ********************************************************************/ if ( output == OFF ) return; /* not doing output on this page */ if ( cur_vpos + n < 0 ) { /* trying to write on last job! */ error(FATAL, "can't backup past start of job"); return; /* in case we ignore this error */ } /* End if */ sign = ( n > 0 ) ? 1 : -1; /* up or down the page */ dist = sign * n; /* total distance to move */ while ( dist > 0 ) { /* not done yet */ PUTC(VSPABS, tf); /* MACRO - absolute vert motion */ putint(sign * ((dist > vert_step) ? vert_step : dist)); dist -= ( dist > vert_step ) ? vert_step : dist ; } /* End while */ vpos += n; /* record our new vertical position */ cur_vpos += n; if ( cur_vpos > max_vpos ) /* this is the farthest we have gone */ max_vpos = cur_vpos; } /* End of vmot */ /*****************************************************************************/ void put1s ( char *s /* print this special character */ ) { int i; /* for loop index */ /******************************************************************** * * * This routine is called to produce the typesetter output * * for the special character string pointed to by s. All of the * * special characters are listed in the charset portion of the * * typsetter's DESC file, and the program makedev reads this part * * of the DESC file and produces two tables called chtab[] and * * chname[]. The character array chname[] contains the special * * character strings separated by '\0', while chtab[i] gives us * * the starting position in chname[] for the special character i. * * * * * * NOTE - Since we just do a sequential search of the strings * * in chname[] when looking for a special character, the speed of * * the post-processor could be improved if we had the most common * * special characters at the start of the list in the DESC file. * * However before doing this we should find out how troff does * * the lookup. * * * ********************************************************************/ if ( output == OFF ) return; /* not doing output for this page */ for ( i = 0; i < nchtab; i++ ) /* lookup the special character */ if ( strcmp(&chname[chtab[i]], s) == SAME_STR ) break; if ( i < nchtab ) { /* found it */ #ifdef ADJUST t_adjust(s); /* adjust vertical positions */ #endif put1(i + 128); /* special characters start at 128 */ } /* End if */ else /* didn't find it - abort */ if ( newfile(s, pstab[size-1]) ) error(FATAL, "special character %s not found", s); if ( debug[4] ) { fprintf(fp_debug,"string = %s ", s); fprintf(fp_debug,"index = %d\n", i); } /* End if */ } /* End of put1s */ /*****************************************************************************/ #ifdef ADJUST void t_adjust ( char *s /* look for this string */ ) { int i; /* for loop index */ int incr; /* incrment v_adjust by this much */ /******************************************************************** * * * Called from put1s() to look for the string *s in adj_tbl[] * * and if found it is used to set the appropriate vertical for the * * character. * * * ********************************************************************/ v_adjust = 0; for ( i = 0; adj_tbl[i] != '\0'; i++ ) if ( strcmp(s, adj_tbl[i]) == 0 ) { incr = (vadjustment[i] < 0) ? -1 : 1; v_adjust = (vadjustment[i] * pstab[size-1]) /dev.unitwidth + incr; break; } /* End if */ } /* End of t_adjust */ #endif /*****************************************************************************/ void put1 ( int c /* print this character */ ) { register int i = 0; /* c's index in font data structures */ register int k; /* look for c on this font */ int j; /* lookup failed on this many fonts */ int k1; /* if not found check this font next */ int code; /* APS-5 code for this character */ int old_font; /* original font number (1..nfonts) */ int old_range; /* original master range setting */ int last_range; /* last master range setting */ int old_slant; /* original device slant angle */ /******************************************************************** * * * This routine is responsible for producing the output codes * * for the characters to be printed by the APS. The integer c * * is the ASCII code for the character if c < 128. Otherwise it * * refers to one of troff's special character sequences. Since we * * are not concerned with unprintable ASCII characters we subtract * * 32 from c to get the right index to use when we do the lookup * * in array fitab[][]. If the character isn't found on the current * * font then we search all the remaining fonts, starting with the * * first special font. If we haven't found the character after we * * search the last font then an error message is written out and * * we quit. Since we can't be guarenteed that font position 0 has * * been loaded with a valid font, we need to make sure that the * * circular search skips this position. * * * * If we find the character c, but it has an APS code that is * * larger than 128, then the makedev program has encoded some * * extra information in this field. Therefore we call the routine * * special_case() to decode this info, and return the correct APS * * code for c. * * * ********************************************************************/ if ( output == OFF ) return; /* not doing output on this page */ old_font = font; /* may find c on a different font */ old_range = last_range = range; /* and in a different master range */ old_slant = aps_slant; /* and may change the slant for c */ k = font; /* while loop looks for c on font k */ k1 = smnt - 1; /* get the next font from this guy */ j = 0; /* c not found on this many fonts */ c -= 32; /* tables don't include unprintable chars */ if ( c <= 0 ) { /* c is a space or unprintable */ if ( c < 0 ) /* can't be in any of our font tables */ error(FATAL, "non-printable character 0%o\n", c+32); lastw = (widthtab[font][0] & BMASK) * pstab[size-1] / dev.unitwidth; return; /* lastw = space width (see t_text()) */ } /* End if */ /* Look for character c in current font and then on the special fonts */ while ( (j < nfonts + 1) && ((i = fitab[k][c] & BMASK) == 0) ) { k = (k1++) % nfonts + 1; /* now check all other fonts */ j++; } /* End while */ /* If j > nfonts or i == 0 then char c not found. no-op if code = 0 */ if ( j > nfonts || i == 0 || (code = codetab[k][i] & BMASK) == 0 ) { if ( i == 0 || j > nfonts ) if ( c+32 < 128 || newfile(&chname[chtab[c+32-128]], pstab[size-1]) ) error(FATAL, "character 0%o not found", c+32); return; } /* End if */ if ( aps_font != fontname[k].number ) /* probably need a new font */ if ( (code < 129) || (fontbase[font]->spare1 != fontbase[k]->spare1) ) CHANGE_FONT(k, last_range); if ( code > 128 && fontbase[k]->spare1 ) { /* got some more stuff to do */ code = special_case(i, k); /* this is the real APS code for c */ last_range = range; /* in case the range was changed */ } /* End if */ #ifdef ADJUST if ( v_adjust != 0 ) vmot(v_adjust); #endif hflush(); /* get to right horizontal position */ PUTC(code, tf); /* MACRO - then print the character */ #ifdef ADJUST if ( v_adjust != 0 ) { vmot(-v_adjust); v_adjust = 0; } /* End if */ #endif if ( (last_range != old_range) || (aps_slant != old_slant) ) CHANGE_FONT(old_font, last_range); /* MACRO - back to the old font */ lastw = ((widthtab[k][i] & BMASK) * pstab[size-1] + dev.unitwidth/2) / dev.unitwidth; htrue += lastw; /* approximate right side of char */ } /* End of put1 */ /*****************************************************************************/ void putint ( int n /* write out this integer */ ) { /******************************************************************** * * * This routine is called to write the integer n out in the * * last two bytes of a type two command on the APS-5 typesetter. * * * ********************************************************************/ PUTC(n >> 8, tf); PUTC(n, tf); } /* End of putint */ /*****************************************************************************/ void setsize ( int n /* new internal size */ ) { /******************************************************************** * * * This routine is called to set the current internal size to * * the value n, and then output the commands needed to change the * * APS-5 point size. The internal size n is an index into the * * array pstab[], which contains the actual point size that is to * * be used. * * * * * * NOTE - This routine always calls setfont in case the range * * has changed, but it may be the case that the range doesn't * * really change even though the point size has changed. Always * * making this call definitely produces some unnecessary APS-5 * * code. Probably fix it in setfont routine. * * * ********************************************************************/ if ( output == OFF ) return; /* not doing output on this page */ if ( n <= 0 || n > nsizes ) { /* internal size out of range */ error(FATAL, "illegal internal size %d", n); n = size; /* in case we return from this error */ } /* End if */ size = n; /* must preceed call to setfont() */ change_font(font); /* in case the range has changed */ PUTC(HVSIZE, tf); /* MACRO - set the new point size */ putint(10 * pstab[n-1]); /* APS expects 10 times the size */ } /* End of setsize */ /*****************************************************************************/ void setfont ( int n /* new font's internal number */ ) { int oldrange; /* current master range */ /******************************************************************** * * * This routine is called to set the current typesetter font * * to the one that corresponds to the parameter n. These internal * * font numbers are determined by the way the font tables are set * * up for the typesetter in the DESC file. * * * * Our APS-5 typesetter typically has only master ranges 1, 2, * * and 3. The actual font that we want to set is determined by the * * current value of the global variable size. Remember that this * * value is an internal size, which is an index into the array * * pstab[]. The following table gives the point sizes that can be * * used in the different master ranges, * * * * * * MASTER RANGE 1: 0 to 12 * * MASTER RANGE 2: 12 to 24 * * MASTER RANGE 3: 24 to 48 * * MASTER RANGE 4: 48 to 96 * * * * * * although any range can actually print characters up to size, * * * * * * 1.5 * limit - 1 * * * * * * where the value of limit is obtained from the above table. * * * ********************************************************************/ if ( output == OFF ) return; /* not doing output for this page */ if ( n < 0 || n > nfonts ) { error(FATAL, "requested font number %d out of range", n); n = font; /* in case we ignore this error */ } /* End if */ oldrange = range; /* new range may be different */ CHANGE_FONT(n, oldrange); /* change the APS font */ font = n; /* current internal font number */ } /* End of setfont */ /*****************************************************************************/ void change_font ( int n /* new font's internal number */ ) { int angle; /* slant angle - used in SETSLANT */ int max_range; /* largest range allowed on font n */ int max_size; /* largest size allowed in max_range */ char f_spare1; /* value of font flags */ /******************************************************************** * * * This routine is called to change the font that the APS is * * currently setting type in. Some extra stuff is done if the font * * has any of its special flags set. * * * ********************************************************************/ range = get_range(pstab[size-1]); /* probably the new range */ f_spare1 = fontbase[n]->spare1; /* get special case font flags */ if ( f_spare1 & RANGE_BIT ) { /* have a maximum range for font n */ max_range = DECODE(f_spare1, RANGE_VAL, TWO_BITS); /* decode this range */ if ( range > max_range ) { /* current range is too big */ max_size = upper_limit(max_range); if ( size > max_size ) /* can't blow max_range up to size */ error(FATAL, "size %d too big for range %d", pstab[size-1], max_range); range = max_range; /* use the biggest possible range */ } /* End if */ } /* End if */ if ( f_spare1 & SLANT_BIT ) /* this font has a default slant */ SETSLANT(f_spare1, angle); /* MACRO - so use it */ else if ( aps_slant != last_req_slant ) /* back to the last requested slant */ t_slant(last_req_slant); PUTC(FONT, tf); /* MACRO - set the new font and range */ if ( range < 3 ) /* APS expects a positive number */ putint(fontname[n].number + range-1); else putint(-(fontname[n].number + range-1)); aps_font = fontname[n].number; /* font that the APS is using */ } /* End of change_font */ /*****************************************************************************/ void t_fp ( int n, /* update this font position */ char *s, /* font's external name (eg. R) */ char *si /* font number used by the APS */ ) { /******************************************************************** * * * This routine is called to update the data structures that * * are maintained by the post-processor to keep track of fonts. * * The parameter n is the font position that we are going to * * update, while s and si are the font's external and internal * * names. * * * ********************************************************************/ fontname[n].name = s; fontname[n].number = atoi(si); fontname[n].nwfont = fontbase[n]->nwfont; } /* End of t_fp */ /*****************************************************************************/ void getuserid(char *buf, size_t size) { struct passwd *pwd; if ((pwd = getpwuid(getuid())) != NULL) strncpy(buf, pwd->pw_name, size)[size-1] = '\0'; } /*****************************************************************************/ void account (void) { char user[100]; /* user's login name */ float pages; /* will charge for this many pages */ /******************************************************************** * * * This is the accounting routine for the post-processor. It * * may have to be changed for your particular system. * * * * NOTE - since the variable res can be changed we better use * * the constant RES to determine how many pages were printed. * * * ********************************************************************/ paper = max_vpos; /* used this much paper */ pages = paper / (RES * PAGE_LENGTH); /* pages that we think were used */ if ( x_stat & DO_ACCT ) { /* got accounting to do */ getuserid(user, sizeof user); fprintf(fp_acct, " user = %-10s", user); fprintf(fp_acct, " paper = %-10.1f", pages); x_stat &= ~DO_ACCT; /* done the important accounting */ fprintf(fp_acct, "exit status = 0%-6o", x_stat); if ( tf == stdout ) fprintf(fp_acct, " ??"); fprintf(fp_acct, "\n"); } /* End if */ if ( report == YES ) fprintf(stderr, " %-3.1f pages\n", pages); } /* End of account */ /*****************************************************************************/ int special_case ( int index, /* char position in tables */ int font /* char info is on this font */ ) { int old_range; /* saved value of current range */ int old_font; /* present APS-5 font number */ int req_font; /* requested APS-5 font number */ int max_range; /* max allowed range for character */ int max_size; /* max size allowed for max_range */ int angle; /* special char angle to set */ int code; /* old code - with bits set */ /******************************************************************** * * * This routine is called by put1() to handle the special any * * special case characters for the APS-5. * * * * Taken on its own, this is a very confusing routine, but one * * which I found from my experience with the APS-5 at Murray Hill * * was definitely needed. I'll try to give a brief, but hopefully * * complete explination here. * * * * The additions that I made here needed to be completely * * transparent to troff, and so the only field in the font tables * * that could be changed was the actual charater code, since troff * * can't possibly need this stuff (it's device independent!). On * * the APS-5, character codes lie between 1 and 128 (inclusive) - * * anything else is an actual function code. Therefore when we are * * ready to print a character in put1(), and we find that its code * * is larger than 128 we know something more has to be done. This * * routine is then called to try to make sense out of the code, * * do any of the special stuff required for this character, and * * finially return its real code. This extra stuff can include * * changing the character's slant, ensuring that the current * * master range is not larger than a given value (max_range), and * * finially getting the actual character from a completely * * different font (alternate_font). What we actually do for each * * special character is determined by its code in the current * * set of font tables. This code is produced by a special version * * of the makedev program, which I changed to interpret some * * extra fields in the ASCII font tables. * * * * * * NOTE - This extra stuff is costly, and should only be used * * when absolutely necessary. The alternate font stuff can * * cause many extra font changes, which in turn will force extra * * disk accesses. We found this to be one of the main reasons for * * slow jobs on our APS, not to mention the extra wear on the disk * * drive. * * * ********************************************************************/ if ( fontname[font].number != alt_tables ) /* don't have font's table */ load_alt(font); /* load font's '.add' tables */ code = codetab[font][index] & BMASK; /* encoded character information */ old_range = range; /* current typesetter range */ old_font = aps_font; /* quick change - fix it later */ req_font = old_font; if ( code & SLANT_BIT ) /* special slant for this character */ SETSLANT(code, angle); /* MACRO - set slant to encoded value */ if ( code & RANGE_BIT ) { /* maximum range specified */ max_range = DECODE(code, RANGE_VAL, TWO_BITS); range = get_range(pstab[size-1]); /* get range for current size */ if ( range > max_range ) { /* check current size first */ max_size = upper_limit(max_range); if ( size > max_size ) /* too big for max_range - abort */ error(FATAL, "size %d too large for range %d", pstab[size-1], max_range); else range = max_range; /* set the range */ } /* End if */ } /* End if */ if ( code & FONT_BIT ) /* alternate font specified */ req_font = alt_font[index]; /* APS-5 alternate font number */ if ( (old_range != range) || (req_font != old_font) ) { aps_font = req_font; PUTC(FONT, tf); /* set new font */ if ( range < 3 ) /* output positive number */ putint(req_font + range - 1); else putint(-(req_font + range - 1)); if ( range != old_range ) { /* Need to set the size */ PUTC(HVSIZE, tf); /* MACRO - set the point size */ putint(10 * pstab[size-1]); } /* End if */ } /* End if */ return(alt_code[index] & BMASK); } /* End of special_case */ /*****************************************************************************/ int get_range ( int n /* find the range for this point size */ ) { int val; /* return this as the range */ int msize; /* size for master range val */ /******************************************************************** * * * This routine is called to return the range corresponding to * * the point size n. Note that n is not an internal size for this * * routine. * * * ********************************************************************/ val = 0; while ( ++val <= MAX_RANGE ) { msize = BASE_SIZE(val); /* base size for master range val */ if ( (val == MAX_RANGE) && (val <= 3) ) /* scale it up */ msize = SCALE_UP(msize); if ( n <= msize ) return(val); /* found the correct master range */ } /* End while */ error(FATAL, "size %d too large", n); return(1); /* in case we ignore this error */ } /* End of get_range */ /*****************************************************************************/ void fileinit (void) { int fin; /* input file descriptor */ int nw; /* number of font table entries */ int i; /* for loop index */ char *filebase; /* pointer to memory block */ char *p; /* pointer used to set up tables */ char temp[60]; /* pathname of the DESC.out file */ /******************************************************************** * * * This routine is responsible for reading the DESC.out file * * for the APS-5 typesetter, and then initializing the appropriate * * data structures for the device and all of the default fonts * * that were mentioned in the typesetter description file DESC. * * * * First the DESC.out file is opened and the structure dev is * * initialized from the first part of the file. This structure * * then contains all the information needed to enable us to finish * * the initialization process. Next the rest of the file is read * * in and the device tables pstab[], chtab[], and chname[] are set * * up. After this has been done we enter a loop which handles the * * initialization for all of the fonts that were mentioned in the * * DESC file. Finially we allocate enough memory so that font * * position 0 can be loaded with the tables from any valid font * * in the library. * * * * * * NOTE - the program 'makedev' creates all of the '.out' * * files in the troff font library. This routine quite obviously * * depends on how 'makedev' has written these files. In addition * * the troff program also reads the '.out' files and it too * * expects the same format as we do here! To really understand * * this routine you need to look at 'makedev.c' and the ASCII * * tables in the troff font library. * * * ********************************************************************/ sprintf(temp, "%s/dev%s/DESC.out", fontdir, devname); if ( (fin = open(temp, O_RDONLY)) < 0 ) /* file didn't open - abort */ error(FATAL, "can't open tables for %s", temp); READ(fin, &dev, sizeof(struct dev)); /* init dev structure */ nsizes = dev.nsizes; /* number of point sizes specified */ nchtab = dev.nchtab; /* number of char table entries */ nfonts = dev.nfonts; /* number of default fonts */ if ( nfonts > NFONT ) /* need to redefine NFONT */ error(FATAL, "internal error - constant NFONT too small"); filebase = malloc(dev.filesize); /* space for rest of the file */ READ(fin, filebase, dev.filesize); /* read in the rest of the file */ pstab = (short *) filebase; /* point size list is first */ chtab = pstab + nsizes + 1; /* next comes chtab list */ chname = (char *) (chtab + dev.nchtab); /* then the char table list */ p = chname + dev.lchname; /* start of font table info */ for (i = 1; i <= nfonts; i++) { /* set up default font tables */ fontbase[i] = (struct Font *) p; nw = *p & BMASK; /* width count comes first */ if (smnt == 0 && fontbase[i]->specfont == 1) smnt = i; /* this is first special font */ p += sizeof(struct Font); /* font structure was written first */ widthtab[i] = p; /* next is this font's width table */ codetab[i] = p + 2 * nw; /* skip kern to get the code table */ fitab[i] = p + 3 * nw; /* last is the font index table */ p += 3 * nw + dev.nchtab + 128 - 32; /* point to next font */ t_fp(i, fontbase[i]->namefont, fontbase[i]->intname); if ( debug[5] ) fontprint(i); /* dump font tables */ } /* End for */ if ( smnt == 0 ) /* no special fonts specified */ smnt = nfonts + 1; /* used in routine put1() */ fontbase[0] = (struct Font *) malloc(3*255 + dev.nchtab + (128-32) + sizeof(struct Font)); widthtab[0] = (char *) fontbase[0] + sizeof(struct Font); fontbase[0]->nwfont = 255; close(fin); } /* End of fileinit */ /*****************************************************************************/ void fontprint ( int i /* index of font to print out */ ) { int j; /* for loop variable */ int n; /* number of width entries */ int pos; /* position of char from fitab array */ int count; /* count of characters in this font */ /******************************************************************** * * * This is a debugging routine that is used to dump all of the * * information about font i that was loaded from the '.out' file. * * It is called from fileinit() when the debug flag 5 is turned * * on, and from loadfont when flag 6 is set. * * * ********************************************************************/ n = fontbase[i]->nwfont & BMASK; /* number of width entries */ fprintf(fp_debug, "\nDUMP FOR FONT %s ", fontbase[i]->namefont); fprintf(fp_debug, " FONT POSITION = %d\n\n", i); fprintf(fp_debug, " font structure data:\n"); fprintf(fp_debug, "\t\tfont.nwfont = %d\n", fontbase[i]->nwfont & BMASK); fprintf(fp_debug, "\t\tfont.specfont = %d\n", fontbase[i]->specfont & BMASK); fprintf(fp_debug, "\t\tfont.ligfont = %d\n", fontbase[i]->ligfont & BMASK); fprintf(fp_debug, "\t\tfont.spare1 = %d\n", fontbase[i]->spare1 & BMASK); fprintf(fp_debug, "\t\tfont.intname = %s\n\n", fontbase[i]->intname); fprintf(fp_debug, " CHAR WIDTH CODE INDEX\n"); count = 0; for (j = 0; j < dev.nchtab + 128 - 32; j++) { if ( (pos = fitab[i][j] & BMASK) != 0 ) { count++; if ( j >= 96 ) /* special chars start at 128-32 */ fprintf(fp_debug, "%5s", &chname[chtab[j-96]]); else fprintf(fp_debug, "%5c", (j + 32) & BMASK); fprintf(fp_debug, "%10d", widthtab[i][pos] & BMASK); fprintf(fp_debug, "%10d", codetab[i][pos] & BMASK); fprintf(fp_debug, "%10d", j); if ( alt_tables == fontname[i].number ) /* print extra info */ fprintf(fp_debug, "%10d%10d", alt_code[pos] & BMASK, alt_font[pos]); fprintf(fp_debug,"\n"); } /* End if */ } /* End for */ fprintf(fp_debug, "\n CHARACTER COUNT FOR THIS FONT = %d\n", count); fprintf(fp_debug, "\n\n"); } /* End of fontprint */ /*****************************************************************************/ void loadfont ( int num, /* font position to load */ char *name, /* name of the font to load */ char *fdir /* name of directory to load from? */ ) { int fin; /* font file descriptor */ int nw; /* width entries in new font file */ int norig; /* width entries in old font file */ char temp[60]; /* path name of font file */ /******************************************************************** * * * This routine is called to load the font position num with * * the data for the font name. If the string fdir is not null then * * it is taken as the pathname of the directory that contains the * * '.out' file for the font that we are to load, otherwise we load * * this data from the standard font library. * * * ********************************************************************/ if ( num < 0 || num > NFONT ) /* illegal font number - abort */ error(FATAL, "illegal fp command %d %s", num, name); if ( strcmp(name, fontbase[num]->namefont) == SAME_STR ) /* in already */ return; if ( fdir == NULL || fdir[0] == '\0' ) /* no alternate directory */ sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, name); else sprintf(temp, "%s/%s.out", fdir, name); if ( (fin = open(temp, O_RDONLY)) < 0 ) /* open the font file */ error(FATAL, "can't open font table %s", temp); norig = fontbase[num]->nwfont & BMASK; /* 'space' available in pos num */ READ(fin, fontbase[num], 3*norig + nchtab+128-32 + sizeof(struct Font)); nw = fontbase[num]->nwfont & BMASK; /* 'space' needed for new font */ if ( nw > norig ) /* new font is too big - abort */ error(FATAL, "font %s too big for position %d", name, num); close(fin); widthtab[num] = (char *) fontbase[num] + sizeof(struct Font); codetab[num] = (char *) widthtab[num] + 2 * nw; fitab[num] = (char *) widthtab[num] + 3 * nw; t_fp(num, fontbase[num]->namefont, fontbase[num]->intname); fontbase[num]->nwfont = norig; /* save size of position num */ if ( debug[6] ) fontprint(num); /* dump font position num */ } /* End of loadfont */ /*****************************************************************************/ void load_alt ( int font /* load '.add' tables for this font */ ) { int nw; /* number of width entries for font */ int fin; /* font file descriptor */ char cmd[60]; /* room for font's .add file */ /******************************************************************** * * * This routine is called to read in the '.add' file for the * * font that is loaded in the position specified by the parameter * * font. These '.add' files are created by the special version of * * the makedev program, which reads and interprets several extra * * fields in the APS font tables. Included in the '.add' files are * * the alternate font table and the APS-5 character code table. * * * ********************************************************************/ sprintf(cmd, "%s/dev%s/%s.add", fontdir, devname, fontname[font].name); if ( (fin = open(cmd, O_RDONLY)) < 0 ) /* couldn't open the file */ error(FATAL, "can't open file %s", cmd); nw = fontname[font].nwfont & BMASK; /* number of width entries */ READ(fin, alt_font, nw * sizeof(alt_font[0])); READ(fin, alt_code, nw); /* read alternate code table */ close(fin); alt_tables = fontname[font].number; /* read in tables for this font */ if ( debug[7] ) /* print all the font information */ fontprint(font); } /* End of load_alt */ /*****************************************************************************/ Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/dhtml/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/dhtml/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dhtml/Makefile.mk (revision 307924) @@ -1,29 +1,29 @@ BST= ../../../stuff/bst BIN= dhtml OBJ= main.o dhtml.o tr_out.o char.o lib.o $(BST)/bst.o CPPFLAGS= -DFNTDIR='"$(FNTDIR)"' -I$(BST) all: $(BIN) install: $(STRIP) $(BIN) $(INSTALL) $(BIN) $(ROOT)$(BINDIR)/ sed 's"$$FNTDIR"$(FNTDIR)"g' $(BIN).1 > \ $(ROOT)$(MANDIR)/man1/$(BIN).1 clean: rm -f $(OBJ) $(BIN) mrproper: clean $(BIN): $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -o $@ + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJ) -o $@ .c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + $(CC) $(_CFLAGS) -c $< char.o: char.h main.h $(BST)/bst.h lib.h tr_out.h dhtml.o: dhtml.h tr_out.h char.h main.h lib.o: main.h $(BST)/bst.h main.o: dhtml.h char.h tr_out.o: tr_out.h main.h $(BST)/bst.h lib.h 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 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/Makefile.mk (revision 307924) @@ -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 \ 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 $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: dpost dpost: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o dpost + $(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 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/dpost.c (revision 307924) @@ -1,4814 +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" 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 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 */ 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); 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 ( 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); 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++); + for (np = fnt; *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); } 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); } 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) + 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 ( 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/ps_include.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/ps_include.c (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/dpost.d/ps_include.c (revision 307924) @@ -1,362 +1,364 @@ /* * 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; + case NORMAL: /* TODO: case is not in original code */ + break; } 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); } 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/draw.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/draw.c (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/draw.c (revision 307924) @@ -1,502 +1,499 @@ /* * 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 "draw.c 1.5 05/06/08 SMI" */ /* * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany * * Sccsid @(#)draw.c 1.3 (gritter) 8/8/05 */ /* * 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 "global.h" #define PI 3.141592654 #define hmot(n) hpos += n #define hgoto(n) hpos = n #define vmot(n) vgoto(vpos + n) extern int hpos; extern int vpos; extern int size; extern short *pstab; extern int DX; /* step size in x */ extern int DY; /* step size in y */ extern int drawdot; /* character to use when drawing */ extern int drawsize; /* shrink point size by this facter */ static int maxdots = 32000; /* maximum number of dots in an object */ #define sgn(n) ((n > 0) ? 1 : ((n < 0) ? -1 : 0)) #define abs(n) ((n) >= 0 ? (n) : -(n)) #define max(x,y) ((x) > (y) ? (x) : (y)) #define min(x,y) ((x) < (y) ? (x) : (y)) #define arcmove(x,y) { hgoto(x); vmot(-vpos-(y)); } - -#ifndef __unused -#define __unused __attribute__((unused)) -#endif extern void setsize(int); extern void vgoto(int); extern int t_size(int); extern void put1(int); void drawline(int, int, const char *); void drawwig(char *); char *getstr(char *, char *); void drawcirc(int); int dist(int, int, int, int); void drawarc(int, int, int, int); void drawellip(int, int); void conicarc(int, int, int, int, int, int, int, int); void putdot(int, int); void drawline(int dx, int dy, const char *s __unused) /* draw line from here to dx, dy using s */ { int xd, yd; float val, slope; int i, numdots; int dirmot, perp; int motincr, perpincr; int ohpos, ovpos, osize; float incrway; int itemp; /*temp. storage for value returned byint function sgn*/ osize = size; setsize(t_size(pstab[osize-1] / drawsize)); ohpos = hpos; ovpos = vpos; xd = dx / DX; yd = dy / DX; if (xd == 0) { numdots = abs (yd); numdots = min(numdots, maxdots); motincr = DX * sgn (yd); for (i = 0; i < numdots; i++) { vmot(motincr); put1(drawdot); } vgoto(ovpos + dy); setsize(osize); return; } if (yd == 0) { numdots = abs (xd); motincr = DX * sgn (xd); for (i = 0; i < numdots; i++) { hmot(motincr); put1(drawdot); } hgoto(ohpos + dx); setsize(osize); return; } if (abs (xd) > abs (yd)) { val = slope = (float) xd/yd; numdots = abs (xd); numdots = min(numdots, maxdots); dirmot = 'h'; perp = 'v'; motincr = DX * sgn (xd); perpincr = DX * sgn (yd); } else { val = slope = (float) yd/xd; numdots = abs (yd); numdots = min(numdots, maxdots); dirmot = 'v'; perp = 'h'; motincr = DX * sgn (yd); perpincr = DX * sgn (xd); } incrway = itemp = sgn ((int) slope); for (i = 0; i < numdots; i++) { val -= incrway; if (dirmot == 'h') hmot(motincr); else vmot(motincr); if (val * slope < 0) { if (perp == 'h') hmot(perpincr); else vmot(perpincr); val += slope; } put1(drawdot); } hgoto(ohpos + dx); vgoto(ovpos + dy); setsize(osize); } void drawwig(char *s) /* draw wiggly line */ { int x[50], y[50], xp, yp, pxp, pyp; float t1, t2, t3, w; int j, numdots; size_t i, N; size_t osize; char temp[50], *p; osize = size; setsize(t_size(pstab[osize-1] / drawsize)); p = s; for (N = 2; (p=getstr(p,temp)) != NULL && N < sizeof(x)/sizeof(x[0]); N++) { x[N] = atoi(temp); p = getstr(p, temp); y[N] = atoi(temp); } x[0] = x[1] = hpos; y[0] = y[1] = vpos; for (i = 1; i < N; i++) { x[i+1] += x[i]; y[i+1] += y[i]; } x[N] = x[N-1]; y[N] = y[N-1]; pxp = pyp = -9999; for (i = 0; i < N-1; i++) { /* interval */ numdots = (dist(x[i],y[i], x[i+1],y[i+1]) + dist(x[i+1],y[i+1], x[i+2],y[i+2])) / 2; numdots /= DX; numdots = min(numdots, maxdots); for (j = 0; j < numdots; j++) { /* points within */ w = (float) j / numdots; t1 = 0.5 * w * w; w = w - 0.5; t2 = 0.75 - w * w; w = w - 0.5; t3 = 0.5 * w * w; xp = t1 * x[i+2] + t2 * x[i+1] + t3 * x[i] + 0.5; yp = t1 * y[i+2] + t2 * y[i+1] + t3 * y[i] + 0.5; if (xp != pxp || yp != pyp) { hgoto(xp); vgoto(yp); put1(drawdot); pxp = xp; pyp = yp; } } } setsize(osize); } char *getstr(char *p, char *temp) /* copy next non-blank string from p to temp, update p */ { while (*p == ' ' || *p == '\t' || *p == '\n') p++; if (*p == '\0') { temp[0] = 0; return(NULL); } while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') *temp++ = *p++; *temp = '\0'; return(p); } void drawcirc(int d) { int xc, yc; xc = hpos; yc = vpos; conicarc(hpos + d/2, -vpos, hpos, -vpos, hpos, -vpos, d/2, d/2); hgoto(xc + d); /* circle goes to right side */ vgoto(yc); } int dist(int x1, int y1, int x2, int y2) /* integer distance from x1,y1 to x2,y2 */ { float dx, dy; dx = x2 - x1; dy = y2 - y1; return sqrt(dx*dx + dy*dy) + 0.5; } void drawarc(int dx1, int dy1, int dx2, int dy2) { int x0, y0, x2, y2, r; x0 = hpos + dx1; /* center */ y0 = vpos + dy1; x2 = x0 + dx2; /* "to" */ y2 = y0 + dy2; r = sqrt((float) dx1 * dx1 + (float) dy1 * dy1) + 0.5; conicarc(x0, -y0, hpos, -vpos, x2, -y2, r, r); } void drawellip(int a, int b) { int xc, yc; xc = hpos; yc = vpos; conicarc(hpos + a/2, -vpos, hpos, -vpos, hpos, -vpos, a/2, b/2); hgoto(xc + a); vgoto(yc); } #define sqr(x) (long int)(x)*(x) void conicarc(int x, int y, int x0, int y0, int x1, int y1, int a, int b) { /* based on Bresenham, CACM, Feb 77, pp 102-3 */ /* by Chris Van Wyk */ /* capitalized vars are an internal reference frame */ long dotcount = 0; int osize; int xs, ys, xt, yt, Xs, Ys, qs, Xt, Yt, qt, M1x, M1y, M2x, M2y, M3x, M3y, Q, move, Xc, Yc; int ox1, oy1; long delta; float xc, yc; float radius, slope; float xstep, ystep; osize = size; setsize(t_size(pstab[osize-1] / drawsize)); ox1 = x1; oy1 = y1; if (a != b) /* an arc of an ellipse; internally, will still think of circle */ if (a > b) { xstep = (float)a / b; ystep = 1; radius = b; } else { xstep = 1; ystep = (float)b / a; radius = a; } else { /* a circular arc; radius is computed from center and first point */ xstep = ystep = 1; radius = sqrt((float)(sqr(x0 - x) + sqr(y0 - y))); } xc = x0; yc = y0; /* now, use start and end point locations to figure out the angle at which start and end happen; use these angles with known radius to figure out where start and end should be */ slope = atan2((double)(y0 - y), (double)(x0 - x) ); if (slope == 0.0 && x0 < x) slope = 3.14159265; x0 = x + radius * cos(slope) + 0.5; y0 = y + radius * sin(slope) + 0.5; slope = atan2((double)(y1 - y), (double)(x1 - x)); if (slope == 0.0 && x1 < x) slope = 3.14159265; x1 = x + radius * cos(slope) + 0.5; y1 = y + radius * sin(slope) + 0.5; /* step 2: translate to zero-centered circle */ xs = x0 - x; ys = y0 - y; xt = x1 - x; yt = y1 - y; /* step 3: normalize to first quadrant */ if (xs < 0) if (ys < 0) { Xs = abs(ys); Ys = abs(xs); qs = 3; M1x = 0; M1y = -1; M2x = 1; M2y = -1; M3x = 1; M3y = 0; } else { Xs = abs(xs); Ys = abs(ys); qs = 2; M1x = -1; M1y = 0; M2x = -1; M2y = -1; M3x = 0; M3y = -1; } else if (ys < 0) { Xs = abs(xs); Ys = abs(ys); qs = 0; M1x = 1; M1y = 0; M2x = 1; M2y = 1; M3x = 0; M3y = 1; } else { Xs = abs(ys); Ys = abs(xs); qs = 1; M1x = 0; M1y = 1; M2x = -1; M2y = 1; M3x = -1; M3y = 0; } Xc = Xs; Yc = Ys; if (xt < 0) if (yt < 0) { Xt = abs(yt); Yt = abs(xt); qt = 3; } else { Xt = abs(xt); Yt = abs(yt); qt = 2; } else if (yt < 0) { Xt = abs(xt); Yt = abs(yt); qt = 0; } else { Xt = abs(yt); Yt = abs(xt); qt = 1; } /* step 4: calculate number of quadrant crossings */ if (((4 + qt - qs) % 4 == 0) && (Xt <= Xs) && (Yt >= Ys) ) Q = 3; else Q = (4 + qt - qs) % 4 - 1; /* step 5: calculate initial decision difference */ delta = sqr(Xs + 1) + sqr(Ys - 1) -sqr(xs) -sqr(ys); /* here begins the work of drawing we hope it ends here too */ while ((Q >= 0) || ((Q > -2) && ((Xt > Xc) && (Yt < Yc) ) ) ) { if (dotcount++ % DX == 0) putdot((int)xc, (int)yc); if (Yc < 0.5) { /* reinitialize */ Xs = Xc = 0; Ys = Yc = sqrt((float)(sqr(xs) + sqr(ys))); delta = sqr(Xs + 1) + sqr(Ys - 1) - sqr(xs) - sqr(ys); Q--; M1x = M3x; M1y = M3y; { int T; T = M2y; M2y = M2x; M2x = -T; T = M3y; M3y = M3x; M3x = -T; } } else { if (delta <= 0) if (2 * delta + 2 * Yc - 1 <= 0) move = 1; else move = 2; else if (2 * delta - 2 * Xc - 1 <= 0) move = 2; else move = 3; switch (move) { case 1: Xc++; delta += 2 * Xc + 1; xc += M1x * xstep; yc += M1y * ystep; break; case 2: Xc++; Yc--; delta += 2 * Xc - 2 * Yc + 2; xc += M2x * xstep; yc += M2y * ystep; break; case 3: Yc--; delta -= 2 * Yc + 1; xc += M3x * xstep; yc += M3y * ystep; break; } } } setsize(osize); drawline((int)xc-ox1,(int)yc-oy1,"."); } void putdot(int x, int y) { arcmove(x, y); put1(drawdot); } Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/font/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/font/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/font/Makefile.mk (revision 307924) @@ -1,57 +1,57 @@ VPATH=.. FONTS = AB AI AR AX BI CB CI CO CW CX GR HB HI HX Hb Hi Hr Hx \ KB KI KR KX NB NI NR NX PA PB PI PX S1 VB VI VR VX ZD ZI B H I R S FLAGS = -I. -I.. -DFNTDIR='"$(FNTDIR)"' .c.o: - $(CC) $(CFLAGS) $(WARN) $(CPPFLAGS) $(FLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: install: all test -d $(ROOT)$(FNTDIR) || mkdir -p $(ROOT)$(FNTDIR) test -d $(ROOT)$(FNTDIR)/devpost/charlib || \ mkdir -p $(ROOT)$(FNTDIR)/devpost/charlib cd devpost && for i in ? ?? H?? H??? ?.name ??.name H??.name \ H???.name DESC* FONTMAP; do \ $(INSTALL) -c -m 644 $$i $(ROOT)$(FNTDIR)/devpost/ || exit; \ done cd $(ROOT)$(FNTDIR)/devpost && \ for i in G HM HK HL; \ do \ rm -f $$i; ln -s H $$i || exit; \ done && \ rm -f GI; ln -s HI GI cd devpost/charlib && for i in ?? ??.map BRACKETS_NOTE README OLD_LH* \ LH_uc; \ do \ $(INSTALL) -c -m 644 $$i $(ROOT)$(FNTDIR)/devpost/charlib \ || exit; \ done test -d $(ROOT)$(FNTDIR)/devps || mkdir -p $(ROOT)$(FNTDIR)/devps cd devps && for i in ? ?.afm ?? ??.afm DESC MustRead.html FONTMAP; \ do \ $(INSTALL) -c -m 644 $$i $(ROOT)$(FNTDIR)/devps/ || exit; \ done rm -f $(ROOT)$(FNTDIR)/devps/charlib ln -s ../devpost/charlib $(ROOT)$(FNTDIR)/devps/charlib rm -f $(ROOT)$(FNTDIR)/devps/postscript ln -s ../devpost/postscript $(ROOT)$(FNTDIR)/devps/postscript for j in devpslow devpsmed; \ do \ test -d $(ROOT)$(FNTDIR)/$$j || mkdir -p $(ROOT)$(FNTDIR)/$$j; \ $(INSTALL) -c -m 644 $$j/DESC $(ROOT)$(FNTDIR)/$$j/; \ (cd $(ROOT)$(FNTDIR)/devps && for i in *; \ do \ test $$i != DESC || continue; \ rm -f ../$$j/$$i; \ ln -s ../devps/$$i ../$$j/$$i ; \ done); \ done clean: rm -f core log *~ mrproper: clean Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/font/devhtml/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/font/devhtml/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/font/devhtml/Makefile.mk (revision 307924) @@ -1,23 +1,23 @@ BIN= makefont OBJS= $(BIN).o FONTS= R I B BI C CW CR CI CB H HI HB S all: $(BIN) install: d=$(ROOT)$(FNTDIR)/devhtml; test -d $$d || mkdir $$d; \ install -m 644 CHAR DESC $$d/; \ echo charset >> $$d/DESC; \ sed '1,2d;s/[[:space:]].*//' charset >> $$d/DESC; \ for i in $(FONTS); do \ install -m 644 $$i $$d/; \ ./$(BIN) $$i >> $$d/$$i; \ done clean: rm -rf $(BIN) $(OBJS) mrproper: clean $(BIN): $(OBJS) - $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(OBJS) -o $@ + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJS) -o $@ Index: projects/doctools/contrib/heirloom-doctools/troff/troff.d/t10.c =================================================================== --- projects/doctools/contrib/heirloom-doctools/troff/troff.d/t10.c (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/troff/troff.d/t10.c (revision 307924) @@ -1,1140 +1,1139 @@ /* * 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; - 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 */ + 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 */ /* for (i = 1; i <= nfonts; i++) - 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", + 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", dev.nchtab, dev.lchname, dev.nchtab+128-32); - dprintf(ptid, "x xxx sizes:\nx xxx "); + fdprintf(ptid, "x xxx sizes:\nx xxx "); for (i = 0; i < nsizes; i++) - dprintf(ptid, " %d", pstab[i]); - dprintf(ptid, "\nx xxx chars:\nx xxx "); + fdprintf(ptid, " %d", pstab[i]); + fdprintf(ptid, "\nx xxx chars:\nx xxx "); for (i = 0; i < dev.nchtab; i++) - dprintf(ptid, " %s", &chname[chtab[i]]); - dprintf(ptid, "\nx xxx\n"); + fdprintf(ptid, " %s", &chname[chtab[i]]); + fdprintf(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); /* - dprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos); + fdprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos); */ - dprintf(ptid, "n%d %d\n", b, a); /* be nice to chuck */ + fdprintf(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(); - dprintf(ptid, "x X "); + fdprintf(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) - dprintf(ptid, "x H -23 %g\n", f); + fdprintf(ptid, "x H -23 %g\n", f); else - dprintf(ptid, "x H %d\n", j); + fdprintf(ptid, "x H %d\n", j); return(pi+outsize); } if (k == SLANT) { if (xflag) { xfont = fbits(i); if (xfont != mfont) ptfont(); } - dprintf(ptid, "x S %d\n", (int)sbits(i)-180); + fdprintf(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: - dprintf(ptid, "D%c %d\n", c, dx); /* dx is diameter */ + fdprintf(ptid, "D%c %d\n", c, dx); /* dx is diameter */ w = 0; hpos += dx; break; case DRAWELLIPSE: case DRAWELLIPSEFI: - dprintf(ptid, "D%c %d %d\n", c, dx, dy); + fdprintf(ptid, "D%c %d %d\n", c, dx, dy); w = 0; hpos += dx; break; case DRAWLINE: /* line */ k = cbits(pi[2]); - dprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy); + fdprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy); if (k < 128) - dprintf(ptid, "%c\n", k); + fdprintf(ptid, "%c\n", k); else - dprintf(ptid, "%s\n", &chname[chtab[k - 128]]); + fdprintf(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; - dprintf(ptid, "D%c %d %d %d %d\n", DRAWARC, + fdprintf(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 */ - dprintf(ptid, "D%c %d %d", (int)cbits(pi[1]), dx, dy); + fdprintf(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 */ - dprintf(ptid, "\n"); + fdprintf(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; - dprintf(ptid, " %d %d", dx, dy); + fdprintf(ptid, " %d %d", dx, dy); hpos += dx; vpos += dy; } - dprintf(ptid, "\n"); + fdprintf(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) { - dprintf(ptid, "c%c\n", k); + fdprintf(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) { - dprintf(ptid, "CPS%s\n", a->nametab[j]); + fdprintf(ptid, "CPS%s\n", a->nametab[j]); } else { - dprintf(ptid, "N%d\n", + fdprintf(ptid, "N%d\n", k - (html ? 0 : (nchtab + 128)) ); } } else { - dprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); + fdprintf(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) - dprintf(ptid, "x X HorScale %g\n", + fdprintf(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)) - dprintf(ptid, "x X Track %d\n", lasttrack + lettrack); + fdprintf(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))) - dprintf(ptid, "s-23 %g\n", s); + fdprintf(ptid, "s-23 %g\n", s); else - dprintf(ptid, "s%d\n", (int)s); /* really should put out string rep of size */ + fdprintf(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; - dprintf(ptid, "f%d\n", xfont); + fdprintf(ptid, "f%d\n", xfont); mtrack = 0; pttrack(1); pthorscale(1); } void ptfpcmd(int f, const char *s, char *path, int flags) { if (ascii) return; - dprintf(ptid, "x font %d %s", f, s); + fdprintf(ptid, "x font %d %s", f, s); if (path) { - dprintf(ptid, " %s", path); + fdprintf(ptid, " %s", path); if (flags) - dprintf(ptid, " %d", flags); + fdprintf(ptid, " %d", flags); } - dprintf(ptid, "\n"); + fdprintf(ptid, "\n"); ptfont(); /* make sure that it gets noticed */ } void ptlead(void) { vpos += lead; if (!ascii) - dprintf(ptid, "V%d\n", vpos); + fdprintf(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 - dprintf(ptid, "%d", esc); + fdprintf(ptid, "%d", esc); } else - dprintf(ptid, "H%d\n", hpos); + fdprintf(ptid, "H%d\n", hpos); esc = 0; } void ptsupplyfont(char *fontname, char *file) { if (ascii) return; - dprintf(ptid, "x X SupplyFont %s %s\n", fontname, file); + fdprintf(ptid, "x X SupplyFont %s %s\n", fontname, file); } void ptpapersize(void) { if (ascii || mediasize.flag == 0) return; - dprintf(ptid, "x X PaperSize %d %d %d\n", + fdprintf(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) - dprintf(ptid, "x X %s %d %d %d %d\n", name, + fdprintf(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; - dprintf(ptid, "x X LC_CTYPE %s\n", lp); + fdprintf(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) { - dprintf(ptid, "x X Anchor %s\n", rp->name); + fdprintf(ptid, "x X Anchor %s\n", rp->name); } else { - dprintf(ptid, "x X Anchor %d,%d %s\n", + fdprintf(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) { - dprintf(ptid, "x X %s\n", type); + fdprintf(ptid, "x X %s\n", type); return; } for (rp = rstart; rp; rp = rp->next) if (rp->cnt == n) { if (html) - dprintf(ptid, "x X %s %s\n", type, rp->name); + fdprintf(ptid, "x X %s %s\n", type, rp->name); else - dprintf(ptid, "x X %s %d,%d,%d,%d %s\n", + fdprintf(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(); - dprintf(ptid, "x X "); + fdprintf(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; - dprintf(ptid, "p%d\n", n); /* new page */ + fdprintf(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); - dprintf(ptid, "x font %d %s %s %d\n", i, + fdprintf(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]) - dprintf(ptid, "x font %d %s\n", i, macname(fontlab[i])); + fdprintf(ptid, "x font %d %s\n", i, macname(fontlab[i])); } ptps(); ptfont(); ptpapersize(); ptcut(); ptlocale(NULL); } void pttrailer(void) { - dprintf(ptid, "x trailer\n"); + fdprintf(ptid, "x trailer\n"); } void ptstop(void) { - dprintf(ptid, "x stop\n"); + fdprintf(ptid, "x stop\n"); } void dostop(void) { if (ascii) return; ptlead(); vpos = 0; - /* dprintf(ptid, "x xxx end of page\n");*/ + /* fdprintf(ptid, "x xxx end of page\n");*/ if (!nofeed) pttrailer(); ptlead(); - dprintf(ptid, "x pause\n"); + fdprintf(ptid, "x pause\n"); flusho(); mpts = mfont = 0; ptesc(); esc = po; hpos = vpos = 0; /* probably in wrong place */ } Index: projects/doctools/contrib/heirloom-doctools/version.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/version.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/version.mk (revision 307924) @@ -1,2 +1,2 @@ -RELEASE = Git snapshot 161006 +RELEASE = Git snapshot 161025 #RELEASE = release 160308 Index: projects/doctools/contrib/heirloom-doctools/vgrind/Makefile.mk =================================================================== --- projects/doctools/contrib/heirloom-doctools/vgrind/Makefile.mk (revision 307923) +++ projects/doctools/contrib/heirloom-doctools/vgrind/Makefile.mk (revision 307924) @@ -1,34 +1,34 @@ OBJ = regexp.o vfontedpr.o vgrindefs.o version.o FLAGS = $(EUC) -DLIBDIR='"$(LIBDIR)"' $(DEFINES) -I../include .c.o: - $(CC) $(CFLAGS) $(WARN) $(FLAGS) $(CPPFLAGS) -c $< + $(CC) $(_CFLAGS) $(FLAGS) -c $< all: vgrind vfontedpr vfontedpr: $(OBJ) - $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o vfontedpr + $(CC) $(_CFLAGS) $(_LDFLAGS) $(OBJ) $(LIBS) -o vfontedpr vgrind: vgrind.sh rm -f $@ echo "#!$(SHELL)" >>$@ echo "_TROFF=$(BINDIR)/troff" >>$@ echo "_VFONTEDPR=$(LIBDIR)/vfontedpr" >>$@ echo "_TMAC_VGRIND=$(MACDIR)/vgrind" >>$@ echo "_DPOST=$(BINDIR)/dpost" >>$@ cat vgrind.sh >>$@ chmod 755 $@ install: $(INSTALL) -c vgrind $(ROOT)$(BINDIR)/vgrind test -d $(ROOT)$(LIBDIR) || mkdir -p $(ROOT)$(LIBDIR) $(INSTALL) -c vfontedpr $(ROOT)$(LIBDIR)/vfontedpr $(STRIP) $(ROOT)$(LIBDIR)/vfontedpr $(INSTALL) -c -m 644 vgrindefs.src $(ROOT)$(LIBDIR)/vgrindefs $(INSTALL) -c -m 644 vgrind.1 $(ROOT)$(MANDIR)/man1/vgrind.1 clean: rm -f $(OBJ) vfontedpr vgrind retest retest.o core log *~ mrproper: clean Index: projects/doctools/contrib/heirloom-doctools =================================================================== --- projects/doctools/contrib/heirloom-doctools (revision 307923) +++ projects/doctools/contrib/heirloom-doctools (revision 307924) Property changes on: projects/doctools/contrib/heirloom-doctools ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /vendor/heirloom-doctools/dist:r307812-307922