home *** CD-ROM | disk | FTP | other *** search
- 2-Jul-85 15:52:11-MDT,21576;000000000001
- Return-Path: <unix-sources-request@BRL.ARPA>
- Received: from BRL-TGR.ARPA by SIMTEL20.ARPA with TCP; Tue 2 Jul 85 15:51:06-MDT
- Received: from usenet by TGR.BRL.ARPA id a023513; 2 Jul 85 6:49 EDT
- From: "Col. G. L. Sicherman" <colonel@gloria.uucp>
- Newsgroups: net.sources
- Subject: roff.c - complete with fixes
- Message-ID: <890@gloria.UUCP>
- Date: 1 Jul 85 15:03:52 GMT
- To: unix-sources@BRL-TGR.ARPA
-
- Here as promised: the up-to-date version of roff.c. If you need the
- manual page, I'll mail it rather than post it. Thanks to those who
- sent fixes!
-
- It still doesn't hyphenate except on demand.
- -----
- /*
- * roff - C version.
- * the Colonel. 19 May 1983.
- *
- * fix by Tim Maroney, 31 Dec 1984.
- * .hc implemented, 8 Feb 1985.
- * fix to hyphenating with underlining, 12 Feb 1985.
- * fixes to long-line hang and .bp by Dave Tutelman, 30 Mar 1985.
- */
-
- #include <sgtty.h>
- #include <signal.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #define SUFTAB "/usr/lib/suftab"
- #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 '\200'
-
- char spacechars[] = " \t\n";
- int sflag, hflag, startpage, stoppage;
- char holdword[MAXLENGTH], *holdp;
- char assyline[MAXLENGTH];
- int assylen;
- 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, o_ul = 0;
- 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 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",0};
- char *mktemp(), *mfilnam = "/tmp/rtmXXXXXX";
- int c; /* LAST CHAR READ */
- struct sgttyb tty;
-
- 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;
- default:
- bomb();
- }
- break;
- default:
- argc++;
- goto endargs;
- }
- endargs:
- if (sflag) gtty(0,&tty);
- mesg(0); /* BLOCK OUT MESSAGES */
- assylen=0;
- assyline[0]='\0';
- if (!argc) {
- File=stdin;
- readfile();
- }
- else while (--argc) {
- File=fopen(*argv,"r");
- if (NULL==File) {
- fprintf(stderr,"roff: cannot read %s\n",*argv);
- exit(1);
- }
- readfile();
- fclose(File);
- argv++;
- }
- writebreak();
- endpage();
- for (; o_sk; o_sk--) blankpage();
- mesg(1); /* ALLOW MESSAGES */
- }
-
- mesg(f)
- int f;
- {
- static int mode;
- struct stat cbuf;
- char *ttyname();
-
- if (!isatty(1)) return;
- if (!f) {
- fstat(1,&cbuf);
- mode = cbuf.st_mode;
- chmod(ttyname(1),mode & ~022);
- }
- else chmod(ttyname(1),mode);
- }
-
- 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 ' ':
- 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) assyline[assylen++]=' ';
- doingword=0;
- if (c=='\n') break;
- }
- if (!isspace(c)) {
- if (doingword) *holdp++ = o_ul? c|UNDERL: c;
- else if (startline && c==o_cc && !o_li) {
- isrequest=1;
- return readreq();
- }
- else {
- doingword=1;
- holdp=holdword;
- *holdp++ = o_ul? c|UNDERL: c;
- }
- }
- startline=0;
- c = suck();
- }
- out:
- if (o_ul) o_ul--;
- 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;
- *holdp = '\0';
- /*
- * Tutelman's fix #1.
- */
- 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&~UNDERL)!=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,"-");
- 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);
- assylen+=strlen(holdword);
- holdp = holdword;
- }
-
- /*
- * dehyph - remove hyphenation marks.
- */
-
- dehyph(s)
- char *s;
- {
- char *t;
- for (t=s; *s; s++) if ((*s&~UNDERL) != 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 != (~UNDERL & *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;
- return;
- }
- /* NO TAB STOPS REMAIN */
- 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=='.') {
- o_ig = 0;
- do (c=suck());
- while (c!=EOF && c!='\n');
- if (depth) endmac();
- return c!=EOF;
- }
- if (o_ig) {
- while (c!=EOF && c!='\n') c=suck();
- return c!=EOF;
- }
- 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);
- 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);
- /*
- * Tutelman's fix #2 - the signs were reversed!
- */
- 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);
- 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) openmac();
- *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;
- }
- macro[n_macros].moff=ftell(Macwrite);
- strcpy(macro[n_macros++].mname,newmac);
- while (c!=EOF && c!='\n') c=suck(); /* FLUSH HEADER LINE */
- while (copyline());
- fflush(Macwrite);
- }
-
- openmac()
- {
- if (NULL==(Macwrite=fopen(mktemp(mfilnam),"w"))) {
- fprintf(stderr,"roff: cannot open temp file\n");
- exit(1);
- }
- Macread=fopen(mfilnam,"r");
- unlink(mfilnam);
- }
-
- 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;
- }
- }
-
- submac(r)
- int r;
- {
- while (c!=EOF && c!='\n') c=suck();
- if (depth) teller[depth-1]=ftell(Macread);
- else {
- Save = File;
- File = Macread;
- }
- depth++;
- fseek(Macread,macro[r].moff,0);
- }
-
- endmac()
- {
- 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,"roff: 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++) 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);
- *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,"roff: 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];
- 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;
- }
-
- waitawhile()
- {
- int nix(), oldflags;
- if (isatty(0)) {
- oldflags=tty.sg_flags;
- tty.sg_flags &= ~ECHO; /* DON'T ECHO THE RUBOUT */
- stty(0,&tty);
- }
- signal(SIGINT,nix);
- pause();
- if (isatty(0)) {
- tty.sg_flags = oldflags;
- stty(0,&tty);
- }
- }
-
- nix()
- {}
-
- writetitle(t)
- char *t;
- {
- char d, *pst, *pgform();
- int j, l, m, n;
- d = *t;
- if (o_hx || !d) {
- spit('\n');
- return;
- }
- pst=pgform();
- for (j=0; j<o_po; j++) spit(' ');
- l=titlen(++t,d,strlen(pst));
- while (*t && *t!=d) {
- if (*t=='%') spits(pst);
- else spit(*t);
- t++;
- }
- if (!*t) {
- spit('\n');
- return;
- }
- m=titlen(++t,d,strlen(pst));
- for (j=l; j<(o_ll-m)/2; j++) spit(' ');
- while (*t && *t!=d) {
- if (*t=='%') spits(pst);
- 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,strlen(pst));
- for (j=m; j<o_ll-n; j++) spit(' ');
- while (*t && *t!=d) {
- if (*t=='%') spits(pst);
- 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;
- }
-
- int
- titlen(t,c,k)
- char *t, c;
- int k;
- {
- int q;
- q=0;
- while (*t && *t!=c) q += *t++ == '%' ? k : 1;
- return q;
- }
-
- spits(s)
- char *s;
- {
- while (*s) spit(*s++);
- }
-
- spit(c)
- char c;
- {
- static int col_no, n_blanks;
- int ulflag;
- char *t;
- ulflag=c&UNDERL;
- c&=~UNDERL;
- for (t = (char *)o_tr; *t; t++) if (*t++==c) {
- /*
- * fix - last char translates to space.
- */
- c = *t? *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 (ulflag && isalnum(c)) fputs("_\b",stdout);
- if (c == ' ') n_blanks++;
- else {
- putc(c,stdout);
- col_no++;
- }
- if (c == '\n') {
- col_no=0;
- n_blanks=0;
- }
- }
-
- int
- suck()
- {
- for (;;) {
- c=getc(File);
- if (islegal(c)) return c;
- }
- }
-
- /*
- * strhas - does string have character? Allow UNDERL flag.
- */
-
- char *
- strhas(p,c)
- char *p, c;
- {
- for (; *p; p++) if ((*p&~UNDERL)==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: roff [+00] [-00] [-s] [-h] file ...\n");
- exit(1);
- }
- --
- Col. G. L. Sicherman
- ...{rocksvax|decvax}!sunybcs!colonel
-