home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_100
/
118_01
/
roff1.bds
< prev
next >
Wrap
Text File
|
1980-07-09
|
13KB
|
658 lines
/* software tools format program -- C version -- Part 1
* source: roff1.bds
* version: November 27, 1981.
*/
#define VERSION "November 27, 1981"
#include tools.h
#include roff.h
main(argc, argv)
int argc;
char **argv;
{
initst(argc, argv);
main1();
endst();
}
main1()
{
/* include: cpage, cparam, cout */
char *arg;
int i, fd, nf;
finit();
query("usage: ROFF [-s] [+n] [-n] [-pon] [files]\n");
putlin("Welcome to roff version 0b:, ",SYS_TERM);
putlin(VERSION, SYS_TERM);
putlin("\n",SYS_TERM);
/* open all files. examine options */
nf = 0; /* number of open files */
for (i = 1; (arg = getarg(i)) != EOS; i++) {
/* -s option: stop after each page */
if (arg [0] == '-' && tolower(arg[1]) == 's') {
stopx = YES;
}
/* -po n option: page offset */
else if ( arg [0] == '-' &&
tolower(arg [1]) == 'p' &&
tolower(arg [2]) == 'o'
) {
set (&offset, atoi(arg + 3),
arg [3], 0, 0, rmval - 1);
}
/* + n option: start printing with page n */
else if (arg [0] == '+') {
frstpg = atoi(arg + 1);
}
/* - n option: stop printing after page n */
else if (arg [0] == '-' && arg[1] != EOS) {
lastpg = atoi(arg + 2);
}
/* - or filename option: process input */
else {
if (arg [0] == '-') {
fd = STDIN;
}
else {
fd = open(arg, READ);
}
if (fd == ERR) {
cant(arg);
continue;
}
/* process one file */
doroff(fd);
nf++;
if (fd != STDIN) {
close(fd);
}
}
} /* end of for loop */
/* if no input files, do STDIN */
if (nf == 0) {
doroff(STDIN);
}
/* end gracefully */
brk();
if ( plval <= 100 &&
(lineno > 0 || outp > 0)
) {
/* flush last output */
space(HUGE);
}
/* comment out ----- disable pagecontrol
ifdef(PAGECONTROL,
putc(PAGEJECT);
putc(NEWLINE);
)
----- end comment out */
}
/* bold - bold-face or overstrike a line */
bold(buf, tbuf, size)
char *buf, *tbuf; int size;
{
int i, j, k, k1;
/* expand into tbuf */
k = 0;
j = 0;
for (i = 0; ; i++) {
if ( buf [i] != ' ' &&
buf [i] != TAB &&
buf [i] != BACKSPACE &&
buf [i] != STARTU &&
buf [i] != STOPU &&
buf [i] != NEWLINE
) {
k++;
}
else {
/* over strike word */
for (k1 = k; k1 > 0; k1--) {
tbuf [j++] = buf [i - k1];
}
for (k1 = k; k1 > 0; k1--) {
tbuf [j++] = BACKSPACE;
}
for (k1 = k; k1 > 0; k1--) {
tbuf [j++] = buf [i - k1];
}
/* copy delimiter */
tbuf [j++] = buf [i];
/* reset counter */
k = 0;
if (buf [i] == NEWLINE) {
break;
}
}
}
tbuf [j] = EOS;
if (j >= size) {
sys_error("bold");
}
/* copy tbuf back to buf */
scopy(tbuf, 0, buf, 0);
}
/* brk - end current filled line */
brk()
{
/* include cout */
if (outp > 0) {
outbuf [outp++] = NEWLINE;
outbuf [outp] = EOS;
put(outbuf);
}
outp = 0;
outw = 0;
outwds = 0;
}
/* center - center a line by setting tival */
center(buf)
char buf [];
{
/* include cparam */
tival = max( (rmval + tival - width(buf)) / 2, 0);
}
/* command - perform formatting command */
command(buf)
char *buf;
{
/* include: cpage, cparam, cfiles, cnr */
char name [MAXLINE], defn[MAXDEF];
int val, argtyp; /* command line values */
int spval; /* temp spacing param */
int ismacro;
int i, j;
/* must look for macros before expanding escapes */
i = 1;
getwrd(buf, &i, name);
ismacro = ludef(name, defn);
doesc(buf, name, MAXLINE);
/* get value of argument following command */
i = 0;
while ( buf [i] != ' ' &&
buf [i] != TAB &&
buf [i] != NEWLINE
) {
i++;
}
/* warning: i used below as index into buf */
val = getval(buf, &i, &argtyp);
if (ismacro == YES) {
/* evaluate args. push back definition */
eval(buf, defn);
return;
}
if (lu(buf,"fi")) {
brk();
fill = YES;
}
else if (lu(buf,"br")) {
brk();
}
else if (lu(buf,"nf")) {
brk();
fill = NO;
}
else if (lu(buf,"ls")) {
set(&lsval, val, argtyp, 1, 1, HUGE);
}
else if (lu(buf,"ce")) {
brk();
set(&ceval, val, argtyp, 1, 0, HUGE);
}
else if (lu(buf,"ul")) {
cuval = 0;
set(&ulval, val, argtyp, 0, 1, HUGE);
}
else if (lu(buf,"bd")) {
set(&boval, val, argtyp, 0, 1, HUGE);
}
else if (lu(buf,"he")) {
gettl(buf, ehead, ehlim);
gettl(buf, ohead, ohlim);
}
else if (lu(buf,"fo")) {
gettl(buf, efoot, eflim);
gettl(buf, ofoot, oflim);
}
else if (lu(buf,"bp")) {
/* perform break explicitly */
brk();
if (lineno > 0) {
space(HUGE);
}
set(&curpag,val,argtyp,curpag+1,-HUGE,HUGE);
newpag = curpag;
}
else if (lu(buf,"sp")) {
set(&spval, val, argtyp, 1, 0, HUGE);
space(spval);
}
else if (lu(buf,"in")) {
brk();
set(&inval, val, argtyp, 0, 0, rmval-1);
tival = inval;
}
else if (lu(buf,"rm")) {
set(&rmval, val, argtyp, PAGEWIDTH,
tival + 1, HUGE);
}
else if (lu(buf,"ti")) {
brk();
set(&tival, val, argtyp, 0, 0, rmval);
}
else if (lu(buf,"pl")) {
set(&plval, val, argtyp, PAGELEN,
m1val+m2val+m3val+m4val+1, HUGE);
bottom = plval - m3val - m4val;
}
else if (lu(buf,"po")) {
set(&offset, val, argtyp, 0, 0, rmval-1);
}
else if (lu(buf,"m1")) {
set(&m1val, val, argtyp, 3, 0,
plval-m2val-m3val-m4val-1);
}
else if (lu(buf,"m2")) {
set(&m2val, val, argtyp, 2, 0,
plval-m1val-m3val-m4val-1);
}
else if (lu(buf,"m3")) {
set(&m3val, val, argtyp, 2, 0,
plval-m1val-m2val-m4val-1);
bottom = plval - m3val - m4val;
}
else if (lu(buf,"m4")) {
set(&m4val, val, argtyp, 3, 0,
plval-m1val-m2val-m3val-1);
bottom = plval - m3val - m4val;
}
else if (lu(buf,"eh")) {
gettl(buf, ehead, ehlim);
}
else if (lu(buf,"oh")) {
gettl(buf, ohead, ohlim);
}
else if (lu(buf,"ef")) {
gettl(buf, efoot, eflim);
}
else if (lu(buf,"of")) {
gettl(buf, ofoot, oflim);
}
else if (lu(buf,"cc")) {
/* change command character */
cchar = argtyp;
if (cchar == EOS || cchar == NEWLINE) {
cchar = '.';
}
}
else if (lu(buf,"ne")) {
if (lineno + val > bottom && lineno <= bottom){
space(val);
lineno = 0;
}
}
else if (lu(buf,"bs")) {
set(&bsval, val, argtyp, 1, 0, HUGE);
}
else if (lu(buf,"ju")) {
rjust = YES;
}
else if (lu(buf,"nj")) {
rjust = NO;
}
else if (lu(buf,"so")) {
/* start new source file */
if (getwrd(buf, &i, name) == 0) {
return;
}
if (level + 1 >= MAXOFILES) {
error("so commands nested too deeply.");
}
infile [level+1] = open(name, READ);
if (infile [level+1] != ERR) {
level++;
}
}
else if (lu(buf,"cu")) {
ulval = 0;
set(&cuval, val, argtyp, 0, 1, HUGE);
}
else if (lu(buf,"de")) {
dodef(buf, infile [level]);
}
else if (lu(buf,"nr")) {
/* set number register */
if (getwrd(buf, &i, name) == 0) {
return;
}
fold(name);
if (name [0] < 'a' || name[0] > 'z') {
error("invalid number register name.");
}
val = getval(buf, &i, &argtyp);
set(&nr [name[0]-'a'], val, argtyp,
0, -HUGE, HUGE);
}
else if (lu(buf,"st")) {
/* space to line n from top of page */
if (argtyp == '-') {
spval = plval;
}
else {
spval = 0;
}
set(&spval, val, argtyp, 0, 1, bottom);
if (spval > lineno && lineno == 0) {
phead();
}
if (spval > lineno) {
space(spval - lineno);
}
}
else {
/* ignore unknown commands */
return;
}
}
/* return true if first two characters of buffer matches
* the string.
*/
BOOL lu (buf, string) char *buf, *string;
{
if ( buf [1] == string[0] &&
buf [2] == string[1]
) {
return(YES);
}
else {
return(NO);
}
}
/* dodef - define a command; .de xx is in buf
* read lines until a .en is found
*/
dodef(buf, fd)
char *buf;
int fd;
{
/* include cparam */
char name [MAXNAME], defn [MAXDEF];
int i;
/* comment out -----
printf("in dodef: buf = %s\n", buf);
----- end comment out */
/* get name */
i = 0;
getwrd(buf, &i, name);
i = getwrd(buf, &i, name);
/* comment out -----
printf("dodef: name = %s\n", name);
----- end comment out */
if (i == 0) {
/* null definition -- ignore */
return;
}
/* allow arbitrary length names */
i = 0;
while (ngetln(buf, fd) != EOF) {
/* .en terminates macro definition */
if ( buf [0] == cchar &&
buf [1] == 'e' &&
buf [2] == 'n'
) {
break;
}
addstr(buf, defn, &i, MAXDEF);
}
if (addset(EOS, defn, &i, MAXDEF) == NO) {
error("definition too long.");
}
entdef(name, defn);
}
/* doesc - expand values of number regs into buf */
doesc(buf, tbuf, size)
char *buf, *tbuf; int size;
{
/* include cnr */
int i, j;
j = 0; /* expand into tbuf */
for (i = 0; buf [i] != EOS && j < size; i++) {
if (buf [i] != '@') {
tbuf [j++] = buf[i];
}
else if (buf [i+1] == '@') {
/* two at signs count as one */
tbuf [j++] = '@';
i++;
}
else if ( buf [i+1] == 'n' &&
isalpha(buf [i+2])
) {
/* @na is request for number reg a */
j += itoc( nr [tolower(buf [i+2])-'a'],
tbuf + j,
size - j - 1
);
i += 2;
}
else {
tbuf [j++] = buf[i];
}
}
tbuf [j] = EOS;
scopy(tbuf, 0, buf, 0);
}
/* doroff - format text in file fd */
doroff(fd)
int fd;
{
/* include cfiles, cparam */
char inbuf [INSIZE];
infile [0] = fd;
for (level = 0; level >= 0; level--) {
while (ngetln(inbuf, infile [level]) != EOF) {
if (inbuf [0] == cchar) {
command(inbuf);
}
else {
text(inbuf);
}
}
/* close an .so file */
if (level > 0 && infile [level] != ERR) {
close(infile [level]);
}
}
}
/* dotabs - expand tabs in buf */
dotabs(buf, tbuf, size)
char *buf, *tbuf; int size;
{
/* include cparam */
int i, j;
/* expand into tbuf */
j = 0;
for (i = 0; buf [i] != EOS && j < size; i++) {
if (buf [i] == TAB) {
while (j < size) {
tbuf [j++] = ' ';
if ( tabs [j] == YES ||
j >= INSIZE
) {
break;
}
}
}
else {
tbuf [j++] = buf [i];
}
}
tbuf [j] = EOS;
scopy(tbuf, 0, buf, 0);
}
/* entdef - enter name and definition in macro table */
entdef (name, defn)
char *name, *defn;
{
/* include cmac */
int i;
char *locn;
/* comment out -----
printf("entdef: name = %s, defn = \n%s\n",name,defn);
----- end comment out */
if ((locn = lookup (name, mactbl)) != 0) {
/* erase old definition */
delete(name, mactbl);
}
enter (name, defn, mactbl);
}
/* eval - evaluate defined command; push back definition.
* buf contains a call to a macro.
* defn contains its definition.
* substitute args from buf into definition and
* push it all back.
*/
eval(buf, defn)
char *buf, *defn;
{
int i, j, k;
int argptr [10];
/* comment out -----
printf("eval: buf = %s\ndefn = %s\n", buf, defn);
----- end comment out */
/* create null string */
buf [0] = EOS;
/* initialize pointers to null string */
for (j = 0; j < 10; j++) {
argptr [j] = 0;
}
/* up to 9 positional arguments are allowed.
* $0 refers to command name.
*/
for (i= 1, j = 0; j < 10; j++) {
/* scan past blanks ending previous argument */
skipbl(buf, &i);
if (buf [i] == NEWLINE || buf[i] == EOS) {
break;
}
/* point argptr at arg */
argptr [j] = i;
while ( buf [i] != ' ' &&
buf [i] != TAB &&
buf [i] != NEWLINE &&
buf [i] != EOS
) {
i++;
}
/* end argument */
buf [i++] = EOS;
/* comment out -----
printf("argptr[%d] = %d,",j, argptr[j]);
printf("buf + argptr[%d] = %s\n",
j, buf + argptr[j]);
----- end comment out */
}
/* push the defintion back in reverse order.
* substitute actual parameters for $1 ... $9
* substitute command name for $0
*/
for (k = length(defn) - 1; k > 0; k--) {
if (defn [k-1] != ARGFLAG) {
putbak(defn [k]);
}
else {
if (defn [k] < '0' || defn [k] > '9') {
putbak(defn [k]);
}
else {
i = defn [k] - '0';
pbstr(buf + argptr [i]);
k--; /* skip over $ */
}
}
}
/* do last character */
if (k >= 0) {
putbak(defn [k]);
}
}
}
/* push the defintion back in reverse order.
* substitute actual parameters for $1 ... $9
* substitute command name