static char sccsid
[] = "@(#)n1.c 2.1 (CWI) 85/07/18";
* consume options, initialization, main loop,
* input routines, escape function calling
#include <time.h> /* See cvtime() (jaap) */
char cfname
[NSO
][NS
] = "<standard input>"; /*file name stack*/
int cfline
[NSO
]; /*input line count stack*/
char *progname
; /* program name (troff) */
extern catch(), kcatch();
if (signal(SIGINT
, catch) == SIG_IGN
) {
signal(SIGQUIT
, SIG_IGN
);
if ((p
= getenv("TYPESETTER")) != 0)
while (--argc
> 0 && (++argv
)[0][0] == '-')
case 'F': /* switch font tables from default */
if (argv
[0][2] != '\0') {
strcpy(termtab
, &argv
[0][2]);
strcpy(fontfile
, &argv
[0][2]);
strcpy(termtab
, argv
[0]);
strcpy(fontfile
, argv
[0]);
case 'u': /* set emboldening amount */
bdtab
[3] = ctoi(&argv
[0][2]);
if (bdtab
[3] < 0 || bdtab
[3] > 50)
if (!(stop
= ctoi(&argv
[0][2])))
eibuf
= sprintf(ibuf
+strlen(ibuf
), ".nr %c %s\n",
argv
[0][2], &argv
[0][3]);
strcat(nextf
, &argv
[0][2]);
strcpy(devname
, &argv
[0][2]);
case 'D': /* select DUTCH as hyphenation style (jaap) */
case 't': /* for backward compatability */
errprint("unknown option %s", argv
[0]);
copyf
= lgf
= nb
= nflush
= nlflg
= 0;
if (ip
&& rbf0(ip
) == 0 && ejf
&& frame
->pframe
<= ejl
) {
if ((j
= cbits(i
)) == XPAR
) {
if (j
== cc
|| j
== c2
) {
while ((j
= cbits(i
= getch())) == ' ' || j
== '\t')
signal(SIGTERM
, SIG_IGN
);
p
= mktemp("/usr/tmp/trtmpXXXXX");
if ((close(creat(p
, 0600))) < 0) {
errprint("cannot create temp file.");
if ((ttyp
=ttyname(j
=0)) != 0 || (ttyp
=ttyname(j
=1)) != 0 || (ttyp
=ttyname(j
=2)) != 0)
numtab
[PID
].val
= getpid();
numtab
[HP
].val
= init
= 0;
eibuf
= sprintf(ibuf
+strlen(ibuf
), ".ds .T %s\n", devname
);
numtab
[CD
].val
= -1; /* compensation */
frame
= stk
= (struct s
*)setbrk(DELTA
);
write(ibf
, (char *) & env
, sizeof(env
));
* This replaces the old cvtime, so on well maintained systems, you don't
* need to change the (quite unknown) ZONE constant in tdef.h
extern struct tm
*localtime();
numtab
[DY
].val
= tym
->tm_mday
; /* Current day of the month */
numtab
[DW
].val
= tym
->tm_wday
+ 1; /* Current day of the week */
numtab
[YR
].val
= tym
->tm_year
; /* Current year */
numtab
[MO
].val
= tym
->tm_mon
+ 1; /* Current month of year */
chmod(ttyp
, mode
& ~0122); /* turn off writing for others */
if (ttyp
&& *ttyp
&& mode
)
errprint(s
, s1
, s2
, s3
, s4
, s5
) /* error message printer */
char *s
, *s1
, *s2
, *s3
, *s4
, *s5
;
fdprintf(stderr
, "%s: ", progname
);
fdprintf(stderr
, s
, s1
, s2
, s3
, s4
, s5
);
fdprintf(stderr
, "; line %d, file %s", numtab
[CD
].val
, cfname
[ifi
]);
* Scaled down version of C Library printf.
* Only %s %u %d (==%u) %o %c %x %D are recognized.
#define putchar(n) (*pfbp++ = (n)) /* NO CHECKING! */
static char *pfbp
= pfbuf
;
int stderr
= 2; /* NOT stdio value */
register unsigned int *adx
;
while ((c
= *fmt
++) != '%') {
write(stderr
, pfbuf
, pfbp
- pfbuf
);
if (obufp
>= &obuf
[OBUFSZ
])
} else if (c
== 'u' || c
== 'o' || c
== 'x')
printn((long)*adx
, c
== 'o' ? 8 : (c
== 'x' ? 16 : 10));
printn(*(long *)adx
, 10);
adx
+= (sizeof(long) / sizeof(int)) - 1;
adx
+= (sizeof(long) / sizeof(int)) - 1;
* Print an unsigned integer in base b.
if (n
< 0) { /* shouldn't happen */
putchar("0123456789ABCDEF"[(int)(n
%b
)]);
/* scaled down version of library sprintf */
/* same limits as fdprintf */
/* returns pointer to \0 that ends the string */
char *sprintf(str
, fmt
, x1
)
register unsigned int *adx
;
while ((c
= *fmt
++) != '%') {
str
= sprintn(str
, (long)i
, 10);
} else if (c
== 'u' || c
== 'o' || c
== 'x')
str
= sprintn(str
, (long)*adx
, c
== 'o' ? 8 : (c
== 'x' ? 16 : 10));
str
= sprintn(str
, *(long *)adx
, 10);
adx
+= (sizeof(long) / sizeof(int)) - 1;
str
= sprintn(str
, *(long *)adx
, 8);
adx
+= (sizeof(long) / sizeof(int)) - 1;
* Print an unsigned integer in base b.
static char *sprintn(s
, n
, b
)
if (n
< 0) { /* shouldn't happen */
*s
++ = "0123456789ABCDEF"[(int)(n
%b
)];
if (a
== 0 || (j
= findmn(a
)) == -1)
return pushi((filep
)contab
[j
].mx
, a
);
return((*contab
[j
].f
)(0));
if (((i
= getach()) == 0) || ((j
= getach()) == 0))
* table encodes some special characters, to speed up tests
* in getchar, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
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,
tchar
setht(), setslant();
numtab
[CD
].val
++; /* line number */
if (k
== 'f' && lg
&& !lgf
) {
if (k
== fc
|| k
== tabch
|| k
== ldrch
) {
if ((i
= setfield(k
)) == 0)
i
= makem(-width(' ' | chbits
));
case 'X': /* \X'...' for copy through */
case '\n': /* concealed newline */
case 'n': /* number register */
case '*': /* string indicator */
case '$': /* argument indicator */
while (cbits(i
= getch0()) != '\n')
case ESC
: /* double backslash */
case 'e': /* printable version of current eschar */
case ' ': /* unpaddable space */
case '-': /* current font minus */
case 'c': /* to be continued */
case '!': /* transparent indicator */
case 'a': /* leader (SOH) */
case 'g': /* return format of a number register */
case 'N': /* absolute character number */
case '(': /* special char name */
case 's': /* size indicator */
case 'H': /* character height */
case 'f': /* font indicator */
case 'w': /* width function */
case 'h': /* horiz mot */
case 'z': /* zero with char */
case 'L': /* vert line */
case 'D': /* drawing function */
case 'o': /* overstrike */
case 'k': /* mark hor place */
if ((k
= findr(getsn())) != -1) {
numtab
[k
].val
= numtab
[HP
].val
;
case '0': /* number space */
return(makem(width('0' | chbits
)));
case '|': /* narrow space */
return(makem((int)(EM
)/6));
case '^': /* half narrow space */
return(makem((int)(EM
)/12));
case 'x': /* extra line space */
case 'u': /* half em up */
case 'r': /* full em up */
case 'd': /* half em down */
setxon() /* \X'...' for copy through */
while ((k
= cbits(c
= getch())) != delim
&& k
!= '\n' && i
< xbuf
+NC
-1) {
0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012};
if ((++ip
& (BLK
- 1)) == 0) {
if (nx
|| ibufp
>= eibuf
) {
if ((j
= read(ifile
, ibuf
, IBUFSZ
)) <= 0)
if (i
>= 040 && i
< 0177)
if (cbits(i
) == IMP
&& !raw
)
if ((i
== 0 || i
== 0177) && !init
&& !raw
) {
if (copyf
== 0 && (i
& ~BYTEMASK
) == 0)
if (cbits(i
) == eschar
&& !raw
)
while (b
> ob
&& pbp
< &pbbuf
[NC
-3])
if (pbp
>= &pbbuf
[NC
-3]) {
errprint("pushback overflow");
while (b
> ob
&& pbp
< &pbbuf
[NC
-3])
if (pbp
>= &pbbuf
[NC
-3]) {
errprint("cpushback overflow");
goto n0
; /* popf error */
if ((nfo
-= mflg
) && !stdi
)
numtab
[CD
].val
= ifile
= stdi
= mflg
= 0;
strcpy(cfname
[ifi
], "<standard input>");
if (p
[0] == '-' && p
[1] == 0) {
strcpy(cfname
[ifi
], "<standard input>");
} else if ((ifile
= open(p
, 0)) < 0) {
errprint("cannot open file %s", p
);
numtab
[CD
].val
= cfline
[ifi
]; /*restore line counter*/
if ((ifile
= ifl
[ifi
]) == 0) {
if (lseek(ifile
, (long)(ioff
& ~(IBUFSZ
-1)), 0) == (long) -1
|| (i
= read(ifile
, ibuf
, IBUFSZ
)) < 0)
if ((ibufp
= ibuf
+ (int)(ioff
& (IBUFSZ
- 1))) > eibuf
)
if (donef
&& (frame
== stk
))
if (ismot(i
) || j
== ' ' || j
== '\n' || j
& 0200) {
for (k
= 0; k
< (NS
- 1); k
++) {
if (((j
= cbits(i
= getch())) <= ' ') || (j
> 0176))
if (skip() || !getname() || ((i
= open(nextf
, 0)) < 0) || (ifi
>= NSO
)) {
errprint("can't open file %s", nextf
);
strcpy(cfname
[ifi
+1], nextf
);
cfline
[ifi
] = numtab
[CD
].val
; /*hold line counter*/
caself() /* set line number and file */
cfline
[ifi
] = numtab
[CD
].val
= n
- 2;
strcpy(cfname
[ifi
], nextf
);
{ /* copy file without change */
extern int hpos
, esc
, po
;
if (skip() || !getname() || (fd
= open(nextf
, 0)) < 0) {
errprint("can't open file %s", nextf
);
/* make it into a clean state, be sure that everything is out */
while ((n
= read(fd
, buf
, sizeof buf
)) > 0)
casesy() /* call system */
for (i
= 0; i
< NTM
- 2; i
++)
if ((sybuf
[i
] = getch()) == '\n')
if (pnp
>= &pnlist
[NPN
-2]) {
errprint("too many page numbers");
if (i
< 0 || cbits(j
= getch0()) == RPT
)
while (i
>0 && pbp
< &pbbuf
[NC
-3]) {