ron@trsvax.UUCP (09/16/83)
#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 --