home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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;
- }
-