home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d197
/
nro.lha
/
Nro
/
nro.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-28
|
9KB
|
498 lines
/*
* NRO Text Formatter -
* similar to Unix NROFF or RSX-11M RNO -
* adaptation of text processor given in
* "Software Tools", Kernighan and Plauger.
*
* Originally by Stephen L. Browning, 5723 North Parker Avenue
* Indianapolis, Indiana 46220
*
* Transformed beyond immediate recognition, and
* adapted for Amiga by Olaf Seibert, KosmoSoft
*
* Vossendijk 149-1 (study) Beek 5 (home)
* 5634 TN Nijmegen 5815 CS Merselo
* The Netherlands The Netherlands
* Phone:
* (...-31)80561045 (...-31)4786205
* or 080-561045 04786-205
*
* This program is NOT in the public domain. It may, however
* be distributed only at no charge, and this notice must be
* included unaltered.
*/
#include <stdio.h>
#include "nro.h"
#include "nroxtrn.h"
main(argc, argv)
int argc;
uchar *argv[];
{
int i;
int ofp;
pout = stdout;
ofp = 0;
init();
for (i=1; i<argc; i++) {
if (*argv[i] == '-' || *argv[i] == '+') {
pswitch(argv[i]);
} else if (*argv[i] == '>') {
if (ofp == 0) {
#ifdef CPM
if (!strcmp(argv[i]+1, "$P")) {
ofp = 1;
co.lpr = TRUE;
} else
#endif
if ((pout = fopen(argv[i]+1, "w")) == NULL) {
error("*** nro: cannot create %s\n", argv[i]+1);
} else {
ofp = 1;
}
} else {
error("*** nro: too many output files\n");
}
}
}
for (i=1; i<argc; i++) {
if (*argv[i] != '-' && *argv[i] != '+' && *argv[i] != '>') {
if ((sofile[0] = fopen(argv[i], "r")) == NULL) {
error("nro: unable to open file %s\n", argv[i]);
continue;
} else {
if (verbose > 2)
error("nro: processing file '%s'\n", argv[i]);
profile();
fclose(sofile[0]);
}
}
}
if (argc == 1) {
error("Usage: nro [-#] [+#] [-p#] [-v] [-b#] [-rn#] [-rd#] [-rp#]\n"
" [-mmacfile] infile(s) ... [>outfile]\n");
fatal();
} else {
endfiles();
}
#ifdef CMPEOF
putc(CPMEOF, pout);
#endif CMPEOF
fflush(pout);
if (pout != stdout) {
fclose(pout);
}
}
/*
* Retrieve one line of input text
*/
getlin(p, infile)
uchar *p;
FILE *infile;
{
int i;
int c;
uchar *q;
q = p;
for (i=0; i<MAXLINE-1; i++) {
c = ngetc(infile);
#ifdef CPMEOF
if (c == CPMEOF || c == EOF) {
#if 0
} /* To keep ctags, cb and such happy */
#endif
#else
if (c == EOF) {
#endif CPMEOF
*q = EOS;
return i == 0 ? EOF : 0;
}
*q++ = c;
if (iseol(c)) break;
}
*q = EOS;
return q - p; /* strlen(p) */
}
/*
* Initialize parameters for nro word processor
*/
init()
{
int i;
static char nl[] = "\n";
dc.bsflg = FALSE;
dc.curmode = FXPLAIN;
dc.envsp = 0;
dc.envstack[0] = 0;
for (i=0; i<26; i++) dc.nr[i] = 0;
#ifdef CPM
dc.lpr = FALSE;
#endif
for (i=0; i<NUMENV; i++) environ[i] = NULL;
initenv();
pg.curpag = 0;
pg.newpag = 1;
pg.lineno = 0;
pg.plval = PAGELEN;
pg.m1val = 2;
pg.m2val = 2;
pg.m3val = 2;
pg.m4val = 2;
pg.bottom = pg.plval - pg.m4val - pg.m3val;
pg.offset = 0;
pg.frstpg = 0;
pg.lastpg = 32767;
pg.prflg = TRUE;
strncpy(pg.ehead, nl, MAXLINE);
strncpy(pg.ohead, nl, MAXLINE);
strncpy(pg.efoot, nl, MAXLINE);
strncpy(pg.ofoot, nl, MAXLINE);
pg.ehlim[LEFT] = pg.ohlim[LEFT] = env.inval;
pg.eflim[LEFT] = pg.oflim[LEFT] = env.inval;
pg.ehlim[RIGHT] = pg.ohlim[RIGHT] = env.rmval;
pg.eflim[RIGHT] = pg.oflim[RIGHT] = env.rmval;
mac.mxmdef = MXMDEF;
mac.macbuf = MACBUF;
mac.mxmlen = MXMLEN;
mac.mnames = NULL;
mac.mb = NULL;
mac.pbb = NULL;
mac.lastp = 0;
mac.ppb = NULL;
}
/*
* Initenv - initialise the environment to default
*/
initenv()
{
int i;
env.fill = YES;
env.lsval = 1;
env.inval = 0;
env.tival = 0;
env.rmval = PAGEWIDTH - 1;
env.tmval = PAGEWIDTH - 1;
env.ceval = 0;
env.ulval = 0;
env.cuval = 0;
env.boval = 0;
env.itval = 0;
env.juval = YES;
env.pgchr = PGCHAR;
env.cmdchr = CMDCHAR;
env.c2chr = C2CHAR;
env.sprdir = 0;
env.dontbrk = FALSE;
env.reqmode = FXPLAIN;
env.expmode = FXPLAIN;
env.curmode = FXPLAIN;
env.outp = 0;
env.outw = 0;
env.outwds = 0;
strncpy(env.outbuf, "", MAXLINE);
for (i=0; i<MAXTAB; i++) env.tabstop[i] = NOTAB;
}
/*
* Initialize buffers for macros
*/
initbuffers()
{
static short inited = FALSE;
int i;
if (inited)
return;
if ((mac.mnames=(uchar **)malloc(sizeof(*mac.mnames)*mac.mxmdef)) &&
(mac.mb =(uchar *)malloc(sizeof(*mac.mb) *mac.macbuf)) &&
(mac.pbb =(uchar *)malloc(sizeof(*mac.pbb) *mac.mxmlen)) ) {
for (i=0; i<mac.mxmdef; i++) mac.mnames[i] = NULL;
mac.emb = mac.mb;
mac.ppb = mac.pbb - 1;
mac.pbbend = mac.pbb + mac.mxmlen;
if (verbose > 1) {
error("nro: max number of macros: %d\n", mac.mxmdef);
error(" max total length of macro definitions: %d\n",
mac.macbuf);
error(" max pushback characters: %d\n", mac.mxmlen);
}
inited = TRUE;
} else {
error("*** nro: cannot allocate memory for macro buffers\n");
}
}
#define rawgetc(infp)\
((mac.ppb >= mac.pbb) ? pbbgetc() : getc(infp))
#define pbbgetc() (*mac.ppb--)
/*
* Get character from input file or push back buffer
*/
ngetc(infp)
FILE *infp;
{
register int chr;
int i, j;
again:
chr = rawgetc(infp);
if (chr != ESCCHAR) {
if (dc.iflvl == 0) return chr;
else goto again;
}
chr = rawgetc(infp);
switch (chr) {
case '\n': /* Concealed newline */
goto again;
case ' ': /* Non breakable space */
chr = NBSP;
break;
case '"': /* A comment */
while (isnteol(chr)) chr = rawgetc(infp);
break;
case ESCCHAR: /* Escaped escape character */
case 'e': /* Current value of escape character */
chr = ESCCHAR;
break;
case 'n': /* Substitute numeric register */
if (dc.iflvl) goto again;
chr = rawgetc(infp);
i = dc.nr[tolower(chr) - 'a'];
j = abs(i);
do {
putbak('0' + j % 10);
j /= 10;
} while (j);
if (i < 0) chr = '-';
else chr = pbbgetc();
break;
case 't': /* Tab */
chr = '\t';
break;
case 'X': /* eXtended Character */
chr = getval(&i, infp);
break;
case '{': /* Begin of if block */
if (dc.iflvl) dc.iflvl++;
chr = BEGIF;
break;
case '}': /* End of if block */
if (dc.iflvl) dc.iflvl--;
goto again;
/* @. to conceal line beginning with command chr */
default: /* Dunno. Somebody is mistakin'. Maybe even EOF. */
if (chr == env.cmdchr) chr |= 0x8000;
}
if (dc.iflvl) goto again;
return chr;
}
/*
* Restore push back buffer after closing a file
*/
restorepbb()
{
mac.ppb = mac.pbb - 1; /* Should not even be necessary */
mac.pbb = sopbb[dc.flevel - 1];
}
/*
* Process input files from command line
*/
profile()
{
int chr;
uchar ibuf[MAXWORD];
initbuffers();
for (dc.flevel=0; dc.flevel>=0; --dc.flevel) {
infile = sofile[dc.flevel];
while (ibuf[0] = chr = ngetc(infile), chr != EOF) {
if (chr == env.cmdchr) {
comand(ibuf); /* Command line */
} else
text(ibuf, infile); /* Text line */
}
if (dc.flevel > 0) {
fclose(infile);
restorepbb();
}
}
}
/*
* End processing of files: eject page if necessary.
*/
endfiles()
{
if (pg.lineno > 0 || env.outp != 0) space(pg.plval);
}
#define K *1024
#define M *1024 K
/*
* Process switch values from command line
*/
pswitch(p)
uchar *p;
{
int swgood;
swgood = TRUE;
if (*p == '-') {
switch (tolower(*++p)) {
case 'b':
set(&dc.bsflg, ctod(++p), '1', 1, 0, 2);
break;
case 'm':
if ((sofile[0] = fopen(++p, "r")) == NULL) {
error("*** nro: unable to open file %s\n", p);
}
if (verbose > 2)
error("nro: processing file '%s'\n", p);
profile();
fclose(sofile[0]);
break;
case 'p':
set(&pg.offset, ctod(++p), '1', 0, 0, HUGE);
break;
case 'r': /* Reserve memory */
switch(tolower(p[1])) {
case 'd': /* Total buffer for definitions */
if (mac.mb == NULL)
set(&mac.macbuf, ctod(&p[2]), '1', MACBUF, 0, 16 M);
else swgood = FALSE;
break;
case 'n': /* Number of definitions */
if (mac.mnames == NULL)
set(&mac.mxmdef, ctod(&p[2]), '1', MXMDEF, 0, 10 K);
else swgood = FALSE;
break;
case 'p': /* Pushback buffer */
if (mac.pbb == NULL)
set(&mac.mxmlen, ctod(&p[2]), '1', MXMLEN, 0, 100 K);
else swgood = FALSE;
break;
default:
swgood = FALSE;
}
break;
case 'v':
error("NRO - KosmoSoft version 1.5 - V25.06.88\n");
verbose = max(1,ctod(++p));
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
pg.lastpg = ctod(p);
break;
default:
swgood = FALSE;
break;
}
} else if (*p == '+') {
pg.frstpg = ctod(++p);
} else {
swgood = FALSE;
}
if (swgood == FALSE) {
error("*** nro: illegal switch %s\n", p);
}
return;
}
#undef K
#undef M
/*
* Print a message at the standard error channel
*/
/*VARARGS1*/
error(format, arg1, arg2, arg3)
uchar *format;
long arg1, arg2, arg3;
{
fflush(pout);
fprintf(stderr, format, arg1, arg2, arg3);
if (*format == '*')
fatal();
}
/*
* fatal - cannot recover from a serious error
*/
fatal()
{
exit(10);
}
int tolower(c)
register char c;
{
if (c >= 'A' && c <= 'Z')
return c - 'A' + 'a';
return c;
}
int toupper(c)
register char c;
{
if (c >= 'a' && c <= 'z')
return c - 'a' + 'A';
return c;
}