/* * 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 #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') { 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 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 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; }