home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
printer
/
pcroff.arc
/
SOURCE.ARC
/
PCROFF.C
< prev
next >
Wrap
Text File
|
1985-03-24
|
35KB
|
1,327 lines
/*
* roff - C version.
* the Colonel (George Sicherman). 19 May 1983.
* fix by Tim Maroney, 31 Dec 1984.
* .hc implemented, 8 Feb 1985.
* ported to PC, + font control - Dave Tutelman
*/
#include <stdio.h>
#include <b:printcap.h> /* use printcap for YOUR printer */
#define TXTLEN (o_pl-o_m1-o_m2-o_m3-o_m4-2)
#define IDTLEN (o_ti>=0?o_ti:o_in)
#define MAXMAC 64
#define MAXDEPTH 10
#define MAXLENGTH 255
#define UNDERL 1
#define BOLD 2
#define ITALIC 4
char spacechars[] = " \t\n";
int sflag, hflag, startpage, stoppage;
char holdword[MAXLENGTH], *holdp;
char assyline[MAXLENGTH]; /* place to assemble output line */
int assylen; /* index into assyline */
int infont = 0, outfont = 0, oldfont = 0;
char assyfont[MAXLENGTH]; /* font indicator for output characters
* bit 0 = ul (underline)
* bit 1 = bo (bold)
* bit 2 = it (italic)
*/
char ehead[100], efoot[100], ohead[100], ofoot[100];
struct macrotype {
char mname[3];
long int moff;
} macro[MAXMAC];
int n_macros;
int depth;
int adjtoggle;
int isrequest = 0;
char o_tr[40][2]; /* OUTPUT TRANSLATION TABLE */
int o_cc = '.'; /* CONTROL CHARACTER */
int o_hc = -1; /* HYPHENATION CHARACTER */
int o_tc = ' '; /* TABULATION CHARACTER */
int o_in = 0; /* INDENT SIZE */
int o_ix = -1; /* NEXT INDENT SIZE */
int o_ta[20] = {
9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105,
113, 121, 129, 137, 145, 153, 161};
int n_ta = 20; /* #TAB STOPS */
int o_ll = 65, o_ad = 1, o_po = 0, o_ls = 1, o_ig = 0, o_fi = 1;
int o_pl = 66, o_ro = 0, o_hx = 0, o_bl = 0, o_sp = 0, o_sk = 0;
int o_ce = 0, o_m1 = 2, o_m2 = 2, o_m3 = 1, o_m4 = 3;
int o_li = 0, o_n1 = 0, o_n2 = 0, o_bp = -1, o_hy = 1;
int o_ni = 1; /* LINE-NUMBER INDENT */
int o_nn = 0; /* #LINES TO SUPPRESS NUMBERING */
int o_ti = -1; /* TEMPORARY INDENT */
int o_ul = 0, o_bo = 0, o_it = 0;
int o_dev = 1; /* 0=SCREEN, 1=PRINTER, 2=TTY */
char printer[4] = ""; /* NAME OF PRINTER, INITIALLY BLANK */
int center = 0;
int page_no = -1;
int line_no = 9999;
int n_outwords;
FILE *File, *Macread, *Macwrite;
FILE *Save;
long int teller[MAXDEPTH], ftell();
char *strcat(), *strcpy(), *strend(), *strhas();
char *sprintf();
char *request[] = {
"ad","ar","bl","bp","br","cc","ce","de",
"ds","ef","eh","fi","fo","hc","he","hx","hy","ig",
"in","ix","li","ll","ls","m1","m2","m3","m4",
"n1","n2","na","ne","nf","ni","nn","nx","of","oh",
"pa","pl","po","ro","sk","sp","ss","ta","tc","ti",
"tr","ul","bo","it",0};
int c; /* LAST CHAR READ */
main(argc,argv)
int argc;
char **argv;
{
while (--argc) switch (**++argv) {
case '+':
startpage=atoi(++*argv);
break;
case '-':
++*argv;
if (isdigit(**argv)) stoppage=atoi(*argv);
else switch(**argv) {
case 's':
sflag++;
break;
case 'h':
hflag++;
break;
case 'd':
o_dev=0;
break;
case 'p':
++*argv; /* GET RID OF "P" */
strncpy(printer,*argv,3);
break;
case 't':
o_dev=2;
break;
default:
bomb();
}
break;
default:
argc++;
goto endargs;
}
endargs:
if (o_dev == 1) printcap(); /* GET PRINTER PARAMETERS */
assylen=0;
assyline[0]='\0';
if (!argc) {
File=stdin;
readfile();
}
else while (--argc) {
File=fopen(*argv,"r");
if (NULL==File) {
fprintf(stderr,"PCroff: cannot read %s\n",*argv);
exit(1);
}
readfile();
fclose(File);
argv++;
}
writebreak();
endpage();
for (; o_sk; o_sk--) blankpage();
/* NOW DO CLEANUP OF FILES */
if (Macwrite) fclose (Macwrite);
if (Macread) fclose (Macread);
unlink ("MACWRITE.TMP");
}
readfile()
{
while (readline()) {
if (isrequest) continue;
if (center || !o_fi) {
if (assylen) writeline(0,1);
else blankline();
}
}
}
readline()
{
int startline, doingword;
isrequest = 0;
startline = 1;
doingword = 0;
c=suck();
if (c == '\n') {
o_sp = 1;
writebreak();
goto out;
}
else if (isspace(c)) writebreak();
for (;;) {
if (c==EOF) {
if (doingword) bumpword();
break;
}
if (c!=o_cc && o_ig) {
while (c!='\n' && c!=EOF) c=suck();
break;
}
if (isspace(c) && !doingword) {
startline=0;
switch (c) {
case ' ':
assyfont[assylen]=infont;
assyline[assylen++]=' ';
break;
case '\t':
tabulate();
break;
case '\n':
goto out;
}
c = suck();
continue;
}
if (isspace(c) && doingword) {
bumpword();
if (c=='\t') tabulate();
else if (assylen) {
assyfont[assylen]=infont;
assyline[assylen++]=' ';
}
doingword=0;
if (c=='\n') break;
}
if (!isspace(c)) {
if (doingword) {
*holdp++ = c;
}
else if (startline && c==o_cc && !o_li) {
isrequest=1;
return readreq();
}
else {
doingword=1;
holdp=holdword;
*holdp++ = c;
}
}
startline=0;
c = suck();
}
out:
if (o_ul) o_ul--;
if (o_bo) o_bo--;
if (o_it) o_it--;
infont = (o_ul? UNDERL:0) | (o_bo? BOLD:0) | (o_it? ITALIC:0);
center=o_ce;
if (o_ce) o_ce--;
if (o_li) o_li--;
return c!=EOF;
}
/*
* bumpword - add word to current line.
*/
bumpword()
{
char *hc;
int i;
*holdp = '\0';
infont = o_ul? UNDERL : 0;
infont |= o_bo? BOLD : 0;
infont |= o_it? ITALIC : 0;
/*
* If in no-fill mode, don't even try to hyphenate.
*/
if (!o_fi) goto giveup;
/*
* We use a while-loop in case of ridiculously long words with
* multiple hyphenation indicators.
*/
if (assylen + reallen(holdword) > o_ll - IDTLEN) {
if (!o_hy) writeline(o_ad,0);
else while (assylen + reallen(holdword) > o_ll - IDTLEN) {
/*
* Try hyphenating it.
*/
if (o_hc && strhas(holdword,o_hc)) {
/*
* There are hyphenation marks. Use them!
*/
for (hc=strend(holdword); hc>=holdword; hc--) {
if (*hc!=o_hc) continue;
*hc = '\0';
if (assylen + reallen(holdword) + 1 >
o_ll - IDTLEN) {
*hc = o_hc;
continue;
}
/*
* Yay - it fits!
*/
dehyph(holdword);
strcpy(&assyline[assylen],holdword);
strcat(assyline,"-");
for (i=assylen;
i<=assylen+strlen(holdword)+1;
i++)
assyfont[i] = infont;
assylen += strlen(holdword) + 1;
strcpy(holdword,++hc);
break; /* STOP LOOKING */
} /* for */
/*
* It won't fit, or we've succeeded in breaking the word.
*/
writeline(o_ad,0);
if (hc<holdword) goto giveup;
}
else {
/*
* If no hyphenation marks, give up.
* Let somebody else implement it.
*/
writeline(o_ad,0);
goto giveup;
}
} /* while */
}
giveup:
/*
* remove hyphenation marks, even if hyphenation is disabled.
*/
if (o_hc) dehyph(holdword);
strcpy(&assyline[assylen],holdword);
for (i=assylen; i<=assylen+strlen(holdword); i++)
assyfont[i] = infont;
assylen+=strlen(holdword);
holdp = holdword;
}
/*
* dehyph - remove hyphenation marks.
*/
dehyph(s)
char *s;
{
char *t;
for (t=s; *s; s++) if (*s != o_hc) *t++ = *s;
*t='\0';
}
/*
* reallen - length of a word, excluding hyphenation marks.
*/
int
reallen(s)
char *s;
{
register n;
n=0;
while (*s) n += (o_hc != *s++);
return n;
}
tabulate()
{
int j;
for (j=0; j<n_ta; j++) if (o_ta[j]-1>assylen+IDTLEN) {
for (; assylen+IDTLEN<o_ta[j]-1; assylen++) {
assyline[assylen]=o_tc;
assyfont[assylen]=infont;
}
return;
}
/* NO TAB STOPS REMAIN */
assyfont[assylen]=infont;
assyline[assylen++]=o_tc;
}
int
readreq()
{
char req[3];
int r, s;
if (skipsp()) return c!=EOF;
c=suck();
if (c==EOF || c=='\n') return c!=EOF;
if (c=='.') { /* END OF MACRO */
o_ig = 0;
do (c=suck());
while (c!=EOF && c!='\n');
if (depth) endmac();
return c!=EOF;
}
if (o_ig) { /* IGNORING THIS LINE */
while (c!=EOF && c!='\n') c=suck();
return c!=EOF;
}
/* MAKE 2-CHAR STRING IN req */
req[0]=c;
c=suck();
if (c==EOF || c=='\n') req[1]='\0';
else req[1]=c;
req[2]='\0';
for (r=0; r<n_macros; r++) if (!strcmp(macro[r].mname,req)) {
submac(r); /* CALL THE MACRO req */
goto reqflsh;
}
for (r=0; request[r]; r++) if (!strcmp(request[r],req)) break;
if (!request[r]) {
do (c=suck());
while (c!=EOF && c!='\n');
return c!=EOF;
}
switch (r) {
case 0: /* ad */
o_ad=1;
writebreak();
break;
case 1: /* ar */
o_ro=0;
break;
case 2: /* bl */
nread(&o_bl);
writebreak();
break;
case 3: /* bp */
case 37: /* pa */
c=snread(&r,&s,1);
if (s>0) o_bp=page_no+r;
else if (s<0) o_bp=page_no-r;
else o_bp=r;
writebreak();
if (line_no) {
endpage();
beginpage();
}
break;
case 4: /* br */
writebreak();
break;
case 5: /* cc */
c=cread(&o_cc);
break;
case 6: /* ce */
nread(&o_ce);
writebreak();
break;
case 7: /* de */
defmac();
break;
case 8: /* ds */
o_ls=2;
writebreak();
break;
case 9: /* ef */
c=tread(efoot);
break;
case 10: /* eh */
c=tread(ehead);
break;
case 11: /* fi */
o_fi=1;
writebreak();
break;
case 12: /* fo */
c=tread(efoot);
strcpy(ofoot,efoot);
break;
case 13: /* hc */
c=cread(&o_hc);
break;
case 14: /* he */
c=tread(ehead);
strcpy(ohead,ehead);
break;
case 15: /* hx */
o_hx=1;
break;
case 16: /* hy */
nread(&o_hy);
break;
case 17: /* ig */
o_ig=1;
break;
case 18: /* in */
writebreak();
snset(&o_in);
o_ix = -1;
break;
case 19: /* ix */
snset(&o_ix);
if (!n_outwords) o_in=o_ix;
break;
case 20: /* li */
nread(&o_li);
break;
case 21: /* ll */
snset(&o_ll);
break;
case 22: /* ls */
snset(&o_ls);
break;
case 23: /* m1 */
nread(&o_m1);
break;
case 24: /* m2 */
nread(&o_m2);
break;
case 25: /* m3 */
nread(&o_m3);
break;
case 26: /* m4 */
nread(&o_m4);
break;
case 27: /* n1 */
o_n1=1;
break;
case 28: /* n2 */
nread(&o_n2);
break;
case 29: /* na */
o_ad=0;
writebreak();
break;
case 30: /* ne */
nread(&r);
if (line_no+(r-1)*o_ls+1 > TXTLEN) {
writebreak();
endpage();
beginpage();
}
break;
case 31: /* nf */
o_fi=0;
writebreak();
break;
case 32: /* ni */
snset(&o_ni);
break;
case 33: /* nn */
snset(&o_nn);
break;
case 34: /* nx */
do_nx();
c='\n'; /* SO WE DON'T FLUSH THE FIRST LINE */
break;
case 35: /* of */
c=tread(ofoot);
break;
case 36: /* oh */
c=tread(ohead);
break;
case 38: /* pl */
snset(&o_pl);
break;
case 39: /* po */
snset(&o_po);
break;
case 40: /* ro */
o_ro=1;
break;
case 41: /* sk */
nread(&o_sk);
break;
case 42: /* sp */
nread(&o_sp);
writebreak();
break;
case 43: /* ss */
writebreak();
o_ls=1;
break;
case 44: /* ta */
do_ta();
break;
case 45: /* tc */
c=cread(&o_tc);
break;
case 46: /* ti */
writebreak();
c=snread(&r,&s,0);
if (s>0) o_ti=o_in+r;
else if (s<0) o_ti=o_in-r;
else o_ti=r;
break;
case 47: /* tr */
do_tr();
break;
case 48: /* ul */
nread(&o_ul);
infont |= o_ul? UNDERL:0;
break;
case 49: /* bo */
nread(&o_bo);
infont |= o_bo? BOLD:0;
break;
case 50: /* it */
nread(&o_it);
infont |= o_it? ITALIC:0;
break;
}
reqflsh:
while (c!=EOF && c!='\n') c=suck();
return c!=EOF;
}
snset(par)
int *par;
{
int r, s;
c=snread(&r,&s,0);
if (s>0) *par+=r;
else if (s<0) *par-=r;
else *par=r;
}
tread(s)
char *s;
{
int leadbl;
leadbl=0;
for (;;) {
c=suck();
if (c==' ' && !leadbl) continue;
if (c==EOF || c=='\n') {
*s = '\0';
return c;
}
*s++ = c;
leadbl++;
}
}
nread(i)
int *i;
{
int f;
f=0;
*i=0;
if (!skipsp()) for (;;) {
c=suck();
if (c==EOF) break;
if (isspace(c)) break;
if (isdigit(c)) {
f++;
*i = *i*10 + c - '0';
}
else break;
}
if (!f) *i=1;
}
int
snread(i,s,sdef)
int *i, *s, sdef;
{
int f;
f = *i = *s = 0;
for (;;) {
c=suck();
if (c==EOF || c=='\n') break;
if (isspace(c)) {
if (f) break;
else continue;
}
if (isdigit(c)) {
f++;
*i = *i*10 + c - '0';
}
else if ((c=='+' || c=='-') && !f) {
f++;
*s = c=='+' ? 1 : -1;
}
else break;
}
while (c!=EOF && c!='\n') c=suck();
if (!f) {
*i=1;
*s=sdef;
}
return c;
}
int
cread(k)
int *k;
{
int u;
*k = -1;
for (;;) {
u=suck();
if (u==EOF || u=='\n') return u;
if (isspace(u)) continue;
if (*k < 0) *k=u;
}
}
defmac()
{
int i;
char newmac[3], *nm;
if (skipsp()) return;
nm=newmac;
if (!Macwrite) openwrite();
*nm++ = suck();
c=suck();
if (c!=EOF && c!='\n' && c!=' ' && c!='\t') *nm++ = c;
*nm = '\0';
/* KILL OLD DEFINITION IF ANY */
for (i=0; i<n_macros; i++) if (!strcmp(newmac,macro[i].mname)) {
macro[i].mname[0]='\0';
break;
}
if ((macro[n_macros].moff=ftell(Macwrite)) == -1) {
fprintf(stderr,"PCroff: positioning error in macwrite\n");
exit(1);
}
strcpy(macro[n_macros++].mname,newmac);
while (c!=EOF && c!='\n') c=suck(); /* FLUSH HEADER LINE */
while (copyline());
}
openwrite() /* OPEN MACWRITE.TMP FOR WRITING */
{
if (Macread) {
fclose (Macread);
Macread=0;
}
if (NULL==(Macwrite=fopen("MACWRITE.TMP","a"))) {
fprintf(stderr,"PCroff: cannot open temp file\n");
exit(1);
}
}
openread() /* OPEN MACWRITE.TMP FOR READING */
{
if (Macwrite) {
fclose (Macwrite);
Macwrite=0;
}
if (NULL==(Macread=fopen("MACWRITE.TMP","r"))) {
fprintf(stderr,"PCroff: cannot read-open temp file\n");
exit(1);
}
}
openmac()
{
if (NULL==(Macwrite=fopen("MACWRITE.TMP","w"))) {
fprintf(stderr,"PCroff: cannot open temp file\n");
exit(1);
}
if (NULL==(Macread=fopen("MACWRITE.TMP","r"))) {
fprintf(stderr,"PCroff: cannot read-open temp file\n");
exit(1);
}
}
/* COPY A LINE FROM INPUT TO MACRO FILE.
* RETURN 0 IF END OF MACRO (..), 1 OTHERWISE
*/
int
copyline()
{
int n, first, second;
if (c==EOF) {
fprintf(Macwrite,"..\n");
return 0;
}
n=0;
first=1;
second=0;
for (;;) {
c=suck();
if (c==EOF) {
if (!first) putc('\n',Macwrite);
return 0;
}
if (c=='\n') {
putc('\n',Macwrite);
return n!=2;
}
if (first && c=='.') n++;
else if (second && n==1 && c=='.') n++;
putc(c,Macwrite);
second=first;
first=0;
}
}
/* MACRO HAS BEEN CALLED. SHIFT INPUT TO MACRO FILE
* AND POSITION AT CALLED MACRO.
*/
submac(r)
int r;
{
while (c!=EOF && c!='\n') c=suck();
if (depth) teller[depth-1]=ftell(Macread); /* ALREADY IN
MACRO FILE. PUSH CURRENT MACRO */
else {
if (!Macread) openread();
Save = File;
File = Macread;
}
depth++;
if (-1 == (fseek(Macread,macro[r].moff,0))) {
fprintf(stderr,"PCroff: error seeking macro %s\n",
macro[r].mname);
exit(1);
}
}
endmac() /* FINISHED USE OF MACRO */
{
depth--;
if (depth) fseek(Macread,teller[depth-1],0);
else File = Save;
c='\n';
}
do_ta()
{
int v;
n_ta = 0;
for (;;) {
nread(&v);
if (v==1) return;
else o_ta[n_ta++]=v;
if (c=='\n' || c==EOF) break;
}
}
do_tr()
{
char *t;
t = &o_tr[0][0];
*t='\0';
if (skipsp()) return;
for (;;) {
c=suck();
if (c==EOF || c=='\n') break;;
*t++ = c;
}
*t = '\0';
}
do_nx()
{
char fname[100], *f;
f=fname;
if (skipsp()) return;
for (;;) switch(c=suck()) {
case EOF:
case '\n':
case ' ':
case '\t':
if (f==fname) return;
goto got_nx;
default:
*f++ = c;
}
got_nx:
fclose(File);
*f = '\0';
if (!(File=fopen(fname,"r"))) {
fprintf(stderr,"PCroff: cannot read %s\n",fname);
exit(1);
}
}
int
skipsp()
{
for (;;) switch(c=suck()) {
case EOF:
case '\n':
return 1;
case ' ':
case '\t':
continue;
default:
ungetc(c,File);
return 0;
}
}
writebreak()
{
int q;
if (assylen) writeline(0,1);
q = TXTLEN;
if (o_bl) {
if (o_bl + line_no > q) {
endpage();
beginpage();
}
for (; o_bl; o_bl--) blankline();
}
else if (o_sp) {
if (o_sp + line_no > q) newpage();
else if (line_no) for (; o_sp; o_sp--) blankline();
}
}
blankline()
{
if (line_no >= TXTLEN) newpage();
if (o_n2) o_n2++;
spit('\n');
line_no++;
}
writeline(adflag,flushflag)
int adflag, flushflag;
{
int j, q;
char lnstring[7];
for (j=assylen-1; j; j--) {
if (assyline[j]==' ') assylen--;
else break;
}
q = TXTLEN;
if (line_no >= q) newpage();
for (j=0; j<o_po; j++) spit(' ');
if (o_n1) {
if (o_nn) for (j=0; j<o_ni+4; j++) spit(' ');
else {
for (j=0; j<o_ni; j++) spit(' ');
sprintf(lnstring,"%3d ",line_no+1);
spits(lnstring);
}
}
if (o_n2) {
if (o_nn) for (j=0; j<o_ni+4; j++) spit(' ');
else {
for (j=0; j<o_ni; j++) spit(' ');
sprintf(lnstring,"%3d ",o_n2++);
spits(lnstring);
}
}
if (o_nn) o_nn--;
if (center) for (j=0; j<(o_ll-assylen+1)/2; j++) spit(' ');
else for (j=0; j<IDTLEN; j++) spit(' ');
if (adflag && !flushflag) fillline();
for (j=0; j<assylen; j++) {
outfont = assyfont[j];
assyfont[j] = 0; /* CLEAR FONT FLAG */
spit(assyline[j]);
}
spit('\n');
assylen=0;
assyline[0]='\0';
line_no++;
for (j=1; j<o_ls; j++) if (line_no <= q) blankline();
if (!flushflag) {
if (o_hc) dehyph(holdword);
strcpy(assyline,holdword);
assylen=strlen(holdword);
for (j=0; j <= assylen; j++) assyfont[j]=infont;
*holdword='\0';
holdp=holdword;
}
if (o_ix>=0) o_in=o_ix;
o_ix = o_ti = -1;
}
fillline()
{
int excess, j, s, inc, spaces;
adjtoggle^=1;
if (!(excess = o_ll - IDTLEN - assylen)) return;
if (excess < 0) {
fprintf(stderr,"PCroff: internal error #2 [%d]\n",excess);
exit(1);
}
for (j=2;; j++) {
if (adjtoggle) {
s=0;
inc = 1;
}
else {
s=assylen-1;
inc = -1;
}
spaces=0;
while (s>=0 && s<assylen) {
if (assyline[s]==' ') spaces++;
else {
if (0<spaces && spaces<j) {
insrt(s-inc);
if (inc>0) s++;
if (!--excess) return;
}
spaces=0;
}
s+=inc;
}
}
}
insrt(p)
int p;
{
int i;
for (i=assylen; i>p; i--) {
assyline[i]=assyline[i-1];
assyfont[i]=assyfont[i-1];
}
assylen++;
}
newpage()
{
if (page_no >= 0) endpage();
else page_no=1;
for (; o_sk; o_sk--) blankpage();
beginpage();
}
beginpage()
{
int i;
if (sflag) waitawhile();
for (i=0; i<o_m1; i++) spit('\n');
writetitle(page_no&1? ohead: ehead);
for (i=0; i<o_m2; i++) spit('\n');
line_no=0;
}
endpage()
{
int i;
for (i=line_no; i<TXTLEN; i++) blankline();
for (i=0; i<o_m3; i++) spit('\n');
writetitle(page_no&1? ofoot: efoot);
for (i=0; i<o_m4; i++) spit('\n');
if (o_bp < 0) page_no++;
else {
page_no = o_bp;
o_bp = -1;
}
}
blankpage()
{
int i;
if (sflag) waitawhile();
for (i=0; i<o_m1; i++) spit('\n');
writetitle(page_no&1? ohead: ehead);
for (i=0; i<o_m2; i++) spit('\n');
for (i=0; i<TXTLEN; i++) spit('\n');
for (i=0; i<o_m3; i++) spit('\n');
writetitle(page_no&1? ofoot: efoot);
page_no++;
for (i=0; i<o_m4; i++) spit('\n');
line_no=0;
}
writetitle(t)
char *t;
{
char d, *pst, *dst, *pgform(), *dtform();
int j, l, m, n;
int pln,dln;
d = *t;
if (o_hx || !d) {
spit('\n');
return;
}
pst=pgform(); /* FORM PAGE NUMBER STRING */
dst=dtform(); /* FORM DATE STRING */
pln=strlen(pst);
dln=strlen(dst);
for (j=0; j<o_po; j++) spit(' ');
l=titlen(++t,d,pln,dln);
while (*t && *t!=d) {
if (*t=='%') spits(pst);
else if (*t=='$') spits(dst);
else spit(*t);
t++;
}
if (!*t) {
spit('\n');
return;
}
m=titlen(++t,d,pln,dln);
for (j=l; j<(o_ll-m)/2; j++) spit(' ');
while (*t && *t!=d) {
if (*t=='%') spits(pst);
else if (*t=='$') spits(dst);
else spit(*t);
t++;
}
if (!*t) {
spit('\n');
return;
}
if ((o_ll-m)/2 > l) m+=(o_ll-m)/2;
else m+=l;
n=titlen(++t,d,pln,dln);
for (j=m; j<o_ll-n; j++) spit(' ');
while (*t && *t!=d) {
if (*t=='%') spits(pst);
else if (*t=='$') spits(dst);
else spit(*t);
t++;
}
spit('\n');
}
char *
pgform()
{
static char pst[11];
int i;
if (o_ro) {
*pst='\0';
i=page_no;
if (i>=400) {
strcat(pst,"cd");
i-=400;
}
while (i>=100) {
strcat(pst,"c");
i-=100;
}
if (i>=90) {
strcat(pst,"xc");
i-=90;
}
if (i>=50) {
strcat(pst,"l");
i-=50;
}
if (i>=40) {
strcat(pst,"xl");
i-=40;
}
while (i>=10) {
strcat(pst,"x");
i-=10;
}
if (i>=9) {
strcat(pst,"ix");
i-=9;
}
if (i>=5) {
strcat(pst,"v");
i-=5;
}
if (i>=4) {
strcat(pst,"iv");
i-=4;
}
while (i--) strcat(pst,"i");
}
else sprintf(pst,"%d",page_no);
return pst;
}
/*
dtform()
USES deSMET C DATE FUNCTION. SEE deSMET-SPECIFIC FILE.
*/
int
titlen(t,c,p_len,d_len)
char *t, c;
int p_len,d_len;
{
int q;
q=0;
while (*t && *t!=c) switch (*t++) {
case '%':
q += p_len;
break;
case '$':
q += d_len;
break;
default:
q++;
break;
}
return q;
}
spits(s)
char *s;
{
while (*s) spit(*s++);
}
spit(c)
char c;
{
static int col_no, n_blanks;
char *t;
for (t = (char *)o_tr; *t; t++) if (*t++==c) {
c = *t;
break;
}
if (page_no < startpage || (stoppage && page_no > stoppage)) return;
if (c != ' ' && c != '\n' && n_blanks) {
if (hflag && n_blanks>1)
while (col_no/8 < (col_no+n_blanks)/8) {
putc('\t',stdout);
n_blanks-= 8 - (col_no & 07);
col_no = 8 + col_no & ~07;
}
for (; n_blanks; n_blanks--) {
putc(' ',stdout);
col_no++;
}
}
if (!isalnum(c)) outfont &= ~UNDERL;
/* DON'T UNDERLINE WHITE SPACE */
if (outfont != oldfont) { /* CHANGE FONTS */
if (o_dev == 1) { /* PRINTER */
if ((oldfont & UNDERL) && !(outfont & UNDERL))
putfont(e_ul);
if (!(oldfont & UNDERL) && (outfont & UNDERL))
putfont(s_ul);
if ((oldfont & BOLD) && !(outfont & BOLD))
putfont(e_bo);
if (!(oldfont & BOLD) && (outfont & BOLD))
putfont(s_bo);
if ((oldfont & ITALIC) && !(outfont & ITALIC))
putfont(e_it);
if (!(oldfont & ITALIC) && (outfont & ITALIC))
putfont(s_it);
}
oldfont = outfont;
}
if (c == ' ') n_blanks++;
else {
if ((c>='!' && c<='~') || (c>='\240')) switch (o_dev) {
case 0: /* DISPLAY SCREEN */
putscrn (c,outfont);
col_no++;
break;
case 1: /* PRINTER, ALREADY DONE WITH FONT CONTROL */
putc (c,stdout);
col_no++;
break;
case 2: /* DUMB TTY-TYPE PRINTER USES OVERSTRIKE */
if (outfont & UNDERL) fputs("_\b",stdout);
if (outfont & BOLD) {
putc(c,stdout); putc('\b',stdout);
putc(c,stdout); putc('\b',stdout);
}
if (outfont & ITALIC) fputs("_\b",stdout);
putc (c,stdout);
col_no++;
break;
}
}
if (c == '\n') {
putc ('\n',stdout);
col_no = 0;
n_blanks = 0;
}
}
int
suck()
{
for (;;) {
c=getc(File);
if (islegal(c)) return c;
}
}
/*
* strhas - does string have character?
* USG and BSD both have this in their libraries. Now, if
* they could just agree on the name of the function ...
*/
char *
strhas(p,c)
char *p, c;
{
for (; *p; p++) if (*p==c) return p;
return NULL;
}
/*
* strend - find NULL at end of string.
*/
char *
strend(p)
char *p;
{
while (*p++);
return p;
}
/*
* isspace, isalnum, isdigit, islegal - classify a character.
* We could just as well use <ctype.h> if it didn't vary from
* one version of Unix to another. As it is, these routines
* must be modified for weird character sets, like EBCDIC and
* CDC Scientific.
*/
int
isspace(c)
int c;
{
char *s;
for (s=spacechars; *s; s++) if (*s==c) return 1;
return 0;
}
int
isalnum(c)
int c;
{
return (c>='A'&&c<='Z') || (c>='a'&&c<='z') || (c>='0'&&c<='9');
}
int
isdigit(c)
int c;
{
return c>='0' && c<='9';
}
int
islegal(c)
int c;
{
return c>=' ' && c<='~' || isspace(c) || c=='\n' || c==EOF;
}
bomb()
{
fprintf(stderr,"usage: PCroff [+00] [-00] ");
fprintf(stderr,"[-s][-h][-d][-t][-pPRINTER] file ...\n");
exit(1);
}
putfont (s) /* SO WE CAN HAVE NUL IN A FONT CONTROL STRING */
struct fontstring *s;
{
int i;
for (i=0; i<s.len; i++)
putc (s.seq[i], stdout);
}