New NRO file 2 of 3 - (nf)
ron at trsvax.UUCP
ron at trsvax.UUCP
Fri Sep 16 13:30:17 AEST 1983
#N:trsvax:66500003:000:26321
trsvax!ron Sep 9 00:37:00 1983
--------------------------------------------------------------------------------
: Run this shell script with "sh" not "csh"
#! /bin/sh
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
all=FALSE
if [ $1x = -ax ]; then
all=TRUE
fi
/bin/echo 'Extracting nro.c'
sed 's/^X//' <<'//go.sysin dd *' >nro.c
X/*
X * Word Processor
X * similar to Unix NROFF or RSX-11M RNO -
X * adaptation of text processor given in
X * "Software Tools", Kernighan and Plauger.
X *
X * Stephen L. Browning
X * 5723 North Parker Avenue
X * Indianapolis, Indiana 46220
X *
X * Modified and enhanced by:
X * Ron Light
X * 6016 Croftway Ct.
X * Ft. Worth, Tx. 76131
X */
X
X#include <stdio.h>
X#include "nro.h"
X
X
X
X
Xstruct docctl dc = 0;
Xstruct page pg = 0;
XFILE *pout = 0;
Xstruct cout co = 0;
Xstruct macros mac = 0;
Xstruct file file[NFILES] = 0;
Xunsigned char newext[200] = 0;
Xunsigned char disk = 0;
Xunsigned char diskx = 0;
Xunsigned char raw = 0;
Xunsigned char *divertbuf = 0;
Xunsigned char *divpnt = 0;
X
X
X
X
Xmain(argc, argv)
Xunsigned int argc;
Xregister unsigned char *argv[];
X{
X register unsigned int i;
X unsigned int ifp, ofp;
X unsigned char x;
X
X
X pout = stdout;
X ifp = ofp = 0;
X init();
X
X for (i = 1; i < argc; ++i)
X {
X if (*argv[i] == '-' || *argv[i] == '+')
X pswitch(argv[i]);
X }
X
X for (i = 1; i < argc; ++i)
X {
X if (*argv[i] != '-' && *argv[i] != '+')
X {
X if(diskx)
X {
X addext(argv[i], newext, "lis", 1);
X pout = fopen(newext, "w+");
X co.lpr =
X diskx = 0;
X }
X
X addext(argv[i], newext, "txt", 0);
X
X if ((file[0].fle = fopen(newext, "r")) == NULL)
X error("unable to open file %s\n", newext);
X else
X {
X strcpy(file[0].fname, newext);
X file[0].fline = 0;
X profile();
X fclose(file[0].fle);
X }
X }
X }
X
X if (argc == 1)
X {
X fprintf (stderr, "Usage: nro [-n] [+n] [-pxx] [-l] [-d] [-mmacfile] infile ...\n");
X exit(1);
X }
X
X br();
X
X if (pg.lineno > 0)
X space(HUGE);
X
X fflush(pout);
X fclose(pout);
X}
X
X
X
X/*
X * retrieve one line of input text
X */
X
Xgetlin(p, in_buf)
Xregister unsigned char *p;
Xregister FILE *in_buf;
X{
X register unsigned int i, c;
X register unsigned char *q;
X
X q = p;
X
X for (i = 0; i < MAXLINE - 1; ++i)
X {
X if((c = ngetc(in_buf)) == EOF)
X {
X *q = EOS;
X c = strlen(p);
X return (c == 0 ? EOF : c);
X }
X
X *q++ = c;
X
X if (c == '\n')
X break;
X }
X
X *q = EOS;
X
X if(*p == '|')
X return(getlin(p, in_buf));
X else
X return (strlen(p));
X}
X
X
X
X
X/*
X * initialize parameters for nro word processor
X */
X
Xinit()
X{
X register int i;
X
X dc.rmval = PAGEWIDTH - 1;
X dc.mauto =
X dc.lsval = 1;
X pg.m1val =
X pg.m2val =
X pg.m3val =
X pg.m4val = 2;
X dc.fill =
X dc.juval = YES;
X dc.pgchr = '#';
X dc.ichr =
X dc.cmdchr = '.';
X dc.prflg = TRUE;
X pg.newpag = 1;
X pg.plval = PAGELEN;
X setbot();
X pg.lastpg = 30000;
X pg.ehead = malloc(MAXLINE);
X pg.ohead = malloc(MAXLINE);
X pg.efoot = malloc(MAXLINE);
X pg.ofoot = malloc(MAXLINE);
X pg.thead = malloc(MAXLINE);
X strcpy(pg.ehead, "\n");
X strcpy(pg.ohead, "\n");
X strcpy(pg.efoot, "\n");
X strcpy(pg.ofoot, "\n");
X pg.ehlim[RIGHT] =
X pg.ohlim[RIGHT] =
X pg.eflim[RIGHT] =
X pg.oflim[RIGHT] =
X dc.tmval = dc.rmval;
X co.lpr = FALSE;
X mac.pbb = malloc(PUSHBUF);
X mac.mb = malloc(MACBUF);
X mac.emb = mac.mb;
X}
X
X
X
X/*
X * get character from input file or push back buffer
X */
X
Xngetc(infp)
Xregister FILE *infp;
X{
X register int c;
X
X
X if (mac.ppb >= mac.pbb)
X c = *mac.ppb--;
X else if((c = getc(infp)) == '\n')
X ++file[dc.flevel].fline;
X
X return (c);
X}
X
X
X
X/*
X * process input files from command line
X */
X
Xprofile()
X{
X unsigned char ibuf[MAXLINE];
X
X for (dc.flevel = 0; dc.flevel >= 0; --dc.flevel)
X {
X while (getlin(ibuf, file[dc.flevel].fle) != EOF)
X {
X if (ibuf[0] == dc.cmdchr)
X comand(ibuf);
X else
X text(ibuf);
X }
X
X if (dc.flevel > 0)
X fclose(file[dc.flevel].fle);
X }
X}
X
X
X
X/*
X * process switch values from command line
X */
X
Xpswitch(p)
Xregister unsigned char *p;
X{
X unsigned int swgood = TRUE;
X unsigned char tempbuf[150];
X
X
X if (*p == '-')
X {
X ++p;
X
X switch (tolower(*p))
X {
X case 'r':
X raw = TRUE;
X break;
X
X case 'm':
X addext(++p, newext, "nro", 0);
X
X if ((file[0].fle = fopen(newext, "r")) == NULL)
X {
X sprintf(tempbuf, "/usr/lib/tmac/tmac.%s", newext);
X strcpy(newext, tempbuf);
X
X if((file[0].fle = fopen(tempbuf, "r")) == NULL)
X error("unable to open macro file %s\n", newext);
X }
X
X strcpy(file[0].fname, newext);
X file[0].fline = 0;
X profile();
X fclose(file[0].fle);
X break;
X
X case 'p':
X set(&pg.offset, ctod(++p), '1', 0, 0, HUGE);
X pg.tofset = pg.offset;
X break;
X
X case 'l':
X co.lpr = TRUE;
X break;
X
X case 'd':
X diskx =
X disk = TRUE;
X break;
X
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 pg.lastpg = ctod(p);
X break;
X
X default:
X swgood = FALSE;
X break;
X }
X }
X else if (*p == '+')
X pg.frstpg = ctod(++p);
X else
X fprintf (stderr, "illegal switch %s\n", p);
X
X return(OK);
X}
X
X
X
Xerror(f, a)
Xchar *f, *a;
X{
X trouble("FATAL ERROR ");
X fprintf(stderr, f, a);
X exit(1);
X}
X
X
X
Xtrouble(f, a)
Xregister unsigned char *f, *a;
X{
X fprintf(stderr, "nro: [%d %s] ", file[dc.flevel].fline, file[dc.flevel].fname);
X fprintf(stderr, f, a);
X}
X
X
Xtolower(byte)
Xregister unsigned char byte;
X{
X register unsigned char x;
X
X x = byte & 0x7f;
X
X if(x >= 'A' && x <= 'Z')
X return(byte + ' ');
X else
X return(byte);
X}
X
X
X
Xisdigit(byte)
Xregister unsigned char byte;
X{
X register unsigned char x;
X
X x = byte & 0x7f;
X
X if(x >= '0' && x <= '9')
X return(1);
X else
X return(0);
X}
X
X
X
Xisalpha(byte)
Xregister unsigned char byte;
X{
X register unsigned char x;
X
X x = tolower(byte) & 0x7f;
X
X if(x >= 'a' && x <= 'z')
X return(1);
X else
X return(0);
X}
X
X
X
X
Xiswhite(byte)
Xregister unsigned char byte;
X{
X register unsigned char x;
X
X x = byte & 0x7f;
X
X if(x == ' ' || x == '\t')
X return(1);
X else
X return(0);
X}
X
X
Xislower(byte)
Xregister unsigned char byte;
X{
X register unsigned char x;
X
X x = byte & 0x7f;
X
X if(x >= 'a' && x <= 'z')
X return(1);
X else
X return(0);
X}
X
X
Xisspace(byte)
Xregister unsigned char byte;
X{
X register unsigned char x;
X
X x = byte & 0x7f;
X
X if(x == ' ')
X return(1);
X else
X return(0);
X}
X
X
X
Xisterm(byte)
Xregister unsigned char byte;
X{
X if(byte == EOS)
X return(1);
X
X return(iscr(byte));
X}
X
X
Xiscr(byte)
Xregister unsigned char byte;
X{
X if(byte == '\n')
X return(1);
X else
X return(0);
X}
X
X
X
X
X/* "addext" - add an extension to a file spec/name. If the */
X/* filespec already has an extension, then the */
X/* condition of 'flag' determines if a new extension */
X/* will be forced. On entry: */
X/* from points to filespec/name */
X/* to points to where you want the new one */
X/* ext points to the extension to add */
X/* flag 1 = force new extension */
X/* 0 = add extension ONLY if one is needed */
X/* */
X
X
Xaddext(from, to, ext, flag)
Xregister unsigned char *to, *from;
Xunsigned char *ext;
Xunsigned char flag;
X{
X register unsigned char *pnt;
X unsigned char name[100];
X unsigned char extension[5];
X unsigned char c;
X
X
X name[0] = 0;
X extension[0] = 0;
X
X
X pnt = move(from, name);
X c = *pnt++;
X
X if(c == '.')
X {
X pnt = move(pnt, extension);
X c = *pnt++;
X }
X
X if(c != 0)
X return(1);
X
X
X strcpy(to, name);
X strcat(to, ".");
X
X if(flag || (extension[0] == 0))
X strcat(to, ext);
X else
X strcat(to, extension);
X}
X
X
X
X
Xstatic move(from, to)
Xregister unsigned char *from, *to;
X{
X while(*from)
X {
X if(*from == '.')
X break;
X
X *to++ = *from++;
X }
X
X *to = 0;
X return(from);
X}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 664 nro.c
/bin/echo -n ' '; /bin/ls -ld nro.c
fi
/bin/echo 'Extracting nrocmd.c'
sed 's/^X//' <<'//go.sysin dd *' >nrocmd.c
X/*
X * Command processor for NRO text processor
X *
X * Stephen L. Browning
X * 5723 North Parker Avenue
X * Indianapolis, Indiana 46220
X *
X * Modified and enhanced by:
X * Ron Light
X * 6016 Croftway Ct.
X * Ft. Worth, Tx. 76131
X */
X
X#include <stdio.h>
X#include "nro.h"
X
X
Xextern struct docctl dc;
Xextern struct page pg;
Xextern FILE *pout;
Xextern struct cout co;
Xextern struct macros mac;
Xextern struct file file[];
Xextern unsigned char newext[];
Xextern unsigned char *divertbuf;
Xextern unsigned char *divpnt;
Xextern unsigned char inbuf[];
X
X
X/* for diversion routines */
Xint xoutp = 0;
Xint xoutw = 0;
Xint xoutwds = 0;
Xint tline = 0;
Xchar xoutbuf[MAXLINE] = 0;
X
X
Xcomand(p)
Xunsigned char *p;
X{
X unsigned int ct, val;
X unsigned int spval;
X unsigned int index;
X unsigned char argtyp;
X unsigned char *x;
X unsigned char name[MAXLINE];
X unsigned char macexp[MXMLEN];
X
X ct = comtyp(p, macexp);
X
X if (ct == UNKNOWN)
X {
X trouble("unrecognized command %s\n", p);
X return;
X }
X
X expesc(p, name);
X val = getval(p, &argtyp);
X
X switch (ct)
X {
X case CB: /* continuous bold */
X dc.cbold = TRUE; /* NO break */
X
X case BO: /* bold face */
X set(&dc.boval, val, argtyp, 1, 0, HUGE);
X dc.cuval = dc.ulval = 0;
X break;
X
X case BP: /* begin page */
X if (pg.lineno > 0)
X space(HUGE);
X
X set(&pg.curpag, val, argtyp, pg.curpag + 1, -HUGE, HUGE);
X pg.newpag = pg.curpag;
X pg.lineno = 0;
X break;
X
X case BR: /* break */
X br();
X break;
X
X case CC: /* command character */
X if (argtyp == '\n')
X dc.cmdchr = '.';
X else
X dc.cmdchr = argtyp;
X
X break;
X
X case CE: /* center */
X br();
X set(&dc.ceval, val, argtyp, 1, 0, HUGE);
X break;
X
X case CU: /* continuous underline */
X set(&dc.cuval, val, argtyp, 1, 0, HUGE);
X dc.ulval = dc.boval = 0;
X break;
X
X case DE: /* define macro */
X defmac(p, file[dc.flevel].fle);
X break;
X
X case EF: /* even footer */
X gettl(p, pg.efoot, &pg.eflim[0]);
X break;
X
X case EH: /* even header */
X gettl(p, pg.ehead, &pg.ehlim[0]);
X break;
X
X case EN: /* end macro definition */
X trouble("missing .de command\n");
X break;
X
X case FI: /* fill */
X br();
X dc.fill = YES;
X break;
X
X case FO: /* footer */
X gettl(p, pg.efoot, &pg.eflim[0]);
X gettl(p, pg.ofoot, &pg.oflim[0]);
X break;
X
X case HE: /* header */
X gettl(p, pg.ehead, &pg.ehlim[0]);
X gettl(p, pg.ohead, &pg.ohlim[0]);
X break;
X
X case IN: /* indenting */
X set(&dc.inval, val, argtyp, 0, 0, dc.rmval - 1);
X dc.tival = dc.inval;
X break;
X
X case JU: /* justify */
X dc.juval = YES;
X break;
X
X case LS: /* line spacing */
X set(&dc.lsval, val, argtyp, 1, 1, HUGE);
X break;
X
X case M1: /* set topmost margin */
X set(&pg.m1val, val, argtyp, 2, 0, HUGE);
X setbot();
X break;
X
X case M2: /* set second top margin */
X set(&pg.m2val, val, argtyp, 2, 0, HUGE);
X setbot();
X break;
X
X case M3: /* set first bottom margin */
X set(&pg.m3val, val, argtyp, 2, 0, HUGE);
X setbot();
X break;
X
X case M4: /* set bottom-most margin */
X set(&pg.m4val, val, argtyp, 2, 0, HUGE);
X setbot();
X break;
X
X case MACRO: /* macro expansion */
X maceval(p, macexp);
X break;
X
X case NE: /* need n lines */
X br();
X
X if (pg.bottom - pg.lineno + 1 < val * dc.lsval)
X space(HUGE);
X
X break;
X
X case NF: /* no fill */
X br();
X dc.fill = NO;
X break;
X
X case NJ: /* no justify */
X dc.juval = NO;
X break;
X
X case NR: /* set number register */
X p = skipbl(skipwd(p));
X
X if (!isalpha(*p))
X trouble("invalid or missing number register name\n");
X else
X {
X index = tolower(*p) - 'a';
X p = skipwd(p);
X val = getval(p, &argtyp);
X set(&dc.nr[index], val, argtyp, 0, -HUGE, HUGE);
X }
X
X break;
X
X case OF: /* odd footer */
X gettl(p, pg.ofoot, &pg.oflim[0]);
X break;
X
X case OH: /* odd header */
X gettl(p, pg.ohead, &pg.ohlim[0]);
X break;
X
X case PC: /* page number character */
X if (argtyp == '\n')
X dc.pgchr = EOS;
X else
X dc.pgchr = argtyp;
X
X break;
X
X case PL: /* page length */
X set(&pg.plval, val, argtyp, PAGELEN,
X pg.m1val + pg.m2val + pg.m3val + pg.m4val + 1, HUGE);
X setbot();
X break;
X
X case PO: /* page offset */
X set(&pg.offset, val, argtyp, 0, 0, HUGE);
X pg.tofset = pg.offset;
X break;
X
X case EP: /* even page offset */
X set(&pg.eofset, val, argtyp, 0, 0, HUGE);
X break;
X
X case OP: /* odd page offset */
X set(&pg.oofset, val, argtyp, 0 , 0, HUGE);
X break;
X
X case RM: /* right margin */
X set(&dc.rmval, val, argtyp, PAGEWIDTH, dc.tival + 1, HUGE);
X dc.tmval = dc.rmval;
X break;
X
X case SO: /* source file */
X p = skipbl(skipwd(p));
X
X if (getwrd(p, name) == 0)
X break;
X
X if (dc.flevel + 1 >= NFILES)
X error(".so commands nested too deeply\n");
X
X addext(name, newext, "txt", 0);
X
X if ((file[dc.flevel + 1].fle = fopen(newext, "r")) == NULL)
X {
X trouble("unable to open %s\n", name);
X break;
X }
X
X ++dc.flevel;
X strcpy(file[dc.flevel].fname, newext);
X file[dc.flevel].fline = 0;
X break;
X
X case SP: /* space */
X set(&spval, val, argtyp, 1, 0, HUGE);
X space(spval);
X break;
X
X case TI: /* temporary indent */
X br();
X set(&dc.tival, val, argtyp, 0, 0, dc.rmval);
X break;
X
X case UL: /* underline */
X set(&dc.ulval, val, argtyp, 0, 1, HUGE);
X dc.cuval = dc.boval = 0;
X break;
X
X case TL: /* temp title */
X br();
X gettl(p, pg.thead, &pg.tlim[0]);
X title(pg.thead, pg.tlim, pg.curpag);
X break;
X
X case PI: /* put inside of indention field */
X br();
X putin(p);
X break;
X
X case AR: /* set (normal) aribic numbers */
X dc.roman =
X dc.rlower = FALSE;
X break;
X
X case CR: /* set capital roman numerials */
X dc.roman = TRUE;
X dc.rlower = FALSE;
X break;
X
X case LR: /* set lower case roman numerials */
X dc.roman =
X dc.rlower = TRUE;
X break;
X
X case DA: /* add current date to text */
X getdate(1);
X break;
X
X case PN: /* new page number */
X set(&pg.curpag, val, argtyp, 0, -HUGE, HUGE);
X
Xbp:
X if(pg.lineno)
X pg.newpag = pg.curpag+1;
X else
X pg.newpag = pg.curpag;
X
X break;
X
X case AI: /* auto increment for registers */
X set(&dc.rauto, val, argtyp, 1, -HUGE, HUGE);
X break;
X
X case DV: /* set divert buffer on */
X if(!divertbuf)
X {
X divertbuf = malloc(2000);
X divpnt = divertbuf;
X }
X
X save();
X dc.divert = TRUE;
X break;
X
X case ED: /* end divert */
X if(dc.divert)
X {
X br();
X dc.divert = FALSE;
X *divpnt = EOS;
X
X if (pg.bottom - pg.lineno < dc.divlin)
X {
X dc.divsav = dc.divlin;
X dc.divlin = 0;
X }
X
X restore();
X setbot();
X }
X
X break;
X
X case RV: /* recall diverted text */
X br();
X
X if(dc.divsav && !dc.divlin)
X dc.divlin = dc.divsav;
X
X dumpdivert();
X break;
X
X case LI: /* output in literal mode */
X br();
X set(&dc.literal, val, argtyp, 1, -HUGE, HUGE);
X break;
X
X case AX: /* set auto index mode */
X dc.aindex = TRUE;
X val = AUTO;
X goto mindex;
X
X case IX: /* set manual index mode */
X val = MANUAL;
Xmindex:
X p = skipbl((x = skipwd(p)));
X
X if(isspace(*x))
X ++x;
X
X if(!isterm(*p))
X {
X dc.indexx = TRUE;
X addsym(p, val, 1);
X text(dc.literal ? x : p);
X }
X
X break;
X
X case EX: /* add word to index, but don't output as text */
X p = skipbl(skipwd(p));
X
X if(!isterm(*p))
X {
X dc.aindex =
X dc.indexx = TRUE;
X addsym(p, AUTO, 0);
X }
X
X break;
X
X case SX: /* set index fill character */
X p = skipbl(skipwd(p));
X
X if(*p == '\'')
X dc.ichr = *++p;
X
X break;
X
X case PX: /* print index page */
X pindex();
X break;
X
X case AU: /* set manual increment value */
X set(&dc.mauto, val, argtyp, 0, -HUGE, HUGE);
X break;
X
X case ST: /* stop processor */
X br();
X fprintf(stderr, "...[stoped]... ");
X fflush(stderr);
X
X val = getc(stdin);
X
X if(tolower(val) == 's')
X exit(1);
X }
X}
X
X
X
X/*
X * convert ascii character to decimal.
X */
X
Xatod(c)
Xunsigned char c;
X{
X return (((c < '0') || (c > '9')) ? -1 : c-'0');
X}
X
X
X
X/*
X * end current filled line
X */
X
Xbr()
X{
X if (co.outp)
X {
X co.outbuf[co.outp] = '\n';
X co.outbuf[co.outp + 1] = EOS;
X put(co.outbuf);
X }
X else if(inbuf[0])
X {
X both();
X prchar('\n');
X }
X
X reset();
X co.outp =
X co.outw =
X co.outwds = 0;
X}
X
X
X
X/*
X * Save text in buffer so we can divert
X */
X
X
Xsave()
X{
X if (co.outp)
X {
X co.outbuf[co.outp] = EOS;
X strcpy(xoutbuf, co.outbuf);
X xoutp = co.outp;
X xoutw = co.outw;
X xoutwds = co.outwds;
X }
X
X co.outp =
X co.outw =
X co.outwds =
X co.outbuf[0] = 0;
X tline = pg.lineno;
X pg.lineno = 7;
X}
X
X
X
X
X/*
X * restore the text we saved from diversion
X */
X
Xrestore()
X{
X if (xoutp)
X {
X strcpy(co.outbuf, xoutbuf);
X co.outp = xoutp;
X co.outw = xoutw;
X co.outwds = xoutwds;
X }
X
X xoutp =
X xoutw =
X xoutwds = 0;
X pg.lineno = tline;
X}
X
X
X
X
X/*
X * Collect macro definition from input stream
X */
X
Xcolmac(p, d, i)
Xregister unsigned char *p, d[];
Xregister int i;
X{
X while (*p != EOS)
X {
X if (i >= MXMLEN - 1)
X {
X d[i - 1] = EOS;
X return (ERR);
X }
X
X d[i++] = *p++;
X }
X
X d[i] = EOS;
X return(i);
X}
X
X
X
X
X/*
X * decodes nro command and returns its associated
X * value.
X */
X
X
Xstruct comm comtab[] =
X{
X ".", EN,
X "ai", AI,
X "ar", AR,
X "au", AU,
X "ax", AX,
X "bo", BO,
X "bp", BP,
X "br", BR,
X "cb", CB,
X "cc", CC,
X "ce", CE,
X "cr", CR,
X "cu", CU,
X "da", DA,
X "de", DE,
X "dv", DV,
X "ed", ED,
X "ef", EF,
X "eh", EH,
X "en", EN,
X "ep", EP,
X "ex", EX,
X "fi", FI,
X "fo", FO,
X "he", HE,
X "in", IN,
X "ix", IX,
X "ju", JU,
X "li", LI,
X "lr", LR,
X "ls", LS,
X "m1", M1,
X "m2", M2,
X "m3", M3,
X "m4", M4,
X "ne", NE,
X "nf", NF,
X "nj", NJ,
X "nr", NR,
X "of", OF,
X "oh", OH,
X "op", OP,
X "pc", PC,
X "pi", PI,
X "pl", PL,
X "pn", PN,
X "po", PO,
X "px", PX,
X "rm", RM,
X "rv", RV,
X "so", SO,
X "sp", SP,
X "st", ST,
X "sx", SX,
X "ti", TI,
X "tl", TL,
X "ul", UL,
X 0, 0
X};
X
X
X
Xcomtyp(p, m)
Xregister unsigned char *p, *m;
X{
X unsigned char macnam[MNLEN];
X register unsigned char *s;
X
X p++;
X
X /*
X * First check to see if the command is a macro.
X * If it is, truncate to two characters and return
X * expansion in m. Note that upper and lower case
X * characters are handled differently for macro names,
X * but not for normal command names.
X */
X gettok(p, macnam);
X macnam[2] = EOS;
X
X if ((s = getmac(macnam)) != NULL)
X {
X strcpy(m, s);
X return (MACRO);
X }
X
X return(findcomm(p));
X}
X
X
Xfindcomm(p)
Xregister unsigned char *p;
X{
X unsigned char xbuff[4];
X register unsigned int i;
X
X xbuff[0] = tolower(*p);
X p++;
X
X if(*p > ' ')
X {
X xbuff[1] = tolower(*p);
X xbuff[2] = 0;
X }
X else
X xbuff[1] = 0;
X
X for(i = 0; ; i++)
X {
X if(!(comtab[i].c1))
X return(UNKNOWN);
X
X if(strcmp(comtab[i].c1, xbuff))
X continue;
X
X return(comtab[i].c2);
X }
X}
X
X
X
X/*
X * convert string to decimal.
X * processes only positive values.
X */
X
Xctod(p)
Xregister unsigned char *p;
X{
X register unsigned int val, d;
X
X
X val = 0;
X
X while(*p != EOS)
X {
X d = atod(*p++);
X
X if (d == -1)
X return (val);
X
X val = 10 * val + d;
X }
X
X return (val);
X}
X
X
X/*
X * Define a macro
X */
X
Xdefmac(p, infp)
Xregister unsigned char *p;
Xregister FILE *infp;
X{
X register unsigned int i;
X register unsigned char *q;
X unsigned char name[MNLEN];
X unsigned char defn[MXMLEN];
X
X q = skipbl(skipwd(p));
X i = getwrd(q, name);
X
X if (!isalpha(*name))
X error("missing or illegal macro definition name\n");
X
X if (i > 2)
X name[2] = EOS;
X
X i = 0;
X
X while (getlin(p, infp) != EOF)
X {
X if(*p == '|')
X continue;
X
X if((*p == '.') && (findcomm(p+1) == EN))
X break;
X
X if ((i = colmac(p, defn, i)) == ERR)
X error("macro definition too long\n");
X }
X
X if (putmac(name, defn) == ERR)
X error("macro definition table full\n");
X}
X
X
X/*
X * Expand escape sequences
X */
X
Xexpesc(p, q)
Xregister unsigned char *p, *q;
X{
X register unsigned char *s, *t, *r;
X register unsigned char byte;
X unsigned char buff[30];
X
X
X s = p;
X t = q;
X
X while (*s != EOS)
X {
X /* look for "don't touch" characters */
X if (*s == '\\')
X {
X ++s;
X byte = *s++;
X byte |= (unsigned) 0x80;
X *t = byte;
X ++t;
X }
X /* look for date substitution */
X else if(*s == '^')
X {
X ++s;
X strcpy(buff, getdate(0));
X r = buff;
X
X while(*r)
X *t++ = *r++;
X }
X /* look for quoted strings and don't touch */
X else if(*s == '"')
X {
X *t++ = *s++; /* store the 1st one */
X
X while(*s && *s != '"')
X *t++ = *s++;
X
X if(*s)
X *t++ = *s++; /* store the 2nd one */
X }
X /* look for number register */
X else if (*s == '@')
X {
X if (s[1] == '@')
X {
X *t++ = *s++;
X ++s;
X }
X else if (tolower(s[1]) == 'n')
X {
X if(s[2] == '+' && isalpha(s[3]))
X {
X s += 3;
X byte = tolower(*s) - 'a';
X dc.nr[byte] += dc.mauto;
X goto figure;
X }
X else if(isalpha(s[2]))
X {
X s += 2;
X byte = tolower(*s) - 'a';
X
X if(dc.rauto)
X dc.nr[byte] += dc.rauto;
X
Xfigure:
X t += itoda(dc.nr[byte], t, 6) - 1;
X ++s;
X }
X }
X }
X else
X *t++ = *s++;
X }
X
X *t = EOS;
X strcpy(p, q);
X}
X
X
X
X/*
X * Get macro definition from table
X */
X
Xgetmac(name)
Xregister unsigned char *name;
X{
X register int i, j;
X
X if(!strcmp(".", name))
X return(NULL);
X
X for (i = mac.lastp; i >= 0; --i)
X if (!strcmp(name, mac.mnames[i]))
X return (mac.mnames[i] + 3);
X
X return(NULL);
X}
X
X
X
X
X/*
X * get header or footer title
X */
X
Xgettl(p, q, limit)
Xregister unsigned char *p, *q;
Xregister unsigned int limit[];
X{
X p = skipbl(skipwd(p));
X strcpy(q, p);
X limit[LEFT] = dc.inval;
X limit[RIGHT] = dc.rmval;
X}
X
X
X
X
X/*
X * retrieves optional argument following nro command.
X * returns positive integer value with sign (if any)
X * saved in character addressed by p_argt.
X */
X
Xgetval(p, p_argt)
Xregister unsigned char *p;
Xregister unsigned char *p_argt;
X{
X p = skipbl(skipwd(p));
X *p_argt = *p;
X
X if ((*p == '+') || (*p == '-'))
X ++p;
X
X return (ctod(p));
X}
X
X
X/*
X * Evaluate macro expansion
X */
X
Xmaceval(p, m)
Xregister unsigned char *p;
Xregister unsigned char m[];
X{
X register unsigned int j;
X register int i;
X register unsigned char hold[200];
X register unsigned char *xx;
X unsigned char *argp[10];
X unsigned char c;
X
X
X *p++ = EOS; /* replace command char with EOS */
X
X /*
X * initialize argp array to substitute command
X * string for any undefined argument
X */
X for (i = 0; i < 10; ++i)
X argp[i] = EOS; /* was "p" */
X
X p = skiptok(p);
X xx = skipbl(p);
X
X if(*xx == '.')
X sprintf(hold, "\\%s", xx);
X else
X sprintf(hold, "%s", xx);
X
X xx = &hold[strlen(hold) -2];
X
X while(*xx)
X if(iscr(*xx))
X break;
X else
X ++xx;
X
X *xx = ' ';
X *xx = EOS;
X *p++ = EOS;
X
X for (i = 0; i < 10; ++i)
X {
X p = skipbl(p);
X
X if (isterm(*p))
X break;
X
X if (*p == '\'' || *p == '"')
X {
X c = *p++;
X argp[i] = p;
X
X while (*p != c && !isterm(*p))
X ++p;
X
X *p++ = EOS;
X }
X else
X {
X argp[i] = p;
X p = skipwd(p);
X *p++ = EOS;
X }
X }
X
X for (i = strlen(m) - 1; i >= 0; --i)
X {
X if (i > 0 && m[i - 1] == '$')
X {
X if(m[i] == '$')
X {
X pbstr(hold);
X --i;
X }
X else if (!isdigit(m[i]))
X putbak(m[i]);
X else
X {
X pbstr(argp[m[i]-'0']);
X --i;
X }
X }
X else
X putbak(m[i]);
X }
X}
X
X
X/*
X * Push back string into input stream
X */
X
Xpbstr(p)
Xregister unsigned char p[];
X{
X register int i;
X
X for (i = strlen(p) - 1; i >= 0; --i)
X putbak(p[i]);
X}
X
X
X
X/*
X * Push character back into input stream
X */
X
Xputbak(c)
Xunsigned char c;
X{
X if (mac.ppb < mac.pbb)
X {
X mac.ppb = mac.pbb;
X *mac.ppb = c;
X }
X else
X {
X if (mac.ppb >= (mac.pbb+PUSHBUF) - 1)
X error("push back buffer overflow\n");
X
X *++mac.ppb = c;
X }
X}
X
X
X
X
X/*
X * Put macro definition into table
X */
X
Xputmac(name, p)
Xregister unsigned char *name, *p;
X{
X if (mac.lastp >= MXMDEF)
X return (ERR);
X
X if (mac.emb + strlen(name) + strlen(p) + 1 > mac.mb+MACBUF)
X return(ERR);
X
X ++mac.lastp;
X mac.mnames[mac.lastp] = mac.emb;
X strcpy(mac.emb, name);
X strcpy(mac.emb + 3, p);
X mac.emb += 3 + strlen(p) + 2;
X return (OK);
X}
X
X
X
X
X/*
X * set parameter and check range
X */
X
Xset(param, val, type, defval, minval, maxval)
Xregister unsigned int *param;
Xregister unsigned int val, defval, minval, maxval;
Xregister unsigned char type;
X{
X switch (type)
X {
X case '\n':
X *param = defval;
X break;
X
X case '+':
X *param += val;
X break;
X
X case '-':
X *param -= val;
X break;
X
X default:
X *param = val;
X break;
X }
X
X *param = min(*param, maxval);
X *param = max(*param, minval);
X}
X
X
X
X/*
X * skip blanks and tabs in character buffer.
X * return number of characters skipped.
X */
X
Xskipbl(p)
Xregister unsigned char *p;
X{
X while (iswhite(*p))
X ++p;
X
X return (p);
X}
X
X
X/*
X * skip over word and punctuation
X */
X
Xskipwd(p)
Xregister unsigned char *p;
X{
X while (!iswhite(*p) && !isterm(*p))
X ++p;
X
X return (p);
X}
X
X
X
X/*
X * skip over token
X */
X
Xskiptok(p)
Xregister unsigned char *p;
X{
X register int i;
X
X for(i = 0; i < 2; i++)
X if(iswhite(*p))
X break;
X else
X ++p;
X
X return(p);
X}
X
X
X
X/*
X * get next token
X */
X
Xgettok(from, to)
Xregister unsigned char *from, *to;
X{
X register int i;
X
X for(i = 0; i < 2; i++)
X if(iswhite(*from))
X break;
X else
X *to++ = *from++;
X
X *to = EOS;
X return(i);
X}
X
X
X
X/*
X * space vertically n lines
X */
X
Xspace(n)
Xregister unsigned int n;
X{
X register unsigned int i;
X
X
X br();
X setbot();
X
X if (pg.lineno > pg.bottom)
X {
X if(!(pg.m1val+pg.m2val+pg.m3val+pg.m4val))
X skip(n * dc.lsval);
X
X return;
X }
X
X if (pg.lineno == 0)
X phead();
X
X skip(min(n, pg.bottom + 1 - pg.lineno));
X chkbot();
X}
X
X
X
Xsetbot()
X{
X if(!dc.divert)
X pg.bottom = pg.plval - (pg.m4val + pg.m3val + dc.divlin + 1);
X}
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
/bin/chmod 664 nrocmd.c
/bin/echo -n ' '; /bin/ls -ld nrocmd.c
fi
--
More information about the Comp.sources.unix
mailing list