Path: utzoo!utgpu!water!watmath!clyde!rutgers!husc6!bu-cs!madd From: madd@bu-cs.BU.EDU (Jim Frost) Newsgroups: comp.sys.ibm.pc Subject: proff (roff like text formatter) part 2 of 3 Message-ID: <19780@bu-cs.BU.EDU> Date: 8 Feb 88 21:21:34 GMT Reply-To: madd@.UUCP (Jim Frost) Organization: Boston University Distributed Systems Group Lines: 2909 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh pinit.c <<'END_OF_pinit.c' X X X X X#include X#include X#include "proff.h" X#include "debug.h" X X/* X * finit - initialise parameters, set default values X * used by .reset command X * X */ Xfinit() X{ X int i; X X inval = 0; X rmval = PAGEWIDTH; X tival = 0; X lsval = 1; X fill = YES; X ceval = 0; X ulval = 0; X boval = 0; X cchar = '.'; X genesc = '_'; X tjust[0] = LEFT; X tjust[1] = CENTER; X tjust[2] = RIGHT; X bsval = 0; X rjust = YES; X ulblnk = BLANK; X X for (i = 0; i < INSIZE; i++) X if (i % 8 == 0) X tabs[i] = YES; X else X tabs[i] = NO; X X lineno = 0; X curpag = 0; X newpag = 1; X plval = PAGELEN; X m1val = 3; X m2val = 2; X m3val = 2; X m4val = 3; X bottom = plval - m3val - m4val; X ehead[0] = '\n'; X ehead[1] = EOS; X ohead[0] = '\n'; X ohead[1] = EOS; X efoot[0] = '\n'; X efoot[1] = EOS; X ofoot[0] = '\n'; X ofoot[1] = EOS; X ehlim[0] = inval; X ehlim[1] = rmval; X ohlim[0] = inval; X ohlim[1] = rmval; X eflim[0] = inval; X eflim[1] = rmval; X oflim[0] = inval; X oflim[1] = rmval; X verbose = NO; X stopx = 0; X frstpg = 0; X lastpg = HUGE; X print = YES; X offset = 0; X outp = 0; X outw = 0; X outwds = 0; X bp = -1; X for (i = 0; i < 26; i++) X nr[i] = 0; X X CEon = FALSE; X ULon = FALSE; X BDon = FALSE; X X onlyrunoff = FALSE; X roman = FALSE; X bolding = YES; X autopar = NO; X} X END_OF_pinit.c if test 1236 -ne `wc -c proff.c <<'END_OF_proff.c' X X X Xchar *version = "v.1.1"; X X#include X#include X#include "debug.h" X#include "defs.h" X#include "lookup.h" X X X/* X * G L O B A L S X * X */ X#ifndef vms X#define globaldef X#endif X X /* next available char; init = 0 */ Xglobaldef int bp = -1; X /* pushed-back characters */ Xglobaldef char buf[BUFSIZE]; X /* stack of file descriptors */ Xglobaldef FILE *infile[NFILES]; X /* current file is infile[level] */ Xglobaldef int level; X /* stack of output file descriptors */ Xglobaldef FILE *outfile[NFILES]; X /* current output is outfile[olevel]; */ Xglobaldef int olevel; X /* current output file pointer */ Xglobaldef FILE *poutput; X /* number registers a..z */ Xglobaldef int nr[26] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; X /* system registers a..z */ Xglobaldef int sr[26] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; X /* last char position in outbuf; init = 0 */ Xglobaldef int outp = 0; X /* width of text currently in outbuf; init = 0 */ Xglobaldef int outw = 0; X /* number of words in outbuf; init = 0 */ Xglobaldef int outwds = 0; X /* lines to be filled collect here */ Xglobaldef char outbuf[MAXOUT]; X /* word in outbuf; init=0 */ X /* current output page number; init = 0 */ Xglobaldef int curpag = 0; X /* next output page number; init = 1 */ Xglobaldef int newpag = 1; X /* next line to be printed; init = 0 */ Xglobaldef int lineno = 0; X /* page length in lines; init = PAGELEN = 66 */ Xglobaldef int plval = PAGELEN; X /* page length save area */ Xglobaldef int savpl = PAGELEN; X /* margin before and including header */ Xglobaldef int m1val = 3; X /* margin after header */ Xglobaldef int m2val = 2; X /* margin after last text line */ Xglobaldef int m3val = 2; X /* bottom margin, including footer */ Xglobaldef int m4val = 3; X /* last live line on page, = plval-m3val-m4val */ Xglobaldef int bottom = PAGELEN - 5; X /* top of page title for even pages;init=NEWLINE */ Xglobaldef char ehead[MAXLINE]; X /* top of page title for odd pages;init=NEWLINE */ Xglobaldef char ohead[MAXLINE]; X /* left,right margins for even header;init=inval,rmval */ Xglobaldef int ehlim[2] = { 0, PAGEWIDTH }; X /* left,right margins for odd header;init=inval,rmval */ Xglobaldef int ohlim[2] = { 0, PAGEWIDTH }; X /* bot of page title for even pages;init=NEWLINE */ Xglobaldef char efoot[MAXLINE]; X /* bot of page title for odd pages;init=NEWLINE */ Xglobaldef char ofoot[MAXLINE]; X /* left,right margins for even footer;init=inval,rmval */ Xglobaldef int eflim[2] = { 0, PAGEWIDTH }; X /* left,right margins for odd footer;init=inval,rmval */ Xglobaldef int oflim[2] = { 0, PAGEWIDTH }; X /* flag for pausing between pages */ Xglobaldef int stopx = 0; X /* first page to begin printing with */ Xglobaldef int frstpg = 0; X /* last page to be printed */ Xglobaldef int lastpg = HUGE; X /* flag to indicate whether page should be printed */ Xglobaldef int print = YES; X /* number of blanks to offset page by; init = 0 */ Xglobaldef int offset = 0; X /* verbose option; init = NO */ Xglobaldef int verbose = NO; X /* bolding option; init = YES; */ Xglobaldef char bolding = YES; X /* fill if YES; init = YES */ Xglobaldef int fill = YES; X /* current line spacing; init = 1 */ Xglobaldef int lsval = 1; X /* current indent; >= 0; init = 0 */ Xglobaldef int inval = 0; X /* current right margin; init = PAGEWIDTH = 60 */ Xglobaldef int rmval = PAGEWIDTH; X /* current temporary indent; init = 0 */ Xglobaldef int tival = 0; X /* number of lines to center; init = 0 */ Xglobaldef int ceval = 0; X /* flag for continuous center */ Xglobaldef char CEon = FALSE; X /* number of lines to underline; init = 0 */ Xglobaldef int ulval = 0; X /* flag for continuous underline */ Xglobaldef char ULon = FALSE; X /* number of lines to boldface; init = 0 */ Xglobaldef int boval = 0; X /* flag for continuous bolding */ Xglobaldef char BDon = FALSE; X /* justification types for heads and foots; */ X /* init = LEFT, CENTER, RIGHT */ Xglobaldef int tjust[3] = { LEFT, CENTER, RIGHT }; X /* number of lines to blank suppress; init=0 */ Xglobaldef int bsval = 0; X /* right justify filled lines if YES; init=YES */ Xglobaldef int rjust = YES; X /* tab stops; init every 8 spaces */ Xglobaldef int tabs[INSIZE]; X /* line control character; init = PERIOD */ Xglobaldef char cchar = '.'; X /* universal escape - init = UNDERBAR */ Xglobaldef char genesc = '_'; X /* character used to underline a BLANK; init = BLANK */ Xglobaldef char ulblnk = ' '; X /* scratch arrays for use by various routines */ Xglobaldef char tbuf1[MAXLINE]; Xglobaldef char tbuf2[MAXLINE]; Xglobaldef char tbuf3[MAXLINE]; Xglobaldef char ttl[MAXLINE]; X /* flag to process runoff symbols only */ Xglobaldef char onlyrunoff = NO; X /* Flag to turn paging off */ Xglobaldef char paging = YES; X /* page number in roman numerals. Init = NO */ Xglobaldef char roman = NO; X /* autopar flag. Init = NO */ Xglobaldef char autopar = NO; X /* temporary indent value for autopar */ Xglobaldef int autoprv = 5; X /* hash tables for macros and variables */ Xglobaldef struct hashlist *macrotab[HASHMAX]; Xglobaldef struct hashlist *gentab[HASHMAX]; X /* linked list entries for contents */ Xglobaldef struct clist *chead = NULL; Xglobaldef struct clist *clast = NULL; X /* keep track of what is done - VERBOSE */ Xglobaldef int p_txtlines = 0; Xglobaldef int p_outlines = 0; Xglobaldef int p_outpages = 0; Xglobaldef int p_memoryus = 0; X X X X/* X * M A I N L I N E OF P R O F F X * X */ X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X int i,j,val,type; X char *p,c; X FILE *fp; X X for (i = 1; i < argc; i++) { X p = argv[i]; X if (*p == '-') { X ++p; X if (isalpha(*p)) { X c = *p++; X switch(c) { X X/* verbose stats */ case 'v': X case 'V': X verbose = TRUE; X break; X/* runoff only */ case 'r': X case 'R': X onlyrunoff = TRUE; X break; X/* stop for page */ case 's': X case 'S': X stopx = 1; X break; X/* page offset */ case 'p': X case 'P': X if (*p == 'o' || *p == 'O') { X p++; X j = 0; X val = getval(p, &j, &type); X set(&offset, val, type, 0, 0, X rmval - 1); X } X else X usage(); X break; X/* include file */ case 'i': X case 'I': /* simulate .so */ X pbstr("\n"); X pbstr(p); X pbstr(".so "); X break; X X/* disable some */ case 'd': X case 'D': X switch (*p) { X X case 'b': X case 'B': X bolding = NO; X break; X case 'p': X case 'P': X paging = NO; X break; X default: X break; X } X break; X X/* garbage */ default: X usage(); X } X } X else X lastpg = atoi(p); X } X else if (*p == '+') { X p++; X if ((frstpg = atoi(p)) == 0) X usage(); X } X else X break; X } X if (i == argc) X usage(); X if ((fp = fopen(argv[i], "r")) == NULL) { X fprintf(stderr, "%s: cannot open.\n",argv[i]); X exit(1); X } X if (p = argv[++i]) { X if ((outfile[0] = fopen(p, "w")) == NULL) { X fprintf(stderr,"%s: cannot create.\n\n", p); X exit(1); X } X } X else X outfile[0] = stdout; X /* set output file level */ X olevel = 0; X poutput = outfile[0]; X /* X * some minor initialisation X */ X X for (i = 0; i < INSIZE; i++) X if (i % 8 == 0) X tabs[i] = YES; X else X tabs[i] = NO; X X ehead[0] = '\n'; X ehead[1] = EOS; X ohead[0] = '\n'; X ohead[1] = EOS; X efoot[0] = '\n'; X efoot[1] = EOS; X ofoot[0] = '\n'; X ofoot[1] = EOS; X X /* initialise contents linked list */ X X chead = (struct clist *) malloc(sizeof(struct clist)); X clast = chead; X p_memoryus += sizeof(struct clist); X X doroff(fp); X lbrk(); X if (plval <= 100 && (lineno > 0 | outp > 0)) X space(HUGE); X putchar('\n'); X X if(verbose) { X fprintf(stderr,"proff read in %6d textlines to produce\n", X p_txtlines); X fprintf(stderr," %6d lines\n", X p_outlines); X fprintf(stderr," %6d pages of formatted text.\n", X p_outpages); X fprintf(stderr,"\n%d bytes of memory was required\n", X p_memoryus); X fprintf(stderr,"for internal tables and lists.\n"); X } X#ifdef vms X exit(1); X#else X exit(0); X#endif X} END_OF_proff.c if test 9151 -ne `wc -c proff.h <<'END_OF_proff.h' X X X#include "defs.h" X#include "lookup.h" X X#ifdef vms X#define extern globalref X#endif X /* next available char; init = 0 */ Xextern int bp; X /* pushed-back characters */ Xextern char buf[BUFSIZE]; X /* stack of file descriptors */ Xextern FILE *infile[NFILES]; X /* current file is infile[level] */ Xextern int level; X /* stack of output file descriptors */ Xextern FILE *outfile[NFILES]; X /* current output file is outfile[olevel] */ Xextern int olevel; X /* current output file pointer */ Xextern FILE *poutput; X /* number registers a..z */ Xextern int nr[26]; X /* system registers a..z */ Xextern int nr[26]; X /* last char position in outbuf; init = 0 */ Xextern int outp; X /* width of text currently in outbuf; init = 0 */ Xextern int outw; X /* number of words in outbuf; init = 0 */ Xextern int outwds; X /* lines to be filled collect here */ Xextern char outbuf[MAXOUT]; X /* word in outbuf; init=0 */ X /* current output page number; init = 0 */ Xextern int curpag; X /* next output page number; init = 1 */ Xextern int newpag; X /* next line to be printed; init = 0 */ Xextern int lineno; X /* page length in lines; init = PAGELEN = 66 */ Xextern int plval; X /* page length save area */ Xextern int savpl; X /* margin before and including header */ Xextern int m1val; X /* margin after header */ Xextern int m2val; X /* margin after last text line */ Xextern int m3val; X /* bottom margin, including footer */ Xextern int m4val; X /* last live line on page, = plval-m3val-m4val */ Xextern int bottom; X /* top of page title for even pages;init=NEWLINE */ Xextern char ehead[MAXLINE]; X /* top of page title for odd pages;init=NEWLINE */ Xextern char ohead[MAXLINE]; X /* left,right margins for even header;init=inval,rmval */ Xextern int ehlim[2]; X /* left,right margins for odd header;init=inval,rmval */ Xextern int ohlim[2]; X /* bot of page title for even pages;init=NEWLINE */ Xextern char efoot[MAXLINE]; X /* bot of page title for odd pages;init=NEWLINE */ Xextern char ofoot[MAXLINE]; X /* left,right margins for even footer;init=inval,rmval */ Xextern int eflim[2]; X /* left,right margins for odd footer;init=inval,rmval */ Xextern int oflim[2]; X /* flag for pausing between pages */ Xextern int stopx; X /* first page to begin printing with */ Xextern int frstpg; X /* last page to be printed */ Xextern int lastpg; X /* flag to indicate whether page should be printed */ Xextern int print; X /* number of blanks to offset page by; init = 0 */ Xextern int offset; X /* verbose option; init = FALSE */ Xextern int verbose; X /* bolding option; init = YES; */ Xextern char bolding; X /* fill if YES; init = YES */ Xextern int fill; X /* current line spacing; init = 1 */ Xextern int lsval; X /* current indent; >= 0; init = 0 */ Xextern int inval; X /* current right margin; init = PAGEWIDTH = 60 */ Xextern int rmval; X /* current temporary indent; init = 0 */ Xextern int tival; X /* number of lines to center; init = 0 */ Xextern int ceval; X /* flag for continuous center */ Xextern char CEon; X /* number of lines to underline; init = 0 */ Xextern int ulval; X /* flag for continuous underline */ Xextern char ULon; X /* number of lines to boldface; init = 0 */ Xextern int boval; X /* flag for continuous bolding */ Xextern char BDon; X /* justification types for heads and foots; */ Xextern int tjust[3]; /* init = LEFT, CENTER, RIGHT */ X /* number of lines to blank suppress; init=0 */ Xextern int bsval; X /* right justify filled lines if YES; init=YES */ Xextern int rjust; X /* tab stops; init every 8 spaces */ Xextern int tabs[INSIZE]; X /* line control character; init = PERIOD */ Xextern char cchar; X /* universal escape - init = UNDERBAR */ Xextern char genesc; X /* character used to underline a BLANK; init = BLANK */ Xextern char ulblnk; X /* scratch arrays for use by various routines */ Xextern char tbuf1[MAXLINE]; Xextern char tbuf2[MAXLINE]; Xextern char tbuf3[MAXLINE]; Xextern char ttl[MAXLINE]; X /* flag to process runoff symbols only */ Xextern char onlyrunoff; X /* flag to turn paging off */ Xextern char paging; X /* page number in roman numerals. Init = NO */ Xextern char roman; X /* autopar flag. Init = NO */ Xextern char autopar; X /* temporary indent value for autopar */ Xextern int autoprv; X /* hash tables for macros and variables */ Xextern struct hashlist *macrotab[HASHMAX]; Xextern struct hashlist *gentab[HASHMAX]; X /* linked list entries for contents */ Xextern struct clist *chead; Xextern struct clist *clast; X /* keep track of the work - VERBOSE opt.*/ X Xextern int p_txtlines; Xextern int p_outlines; Xextern int p_outpages; Xextern int p_memoryus; X X#ifdef vms X#undef extern X#endif X END_OF_proff.h if test 4562 -ne `wc -c proff.pro <<'END_OF_proff.pro' X name %time cumsecs #call ms/call X _doesc 14.6 6.48 1929 3.36 X _ngetln 12.0 11.79 2004 2.65 X _dotabs 10.6 16.46 1118 4.18 X _getwrb 8.5 20.21 5493 0.68 X _put 8.4 23.91 1311 2.82 X _width 7.2 27.11 5060 0.63 X _dovar 6.7 30.05 1962 1.50 X cret 3.6 31.62 X csv 3.3 33.10 X _strcpy 3.3 34.57 X _spread 3.0 35.88 389 3.39 X _putwrd 1.8 36.69 4947 0.16 X mcount 1.7 37.44 X _strlen 1.6 38.14 X _leadbl 1.2 38.69 227 2.42 X _text 1.2 39.23 1118 0.48 X _getwrd 0.9 39.64 860 0.48 X _eval 0.9 40.03 95 4.04 X _puttl 0.9 40.41 74 5.18 X _hash 0.8 40.76 1827 0.19 X _getarg 0.7 41.06 861 0.35 X_docline 0.6 41.34 75 3.78 X_command 0.6 41.61 844 0.32 X _bold 0.5 41.84 33 7.07 X _malloc 0.4 42.03 X _putbak 0.4 42.21 3624 0.05 X_comtype 0.4 42.38 844 0.20 X _doroff 0.3 42.53 1 150.03 X _gfield 0.3 42.66 150 0.89 X _skipl 0.3 42.79 1623 0.08 X _brk 0.3 42.90 1073 0.10 X _strcmp 0.2 43.01 X _lookup 0.2 43.11 1053 0.10 X _pbstr 0.2 43.21 443 0.23 X_lexlook 0.2 43.31 716 0.14 X _write 0.2 43.41 X _subst 0.2 43.50 208 0.44 X _skipbl 0.2 43.57 1205 0.06 X__strout 0.2 43.63 X__flsbuf 0.2 43.70 X _jcopy 0.2 43.77 104 0.64 X _underl 0.1 43.83 15 3.89 X _read 0.1 43.88 X _set 0.1 43.91 409 0.09 X_strsave 0.1 43.95 191 0.17 X _atoi 0.1 43.98 X_install 0.1 44.01 58 0.50 X _getval 0.1 44.03 1 25.01 X _getnow 0.1 44.06 74 0.34 X _center 0.0 44.08 9 2.32 X _phead 0.0 44.10 37 0.45 X _main 0.0 44.11 1 16.67 X_sprintf 0.0 44.13 X _justfy 0.0 44.15 104 0.16 X_cvtroma 0.0 44.16 4 4.17 X _dodef 0.0 44.18 8 2.08 X _addstr 0.0 44.20 33 0.51 X _sbrk 0.0 44.21 X _itoc 0.0 44.23 83 0.20 X _close 0.0 44.24 X _fopen 0.0 44.24 X _space 0.0 44.24 219 0.00 X_fprintf 0.0 44.24 X _etext 0.0 44.24 X _gets 0.0 44.24 X _printf 0.0 44.24 X _pfoot 0.0 44.24 37 0.00 X__filbuf 0.0 44.24 X__doprnt 0.0 44.24 X pgen 0.0 44.24 X pfloat 0.0 44.24 X pscien 0.0 44.24 X_getpstr 0.0 44.24 X _finit 0.0 44.24 X _fflush 0.0 44.24 X__cleanu 0.0 44.24 X _fclose 0.0 44.24 X__endope 0.0 44.24 X__findio 0.0 44.24 X _remove 0.0 44.24 X_lexinst 0.0 44.24 X _free 0.0 44.24 X_realloc 0.0 44.24 X _isatty 0.0 44.24 X_monitor 0.0 44.24 X _stty 0.0 44.24 X _gtty 0.0 44.24 X _strcat 0.0 44.24 X _exit 0.0 44.24 X _usage 0.0 44.24 X _error 0.0 44.24 X _ctoi 0.0 44.24 1 0.00 X _creat 0.0 44.24 X _ioctl 0.0 44.24 X _lseek 0.0 44.24 X _open 0.0 44.24 X _profil 0.0 44.24 X _addset 0.0 44.24 8 0.00 X _save 0.0 44.24 4 0.00 X_restore 0.0 44.24 4 0.00 X cerror 0.0 44.24 X ldiv 0.0 44.24 X _map 0.0 44.24 4 0.00 X _prmpt 0.0 44.24 X _gettl 0.0 44.24 8 0.00 END_OF_proff.pro if test 3302 -ne `wc -c proff01.c <<'END_OF_proff01.c' X X X X X#include X#include X#include "proff.h" X#include "debug.h" X X/* X * bold - bold face or overstrike a line X * X */ Xbold(buf,tbuf,size) Xchar buf[]; Xchar tbuf[]; Xint size; X{ X int i,j; X dprintf("bold "); X X j = 0; X for (i = 0; buf[i] != '\n' && j < size - 2; i++) { X tbuf[j] = buf[i]; X j++; X if (buf[i] != ' ' && buf[i] != '\t' && X buf[i] != BACKSPACE ) { X tbuf[j] = BACKSPACE; X tbuf[j+1] = tbuf[j-1]; X j += 2; X } X } X tbuf[j] = '\n'; X tbuf[j+1] = '\0'; X strcpy(buf,tbuf); X} X X/* X * lbrk - end current filled line X * X */ Xlbrk() X{ X dprintf("lbrk "); X if (outp > 0) { X outbuf[outp] = '\n'; X outbuf[outp+1] = EOS; X put(outbuf); X } X outp = 0; X outw = 0; X outwds = 0; X} X X/* X * center - center a line by setting tival X * X */ Xcenter(buf) Xchar buf[]; X{ X int i; X X dprintf("center "); X X i = (rmval + tival - width(buf)) / 2; X tival = (i > 0) ? i : 0; X} X X/* X * doroff - format text in file fp X * X */ Xdoroff(fp) XFILE *fp; X{ X char inbuf[INSIZE]; X X infile[0] = fp; X for (level = 0; level > -1; level--) { X while (ngetln(inbuf, infile[level]) != EOF) { X if (inbuf[0] == cchar) /* a command */ X command(inbuf); X else { X#ifdef rainbow X if (biosb(2)) X exit(0); X#endif X text(inbuf); X p_txtlines++; X } X } X if (level > 0 && infile[level] > 0) { X fclose(infile[level]); X if (verbose) X fprintf(stderr," done.\n"); X } X } X} X X/* X * gettl - copy title from buf to ttl X * X * modifies lim X */ Xgettl(buf,ttl,lim) Xchar *buf; Xchar *ttl; Xint lim[]; X{ X while (!isspace(*buf)) X buf++; X while (isspace(*buf)) X buf++; X strcpy(ttl,buf); X lim[0] = inval; X lim[1] = rmval; X} X X/* X * getwrb - get a word INCLUDING the trailing blanks X * X */ Xint Xgetwrb(in,i,out) Xchar in[]; Xchar out[]; Xint *i; X{ X int j,k; X dprintf("getval "); X k = *i; X j = 0; X while (in[k] != EOS && in[k] != ' ' && X in[k] != '\t' && in[k] != '\n') { X out[j] = in[k]; X k++; X j++; X } X while (in[k] == ' ') { X out[j] = ' '; X k++; X j++; X } X *i = k; X out[j] = EOS; X return(j); X} X X X/* X * gfield - get next tab or title field X * X */ Xint Xgfield(buf, i, n, temp, delim) Xchar buf[]; Xint *i; Xint n; Xchar temp[]; Xchar delim; X{ X int j,k; X X dprintf("gfield "); X j = 0; X k = *i; X if (n > 0) { X if (buf[k] == delim) X k++; X while (buf[k] != delim && buf[k] != EOS && buf[k] != '\n' && X j <= n) { X temp[j] = buf[k]; X j++; X k++; X } X } X temp[j] = EOS; X while (buf[k] != delim && buf[k] != EOS && buf[k] != '\n') X k++; X *i = k; X return(j); X} X X/* X * jcopy - scopy without copying EOS X * X */ Xjcopy(from, i, to, j) Xchar from[]; Xchar to[]; Xint i; Xint j; X{ X int k1, k2; X dprintf("jcopy "); X X k1 = i; X k2 = j; X while (from[k1] != EOS) { X to[k2] = from[k1]; X k1++; X k2++; X } X} X X/* X * justfy - justifies string in its tab column X * */ Xjustfy(in, left, right, type, out) Xchar in[]; Xchar out[]; Xint left; Xint right; Xint type; X{ X int j,k, n; X X dprintf("justfy "); X n = width(in); X if (type == RIGHT) X jcopy(in, 0, out, right-n); X else if (type == CENTER) { X k = (right+left-n) / 2; X j = (k > left) ? k : left; X jcopy(in, 0, out, j); X } X else X jcopy(in, 0, out, left); X} X X/* X * leadbl - delete leading blanks, set tival X * X */ Xleadbl(buf) Xchar buf[]; X{ X int i, j; X X dprintf("leadbl "); X lbrk(); X for (i = 0; buf[i] == ' '; i++) /* find 1st non-blank */ X ; X if (buf[i] != '\n') X if (autopar) { X put("\n"); /* blank line */ X tival = inval + autoprv; X } X else X tival = inval + i; /* ??????????? */ X for (j = 0; buf[i] != EOS; j++) { /* move line to left */ X buf[j] = buf[i]; X i++; X } X buf[j] = EOS; X} X X/* X * ngetln - get next line from f into line X * X */ Xint Xngetln(line, f) Xchar line[]; XFILE *f; X{ X int c, i; X X for (i = 0; (c = (bp >= 0) ? buf[bp--] : getc(f)) != EOF; ) { X if (i < MAXLINE - 1) { X line[i++] = (char) c; X } X if (c == '\n' || c == '\r') X break; X } X line[i] = EOS; X if (i == 0 && c == EOF) X i = EOF; X#ifdef DEBUG X printf("ngetln: %s (line)\n",line); X#endif X return(i); X} X X/* X * pbstr - push string back onto input X * X */ Xpbstr(in) Xchar in[]; X{ X X int i; X X dprintf("pbstr "); X for (i = strlen(in) - 1; i >= 0; i--) X putbak(in[i]); X} X X/* X * pfoot - put out page footer X * X */ Xpfoot() X{ X X dprintf("pfoot "); X skipl(m3val); X if (m4val > 0) { X if (curpag % 2 == 1) X puttl(efoot, eflim, curpag); X else X puttl(ofoot, oflim, curpag); X } X if (print == YES) /* flush the page */ X { X putchar(PAGEJECT); /* ... */ X p_outpages++; X if (stopx > 0) /* -s, so flush ^L*/ X putchar('\n'); X } X} X X/* X * phead - put out page header X * X */ Xphead() X{ X dprintf("phead "); X X curpag = newpag; X if (curpag >= frstpg && curpag <= lastpg) X print = YES; X else X print = NO; X if(stopx > 0 && print == YES) X prmpt(&stopx); X newpag++; X if (m1val > 0) { X skipl(m1val-1); X if (curpag % 2 == 0) X puttl(ehead, ehlim, curpag); X else X puttl(ohead, ohlim, curpag); X } X skipl(m2val); X lineno = m1val + m2val + 1; X} X X/* X * prmpt - pause for paper insertion X * prompt if i == 1; increment i X * X */ Xprmpt(i) Xint *i; X{ X int junk,j; X static char bellst[2] = { BEL, EOS}; X X dprintf("prmpt "); X j = *i; X if (j == 1) X#ifdef rainbow X printf("%s\033[7minsert paper and type return\033[0m ",bellst); X#else X printf("%sinsert paper and type return ",bellst); X#endif X else X printf(bellst); X junk = getchar(); X *i = ++j; X} X X/* X * Put - put out line with proper spacing and indenting X * X */ Xput(buf) Xchar buf[]; X{ X register int i; X dprintf("put "); X if (lineno == 0 || lineno > bottom) X phead(); X X if ( print == YES ) { X if (buf[0] == '\n') { /* empty line.. */ X putchar('\n'); X p_outlines++; X } X else { X for ( i = 1 ; i <= offset ; i++ ) /* page offset */ X putchar(' '); X for ( i = 1 ; i <= tival ; i++ ) /* indenting */ X putchar(' '); X X while (*buf != '\0') { X putchar(*buf); X buf++; X } X p_outlines++; X } X } X X tival = inval; X skipl(((lsval-1 < bottom-lineno) ? lsval-1 : bottom-lineno)); X lineno += lsval; X X if (lineno > bottom) X pfoot(); X X} X X/* X * putbak - push character back onto input X * X */ Xputbak(c) Xchar c; X{ X dprintf("putbak "); X X bp++; X if (bp > BUFSIZE) X error("too many characters pushed back.\n"); X buf[bp] = c; X} X X X/* X * puttl - put out title line with optional page number & date X * X */ Xputtl(buf, lim, pageno) Xchar buf[]; Xint lim[]; Xint pageno; X{ X char chars[9],cdate[27]; X char rmstr[MAXTOK]; X char delim; X char *tp; X int j; X int nc, n, i, left, right, ncd; X X dprintf("puttl "); X if (print == NO) X return; X left = lim[0]; /* no more +1 here */ X right = lim[1]; /* no more +1 here */ X nc = itoc(pageno, chars, MAXCHARS); X if (roman) { X nc = cvtroman(chars,rmstr); X strcpy(chars,rmstr); X } X getnow(cdate); X ncd = strlen(cdate); X i = 0; X delim = buf[i]; X for (j = 0; j < right; j++) X ttl[j] = ' '; X n = 0; X do { X if (gfield(buf, &i, right-left, tbuf1, delim) > 0) { X subst(tbuf1, PAGENUM, tbuf2, chars, nc); X subst(tbuf2, CURRENTDATE, tbuf1, cdate, ncd); X justfy(tbuf1, left, right, tjust[n], ttl); X } X n++; /* update title counter */ X } X while (buf[i] != EOS && buf[i] != '\n' && n != 3); X X for( ; right >= 1 ; right--) X if( ttl[right-1] != ' ' ) X break; X ttl[right] = '\n'; X ttl[right+1] = EOS; X for (i = 1; i <= offset; i++) X putchar(' '); /* offset */ X tp = ttl; X while (*tp != '\0') { X putchar(*tp); X tp++; X } X p_outlines++; X} X X/* X * set - set parameter and check range X * X */ Xset(param, val, argtyp, defval, minval, maxval) Xint *param; Xint val; Xint argtyp; Xint defval; Xint minval; Xint maxval; X{ X int i; X dprintf("set "); X i = *param; X if (argtyp == '\n') /* defaulted */ X i = defval; X else if (argtyp == '+') /* relative +*/ X i += val; X else if (argtyp == '-') /* relative -*/ X i -= val; X else /* absolute */ X i = val; X i = (i < maxval) ? i : maxval; /* min */ X i = (i > minval) ? i : minval; /* max */ X *param = i; X} X X/* X* skipl - output n blank lines X* X*/ Xskipl(n) Xregister int n; X{ X register int i; X X dprintf("skip "); X if (print == YES) X for (i = 1; i <= n; i++) { X putchar('\n'); X p_outlines++; X } X} X X/* X * space - space n lines or to bottom of page X * X */ Xspace(n) Xint n; X{ X X dprintf("space "); X lbrk(); X if (lineno > bottom) X return; X if (lineno == 0) X phead(); X skipl(((n < bottom+1-lineno) ? n : bottom+1-lineno)); X lineno += n; X if (lineno > bottom) X pfoot(); X} X X/* X * spread - spread words to justify right margin X * X */ Xspread(buf, outp, nextra, outwds) Xchar buf[]; Xint outp; Xint nextra; Xint outwds; X{ X int dir = 0; X X register int i, j; X int nb, ne, nholes; X X dprintf("spread "); X if (nextra <= 0 || outwds <= 1) X return; X dir = 1 - dir; /* reverse previous direction */ X ne = nextra; X nholes = outwds - 1; X if (tival != inval && nholes > 1) X nholes--; X i = outp - 1; X j = (MAXOUT-2 < i+ne) ? MAXOUT-2 : i+ne; /* leave room for '\n', EOS */ X while (i < j) { X buf[j] = buf[i]; X if (buf[i] == ' ' && buf[i-1] != ' ') { X if (dir == 0) X nb = (ne-1) / nholes + 1; X else X nb = ne / nholes; X ne -= nb; X nholes--; X for ( ; nb > 0; nb--) { X j--; X buf[j] = ' '; X } X } X i--; X j--; X } X} X X/* X * subst - substitutes a string for a specified character X * X */ Xsubst(in, chr, out, subara, n) Xchar in[]; Xchar chr; Xchar out[]; Xchar subara[]; Xint n; X{ X register int i, j, k; X X dprintf("subst "); X j = 0; X for (i = 0; in[i] != EOS; i++) X if (in[i] == chr) X for (k = 0; k < n; k++) { X out[j] = subara[k]; X j++; X } X else { X out[j] = in[i]; X j++; X } X out[j] = EOS; X} X X/* X * Text process text lines X * X */ X Xtext(inbuf) Xchar inbuf[]; X{ X int i; X register int j; X char wrdbuf[INSIZE]; X X dovar(wrdbuf,inbuf); /* expand variables */ X strcpy(inbuf,wrdbuf); X doesc(inbuf, wrdbuf, INSIZE); /* expand escapes */ X dotabs(inbuf, wrdbuf, INSIZE); /* expand tabs */ X X if(inbuf[0] == ' ' || inbuf[0] == '\n') X leadbl(inbuf); /* move left, set tival */ X if(ulval > 0 || ULon) /* word underlining */ X { X underl(inbuf, wrdbuf, INSIZE); X ulval--; X } X if(boval > 0 || BDon) /* boldfacing */ X { X bold( inbuf, wrdbuf, INSIZE); X boval--; X } X if(ceval > 0 || CEon) /* centering */ X { X center(inbuf); X put(inbuf); X ceval--; X } X else if( inbuf[0] == '\n' ) /* all blank line */ X put(inbuf); X else if( fill == NO ) /* unfilled text */ X put(inbuf); X else /* filled text */ X { X i = strlen(inbuf) - 1; X inbuf[i] = ' '; X if( inbuf[i-1] == '.' ) X { X i++; X inbuf[i] = ' '; X } X inbuf[i+1] = EOS; X for( i = 0 ; getwrb(inbuf, &i, wrdbuf) > 0 ; ) X putwrd(wrdbuf); X } X} X X/* X * Underl underline words in a line X * X */ Xunderl(buf, tbuf, size) Xchar buf[]; Xchar tbuf[]; Xint size; X{ X int i, j; X X j = 0; X for(i = 0 ; buf[i] != '\n' && j < size - 2; i++) { X if( buf[i] != ' ' && buf[i] != BACKSPACE && buf[i] != '_' ) { X tbuf[j++] = '_'; X tbuf[j++] = BACKSPACE; X } X if( buf[i] == BLANK ) X tbuf[j++] = ulblnk; X else X tbuf[j++] = buf[i]; X } X X tbuf[j] = '\n'; X tbuf[j+1] = '\0'; X strcpy(buf, tbuf); X} X X/* X * width - compute width of character string X * X */ Xint Xwidth(buf) Xchar buf[]; X{ X int k,i; X X dprintf("width "); X k = 0; X for (i = 0; buf[i] != EOS; i++) X if (buf[i] == BACKSPACE) X k--; X else if (buf[i] >= ' ' && buf[i] <= '~') X k++; X return(k); X} X/* X * getnow - get the date from command line if present. X * if not specified, prompt user for it. X * X * (stub) X */ Xgetnow(date) Xchar date[]; X{ X dprintf("getnow "); X strcpy(date,"00-xxx-1900 00:00:00"); X} END_OF_proff01.c if test 11318 -ne `wc -c proff02.c <<'END_OF_proff02.c' X X X X X#include X#include X#include "defs.h" X#include "debug.h" X X/* X * addset - put c in array[i], if it fits, increment i X * X */ Xint Xaddset(c,array,i,maxsize) Xchar c; Xchar array[]; Xint *i; Xint maxsize; X{ X int n,status = NO; X dprintf("addset "); X n = *i; X if (n <= maxsize - 1) { X array[n++] = c; X status = YES; X } X *i = n; X return(status); X} X X/* X * addstr - add string s to str[i] if it fits, increment i X * X */ Xint Xaddstr(s,str,i,maxsize) Xchar s[]; Xchar str[]; Xint *i; Xint maxsize; X{ X int k,j,status = NO; X X dprintf("addstr "); X j = *i; X if (j + strlen(s) <= maxsize - 1) { X for (k = 0; s[k] != EOS; k++) X str[j++] = s[k]; X status = YES; X } X *i = j; X return(status); X} X X/* X * ctoi - convert string at in[i] to integer, increment i X * X */ Xint Xctoi(in,i) Xchar in[]; Xint *i; X{ X int j,n,sign; X X dprintf("ctoi "); X n = 0; X for (j = *i; in[j] == ' ' || in[j] == '\t'; j++) X ; /* skip leading garbage */ X sign = 1; X if (in[j] == '+' || in[j] == '-') /* sign */ X sign = (in[j++] == '+') ? 1 : -1; X for (n = 0; in[j] >= '0' && in[j] <= '9'; j++) X n = 10 * n + in[j] - '0'; X *i = j; X return(sign * n); X} X X/* X * error - print message and terminate X * X */ Xerror(s) Xchar s[]; X{ X fprintf(stderr,"%s\n",s); X exit(1); X} X X/* X * getwrd - get non-blank word from in[i] into out, increment i X * X */ Xint Xgetwrd(in,i,out) Xchar in[]; Xint *i; Xchar out[]; X{ X int j,size = 0; X X for (j = *i; in[j] == '\t' || in[j] == ' '; j++) X ; /* skip leading garbage */ X while (in[j] != ' ' && in[j] != '\t' && X in[j] != EOS && in[j] != '\n') X out[size++] = in[j++]; X out[size++] = EOS; X *i = j; X#ifdef DEBUG X printf("getwrd: %s\n",out); X#endif X return(size); X} X/* X * skipbl - skip blanks, tabs at str[i], increment i X * X */ Xskipbl(str,i) Xchar str[]; Xint *i; X{ X int n; X dprintf("skipbl "); X n = *i; X while (str[n] == ' ' || str[n] == '\t') X n++; X *i = n; X} X X/* X * itoc - special version of itoa X * X */ Xint Xitoc(n,str,size) Xint n; Xchar str[]; Xint size; X{ X X int i,j,k,sign; X char c; X X dprintf("itoc "); X if ((sign = n) < 0) X n = -n; X i = 0; X do { X str[i++] = n % 10 + '0'; X } X while ((n /= 10) > 0 && i < size-2); X if (sign < 0 && i < size-1) X str[i++] = '-'; X str[i] = EOS; X /* X * reverse the string and plug it back in X * X */ X for (j = 0, k = strlen(str) - 1; j < k; j++, k--) { X c = str[j]; X str[j] = str[k]; X str[k] = c; X } X return(i); X} X X/* X * usage - obvious.. X * X */ Xusage() X{ X#ifdef rainbow X fprintf(stderr,"%s %s", X "usage: proff \033[7m[+n] [-n] [-v] [-ifile] [-s] [-pon]\033[0m", X "\033[1minfile\033[0m \033[7m[outfile]\033[0m\n"); X#else X fprintf(stderr, X "usage: proff [+n] [-n] [-v] [-ifile] [-s] [-pon] infile [outfile]\n"); X#endif X exit(0); X} END_OF_proff02.c if test 2684 -ne `wc -c proffsym.new <<'END_OF_proffsym.new' X X! proff symbols X! flag value of 1 indicate X! a runoff-supported symbol X! feb. 1984 X! X! reset the formatter X! Xreset RESET X! X! bolding X! Xbd BD Xbold * X!disable_bolding DBO 1 Xdisablebolding DBO 1 Xdbo * 1 Xdb * X!enable_bolding EBO 1 Xenablebolding EBO 1 Xebo * 1 Xeb * X! X! new page & paging modes X! Xbp BP Xpage * 1 Xpg * 1 Xpaging PGI 1 Xpa * 1 Xnopaging NPA 1 Xnp * X! X! break X! Xbr BR 1 Xbreak * 1 X! Xbs BS X! X! setup control character X! Xcc CC Xcchar * X! X! centering X! Xce CE Xcenter * X! Xcu CU X! X! macro definitions X! Xde DE Xdefine * X! X! setup generic escape character X! Xec EC Xechar * X! X! even footers and headers X! Xef EF Xeh EH X! X! end macro definition X! X!en EN X! X! fill the lines X! Xfi FI Xf * 1 Xfill * 1 X! X! general footers and headers X! Xfo FO Xfooter * Xhe HE Xheader * X! X! indentation (permanent) X! Xin IN Xlm * 1 X!left_margin * 1 Xleftmargin * 1 X! X! justification X! Xju JU Xj * 1 Xjustify * 1 X! X! line spacing X! Xls LS Xspacing * 1 Xspc * 1 X! X! margin spacing X! Xm1 M1 Xm2 M2 Xm3 M3 Xm4 M4 X! X! test for page X! Xne NE Xneed * X!test_page * 1 Xtestpage * 1 Xtp * 1 X! X! disable fill X! Xnf NF 1 Xnofill * X!no_fill * 1 X! X! disable justification X! Xnj NJ 1 Xnojustify * X!no_justify * 1 X! X! number registers X! Xnr NR X! X! external output X! Xou OU Xoutput * Xoe OE Xoutend * X! X! odd footers and headers X! Xof OF Xoh OH X! X! page length X! Xpl PL Xps * 1 X!page_size * 1 Xpagesize * 1 X! X! page offset X! Xpo PO Xoffset * X! X! right margin X! Xrm RM 1 X!right_margin * 1 Xrightmargin * 1 X! X! external input (include) X! Xso SO Xsource * Xinclude * Xrequire * 1 Xreq * 1 X! X! skip line (blank lines) according to spacing X! sp is not the same as runoff sp X! Xsp SP Xskip * 1 Xs * 1 X! X! blank line X! X!blank BL 1 X!b * 1 X! X! space from top (or bottom) X! Xst ST Xskipto * X! X! temporary indent X! Xti TI Xleft * 1 X! X! underline X! Xul UL Xunderline * X! X! substitute (using reqular expresions) X! X!su SU X!subs * X!substitute * X!esu ESU X!enable_subs * X!dsu DSU X!disable_subs * X! X! save and restore of FSECT X! Xsv SAV Xsave * Xrs RST Xrestore * X! X! looping formatting for each variable X! X!for FOR X!foreach * X!enf ENF X!endfor * X! X! permanent symbol replacement X! Xlx LEX Xlex LEX X! X! ignore character X! Xig IG Xignore IG X! X! variable definition X! Xvs SET Xset * Xvg GET Xget * X! X! page numbering (roman or arabic) X! Xpn PN Xpagenumber * X! X! paragraphing X! Xap AP 1 Xautoparagraph * 1 Xna * Xnap NAP 1 X!no_autoparagraph * 1 Xnoautoparagraph * 1 X!paragraph PAR 1 X!p * 1 X!set_paragraph SPR 1 X!setparagraph * 1 X!spr * 1 X! X! X!comment COM 1 X! X! same as pagenumber X! X!display_number DNM 1 X!dnm * 1 X! X! entry into an index listing X! X!entry ENT 1 X!y * 1 X! X! entry into contents table X! Xcl CL Xcontline * Xpc PC Xprintcont * X! X! conditional formatting X! X!if CIF 1 X!else CELSE 1 X!endif CENDIF 1 X!ifnot CIFNOT 1 X! X! list generation X! X!list LST 1 X!end_list ELS 1 X!endlist ELS 1 X!els * 1 X!list_element LEM 1 X!listelement LEM 1 X!le * 1 X! X! literal mode (nf-nj-lm0-rm150) X! Xliteral LTR 1 Xlt * 1 X!end_literal ELT 1 Xendliteral ELT 1 Xel * 1 X! X! overstrike control X! X!enable_overstriking EOV 1 X!eov * 1 X!disable_overstriking DOV 1 X!dov * 1 X! X! repeat a string X! X!repeat REP 1 X!rpt * 1 X! X! flush right margin X! X!right RIG 1 X!r * 1 X! X! write out a special string X! Xwr WR Xwrite * X! X! end of definitions X END_OF_proffsym.new if test 3452 -ne `wc -c putwrd.c <<'END_OF_putwrd.c' X X X X X#include X#include "proff.h" X#include "debug.h" X X/* X * putwrd - put a word in outbuf; includes margin justification X * X */ Xputwrd(wrdbuf) Xchar wrdbuf[]; X{ X int last, llval, extra, w; X Xdprintf("putwrd "); X w = width(wrdbuf); X last = strlen(wrdbuf) + outp; /* new end of outbuf */ X#ifdef DEBUG Xprintf("strlen(wrdbuf) = %d\n",strlen(wrdbuf)); X#endif X llval = rmval - tival; X if (outw + w > llval || last >= MAXOUT) { /* too big */ X last -= outp; X extra = llval - outw; X#ifdef DEBUG Xprintf("extra = %d\n",extra); X#endif X for ( ; outp > 0; outp--) X if (outbuf[outp-1] == ' ') X extra++; X else X break; X if (rjust == YES) { X spread(outbuf, outp, extra, outwds); X if (extra > 0 && outwds > 1) X outp += extra; X } X lbrk(); /* flush previous line */ X } X#ifdef DEBUG Xprintf("putwrd: last=%d w=%d outp=%d llval=%d outw=%d extra=%d\n", X last,w,outp,llval,outw,extra); X#endif X strcpy(&outbuf[outp],wrdbuf); X outp = last; X outw += w; X outwds++; X} X END_OF_putwrd.c if test 981 -ne `wc -c pxlex.c <<'END_OF_pxlex.c' X X X#include X#include X#include X X/* translation table for control chars */ X Xchar c_ctrl[] = { X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, X 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, X 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, X 23, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, X 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, X 20, 21, 22, 23, 24, 25, 26, 0, 0, 0, 0, 0 X }; X X/* X * getval - evaluate optional numeric argument X * X * increments i X */ Xint Xgetval(buf,i,argtyp) Xchar buf[]; Xint *i; Xint *argtyp; X{ X int j,k; X X j = *i; X k = *argtyp; X X skipbl(buf, &j); X k = buf[j]; X if (k == '+' || k == '-') X j++; X *i = j; X *argtyp = k; X return(ctoi(buf,i)); X} X X/* X * getarg - get the next argument from the buffer X * X * return values: -1 - no argument X * n - number of chars in argument X * X * also handles quoted ("..") strings. If a quote is wanted X * in the string, use "" or \". quotes are stripped. X * X * argument delimiters: blank, tab or comma (,). X * X * increments i X * X */ Xint Xgetarg(buf,i,arg) Xchar buf[]; Xint *i; Xchar arg[]; X{ X int j,k; X register char ch; X X j = *i; X X k = -1; X skipbl(buf,&j); X if (buf[j] != '\0') { X k = 0; X if (buf[j] == '\"') { X j++; X while (buf[j] != '\0') { X if (buf[j] == '\"') { X if (buf[j+1] == '\"') { X arg[k++] = '\"'; X j += 2; X } X else X break; X } X arg[k++] = buf[j++]; X } X arg[k] = '\0'; X j++; /* skip the quote */ X /* peek next char */ X if (isalnum(buf[j])) X error("improper argument list."); X j++; /* skip the delimeter */ X } X else { X ch = buf[j]; X while (ch != ' '&& X ch != '\t' && X ch != ',' && X ch != '\r' && X ch != '\n' && X ch != '\0') { X arg[k++] = buf[j++]; X ch = buf[j]; X } X arg[k] = '\0'; X if (ch != '\0') /* if non-null delimiter, skip */ X j++; X } X *i = j; X } X return(k); X} X X/* X * getpstr - get a special string to print out X * X */ Xgetpstr(buf,out) Xregister char *buf; Xregister char *out; X{ X register int i; X register char c, cc; X register char *num; X char numbuf[9]; X X while(*buf != '\n' && *buf != '\0') { X c = *buf; X switch(c) { X case ' ': X case '\t': X while (*buf == ' ' || *buf == '\t') X buf++; /* skip blanks */ X break; X case '\\': X if (*(buf+1) != '\0') { X *out++ = *(buf+1); X buf += 2; X } X else X buf++; X break; X case '^': X if ((cc = c_ctrl[*(buf+1)]) != 0) X *out++ = cc; X buf += 2; X break; X case '\"': X buf++; /* skip the quote */ X while (*buf != '\0') { X if (*buf != '\"') X *out++ = *buf++; X else if (*(buf+1) == '\"') { X *out++ = '\"'; X buf += 2; X } X else X break; X } X buf++; /* skip the quote */ X break; X case '0': X case '1': X case '2': X case '3': X case '4': X case '5': X case '6': X case '7': X case '8': X case '9': X num = numbuf; X while (isdigit(*buf)) X *num++ = *buf++; X *num = '\0'; X if ((i = atoi(numbuf)) > 256) X error("non-ascii char value in write string."); X else if (i > 0) /* do not output null */ X *out++ = (char) i; X break; X default: X *out++ = *buf++; X } X } X *out = '\0'; X} X END_OF_pxlex.c if test 3358 -ne `wc -c pxxparse.c <<'END_OF_pxxparse.c' X#include X#include X#include "proff.h" X#include "debug.h" X#include "lextab.h" X X#define RUNOFF 1 /* recognise RUNOFF commands */ X Xchar literal = NO; /* literal flag */ X X/* X * command - perform formatting command X * X */ Xcommand(buf) Xchar buf[]; X{ X char token[MAXTOK], xtoken[MAXTOK], variable[MAXTOK], *defn; X char special[MAXTOK]; X int argtyp, ct, at, spval, i, flags; X register int val, n, rest; X char onflag = FALSE; X char offlag = FALSE; X struct lexlist *xp; X X dovar(tbuf1,buf); /* use scratch buffer to expand variables */ X strcpy(buf,tbuf1); X X i = 1; X n = getwrd(buf, &i, token); /* get the command token */ X rest = i; /* remaining string */ X ct = comtype(token, n, &defn, &flags); X if (ct == UNKNOWN) X return; X if (literal && ct != ELT) { /* ignore while literal */ X put(buf); X return; X } X X#ifdef DOUBLEWORD X if (flags == 2) { /* check for 2-word command */ X n = getwrd(buf, &i, xtoken); X if (n == 0) { X fprintf(stderr,"%c%s what ?\n", cchar, token); X return; X } X if ((at = comtype(xtoken, n, &defn, &flags)) == UNKNOWN) { X fprintf(stderr,"%c%s %s unknown.\n", cchar, X token, X xtoken); X return; X } X else X ct += at; X } X#endif X X doesc(buf, variable, MAXLINE); /* expand escapes */ X n = getarg(buf, &i, xtoken); /* first parameter*/ X argtyp = '\n'; /* defaulted ** cludge ** */ X val = 0; X if (n > 0) { X if (*xtoken == '+' || *xtoken == '-') { X argtyp = *xtoken; X val = atoi(xtoken+1); X } X else if (isdigit(*xtoken)) { X argtyp = 0; X val = atoi(xtoken); X } X else { X /* check some common flags */ X if (strcmp("on",xtoken) == 0) X onflag = TRUE; X else if (strcmp("off",xtoken) == 0) X offlag = TRUE; X } X } X X switch(ct) { X X case MACRO: X eval(buf, defn); X break; X case FI: X lbrk(); X fill = YES; X break; X case NF: X lbrk(); X fill = NO; X break; X case BR: X lbrk(); X break; X case LS: X set(&lsval, val, argtyp, 1, 1, HUGE); X break; X case CE: X lbrk(); X if (onflag) X CEon = TRUE; X else if (offlag) { X CEon = FALSE; X ceval = 0; /* reset */ X } X else X set(&ceval, val, argtyp, 1, 0, HUGE); X break; X case UL: X if (onflag) { X ULon = TRUE; X break; X } X else if (offlag) { X ULon = FALSE; X ulval = 0; /* reset */ X break; X } X else X set(&ulval, val, argtyp, 0, 1, HUGE); X X if (!isdigit(*xtoken)) { X if (strcmp("all",xtoken) == 0) { X ulblnk = '_'; X ulval = 0; X } X else if (strcmp("words",xtoken) == 0) { X ulblnk = ' '; X ulval = 0; X } X } X break; X case BD: X if (bolding == YES) { X if (onflag) X BDon = TRUE; X else if (offlag) { X BDon = FALSE; X boval = 0; /* reset */ X } X else X set(&boval, val, argtyp, 0, 1, HUGE); X } X break; X case HE: X gettl(buf, ehead, ehlim); X gettl(buf, ohead, ohlim); X break; X case FO: X gettl(buf, efoot, eflim); X gettl(buf, ofoot, oflim); X break; X case BP: X if (paging == NO) X break; X lbrk(); X if (lineno > 0) X space(HUGE); X set(&curpag, val, argtyp, curpag+1, -HUGE, HUGE); X newpag = curpag; X break; X case SP: X set(&spval, val, argtyp, 1, 0, HUGE); X space(spval); X break; X case IN: X lbrk(); X set(&inval, val, argtyp, 0, 0, rmval-1); X tival = inval; X break; X case RM: X set(&rmval, val, argtyp, PAGEWIDTH, tival+1, HUGE); X break; X case TI: X lbrk(); X set(&tival, val, argtyp, 0, 0, rmval); X break; X case LEX: /****/ X if ((xp = remove(xtoken,lextab)) != NULL) { X if (getwrd(buf, &i, variable) != 0) X lexinstal(variable,xp->val,xp->flag,lextab); X } X else X fprintf(stderr,"%s undefined.\n",xtoken); X break; X case PN: /****/ X if (strcmp(xtoken,"roman") == 0) X roman = TRUE; X else if (strcmp(xtoken,"arabic") == 0) X roman = FALSE; X else X fprintf(stderr,"%c%s does not have %s option.\n", X cchar,token,xtoken); X break; X case IG: /****/ X break; X case SET: /****/ X if (n > 0) { X if (isdigit(*xtoken)) { X fprintf(stderr,"illegal variable name %s\n", X xtoken); X break; X } X *variable = '\0'; X n = getarg(buf, &i, variable); X if (n <= 0) { X fprintf(stderr,"%s: ", xtoken); X gets(variable); X X } X if (*variable != '\0') X install(xtoken, variable, gentab); X } X else X fprintf(stderr,"%c%s needs a variable name.\n", X cchar, token); X break; X case GET: /****/ X if (n > 0) { X if (isdigit(*xtoken)) { X fprintf(stderr,"illegal variable name %s\n", X xtoken); X break; X } X *variable = '\0'; X n = getarg(buf, &i, tbuf3); /* using temp buf3 */ X if (n > 0) { X fprintf(stderr,"%s", tbuf3); X gets(variable); X X } X if (*variable != '\0') X install(xtoken,variable, gentab); X } X else X fprintf(stderr,"%c%s needs a variable name.\n", X cchar, token); X break; X case CL: /****/ X if (argtyp == '\n') { X clast->level = 0; X clast->str = NULL; X } X else { X skipbl(buf,&i); X if (*(buf+i) == '\0') X break; /* no contents line here ! */ X clast->level = val * 3; /* level * indent */ X n = i; X while(*(buf+n) != '\n') X n++; X *(buf+n) = '\0'; /* destroy CR with a null */ X clast->str = strsave(buf+i); X clast->page = curpag; X } X clast->nextc = (struct clist *) malloc(sizeof(struct clist)); X p_memoryus += sizeof(struct clist); X clast = clast->nextc; X clast->nextc = NULL; X break; X case PC: /****/ X lbrk(); X clast = chead; X while(clast->nextc != NULL) { X if (clast->str == NULL) X put("\n"); X else { X tival = (int) clast->level + inval; X i = rmval - tival; X docline(variable, i, clast->str, clast->page); X put(variable); X } X clast = clast->nextc; X } X break; X case DBO: /****/ X bolding = NO; X break; X case EBO: /****/ X bolding = YES; X break; X case AP: /****/ X autopar = YES; X break; X case NAP: /****/ X autopar = NO; X break; X case SAV: /****/ X lbrk(); X save(); X break; X case RST: /****/ X lbrk(); X restore(); X break; X case NPA: /****/ X paging = NO; X savpl = plval; X plval = HUGE; X bottom = plval - m3val - m4val; X break; X case PGI: /****/ X bottom = lineno - 1; /* force end-of-page */ X lbrk(); X plval = savpl; X break; X case LTR: /****/ X lbrk(); X if (save()) { X inval = 0; X rmval = 132; X autopar = NO; X lsval = 0; X fill = NO; X literal = YES; X } X break; X case ELT: /****/ X restore(); X literal = NO; X break; X case WR: /****/ X lbrk(); X getpstr(buf+rest,special); X defn = special; X while(*defn) X putchar(*defn++); X break; X case PL: X if (paging == NO) X break; X set(&plval, val, argtyp, PAGELEN, X m1val + m2val + m3val + m4val + 1, HUGE); X bottom = plval - m3val - m4val; X break; X case PO: X set(&offset, val, argtyp, 0, 0, rmval - 1); X break; X case M1: X set(&m1val, val, argtyp, 3, 0, X plval - m2val - m3val - m4val - 1); X break; X case M2: X set(&m2val, val, argtyp, 2, 0, X plval - m1val - m3val - m4val - 1); X break; X case M3: X set(&m3val, val, argtyp, 2, 0, X plval - m1val - m2val - m4val - 1); X bottom = plval - m3val - m4val; X break; X case M4: X set(&m4val, val, argtyp, 3, 0, X plval - m1val - m2val - m3val - 1); X bottom = plval - m3val - m4val; X break; X case EH: X gettl(buf, ehead, ehlim); X break; X case OH: X gettl(buf, ohead, ohlim); X break; X case EF: X gettl(buf, efoot, eflim); X break; X case OF: X gettl(buf, ofoot, oflim); X break; X case CC: X cchar = *xtoken; X if (cchar == '\0' || cchar == '\n') X cchar = '.'; X if ((lineno + val) > bottom && lineno <= bottom) { X space(val); X lineno = 0; X } X break; X case EC: X genesc = *xtoken; X if (genesc == '\0' || genesc == '\n') X genesc = '_'; X break; X case NE: X if ((lineno + val) > bottom && lineno <= bottom) { X space(val); X lineno = 0; X } X break; X case BS: X set(&bsval, val, argtyp, 1, 0, HUGE); X break; X case JU: X rjust = YES; X break; X case NJ: X rjust = NO; X break; X case SO: X if (n <= 0) X return; X if (level + 1 == NFILES) X error("? SO commands nested too deeply."); X if ((infile[level + 1] = fopen(xtoken, "r")) != NULL) { X level++; X if (verbose == YES) X#ifdef rainbow X fprintf(stderr,"source \033[7m%s\033[0m\n", X xtoken); X#else X fprintf(stderr,"source %s\n",xtoken); X#endif X } X else X fprintf(stderr,"%s: cannot open.\n",xtoken); X break; X case OU: /*****/ X /* skip for now. */ X break; X X case OE: /*****/ X /* skip for now. */ X break; X X case CU: X ulblnk = '_'; X set(&ulval, val, argtyp, 0, 1, HUGE); X break; X case DE: X dodef(buf, infile[level]); X break; X case NR: X if (n <= 0) X return; X if (*xtoken < 'a' || *xtoken > 'z') X error("invalid number register [%c].",*xtoken); X X val = getval(buf, &i, &argtyp); X set(&nr[xtoken[0] - 'a'], val, argtyp, 0, -HUGE, HUGE); X break; X case ST: X if (argtyp == '-') X spval = plval; X else X spval = 0; X set(&spval, val, argtyp, 0, 1, bottom); X if (spval > lineno && lineno == 0) X phead(); X if (spval > lineno) X space(spval - lineno); X break; X case RESET: /****/ X finit(); X break; X default: X error("? Botch in command."); X break; X } X} X X/* X * comtype - decode the command type X * X */ Xint Xcomtype(buf, siz, defn, flags) Xchar buf[]; Xint siz; Xchar **defn; Xint *flags; X{ X X struct hashlist *np; X struct lexlist *xp; X extern struct lexlist *lexlook(); X int i,comtyp; X char c1,c2; X X X#ifdef DEBUG X printf("comtype: %s (token)\n",token1); X#endif X X if ((np = lookup(buf, macrotab)) != NULL) { X *defn=np->def; X return(MACRO); X } X comtyp = UNKNOWN; X X if (*buf == '#' || *buf == '!') X return(comtyp); X X if ((xp = lexlook(buf,lextab)) != NULL) X if (onlyrunoff && (xp->flag != RUNOFF)) { X fprintf(stderr,"%c%s is not a runoff command.\n", X cchar,buf); X return(UNKNOWN); X } X else { X comtyp = xp->val; X *flags = xp->flag; X } X X if (comtyp == UNKNOWN) X fprintf(stderr,"unknown command %c%s\n",cchar,buf); X return(comtyp); X} END_OF_pxxparse.c if test 9589 -ne `wc -c stack.c <<'END_OF_stack.c' X X X#include X#include "proff.h" X Xstruct _proffitem { X int Xinval; X int Xrmval; X int Xoffset; X int Xlsval; X int Xplval; X int Xm1val; X int Xm2val; X int Xm3val; X int Xm4val; X int Xfill; X int Xrjust; X X char Xcchar; X char Xgenesc; X char Xroman; X char Xbolding; X char Xpaging; X char Xautopar; X X struct _proffitem *prev; X}; X Xstatic struct X_proffitem *head = NULL; Xstatic struct X_proffitem *top = NULL; X X Xchar *pusherr = "save: stack overflow.\n"; Xchar *poperr = "restore: stack underflow.\n"; X X/* X * save - save proff parameters X * X */ Xsave() X{ X struct _proffitem *sp; X char *malloc(); X X if ((sp = (struct _proffitem *) malloc(sizeof(*sp))) == NULL) { X fprintf(stderr,pusherr); X return(FALSE); X } X else { X p_memoryus += sizeof(struct _proffitem); X if (head == NULL) { /* first element in stack */ X head = sp; X top = NULL; X } X X sp->Xinval = inval; X sp->Xrmval = rmval; X sp->Xoffset= offset; X sp->Xlsval = lsval; X sp->Xplval = plval; X sp->Xm1val = m1val; X sp->Xm2val = m2val; X sp->Xm3val = m3val; X sp->Xm4val = m4val; X sp->Xfill = fill; X sp->Xrjust = rjust; X sp->Xcchar = cchar; X sp->Xgenesc= genesc; X sp->Xroman = roman; X sp->Xbolding = bolding; X sp->Xpaging = paging; X sp->Xautopar = autopar; X X sp->prev = top; X top = sp; X } X return(TRUE); X} X Xrestore() X{ X struct _proffitem *sp; X X if (top != NULL) { X X inval = top->Xinval; X rmval = top->Xrmval; X offset= top->Xoffset; X lsval = top->Xlsval; X plval = top->Xplval; X m1val = top->Xm1val; X m2val = top->Xm2val; X m3val = top->Xm3val; X m4val = top->Xm4val; X fill = top->Xfill; X rjust = top->Xrjust; X cchar = top->Xcchar; X genesc= top->Xgenesc; X roman = top->Xroman; X bolding = top->Xbolding; X paging = top->Xpaging; X autopar = top->Xautopar; X X sp = top->prev; X free(top); X p_memoryus -= sizeof(struct _proffitem); X if ((top = sp) == NULL) X head = NULL; X } X else X fprintf(stderr,poperr); X} END_OF_stack.c if test 1911 -ne `wc -c