mirror of https://github.com/GnoConsortium/gno.git
initial checkin
This commit is contained in:
parent
e5b9329e55
commit
50a93eb0a9
|
@ -0,0 +1,39 @@
|
|||
CHANGES
|
||||
-------
|
||||
|
||||
2.0
|
||||
- Maintenance of nroff has been taken over by Devin Reade,
|
||||
<gdr@myrias.com>
|
||||
- Fixed a significant number of memory trashing bugs with the
|
||||
help of Insight.
|
||||
- Optimized for speed, mainly by translating some functions
|
||||
into inline code via macros.
|
||||
- Prototyped, indented and otherwise cleaned up code. Made use
|
||||
of some GNO v2.0.6 libc routines to reduce source code size.
|
||||
- Indented source.
|
||||
|
||||
=== The remaining versions listed below were by Mike Horwath, ===
|
||||
=== <mfrankow@seq.hamline.edu> and Jawaid Bazyar <bazyar@hypermall.com> ===
|
||||
|
||||
1.1p3.4
|
||||
Well, guess what? I caused a hell of an error in the last
|
||||
version of this, and now it is fixed. The problem stemmed
|
||||
from a library error and has been fixed. All thanks to Jawaid
|
||||
for creating and fixing the error all by himself. (no flame
|
||||
to ya Jawaid...heh)
|
||||
|
||||
1.1p3.3
|
||||
Fixed the problem with nroffing the LESS manpage. I don't
|
||||
really know how the hell I fixed it, but that bug is now gone.
|
||||
I also optimized the source to a great extent. There is no real
|
||||
speed increase in output, but the executable is MUCH smaller
|
||||
than the original posted version. Enjoy.
|
||||
|
||||
4/21/92 jb
|
||||
Fixed double-line problem when redirecting and piping the output
|
||||
of nroff. (It sticks \r's in the output text all over the place.
|
||||
I simply filter them out in prchar.)
|
||||
|
||||
[previous versions]
|
||||
Well, first release. The versions suck for now till I can
|
||||
figure out a better way to do it. It worked, but had bugs.
|
|
@ -0,0 +1,38 @@
|
|||
nroff - Text Processing Typesetter
|
||||
----------------------------------
|
||||
|
||||
This is 'nroff 1.2' for GNO/ME 1.0. This is fairly close to
|
||||
the real Unix nroff, although there are still some things that
|
||||
this one doesn't do that it should.
|
||||
|
||||
This software was ported by Mike Horwath and Jawaid Bazyar for
|
||||
the GNO Multitasking Environment. Various bug fixes were applied
|
||||
by Devin Reade.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Type 'dmake install' in this directory, or copy the following
|
||||
files:
|
||||
|
||||
nroff --> /usr/bin/nroff
|
||||
tmac.an --> /usr/lib/tmac/tmac.an
|
||||
tmac.s --> /usr/lib/tmac/tmac.s
|
||||
nroff.1 --> /usr/man/man1/nroff.1
|
||||
man.7 --> /usr/man/man7/man.7
|
||||
ms.7 --> /usr/man/man7/ms.7
|
||||
|
||||
If you want to put the macro files somewhere other than in
|
||||
/usr/lib/tmac, then set your TMACDIR environment variable to
|
||||
point to the directory in which they reside.
|
||||
|
||||
Compatibility
|
||||
-------------
|
||||
This software works with any GNO-compatible shell (Orca suffices,
|
||||
but pipes don't work very well under Orca, and according to
|
||||
dozens of GNO users, GNO is "simply superior".)
|
||||
|
||||
Bugs
|
||||
----
|
||||
This program uses recursion, Not A Good Thing on the IIgs.
|
||||
It really needs a rewrite.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* for diffent os, define tos, unix, or minix. for gemdos, pick
|
||||
* a compiler (alcyon, mwc, etc). see makefile for VERSFLAGS.
|
||||
*
|
||||
* for atari TOS, do: cc -Dtos -Dalcyon ...
|
||||
*
|
||||
* for minix, do: cc -D_MINIX -D_ST ... (ST minix)
|
||||
* cc -D_MINIX ... (PC minix)
|
||||
*
|
||||
* for unix, do: cc -Dunix ... (generic)
|
||||
* cc -Dunix -DBSD... (BSD)
|
||||
*
|
||||
* note: so far there is no specific ST minix version. -D_ST is ignored.
|
||||
*
|
||||
* nroff uses index/rindex. you may need -Dindex=strchr -Drindex=strrchr
|
||||
* as well. this file is included in "nroff.h" which gets included in all
|
||||
* sources so any definitions you need should be added here.
|
||||
*
|
||||
* all os-dependent code is #ifdef'ed with GEMDOS, MINIX_ST, MINIX_PC,
|
||||
* MINIX, or UNIX. most of the differences deal with i/o only.
|
||||
*/
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#ifdef __GNO__
|
||||
#define unix
|
||||
#define NEWLINE '\r'
|
||||
#endif
|
||||
|
||||
#ifdef ALCYON
|
||||
# ifndef tos
|
||||
# define tos
|
||||
# endif
|
||||
# ifndef alcyon
|
||||
# define alcyon
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef tos
|
||||
# define GEMDOS
|
||||
# undef minix
|
||||
# undef unix
|
||||
# undef MINIX
|
||||
# undef MINIX_ST
|
||||
# undef MINIX_PC
|
||||
# undef UNIX
|
||||
/*#define register*/
|
||||
#endif
|
||||
|
||||
#ifdef alcyon
|
||||
# ifndef ALCYON
|
||||
# define ALCYON /* for gemdos version, alcyon C */
|
||||
# endif
|
||||
# ifndef GEMDOS
|
||||
# define GEMDOS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef minix
|
||||
# ifndef _MINIX
|
||||
# define _MINIX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _MINIX
|
||||
# define MINIX
|
||||
# undef tos
|
||||
# undef unix
|
||||
# undef GEMDOS
|
||||
# undef MINIX_ST
|
||||
# undef MINIX_PC
|
||||
# undef UNIX
|
||||
# ifdef _ST
|
||||
# ifndef atariST
|
||||
# define atariST
|
||||
# endif
|
||||
# endif
|
||||
# ifdef atariST
|
||||
# define MINIX_ST
|
||||
# else
|
||||
# define MINIX_PC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef unix
|
||||
/* just in case <ctype.h> does not define it (slightly different anyway) */
|
||||
/*#define tolower(x) (isupper(x)?((x)-'A'+'a'):(x))*/
|
||||
# undef tos
|
||||
# undef minix
|
||||
# undef _MINIX
|
||||
# undef GEMDOS
|
||||
# undef _ST
|
||||
# undef MINIX_ST
|
||||
# undef MINIX_PC
|
||||
# ifndef UNIX
|
||||
# define UNIX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /*CONFIG_H*/
|
|
@ -0,0 +1,759 @@
|
|||
/*
|
||||
* escape.c - Escape and special character input processing portion of
|
||||
* nroff word processor
|
||||
*
|
||||
* adapted for atariST/TOS by Bill Rosenkranz 11/89
|
||||
* net: rosenkra@hall.cray.com
|
||||
* CIS: 71460,17
|
||||
* GENIE: W.ROSENKRANZ
|
||||
*
|
||||
* original author:
|
||||
*
|
||||
* Stephen L. Browning
|
||||
* 5723 North Parker Avenue
|
||||
* Indianapolis, Indiana 46220
|
||||
*
|
||||
* history:
|
||||
*
|
||||
* - Originally written in BDS C;
|
||||
* - Adapted for standard C by W. N. Paul
|
||||
* - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
|
||||
* - Heavily modified by Devin Reade to avoid memory trashing bugs.
|
||||
*
|
||||
* $Id: escape.c,v 1.1 1997/03/14 06:22:27 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "escape____";
|
||||
#endif
|
||||
|
||||
#define INVERSE '\xF'
|
||||
#define NORMAL '\xE'
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __GNO__
|
||||
#include <err.h>
|
||||
#else
|
||||
#include "err.h"
|
||||
#endif
|
||||
|
||||
#ifdef sparc
|
||||
#include "sunos.h"
|
||||
#endif
|
||||
|
||||
#include "nroff.h"
|
||||
#include "escape.h"
|
||||
#include "macros.h"
|
||||
|
||||
static int specialchar (char *s, char *c);
|
||||
|
||||
/*
|
||||
* expesc
|
||||
*
|
||||
* Expand escape sequences in the buffer <src>, placing the results
|
||||
* in buffer <dest>. If the number of characters written into <dest>
|
||||
* would be more than <len-1> characters, then abort with an error
|
||||
* message.
|
||||
*/
|
||||
void
|
||||
expesc (char *src, char *dest, size_t len) {
|
||||
register char *s;
|
||||
register char *t;
|
||||
register char *pstr;
|
||||
register int i;
|
||||
register int val;
|
||||
register int autoinc;
|
||||
char c;
|
||||
char fs[5]; /* for font change */
|
||||
char nrstr[20];
|
||||
char fmt[20];
|
||||
char name[10];
|
||||
int nreg;
|
||||
char *pfs;
|
||||
int inc;
|
||||
int tmp;
|
||||
char delim;
|
||||
const char *percent = "%";
|
||||
char *scratch;
|
||||
|
||||
|
||||
s = src;
|
||||
t = dest;
|
||||
|
||||
|
||||
/*
|
||||
* if escape parsing is not on, just copy string
|
||||
*/
|
||||
if (dc.escon == NO) {
|
||||
if (strlen(src) > len-1) {
|
||||
errx(-1, "buffer overflow at %s:%d", __FILE__, __LINE__);
|
||||
}
|
||||
strcpy (dest, src);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* do it...
|
||||
*/
|
||||
while (*s != EOS) {
|
||||
if (*s != dc.escchr) {
|
||||
/*
|
||||
* not esc, continue...
|
||||
*/
|
||||
*t++ = *s++;
|
||||
} else if (*(s + 1) == dc.escchr) {
|
||||
/*
|
||||
* \\ escape escape
|
||||
*/
|
||||
*t++ = *s++;
|
||||
++s;
|
||||
} else {
|
||||
switch(*(s+1)) {
|
||||
|
||||
|
||||
case 'n':
|
||||
/*
|
||||
* \nx, \n(xx register
|
||||
*
|
||||
* first check for \n+... or \n-... (either form)
|
||||
*/
|
||||
s += 2;
|
||||
autoinc = 0;
|
||||
if (*s == '+') {
|
||||
autoinc = 1;
|
||||
s += 1;
|
||||
}
|
||||
if (*s == '-') {
|
||||
autoinc = -1;
|
||||
s += 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* was this \nx or \n(xx form?
|
||||
*/
|
||||
if (isalpha (*s)) {
|
||||
/*
|
||||
* \nx form. find reg (a-z)
|
||||
*/
|
||||
nreg = tolower (*s) - 'a';
|
||||
|
||||
|
||||
/*
|
||||
* was this \n+x or \n-x? if so, do the
|
||||
* auto incr
|
||||
*/
|
||||
if (autoinc > 0) {
|
||||
dc.nr[nreg] += dc.nrauto[nreg];
|
||||
} else if (autoinc < 0) {
|
||||
dc.nr[nreg] -= dc.nrauto[nreg];
|
||||
}
|
||||
|
||||
/*
|
||||
* display format
|
||||
*/
|
||||
if (dc.nrfmt[nreg] == '1') {
|
||||
/*
|
||||
* normal decimal digits
|
||||
*/
|
||||
t += itoda (dc.nr[nreg], t, 6) - 1;
|
||||
} else if (dc.nrfmt[nreg] == 'i') {
|
||||
/*
|
||||
* lower roman
|
||||
*/
|
||||
t += itoroman (dc.nr[nreg], t, 24) - 1;
|
||||
} else if (dc.nrfmt[nreg] == 'I') {
|
||||
/*
|
||||
* upper roman
|
||||
*/
|
||||
t += itoROMAN (dc.nr[nreg], t, 24) - 1;
|
||||
} else if (dc.nrfmt[nreg] == 'a') {
|
||||
/*
|
||||
* lower letters
|
||||
*/
|
||||
t += itoletter (dc.nr[nreg], t, 12) - 1;
|
||||
} else if (dc.nrfmt[nreg] == 'A') {
|
||||
/*
|
||||
* upper letters
|
||||
*/
|
||||
t += itoLETTER (dc.nr[nreg], t, 12) - 1;
|
||||
} else if (dc.nrfmt[nreg] & 0x80) {
|
||||
/*
|
||||
* zero-filled decimal
|
||||
*/
|
||||
sprintf (fmt, "%%0%dld", (int)(dc.nrfmt[nreg] & 0x7F));
|
||||
fmt[5] = '\0';
|
||||
sprintf (nrstr, fmt, (long) dc.nr[nreg]);
|
||||
tmp = dc.nrfmt[nreg] & 0x7F;
|
||||
nrstr[tmp] = '\0';
|
||||
|
||||
strcpy (t, nrstr);
|
||||
t += strlen (nrstr);
|
||||
} else {
|
||||
/*
|
||||
* normal (default)
|
||||
*/
|
||||
t += itoda (dc.nr[nreg], t, 6) - 1;
|
||||
}
|
||||
++s;
|
||||
} else if (*s == '%') {
|
||||
/*
|
||||
* \n% form. find index into reg struct
|
||||
*/
|
||||
FINDREG(percent, nreg, scratch);
|
||||
if (nreg < 0) {
|
||||
errx(-1, "no register match");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* was this \n+% or \n-%? if so, do the
|
||||
* auto incr
|
||||
*/
|
||||
if (autoinc > 0) {
|
||||
rg[nreg].rval += rg[nreg].rauto;
|
||||
} else if (autoinc < 0) {
|
||||
rg[nreg].rval -= rg[nreg].rauto;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* display format
|
||||
*/
|
||||
if (rg[nreg].rfmt == '1') {
|
||||
/*
|
||||
* normal decimal digits
|
||||
*/
|
||||
t += itoda (rg[nreg].rval, t, 6) - 1;
|
||||
} else if (rg[nreg].rfmt == 'i') {
|
||||
/*
|
||||
* lower roman
|
||||
*/
|
||||
t += itoroman (rg[nreg].rval, t, 24) - 1;
|
||||
} else if (rg[nreg].rfmt == 'I') {
|
||||
/*
|
||||
* upper roman
|
||||
*/
|
||||
t += itoROMAN (rg[nreg].rval, t, 24) - 1;
|
||||
} else if (rg[nreg].rfmt == 'a') {
|
||||
/*
|
||||
* lower letters
|
||||
*/
|
||||
t += itoletter (rg[nreg].rval, t, 12) - 1;
|
||||
} else if (rg[nreg].rfmt == 'A') {
|
||||
/*
|
||||
* upper letters
|
||||
*/
|
||||
t += itoLETTER (rg[nreg].rval, t, 12) - 1;
|
||||
} else if (rg[nreg].rfmt & 0x80) {
|
||||
/*
|
||||
* zero-filled decimal
|
||||
*/
|
||||
sprintf (fmt, "%%0%dld",
|
||||
(int)(rg[nreg].rfmt & 0x7F));
|
||||
fmt[5] = '\0';
|
||||
sprintf (nrstr, fmt, (long) rg[nreg].rval);
|
||||
tmp = rg[nreg].rfmt & 0x7F;
|
||||
nrstr[tmp] = '\0';
|
||||
|
||||
strcpy (t, nrstr);
|
||||
t += strlen (nrstr);
|
||||
} else {
|
||||
/*
|
||||
* normal (default)
|
||||
*/
|
||||
t += itoda (rg[nreg].rval, t, 6) - 1;
|
||||
}
|
||||
s += 1;
|
||||
} else if (*s == '(') {
|
||||
/*
|
||||
* \n(xx form. find index into reg struct
|
||||
*/
|
||||
s += 1;
|
||||
name[0] = *s;
|
||||
name[1] = *(s + 1);
|
||||
if (name[1] == ' ' || name[1] == '\t'
|
||||
|| name[1] == '\n' || name[1] == '\r') {
|
||||
name[1] = '\0';
|
||||
}
|
||||
name[2] = '\0';
|
||||
FINDREG(name, nreg, scratch);
|
||||
if (nreg < 0) {
|
||||
errx(-1, "no register match");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* was this \n+(xx or \n-(xx? if so, do the
|
||||
* auto incr
|
||||
*/
|
||||
if (rg[nreg].rflag & RF_WRITE) {
|
||||
if (autoinc > 0) {
|
||||
rg[nreg].rval += rg[nreg].rauto;
|
||||
} else if (autoinc < 0) {
|
||||
rg[nreg].rval -= rg[nreg].rauto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* display format
|
||||
*/
|
||||
if (rg[nreg].rfmt == '1') {
|
||||
/*
|
||||
* normal decimal digits
|
||||
*/
|
||||
t += itoda (rg[nreg].rval, t, 6) - 1;
|
||||
} else if (rg[nreg].rfmt == 'i') {
|
||||
/*
|
||||
* lower roman
|
||||
*/
|
||||
t += itoroman (rg[nreg].rval, t, 24) - 1;
|
||||
} else if (rg[nreg].rfmt == 'I') {
|
||||
/*
|
||||
* upper roman
|
||||
*/
|
||||
t += itoROMAN (rg[nreg].rval, t, 24) - 1;
|
||||
} else if (rg[nreg].rfmt == 'a') {
|
||||
/*
|
||||
* lower letters
|
||||
*/
|
||||
t += itoletter (rg[nreg].rval, t, 12) - 1;
|
||||
} else if (rg[nreg].rfmt == 'A') {
|
||||
/*
|
||||
* upper letters
|
||||
*/
|
||||
t += itoLETTER (rg[nreg].rval, t, 12) - 1;
|
||||
} else if (rg[nreg].rfmt & 0x80) {
|
||||
/*
|
||||
* zero-filled decimal
|
||||
*/
|
||||
sprintf (fmt, "%%0%dld",
|
||||
(int)(rg[nreg].rfmt & 0x7F));
|
||||
fmt[5] = '\0';
|
||||
sprintf (nrstr, fmt, (long) rg[nreg].rval);
|
||||
tmp = rg[nreg].rfmt & 0x7F;
|
||||
nrstr[tmp] = '\0';
|
||||
|
||||
strcpy (t, nrstr);
|
||||
t += strlen (nrstr);
|
||||
} else {
|
||||
/*
|
||||
* normal (default)
|
||||
*/
|
||||
t += itoda (rg[nreg].rval, t, 6) - 1;
|
||||
}
|
||||
s += 2;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case '"': /* \" comment */
|
||||
*s = EOS;
|
||||
*t = *s;
|
||||
return;
|
||||
|
||||
case '*': /* \*x, \*(xx string */
|
||||
/*
|
||||
|
||||
*/
|
||||
s += 2;
|
||||
if (*s == '(') {
|
||||
/*
|
||||
* \*(xx form
|
||||
*/
|
||||
s += 1;
|
||||
name[0] = *s;
|
||||
name[1] = *(s + 1);
|
||||
name[2] = '\0';
|
||||
pstr = getstr (name);
|
||||
if (!pstr) {
|
||||
errx(-1,"string not found");
|
||||
}
|
||||
while (*pstr) {
|
||||
*t++ = *pstr++;
|
||||
}
|
||||
s += 2;
|
||||
} else {
|
||||
/*
|
||||
* \*x form
|
||||
*/
|
||||
name[0] = *s;
|
||||
name[1] = '\0';
|
||||
pstr = getstr (name);
|
||||
if (!pstr) {
|
||||
errx(-1, "string not found");
|
||||
}
|
||||
while (*pstr) {
|
||||
*t++ = *pstr++;
|
||||
}
|
||||
s += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f': /* \fx font */
|
||||
s += 2;
|
||||
pfs = fs; /* set up ret string */
|
||||
fs[0] = '\0';
|
||||
|
||||
/*
|
||||
* it parses 1-2 char of s and returns esc seq for
|
||||
* \fB and \fR (\fI is same as \fB)
|
||||
*/
|
||||
fontchange (*s, pfs);
|
||||
|
||||
/*
|
||||
* imbed the atari (vt52) escape seq
|
||||
*/
|
||||
while (*pfs) {
|
||||
*t++ = *pfs++;
|
||||
}
|
||||
++s; /* skip B,I,R,S,P */
|
||||
break;
|
||||
|
||||
case '(': /* \(xx special char */
|
||||
s += 2;
|
||||
|
||||
/*
|
||||
* it returns num char to skip and sets c to
|
||||
* the ascii value of the char
|
||||
*/
|
||||
inc = specialchar (s, &c);
|
||||
|
||||
/*
|
||||
* skip proper num char in s and add c to target
|
||||
*/
|
||||
if (inc) {
|
||||
s += inc;
|
||||
*t++ = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e': /* \e printable version of escape */
|
||||
*t++ = dc.escchr;
|
||||
s += 2;
|
||||
break;
|
||||
|
||||
case '-': /* \- minus */
|
||||
case '`': /* \` grave, like \(ga */
|
||||
case '\'': /* \' accute, like \(aa */
|
||||
case '.': /* \. period */
|
||||
case ' ': /* \(space) space */
|
||||
|
||||
/* verbatim */
|
||||
*t++ = *(s+1);
|
||||
s += 2;
|
||||
break;
|
||||
|
||||
case '0': /* \0 digital width space */
|
||||
*t++ = ' ';
|
||||
s += 2;
|
||||
break;
|
||||
|
||||
case '|': /* \| narrow width char (0 in nroff) */
|
||||
case '^': /* \^ narrow width char (0 in nroff) */
|
||||
case '&': /* \& non-printing zero width */
|
||||
case '!': /* \! transparent copy line */
|
||||
case '$': /* \$N interpolate arg 1<=N<=9 */
|
||||
case 'a': /* \a */
|
||||
case 'b': /* \b'abc...' */
|
||||
case 'c': /* \c */
|
||||
case 'd': /* \d */
|
||||
case 'k': /* \kx */
|
||||
case 'l': /* \l'Nc' */
|
||||
case 'L': /* \L'Nc' */
|
||||
case 'p': /* \p */
|
||||
case 'r': /* \r */
|
||||
case 's': /* \sN,\s+-N */
|
||||
case 'u': /* \u */
|
||||
case 'w': /* \w'str' */
|
||||
case 'x': /* \x'N' */
|
||||
case '{': /* \{ */
|
||||
case '}': /* \} */
|
||||
case '\n': /* \(newline) ignore newline */
|
||||
case '\r': /* \(newline) ignore newline */
|
||||
|
||||
s += 2; /* currently ignored */
|
||||
break;
|
||||
|
||||
case '%': /* \% hyphen */
|
||||
*t++ = '-';
|
||||
*t++ = '-';
|
||||
s += 2;
|
||||
break;
|
||||
|
||||
case 'h': /* \h'N' horiz motion*/
|
||||
s += 2;
|
||||
delim = *s++;
|
||||
val = atoi (s);
|
||||
for (i = 0; i < val; i++) {
|
||||
*t++ = ' ';
|
||||
}
|
||||
while (*s != delim) {
|
||||
if (*s == 0) {
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if (*s) {
|
||||
s++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o': /* \o'abc...' overstrike*/
|
||||
s += 2;
|
||||
delim = *s++;
|
||||
while (*s != EOS && *s != delim) {
|
||||
*t++ = *s++;
|
||||
*t++ = 0x08;
|
||||
}
|
||||
s++;
|
||||
break;
|
||||
|
||||
case 't': /* \t horizontal tab*/
|
||||
*t++ = '\t';
|
||||
s += 2;
|
||||
break;
|
||||
|
||||
case 'v': /* \v'N' vert tab*/
|
||||
s += 2;
|
||||
delim = *s++;
|
||||
val = atoi (s);
|
||||
for (i = 0; i < val; i++) {
|
||||
*t++ = 0x0A;
|
||||
}
|
||||
while (*s != delim) {
|
||||
if (*s == 0) {
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if (*s) {
|
||||
s++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'z': /* \zc print c w/o spacing*/
|
||||
s += 2;
|
||||
*t++ = *s++;
|
||||
*t++ = 0x08;
|
||||
break;
|
||||
|
||||
default: /* \X any other character not above*/
|
||||
s += 1;
|
||||
*t++ = *s++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* end the string and return it in original buf
|
||||
*/
|
||||
*t = EOS;
|
||||
/* gdr: this seems to defeat the expansion we just did. */
|
||||
strcpy (src, dest);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* specialchar
|
||||
* handles \(xx escape sequences for special characters (atari-specific)
|
||||
*/
|
||||
static int
|
||||
specialchar (register char *s, register char *c) {
|
||||
register char c1;
|
||||
register char c2;
|
||||
|
||||
c1 = *s;
|
||||
c2 = *(s+1);
|
||||
|
||||
/*
|
||||
* symbols (std font)
|
||||
*/
|
||||
if (c1 == 'e' && c2 == 'm') {*c = 0x2D; return 2;} /* dash */
|
||||
if (c1 == 'h' && c2 == 'y') {*c = 0x2D; return 2;} /* hyphen */
|
||||
if (c1 == 'b' && c2 == 'u') {*c = 0xF9; return 2;} /* bullet */
|
||||
if (c1 == 's' && c2 == 'q') {*c = 0xF9; return 2;} /* square */
|
||||
if (c1 == 'r' && c2 == 'u') {*c = 0x5F; return 2;} /* rule */
|
||||
if (c1 == '1' && c2 == '2') {*c = 0xAB; return 2;} /* 1/2 */
|
||||
if (c1 == '1' && c2 == '4') {*c = 0xAC; return 2;} /* 1/4 */
|
||||
if (c1 == 'd' && c2 == 'e') {*c = 0xF8; return 2;} /* degree */
|
||||
if (c1 == 'd' && c2 == 'g') {*c = 0xBB; return 2;} /* dagger */
|
||||
if (c1 == 'f' && c2 == 'm') {*c = 0xBA; return 2;} /* dagger */
|
||||
if (c1 == 'c' && c2 == 't') {*c = 0x9B; return 2;} /* cent */
|
||||
if (c1 == 'c' && c2 == 'o') {*c = 0xBD; return 2;} /* copyrite */
|
||||
if (c1 == 'r' && c2 == 'g') {*c = 0xBE; return 2;} /* registered */
|
||||
if (c1 == 't' && c2 == 'm') {*c = 0xBF; return 2;} /* trademark */
|
||||
if (c1 == 'p' && c2 == '2') {*c = 0xFD; return 2;} /* ^2 */
|
||||
if (c1 == 'p' && c2 == '3') {*c = 0xFE; return 2;} /* ^3 */
|
||||
if (c1 == 'p' && c2 == 'n') {*c = 0xFC; return 2;} /* ^n */
|
||||
if (c1 == 'a' && c2 == 'a') {*c = 0xBA; return 2;} /* acute */
|
||||
if (c1 == 'g' && c2 == 'a') {*c = 0x60; return 2;} /* grave */
|
||||
if (c1 == 'd' && c2 == 't') {*c = 0xFA; return 2;} /* dot */
|
||||
if (c1 == 'p' && c2 == 'p') {*c = 0xBC; return 2;} /* paragraph */
|
||||
if (c1 == '^' && c2 == 'g') {*c = 0x07; return 2;} /* ring bell */
|
||||
if (c1 == 'u' && c2 == 'a') {*c = 0x01; return 2;} /* up arrow */
|
||||
if (c1 == 'd' && c2 == 'a') {*c = 0x02; return 2;} /* dn arrow */
|
||||
if (c1 == '-' && c2 == '>') {*c = 0x03; return 2;} /* rt arrow */
|
||||
if (c1 == '<' && c2 == '-') {*c = 0x04; return 2;} /* lf arrow */
|
||||
if (c1 == 'd' && c2 == 'i') {*c = 0xF6; return 2;} /* divide */
|
||||
if (c1 == 's' && c2 == 'r') {*c = 0xFB; return 2;} /* sq root */
|
||||
if (c1 == '=' && c2 == '=') {*c = 0xF0; return 2;} /* == */
|
||||
if (c1 == '>' && c2 == '=') {*c = 0xF2; return 2;} /* >= */
|
||||
if (c1 == '<' && c2 == '=') {*c = 0xF3; return 2;} /* <= */
|
||||
if (c1 == '+' && c2 == '-') {*c = 0xF1; return 2;} /* +- */
|
||||
if (c1 == '~' && c2 == '=') {*c = 0xF7; return 2;} /* ~= */
|
||||
if (c1 == 'a' && c2 == 'p') {*c = 0x7E; return 2;} /* approx */
|
||||
if (c1 == 'n' && c2 == 'o') {*c = 0xAA; return 2;} /* not */
|
||||
if (c1 == 'm' && c2 == 'o') {*c = 0xEE; return 2;} /* member */
|
||||
if (c1 == 'c' && c2 == 'a') {*c = 0xEF; return 2;} /* intersect */
|
||||
if (c1 == 'c' && c2 == 'u') {*c = 0x55; return 2;} /* union */
|
||||
if (c1 == 'i' && c2 == '1') {*c = 0xF4; return 2;} /* integral1 */
|
||||
if (c1 == 'i' && c2 == '2') {*c = 0xF5; return 2;} /* integral2 */
|
||||
if (c1 == 'b' && c2 == 'r') {*c = 0x7C; return 2;} /* box v rule */
|
||||
if (c1 == 'b' && c2 == 'v') {*c = 0x7C; return 2;} /* bold vert */
|
||||
if (c1 == 'p' && c2 == 'l') {*c = 0x2B; return 2;} /* math plus */
|
||||
if (c1 == 'm' && c2 == 'i') {*c = 0x2D; return 2;} /* math minus */
|
||||
if (c1 == 'e' && c2 == 'q') {*c = 0x3D; return 2;} /* math equal */
|
||||
if (c1 == '*' && c2 == '*') {*c = 0x2A; return 2;} /* math star */
|
||||
if (c1 == 's' && c2 == 'l') {*c = 0x2F; return 2;} /* slash */
|
||||
if (c1 == 'u' && c2 == 'l') {*c = 0x5F; return 2;} /* underrule */
|
||||
if (c1 == 's' && c2 == 'c') {*c = 0xDD; return 2;} /* section */
|
||||
|
||||
|
||||
/*
|
||||
* greek
|
||||
*/
|
||||
if (c1 == '*' && c2 == 'a') {*c = 0xE0; return 2;} /* alpha */
|
||||
if (c1 == '*' && c2 == 'b') {*c = 0xE1; return 2;} /* beta */
|
||||
if (c1 == '*' && c2 == 'g') {*c = 0xE2; return 2;} /* gamma */
|
||||
if (c1 == '*' && c2 == 'd') {*c = 0x7F; return 2;} /* delta */
|
||||
if (c1 == '*' && c2 == 's') {*c = 0xE4; return 2;} /* sigma */
|
||||
if (c1 == '*' && c2 == 'p') {*c = 0xE3; return 2;} /* pi */
|
||||
if (c1 == '*' && c2 == 'm') {*c = 0xE6; return 2;} /* mu */
|
||||
|
||||
*c = ' ';
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* fontchange
|
||||
* handles \fx font change escapes for R,B,I,S,P (atari-specific)
|
||||
* resets current and last font in dc struct (last used for .ft
|
||||
* with no args)
|
||||
*/
|
||||
#undef SHORT_STANDOUT
|
||||
|
||||
void
|
||||
fontchange (char fnt, char *s) {
|
||||
int tmp;
|
||||
|
||||
*s = '\0';
|
||||
switch (fnt) {
|
||||
case 'R': /* Times Roman */
|
||||
if (dc.dofnt == YES) {
|
||||
#ifdef SHORT_STANDOUT
|
||||
s[0] = E_STANDOUT; s[1] = 0;
|
||||
#else
|
||||
strcpy (s, e_standout);
|
||||
#endif
|
||||
}
|
||||
dc.lastfnt = dc.thisfnt;
|
||||
dc.thisfnt = 1;
|
||||
break;
|
||||
case 'I': /* Times italic */
|
||||
if (dc.dofnt == YES) {
|
||||
#ifdef SHORT_STANDOUT
|
||||
s[0] = S_STANDOUT; s[1] = 0;
|
||||
#else
|
||||
strcpy (s, s_standout);
|
||||
#endif
|
||||
}
|
||||
dc.lastfnt = dc.thisfnt;
|
||||
dc.thisfnt = 2;
|
||||
break;
|
||||
case 'B': /* Times bold */
|
||||
if (dc.dofnt == YES) {
|
||||
#ifdef SHORT_STANDOUT
|
||||
s[0] = S_STANDOUT; s[1] = 0;
|
||||
#else
|
||||
strcpy (s, s_standout);
|
||||
#endif
|
||||
}
|
||||
dc.lastfnt = dc.thisfnt;
|
||||
dc.thisfnt = 3;
|
||||
break;
|
||||
case 'S': /* math/special */
|
||||
*s = '\0';
|
||||
dc.lastfnt = dc.thisfnt;
|
||||
dc.thisfnt = 4;
|
||||
break;
|
||||
case 'P': /* previous (exchange) */
|
||||
if (dc.dofnt == YES) {
|
||||
if (dc.lastfnt == 1) {
|
||||
#ifdef SHORT_STANDOUT
|
||||
s[0] = E_STANDOUT; s[1] = 0;
|
||||
#else
|
||||
strcpy (s, e_standout); /* to R */
|
||||
#endif
|
||||
} else if (dc.lastfnt == 2) {
|
||||
#ifdef SHORT_STANDOUT
|
||||
s[0] = S_STANDOUT; s[1] = 0;
|
||||
#else
|
||||
strcpy (s, s_standout); /* to I */
|
||||
#endif
|
||||
} else if (dc.lastfnt == 3) {
|
||||
#ifdef SHORT_STANDOUT
|
||||
s[0] = S_STANDOUT; s[1] = 0;
|
||||
#else
|
||||
strcpy (s, s_standout); /* to B */
|
||||
#endif
|
||||
} else {
|
||||
*s = '\0'; /* nothing */
|
||||
}
|
||||
}
|
||||
tmp = dc.thisfnt; /* swap this/last */
|
||||
dc.thisfnt = dc.lastfnt;
|
||||
dc.lastfnt = tmp;
|
||||
break;
|
||||
default:
|
||||
*s = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
set_ireg (".f", dc.thisfnt, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0 /* using macro version */
|
||||
|
||||
/*
|
||||
* findreg
|
||||
*
|
||||
* find register named 'name' in pool. return index into array or -1
|
||||
* if not found.
|
||||
*/
|
||||
int
|
||||
findreg (register char *name) {
|
||||
register int i;
|
||||
register char *prname;
|
||||
|
||||
for (i = 0; i < MAXREGS; i++) {
|
||||
prname = rg[i].rname;
|
||||
if (*prname == *name && *(prname + 1) == *(name + 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ((i < MAXREGS) ? i : -1);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* $Id: escape.h,v 1.1 1997/03/14 06:22:27 gdr Exp $
|
||||
*
|
||||
* FINDREG -- macro version of findreg().
|
||||
* <name> is the register name to find
|
||||
* <result> is the returned index (-1 iff <name> was not found)
|
||||
* <scratch_i> is a scratch integer variable
|
||||
* <scratch_p> is a scratch char * variable
|
||||
*/
|
||||
|
||||
#define FINDREG(name,result,scratch_p) \
|
||||
{ \
|
||||
for (result = 0; result < MAXREGS; result++) { \
|
||||
scratch_p = rg[result].rname; \
|
||||
if (*scratch_p == *name && *(scratch_p + 1) == *(name + 1)) { \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (result >= MAXREGS) { \
|
||||
result = -1; \
|
||||
} \
|
||||
}
|
||||
|
||||
void expesc (char *src, char *dest, size_t len);
|
||||
void fontchange (char fnt, char *s);
|
|
@ -0,0 +1,325 @@
|
|||
/*
|
||||
* io.c - low level I/O processing portion of nroff word processor
|
||||
*
|
||||
* adapted for atariST/TOS by Bill Rosenkranz 11/89
|
||||
* net: rosenkra@hall.cray.com
|
||||
* CIS: 71460,17
|
||||
* GENIE: W.ROSENKRANZ
|
||||
*
|
||||
* original author:
|
||||
*
|
||||
* Stephen L. Browning
|
||||
* 5723 North Parker Avenue
|
||||
* Indianapolis, Indiana 46220
|
||||
*
|
||||
* history:
|
||||
*
|
||||
* - Originally written in BDS C;
|
||||
* - Adapted for standard C by W. N. Paul
|
||||
* - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
|
||||
* - Heavily modified by Devin Reade to avoid memory trashing bugs.
|
||||
*
|
||||
* $Id: io.c,v 1.1 1997/03/14 06:22:27 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "io________";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#ifdef __GNO__
|
||||
#include <err.h>
|
||||
#include <termcap.h>
|
||||
#else
|
||||
#include "err.h"
|
||||
#include "termcap.h"
|
||||
#endif
|
||||
|
||||
#ifdef sparc
|
||||
#include "sunos.h"
|
||||
#endif
|
||||
|
||||
#include "nroff.h"
|
||||
#include "macros.h"
|
||||
#include "io.h"
|
||||
#include "escape.h"
|
||||
|
||||
char __i;
|
||||
char *__s;
|
||||
FILE *fpGLOB;
|
||||
|
||||
int
|
||||
tprchar(char c)
|
||||
{
|
||||
return putc( c, fpGLOB );
|
||||
}
|
||||
|
||||
/*
|
||||
* getlin
|
||||
*
|
||||
* retrieve one line of input text from the push-back buffer or
|
||||
* in_buf, place it in out_buf
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
getlin (char *out_buf, FILE *in_buf) {
|
||||
#if 0
|
||||
/*
|
||||
* gdr: these optimizations should work, but don't as yet ...
|
||||
*/
|
||||
register char *q;
|
||||
register int i;
|
||||
int c;
|
||||
int nreg;
|
||||
const char *dotc = ".c";
|
||||
|
||||
|
||||
i = 0;
|
||||
|
||||
/* get characters from the push-back buffer */
|
||||
q = out_buf;
|
||||
while ((i < MAXLINE - 1) && (mac.ppb >= mac.pbb)) {
|
||||
#if 1 /* doesn't happen */
|
||||
c = *mac.ppb--;
|
||||
if (c == EOF) {
|
||||
*q = EOS;
|
||||
return (i == 0) ? EOF : i;
|
||||
}
|
||||
*q++ = c;
|
||||
#else
|
||||
*q++ = c = *mac.ppb--;
|
||||
#endif
|
||||
if (c == '\n') {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
*q = EOS;
|
||||
|
||||
/* get characters from stream */
|
||||
c = MAXLINE - i;
|
||||
if (c > 0) {
|
||||
fgets(q, c, in_buf);
|
||||
}
|
||||
|
||||
FINDREG(dotc, nreg, q);
|
||||
if (nreg > 0) {
|
||||
set_ireg (dotc, rg[nreg].rval + 1, 0);
|
||||
}
|
||||
|
||||
i = strlen(out_buf);
|
||||
assert(i || feof(in_buf));
|
||||
return (i == 0) ? EOF : i;
|
||||
#else /* gdr: old way */
|
||||
register char *q;
|
||||
register int i;
|
||||
int c;
|
||||
int nreg;
|
||||
const char *dotc = ".c";
|
||||
|
||||
q = out_buf;
|
||||
for (i = 0; i < MAXLINE - 1; ++i) {
|
||||
c = NGETC (in_buf);
|
||||
if (c == EOF) {
|
||||
*q = EOS;
|
||||
c = strlen (out_buf);
|
||||
return (c == 0 ? EOF : c);
|
||||
}
|
||||
*q++ = c;
|
||||
if (c == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*q = EOS;
|
||||
|
||||
FINDREG(dotc, nreg, q);
|
||||
if (nreg > 0) {
|
||||
set_ireg (dotc, rg[nreg].rval + 1, 0);
|
||||
}
|
||||
|
||||
return (strlen (out_buf));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pbstr
|
||||
* Push back string into input stream
|
||||
*/
|
||||
void
|
||||
pbstr (char *str) {
|
||||
char *p;
|
||||
|
||||
if (str == NULL) {
|
||||
return;
|
||||
}
|
||||
p = str + strlen(str) - 1;
|
||||
while (p >= str) {
|
||||
PUTBAK(*p);
|
||||
--p;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* put
|
||||
* put out line with proper spacing and indenting
|
||||
*/
|
||||
void
|
||||
put (char *p) {
|
||||
register int j;
|
||||
char os[MAXLINE];
|
||||
|
||||
if (pg.lineno == 0 || pg.lineno > pg.bottom) {
|
||||
phead ();
|
||||
}
|
||||
if (dc.prflg == TRUE) {
|
||||
if (!dc.bsflg) {
|
||||
if (strkovr (p, os) == TRUE) {
|
||||
for (j = 0; j < pg.offset; ++j) {
|
||||
PRCHAR2(' ', out_stream);
|
||||
}
|
||||
for (j = 0; j < dc.tival; ++j) {
|
||||
PRCHAR2(' ', out_stream);
|
||||
}
|
||||
putlin (os, out_stream);
|
||||
}
|
||||
}
|
||||
for (j = 0; j < pg.offset; ++j) {
|
||||
PRCHAR2(' ', out_stream);
|
||||
}
|
||||
for (j = 0; j < dc.tival; ++j) {
|
||||
PRCHAR2(' ', out_stream);
|
||||
}
|
||||
putlin (p, out_stream);
|
||||
}
|
||||
dc.tival = dc.inval;
|
||||
skip (MIN(dc.lsval - 1, pg.bottom - pg.lineno));
|
||||
pg.lineno = pg.lineno + dc.lsval;
|
||||
set_ireg ("ln", pg.lineno, 0);
|
||||
if (pg.lineno > pg.bottom) {
|
||||
pfoot ();
|
||||
#ifdef GEMDOS
|
||||
if (stepping) {
|
||||
wait_for_char();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* putlin
|
||||
* output a null terminated string to the file
|
||||
* specified by pbuf.
|
||||
*/
|
||||
void
|
||||
putlin (char *p, FILE *pbuf)
|
||||
{
|
||||
while (*p != EOS) {
|
||||
PRCHAR(*p, pbuf);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef NOT_USED
|
||||
|
||||
/*
|
||||
* prchar
|
||||
* print character with test for printer
|
||||
*/
|
||||
void
|
||||
prchar (char __c, FILE *fp)
|
||||
{
|
||||
#if 0
|
||||
/* this really slows things down. it should be fixed. for now, ignore
|
||||
* line printer...
|
||||
*/
|
||||
if (fp == stdout) {
|
||||
putc (c, fp);
|
||||
} else {
|
||||
putc_lpr (c, fp);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
switch(c) {
|
||||
case S_STANDOUT:
|
||||
fpGLOB = fp;
|
||||
tputs(s_standout,1,tprchar);
|
||||
break;
|
||||
case E_STANDOUT:
|
||||
fpGLOB = fp;
|
||||
tputs(e_standout,1,tprchar);
|
||||
break;
|
||||
case S_BOLD:
|
||||
fpGLOB = fp;
|
||||
tputs(s_bold,1,tprchar);
|
||||
break;
|
||||
case E_BOLD:
|
||||
fpGLOB = fp;
|
||||
tputs(e_bold,1,tprchar);
|
||||
break;
|
||||
case S_ITALIC:
|
||||
fpGLOB = fp;
|
||||
tputs(s_italic,1,tprchar);
|
||||
break;
|
||||
case E_ITALIC:
|
||||
fpGLOB = fp;
|
||||
tputs(e_italic,1,tprchar);
|
||||
break;
|
||||
case 13:
|
||||
break;
|
||||
default:
|
||||
putc(c, fp);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Don't use a case statement here; the macros are out of range
|
||||
* for some compilers.
|
||||
*/
|
||||
if (__c == S_STANDOUT) {
|
||||
fpGLOB = fp;
|
||||
tputs(s_standout,1,tprchar);
|
||||
} else if (__c == E_STANDOUT) {
|
||||
fpGLOB = fp;
|
||||
tputs(e_standout,1,tprchar);
|
||||
} else if (__c == S_BOLD) {
|
||||
fpGLOB = fp;
|
||||
tputs(s_bold,1,tprchar);
|
||||
} else if (__c == E_BOLD) {
|
||||
fpGLOB = fp;
|
||||
tputs(e_bold,1,tprchar);
|
||||
} else if (__c == S_ITALIC) {
|
||||
fpGLOB = fp;
|
||||
tputs(s_italic,1,tprchar);
|
||||
} else if (__c == E_ITALIC) {
|
||||
fpGLOB = fp;
|
||||
tputs(e_italic,1,tprchar);
|
||||
} else if (__c == 13) {
|
||||
;
|
||||
} else {
|
||||
putc(c, fp);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* putc_lpr
|
||||
* write char to printer
|
||||
*/
|
||||
void
|
||||
putc_lpr (char c, FILE *fp)
|
||||
{
|
||||
putc (c, fp);
|
||||
}
|
||||
|
||||
#endif /* NOT_USED */
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* $Id: io.h,v 1.1 1997/03/14 06:22:27 gdr Exp $
|
||||
*
|
||||
* prchar
|
||||
* print character with test for printer -- macro version
|
||||
*
|
||||
* profiling has shown that this is where we spend most of our time
|
||||
* Don't use a case statement here; the macros are out of range
|
||||
* for some compilers.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
|
||||
#define PRCHAR(__c, fp) \
|
||||
{ \
|
||||
if (__c == S_STANDOUT) { \
|
||||
fpGLOB = fp; \
|
||||
tputs(s_standout,1,tprchar); \
|
||||
} else if (__c == E_STANDOUT) { \
|
||||
fpGLOB = fp; \
|
||||
tputs(e_standout,1,tprchar); \
|
||||
} else if (__c == S_BOLD) { \
|
||||
fpGLOB = fp; \
|
||||
tputs(s_bold,1,tprchar); \
|
||||
} else if (__c == E_BOLD) { \
|
||||
fpGLOB = fp; \
|
||||
tputs(e_bold,1,tprchar); \
|
||||
} else if (__c == S_ITALIC) { \
|
||||
fpGLOB = fp; \
|
||||
tputs(s_italic,1,tprchar); \
|
||||
} else if (__c == E_ITALIC) { \
|
||||
fpGLOB = fp; \
|
||||
tputs(e_italic,1,tprchar); \
|
||||
} else if (__c == 13) { \
|
||||
; \
|
||||
} else { \
|
||||
putc(c, fp); \
|
||||
} \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
#define PRCHAR(c, fp) \
|
||||
{ \
|
||||
__i = c; \
|
||||
switch(__i) { \
|
||||
case S_STANDOUT: __s = s_standout; break; \
|
||||
case E_STANDOUT: __s = e_standout; break; \
|
||||
case S_BOLD: __s = s_bold; break; \
|
||||
case E_BOLD: __s = e_bold; break; \
|
||||
case S_ITALIC: __s = s_italic; break; \
|
||||
case E_ITALIC: __s = e_italic; break; \
|
||||
case 13: __s = (char *)0x01L; break; \
|
||||
default: __s = NULL; \
|
||||
} \
|
||||
switch((unsigned long)__s) { \
|
||||
case 0L: putc(c, fp); break; \
|
||||
case 1L: ; break; \
|
||||
default: fpGLOB = fp; tputs(__s, 1, tprchar); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PRCHAR2(c,fp) putc(c,fp)
|
||||
|
||||
extern char __i;
|
||||
extern char *__s;
|
||||
extern FILE *fpGLOB;
|
||||
|
||||
int getlin (char *p, FILE *in_buf);
|
||||
void pbstr (char *str);
|
||||
void put (char *p);
|
||||
void putlin (char *p, FILE *pbuf);
|
||||
int tprchar(char c);
|
||||
#endif
|
|
@ -0,0 +1,928 @@
|
|||
/*
|
||||
* low.c - misc low-level functions for nroff word processor
|
||||
*
|
||||
* adapted for atariST/TOS by Bill Rosenkranz 11/89
|
||||
* net: rosenkra@hall.cray.com
|
||||
* CIS: 71460,17
|
||||
* GENIE: W.ROSENKRANZ
|
||||
*
|
||||
* original author:
|
||||
*
|
||||
* Stephen L. Browning
|
||||
* 5723 North Parker Avenue
|
||||
* Indianapolis, Indiana 46220
|
||||
*
|
||||
* history:
|
||||
*
|
||||
* - Originally written in BDS C;
|
||||
* - Adapted for standard C by W. N. Paul
|
||||
* - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
|
||||
* - Heavily modified by Devin Reade to avoid memory trashing bugs.
|
||||
*
|
||||
* $Id: low.c,v 1.1 1997/03/14 06:22:27 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "low_______";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#ifdef __GNO__
|
||||
#include <err.h>
|
||||
#else
|
||||
#include "err.h"
|
||||
#endif
|
||||
|
||||
#ifdef sparc
|
||||
#include "sunos.h"
|
||||
#endif
|
||||
|
||||
#include "nroff.h"
|
||||
|
||||
|
||||
/* convert ascii character to decimal */
|
||||
#define ATOD(c) (((c) < '0') || ((c) > '9')) ? -1 : ((c) - '0')
|
||||
|
||||
#if 0 /* not currently used */
|
||||
static void inptobu (char *); /* convert input units to b.u. */
|
||||
static void butochar (char *); /* convert b.u. to char spaces */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ctod
|
||||
*
|
||||
* convert string to decimal. processes only positive values.
|
||||
* this takes a constant like "1", "1.0i", etc.
|
||||
*
|
||||
* Returns converted value (including zero) on success, zero on failure.
|
||||
*/
|
||||
int
|
||||
ctod (char *p) {
|
||||
long val;
|
||||
int d;
|
||||
char *pp = p;
|
||||
char *ptmp;
|
||||
int rside = 0;
|
||||
int lside = 0;
|
||||
int has_rside = 0;
|
||||
int has_lside = 0;
|
||||
|
||||
if (*p == EOS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ptmp = skipwd (pp);
|
||||
pp = --ptmp;
|
||||
|
||||
switch (*pp) {
|
||||
case 'i':
|
||||
case 'c':
|
||||
val = 0L;
|
||||
while (*p != EOS && isdigit (*p)) {
|
||||
has_lside++;
|
||||
lside = ATOD(*p);
|
||||
p++;
|
||||
if (lside == -1) {
|
||||
break;
|
||||
}
|
||||
val = 10L * val + (long) lside;
|
||||
}
|
||||
lside = (int) val;
|
||||
if (*p == '.') {
|
||||
p++;
|
||||
val = 0L;
|
||||
while (*p != EOS && isdigit (*p)) {
|
||||
has_rside++;
|
||||
rside = ATOD(*p);
|
||||
p++;
|
||||
if (rside == -1) {
|
||||
break;
|
||||
}
|
||||
val = 10L * val + (long) rside;
|
||||
if (has_rside > 2) { /* more than enough */
|
||||
break;
|
||||
}
|
||||
}
|
||||
rside = (int) val;
|
||||
}
|
||||
|
||||
/*
|
||||
* now put it together. 1.0i -> 240, 1.50i -> 360, etc.
|
||||
*/
|
||||
val = 0L;
|
||||
if (has_lside) {
|
||||
val = (long) lside * BU_INCH;
|
||||
}
|
||||
switch (has_rside) {
|
||||
case 1:
|
||||
val = val + ((long) rside * BU_INCH / 10L);
|
||||
break;
|
||||
case 2:
|
||||
val = val + ((long) rside * BU_INCH / 100L);
|
||||
break;
|
||||
case 3:
|
||||
val = val + ((long) rside * BU_INCH / 1000L);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (*pp == 'c') {
|
||||
val = (val * BU_CM) / BU_INCH;
|
||||
}
|
||||
|
||||
/*
|
||||
* for now we convert to basic char size, 1 em...
|
||||
*/
|
||||
val = val / BU_EM;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
case 'm':
|
||||
case 'n':
|
||||
case 'p':
|
||||
case 'u':
|
||||
case 'v':
|
||||
val = 0L;
|
||||
while (*p != EOS) {
|
||||
d = ATOD(*p);
|
||||
p++;
|
||||
if (d == -1)
|
||||
break;
|
||||
val = 10L * val + (long) d;
|
||||
}
|
||||
switch (*pp) {
|
||||
case 'P':
|
||||
val = val * BU_PICA;
|
||||
break;
|
||||
case 'p':
|
||||
val = val * BU_POINT;
|
||||
break;
|
||||
case 'u':
|
||||
val = val * BU_BU;
|
||||
break;
|
||||
case 'm':
|
||||
val = val * BU_EM;
|
||||
break;
|
||||
case 'n':
|
||||
val = val * BU_EN;
|
||||
break;
|
||||
case 'v':
|
||||
val = val * BU_EM;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* for now we convert to basic char size, 1 em...
|
||||
*/
|
||||
val = val / BU_EM;
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* this is the default behavior. it SHOULD make things
|
||||
* compatible with the old way...
|
||||
*/
|
||||
val = 0L;
|
||||
while (*p != EOS) {
|
||||
d = ATOD(*p);
|
||||
p++;
|
||||
if (d == -1) {
|
||||
break;
|
||||
}
|
||||
val = 10L * val + (long) d;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return (int) val;
|
||||
}
|
||||
|
||||
#if 0 /* not currently used */
|
||||
|
||||
/*
|
||||
* inptobu
|
||||
*
|
||||
* convert input units to b.u.
|
||||
*/
|
||||
static void
|
||||
inptobu (char *ps)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* butochar
|
||||
*
|
||||
* convert b.u. to char spaces
|
||||
*/
|
||||
static void
|
||||
butochar (char *ps)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
/*
|
||||
* skipbl
|
||||
*
|
||||
* skip blanks and tabs in character buffer. return ptr to first
|
||||
* non-space or non-tab char. this could mean EOS or \r or \n.
|
||||
*/
|
||||
char *
|
||||
skipbl (register char *p)
|
||||
{
|
||||
while ((*p != EOS) && (*p == ' ' || *p == '\t')) {
|
||||
p++;
|
||||
}
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* skipwd
|
||||
*
|
||||
* skip over word and punctuation. anything but space,\t,\r,\n, and EOS
|
||||
* is skipped. return ptr to the first of these found.
|
||||
*/
|
||||
char *
|
||||
skipwd (register char *p) {
|
||||
while (*p != EOS && *p != ' ' && *p != '\t' && *p != '\r' && *p != '\n') {
|
||||
p++;
|
||||
}
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nroffSpace
|
||||
*
|
||||
* space vertically n lines. this does header and footer also.
|
||||
*/
|
||||
void
|
||||
nroffSpace (int n) {
|
||||
robrk ();
|
||||
if (pg.lineno > pg.bottom) {
|
||||
return;
|
||||
}
|
||||
if (pg.lineno == 0) {
|
||||
phead ();
|
||||
}
|
||||
skip (MIN(n, pg.bottom + 1 - pg.lineno));
|
||||
pg.lineno += n;
|
||||
set_ireg ("ln", pg.lineno, 0);
|
||||
if (pg.lineno > pg.bottom) {
|
||||
pfoot ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getfield
|
||||
* get field from title
|
||||
*/
|
||||
char *
|
||||
getfield (register char *p, register char *q, char delim) {
|
||||
while (*p != delim && *p != '\r' && *p != '\n' && *p != EOS) {
|
||||
*q++ = *p++;
|
||||
}
|
||||
*q = EOS;
|
||||
if (*p == delim) {
|
||||
++p;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getwrd
|
||||
*
|
||||
* get non-blank word from p0 into p1.
|
||||
* return number of characters processed.
|
||||
*/
|
||||
int
|
||||
getwrd (register char *src, register char *dest) {
|
||||
#if 0 /* gdr changes */
|
||||
char *orgsrc, *orgdest;
|
||||
|
||||
orgsrc = src;
|
||||
orgdest = dest;
|
||||
|
||||
/*
|
||||
* skip leading whitespace
|
||||
*/
|
||||
while (*src == ' ' || *src == '\t') {
|
||||
src++;
|
||||
}
|
||||
|
||||
/* find end of word */
|
||||
while (*src != '\0' && !isspace(*src)) {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
/* I don't understand what this is supposed to achieve */
|
||||
#ifdef WHATTHEFUCK
|
||||
assert (dest - orgdest >= 1); /* gdr */
|
||||
c = *(dest - 1);
|
||||
if (c == '"') {
|
||||
asssert(dest - orgdest >= 2); /* gdr */
|
||||
c = *(dest - 2);
|
||||
}
|
||||
if (c == '?' || c == '!') {
|
||||
*dest++ = ' ';
|
||||
}
|
||||
if (c == '.' && (*src == '\n' || *src == '\r' || islower (*p))) {
|
||||
*dest++ = ' ';
|
||||
}
|
||||
#endif /* WHATTHEFUCK */
|
||||
*dest = EOS;
|
||||
|
||||
return src - orgsrc;
|
||||
#elif 1
|
||||
char c;
|
||||
register int i;
|
||||
register char *p;
|
||||
char *orgsrc, *orgdest;
|
||||
|
||||
orgsrc = src;
|
||||
orgdest = dest;
|
||||
/*
|
||||
* init counter...
|
||||
*/
|
||||
i = 0;
|
||||
|
||||
/*
|
||||
* skip leading whitespace
|
||||
*/
|
||||
while (*src == ' ' || *src == '\t') {
|
||||
++i;
|
||||
++src;
|
||||
}
|
||||
|
||||
/*
|
||||
* set ptr and start to look for end of word
|
||||
*/
|
||||
p = src;
|
||||
while (*src != ' ' && *src != EOS && *src != '\t') {
|
||||
if (*src == '\n' || *src == '\r') {
|
||||
break;
|
||||
}
|
||||
*dest = *src++;
|
||||
++dest;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (dest > orgdest) {
|
||||
c = *(dest - 1);
|
||||
if (c == '"' && (dest > orgdest + 1)) {
|
||||
c = *(dest - 2);
|
||||
}
|
||||
if (c == '?' || c == '!') {
|
||||
*dest++ = ' ';
|
||||
++i;
|
||||
}
|
||||
if (c == '.' && (*src == '\n' || *src == '\r' || islower (*p))) {
|
||||
*dest++ = ' ';
|
||||
++i;
|
||||
}
|
||||
}
|
||||
*dest = EOS;
|
||||
|
||||
return (i);
|
||||
#else
|
||||
char c;
|
||||
register int i;
|
||||
register char *p;
|
||||
char *orgsrc, *orgdest;
|
||||
|
||||
orgsrc = src;
|
||||
orgdest = dest;
|
||||
/*
|
||||
* init counter...
|
||||
*/
|
||||
i = 0;
|
||||
|
||||
/*
|
||||
* skip leading whitespace
|
||||
*/
|
||||
while (*src == ' ' || *src == '\t') {
|
||||
++i;
|
||||
++src;
|
||||
}
|
||||
|
||||
/*
|
||||
* set ptr and start to look for end of word
|
||||
*/
|
||||
p = src;
|
||||
while (*src != ' ' && *src != EOS && *src != '\t') {
|
||||
if (*src == '\n' || *src == '\r') {
|
||||
break;
|
||||
}
|
||||
*dest = *src++;
|
||||
++dest;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (dest > orgdest) {
|
||||
c = *(dest - 1);
|
||||
if (c == '"') {
|
||||
ASSERT(dest > orgdest + 1,
|
||||
("%s:%d: array indexing error", __FILE__, __LINE__));
|
||||
c = *(dest - 2);
|
||||
}
|
||||
if (c == '?' || c == '!') {
|
||||
*dest++ = ' ';
|
||||
++i;
|
||||
}
|
||||
if (c == '.' && (*src == '\n' || *src == '\r' || islower (*p))) {
|
||||
*dest++ = ' ';
|
||||
++i;
|
||||
}
|
||||
}
|
||||
*dest = EOS;
|
||||
|
||||
return (i);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* countesc
|
||||
* count atari escape sequence characters in given null-terminated
|
||||
* string
|
||||
*/
|
||||
|
||||
#define ESC 27
|
||||
|
||||
int
|
||||
countesc (register char *p) {
|
||||
register char *pp;
|
||||
register int num;
|
||||
|
||||
pp = p;
|
||||
num = 0;
|
||||
|
||||
while (*pp != EOS) {
|
||||
if (*pp == ESC) {
|
||||
/*
|
||||
* count escape char (atari-specific, vt52)
|
||||
* generally only p,q,b,and c will show up...
|
||||
*/
|
||||
switch (*(pp+1)) {
|
||||
case 'A': /* ESC-a */
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'H':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'K':
|
||||
case 'L':
|
||||
case 'M':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 'l':
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'q':
|
||||
case 'v':
|
||||
case 'w':
|
||||
num += 2;
|
||||
break;
|
||||
case 'b': /* ESC-a-b */
|
||||
case 'c':
|
||||
num += 3;
|
||||
break;
|
||||
case 'Y': /* ESC-a-b-c */
|
||||
case '[': /* Esc [ 7 m */
|
||||
num += 4;
|
||||
break;
|
||||
default:
|
||||
num += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pp++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* itoda
|
||||
* convert integer to decimal ascii string
|
||||
*
|
||||
* Pre: <value> is the number to convert
|
||||
* <p> is the output buffer
|
||||
* <size> is the number of bytes in the output buffer
|
||||
*
|
||||
* Post: <p> contains an ascii representation of <value>
|
||||
*
|
||||
* Returns:
|
||||
*/
|
||||
int
|
||||
itoda (int value, register char *p, register int size) {
|
||||
#if 0
|
||||
int len;
|
||||
/*
|
||||
* buffer must be big enough for representation of largest integer,
|
||||
* plus 1 byte for sign, plus 1 byte for terminator. On a 32-bit
|
||||
* machine this is 10+1+1 == 12 bytes.
|
||||
*/
|
||||
#define MAX_INT_LENGTH 15
|
||||
char buffer[MAX_INT_LENGTH];
|
||||
|
||||
len = sprintf(buffer, "%d", value);
|
||||
if (len == EOF) {
|
||||
errx(1, "itoda failed with EOF");
|
||||
}
|
||||
if (len >= size) {
|
||||
errx(1, "%s:%d: buffer overflow", __FILE__, __LINE__);
|
||||
}
|
||||
strncpy(p, buffer, len);
|
||||
return len;
|
||||
#else
|
||||
|
||||
int i, j, aval;
|
||||
char c[20];
|
||||
|
||||
aval = abs (value);
|
||||
c[0] = EOS;
|
||||
i = 1;
|
||||
do {
|
||||
c[i++] = (aval % 10) + '0';
|
||||
aval /= 10;
|
||||
} while (aval > 0 && i <= size);
|
||||
|
||||
if (value < 0 && i <= size) {
|
||||
c[i++] = '-';
|
||||
}
|
||||
for (j = 0; j < i; ++j) {
|
||||
*p++ = c[i - j - 1];
|
||||
}
|
||||
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* itoROMAN
|
||||
* convert integer to upper roman. must be positive
|
||||
*/
|
||||
int
|
||||
itoROMAN (int value, register char *p, register int size) {
|
||||
register int i;
|
||||
register int j;
|
||||
register int aval;
|
||||
char c[100];
|
||||
int rem;
|
||||
|
||||
aval = abs (value);
|
||||
c[0] = EOS;
|
||||
i = 1;
|
||||
|
||||
/*
|
||||
* trivial case:
|
||||
*/
|
||||
if (aval == 0) {
|
||||
c[i++] = '0';
|
||||
goto done_100;
|
||||
}
|
||||
|
||||
/*
|
||||
* temporarily mod 100...
|
||||
*/
|
||||
aval = aval % 100;
|
||||
|
||||
if (aval > 0) {
|
||||
/*
|
||||
* build backward
|
||||
*
|
||||
* | I| 1
|
||||
* | II| 2
|
||||
* | III| 3
|
||||
* | VI| 4
|
||||
* | V| 5
|
||||
* | IV| 6
|
||||
* | IIV| 7
|
||||
* | IIIV| 8
|
||||
* | XI| 9
|
||||
* | X| 0
|
||||
* | IX| 11
|
||||
* | IIX| 12
|
||||
*/
|
||||
if ((aval % 5 == 0) && (aval % 10 != 0)) { /* 5 */
|
||||
c[i++] = 'V';
|
||||
} else {
|
||||
rem = aval % 10;
|
||||
if (rem == 9) { /* 9 */
|
||||
c[i++] = 'X';
|
||||
c[i++] = 'I';
|
||||
}else if (rem == 8) { /* 8 */
|
||||
c[i++] = 'I';
|
||||
c[i++] = 'I';
|
||||
c[i++] = 'I';
|
||||
c[i++] = 'V';
|
||||
} else if (rem == 7) { /* 7 */
|
||||
c[i++] = 'I';
|
||||
c[i++] = 'I';
|
||||
c[i++] = 'V';
|
||||
} else if (rem == 6) { /* 6 */
|
||||
c[i++] = 'I';
|
||||
c[i++] = 'V';
|
||||
} else if (rem == 4) { /* 4 */
|
||||
c[i++] = 'V';
|
||||
c[i++] = 'I';
|
||||
} else { /* 3,2,1 */
|
||||
for (j = 0; j < rem; j++) {
|
||||
c[i++] = 'I';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aval /= 10;
|
||||
if (aval == 0) {
|
||||
goto done_100;
|
||||
}
|
||||
|
||||
rem = aval % 10;
|
||||
if (rem == 4) {
|
||||
c[i++] = 'L';
|
||||
c[i++] = 'X';
|
||||
} else if (rem == 5) {
|
||||
c[i++] = 'L';
|
||||
} else if (rem < 4) {
|
||||
for (j = 0; j < rem; j++) {
|
||||
c[i++] = 'X';
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < rem - 5; j++) {
|
||||
c[i++] = 'X';
|
||||
}
|
||||
c[i++] = 'L';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
done_100:
|
||||
/*
|
||||
* divide by 100 (they are done) and temp mod by another 10
|
||||
*/
|
||||
aval = abs (value);
|
||||
aval /= 100;
|
||||
|
||||
if (aval > 0) {
|
||||
rem = aval % 10;
|
||||
if (rem == 4) {
|
||||
c[i++] = 'D';
|
||||
c[i++] = 'C';
|
||||
}
|
||||
if (rem == 5) {
|
||||
c[i++] = 'D';
|
||||
} else if (rem < 4) {
|
||||
for (j = 0; j < rem; j++) {
|
||||
c[i++] = 'C';
|
||||
}
|
||||
} else if (rem == 9) {
|
||||
c[i++] = 'M';
|
||||
c[i++] = 'C';
|
||||
} else if (rem < 9) {
|
||||
for (j = 0; j < rem - 5; j++) {
|
||||
c[i++] = 'C';
|
||||
}
|
||||
c[i++] = 'D';
|
||||
}
|
||||
}
|
||||
|
||||
aval /= 10;
|
||||
|
||||
if (aval > 0) {
|
||||
rem = aval % 10;
|
||||
if (rem < 4) {
|
||||
for (j = 0; j < rem; j++) {
|
||||
c[i++] = 'M';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value < 0) {
|
||||
c[i++] = '-';
|
||||
}
|
||||
|
||||
for (j = 0; j < i; ++j) {
|
||||
*p++ = c[i - j - 1];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* itoroman
|
||||
* convert integer to lower roman
|
||||
*/
|
||||
int
|
||||
itoroman (int value, char *p, int size)
|
||||
{
|
||||
register int i;
|
||||
register int len;
|
||||
char c[100];
|
||||
|
||||
c[0] = EOS;
|
||||
len = itoROMAN (value, c, size);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
p[i] = c[i];
|
||||
if (isalpha (p[i])) {
|
||||
p[i] = tolower (c[i]);
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* itoLETTER
|
||||
* convert integer to upper letter value: 0,A,B,C,...,AA,AB,AC,...
|
||||
*/
|
||||
int
|
||||
itoLETTER (int value, register char *p, register int size) {
|
||||
register int i;
|
||||
register int j;
|
||||
register int aval;
|
||||
char c[20];
|
||||
|
||||
aval = abs (value);
|
||||
c[0] = EOS;
|
||||
i = 1;
|
||||
|
||||
/*
|
||||
* 1 based:
|
||||
*
|
||||
* 0 0
|
||||
* 1 A
|
||||
* 25 Z
|
||||
* 26 AA
|
||||
* 51 AZ
|
||||
* 52 AAA
|
||||
* ...
|
||||
*/
|
||||
if (aval == 0) {
|
||||
c[i++] = '0';
|
||||
} else if (aval < 27) {
|
||||
c[i++] = aval - 1 + 'A';
|
||||
} else {
|
||||
do {
|
||||
c[i++] = ((aval - 1) % 26) + 'A';
|
||||
aval = (aval - 1) / 26;
|
||||
} while (aval > 0 && i <= size);
|
||||
}
|
||||
|
||||
if (value < 0 && i <= size) {
|
||||
c[i++] = '-';
|
||||
}
|
||||
|
||||
for (j = 0; j < i; ++j) {
|
||||
*p++ = c[i - j - 1];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* itoletter
|
||||
* convert integer to upper letter value: 0,a,b,c,...,aa,ab,ac,...
|
||||
*/
|
||||
int
|
||||
itoletter (int value, register char *p, register int size) {
|
||||
register int i;
|
||||
register int j;
|
||||
register int aval;
|
||||
char c[20];
|
||||
|
||||
aval = abs (value);
|
||||
c[0] = EOS;
|
||||
i = 1;
|
||||
|
||||
/*
|
||||
* 1 based:
|
||||
*
|
||||
* 0 0
|
||||
* 1 A
|
||||
* 25 Z
|
||||
* 26 AA
|
||||
* 51 AZ
|
||||
* 52 AAA
|
||||
* ...
|
||||
*/
|
||||
if (aval == 0) {
|
||||
c[i++] = '0';
|
||||
} else if (aval < 27) {
|
||||
c[i++] = aval - 1 + 'a';
|
||||
} else {
|
||||
do {
|
||||
c[i++] = ((aval - 1) % 26) + 'a';
|
||||
aval = (aval - 1) / 26;
|
||||
} while (aval > 0 && i <= size);
|
||||
}
|
||||
|
||||
if (value < 0 && i <= size) {
|
||||
c[i++] = '-';
|
||||
}
|
||||
|
||||
for (j = 0; j < i; ++j) {
|
||||
*p++ = c[i - j - 1];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* min, max not needed */
|
||||
/*
|
||||
* min
|
||||
* find minimum of two integer ONLY
|
||||
*/
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
int
|
||||
min (register int v1, register int v2) {
|
||||
return ((v1 < v2) ? v1 : v2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* max
|
||||
* find maximum of two integers ONLY
|
||||
*/
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
int
|
||||
max (register int v1, register int v2) {
|
||||
return ((v1 > v2) ? v1 : v2);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/*
|
||||
* err_exit
|
||||
* exit cleanly on fatal error (close files, etc). also handles normal
|
||||
* exit.
|
||||
*/
|
||||
void
|
||||
err_exit (int code) {
|
||||
if (err_stream != stderr && err_stream != (FILE *) 0) {
|
||||
/*
|
||||
* not going to stderr (-o file)
|
||||
*/
|
||||
fflush (err_stream);
|
||||
fclose (err_stream);
|
||||
}
|
||||
if (debugging && dbg_stream != stderr && dbg_stream != (FILE *) 0) {
|
||||
fflush (dbg_stream);
|
||||
fclose (dbg_stream);
|
||||
}
|
||||
if (out_stream != stdout && out_stream != (FILE *) 0) {
|
||||
/*
|
||||
* not going to stdout (-l)
|
||||
*/
|
||||
fflush (out_stream);
|
||||
fclose (out_stream);
|
||||
}
|
||||
|
||||
#ifdef GEMDOS
|
||||
if (hold_screen) {
|
||||
wait_for_char();
|
||||
}
|
||||
#endif
|
||||
exit(code);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef GEMDOS
|
||||
#include <osbind.h>
|
||||
|
||||
/*
|
||||
* Wait for a character
|
||||
*/
|
||||
void
|
||||
wait_for_char (void) {
|
||||
printf ("enter any key..."); fflush (stdout);
|
||||
Cconin ();
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,692 @@
|
|||
/*
|
||||
* macros.c - macro input/output processing for nroff word processor
|
||||
*
|
||||
* adapted for atariST/TOS by Bill Rosenkranz 11/89
|
||||
* net: rosenkra@hall.cray.com
|
||||
* CIS: 71460,17
|
||||
* GENIE: W.ROSENKRANZ
|
||||
*
|
||||
* original author:
|
||||
*
|
||||
* Stephen L. Browning
|
||||
* 5723 North Parker Avenue
|
||||
* Indianapolis, Indiana 46220
|
||||
*
|
||||
* history:
|
||||
*
|
||||
* - Originally written in BDS C;
|
||||
* - Adapted for standard C by W. N. Paul
|
||||
* - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
|
||||
* - Heavily modified by Devin Reade to avoid memory trashing bugs.
|
||||
*
|
||||
* $Id: macros.c,v 1.1 1997/03/14 06:22:27 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "macros____";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "err.h"
|
||||
|
||||
#ifdef sparc
|
||||
#include "sunos.h"
|
||||
#endif
|
||||
|
||||
#include "nroff.h"
|
||||
#include "macros.h"
|
||||
#include "io.h"
|
||||
|
||||
static int colmac (char *p, char *d, int i);
|
||||
static int putmac (char *name, char *p);
|
||||
|
||||
void
|
||||
initMacros (void) {
|
||||
memset(mac.mnames, 0, MXMDEF * sizeof(char*));
|
||||
memset(mac.mb, 0, MACBUF);
|
||||
memset(mac.pbb, 0, MAXLINE);
|
||||
#if 0
|
||||
for (i = 0; i < MXMDEF; ++i) {
|
||||
mac.mnames[i] = NULL_CPTR;
|
||||
}
|
||||
for (i = 0; i < MACBUF; ++i) {
|
||||
mac.mb[i] = EOS;
|
||||
}
|
||||
for (i = 0; i < MAXPBB; ++i) {
|
||||
mac.pbb[i] = EOS;
|
||||
}
|
||||
#endif
|
||||
mac.lastp = 0;
|
||||
mac.emb = &mac.mb[0];
|
||||
mac.ppb = NULL_CPTR;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* defmac
|
||||
*
|
||||
* Define a macro. top level, read from stream.
|
||||
*
|
||||
* we should read macro without interpretation EXCEPT:
|
||||
*
|
||||
* 1) number registers are interpolated
|
||||
* 2) strings indicated by \* are interpolated
|
||||
* 3) arguments indicated by \$ are interpolated
|
||||
* 4) concealed newlines indicated by \(newline) are eliminated
|
||||
* 5) comments indicated by \" are eliminated
|
||||
* 6) \t and \a are interpreted as ASCII h tab and SOH.
|
||||
* 7) \\ is interpreted as backslash and \. is interpreted as a period.
|
||||
*
|
||||
* currently, we do only 3. a good place to do it would be here before
|
||||
* putmac, after colmac...
|
||||
*/
|
||||
|
||||
void
|
||||
defmac (char *line, FILE *infp)
|
||||
{
|
||||
register char *q;
|
||||
register int i;
|
||||
char name[MNLEN];
|
||||
char defn[MXMLEN];
|
||||
char newend[10];
|
||||
|
||||
|
||||
#ifdef BORK
|
||||
fprintf(stderr, "DEBUG: defmac: \"%s\"\n", line);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* terminate defn; if it's still this way when we're ready to putmac(),
|
||||
* then the macro definition was empty and we're going to ignore it.
|
||||
*/
|
||||
defn[0] = '\0';
|
||||
|
||||
/*
|
||||
* skip the .de and get to the name...
|
||||
*/
|
||||
q = skipwd (line);
|
||||
q = skipbl (q);
|
||||
|
||||
/*
|
||||
* q now points to the name. Copy it into the "name" buffer.
|
||||
* Make sure it is valid (i.e. first char is alpha...). The
|
||||
* getwrd function returns the length of the word.
|
||||
*/
|
||||
i = getwrd (q, name);
|
||||
if (!isprint (*name)) {
|
||||
errx(-1, "missing or illegal macro definition name");
|
||||
}
|
||||
|
||||
/*
|
||||
* truncate to 2 char max name.
|
||||
*/
|
||||
if (i > 2) {
|
||||
name[2] = EOS;
|
||||
}
|
||||
|
||||
/*
|
||||
* skip the name and see if we have a new end defined...
|
||||
*/
|
||||
q = skipwd (line);
|
||||
q = skipbl (q);
|
||||
for (i = 0; i < 10; i++) {
|
||||
newend[i] = EOS;
|
||||
}
|
||||
|
||||
for (i = 0; (i < 10) && ( isalpha (q[i]) || isdigit (q[i]) ); i++) {
|
||||
newend[i] = q[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* read a line from input stream until we get the end of macro
|
||||
* command (.en or ..). actually. we should have read the next
|
||||
* field just above here to get the .de NA . or .de NA en string
|
||||
* to be new end of macro.
|
||||
*/
|
||||
i = 0;
|
||||
while (getlin (line, infp) != EOF) {
|
||||
#ifdef BORK
|
||||
fprintf(stderr,"DEBUG: %s:%d line is \"%s\"\n", __FILE__, __LINE__,
|
||||
line);
|
||||
#endif
|
||||
if (line[0] == dc.cmdchr && line[1] == '\\' && line[2] == '\"') {
|
||||
/*
|
||||
* comment, ignore it
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (line[0] == dc.cmdchr && newend[0] != EOS
|
||||
&& line[1] == newend[0] && line[2] == newend[1]) {
|
||||
/*
|
||||
* replacement end found
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (line[0] == dc.cmdchr && line[1] == 'e' && line[2] == 'n') {
|
||||
/*
|
||||
* .en found
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (line[0] == dc.cmdchr && line[1] == dc.cmdchr) {
|
||||
/*
|
||||
* .. found
|
||||
*/
|
||||
#ifdef BORK
|
||||
fprintf(stderr,"DEBUG: %s:%d: dot-dot found\n",__FILE__,__LINE__);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* collect macro from the line we just read. all this does
|
||||
* is put it in the string defn.
|
||||
*/
|
||||
#ifdef BORK
|
||||
fprintf(stderr,"DEBUG: %s:%d: collecting macro\n",__FILE__,__LINE__);
|
||||
#endif
|
||||
if ((i = colmac (line, defn, i)) == ERR) {
|
||||
errx(1, "macro definition too long");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* store the macro
|
||||
*/
|
||||
if (!ignoring && defn[0] != '\0') {
|
||||
if (putmac (name, defn) == ERR) {
|
||||
errx(-1, "macro definition table full");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* colmac
|
||||
*
|
||||
* Collect macro definition from input stream
|
||||
*/
|
||||
static int
|
||||
colmac (char *p, char *d, int i) {
|
||||
|
||||
char *pstart;
|
||||
int istart;
|
||||
|
||||
pstart = p;
|
||||
istart = i;
|
||||
while (*p != EOS) {
|
||||
/*
|
||||
* are we over the length limit for a single macro?
|
||||
*/
|
||||
if (i >= MXMLEN - 1) {
|
||||
d[i - 1] = EOS;
|
||||
return (ERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* "i break for comments..."
|
||||
*/
|
||||
if (*p == '\\' && *(p+1) == '\"') {
|
||||
/*
|
||||
* first back over any whitespace between comment
|
||||
* start and last character in line. remember to
|
||||
* decrement counter i, too...
|
||||
*/
|
||||
p--;
|
||||
while (isspace (*p) && p > pstart && i > istart) {
|
||||
p--;
|
||||
i--;
|
||||
}
|
||||
|
||||
/*
|
||||
* now skip over the comment until we reach the
|
||||
* trailing newline
|
||||
*/
|
||||
while (*p != EOS) {
|
||||
if (*p == '\n' || *p == '\r') {
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* skip quoted things
|
||||
*/
|
||||
if (*p == '\\' && *(p+1) == '\\') {
|
||||
p++;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy it
|
||||
*/
|
||||
d[i++] = *p++;
|
||||
}
|
||||
d[i] = EOS;
|
||||
return (i);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* putmac
|
||||
*
|
||||
* Put macro definition into table
|
||||
*
|
||||
* NOTE: any expansions of things like number registers SHOULD
|
||||
* have been done already.
|
||||
*/
|
||||
|
||||
static int
|
||||
putmac (char *name, char *p) {
|
||||
|
||||
/*
|
||||
* any room left? (did we exceed max number of possible macros)
|
||||
*/
|
||||
if (mac.lastp >= MXMDEF) {
|
||||
return (ERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* will new one fit in big buffer?
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
strlen(name);
|
||||
strlen(p);
|
||||
#endif
|
||||
if (mac.emb + strlen (name) + strlen (p) + 1 > &mac.mb[MACBUF]) {
|
||||
return (ERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* add it...
|
||||
*
|
||||
* bump counter, set ptr to name, copy name, copy def.
|
||||
* finally increment end of macro buffer ptr (emb).
|
||||
*
|
||||
* macro looks like this in mb:
|
||||
*
|
||||
* mac.mb[MACBUF] size of total buf
|
||||
* lastp < MXMDEF number of macros possible
|
||||
* *mnames[MXMDEF] -> names, each max length
|
||||
* ..._____________________________...____________________...
|
||||
* / / /|X|X|0|macro definition |0| / / / / / / /
|
||||
* .../_/_/_|_|_|_|________________...___|_|/_/_/_/_/_/_/_...
|
||||
* ^
|
||||
* |
|
||||
* \----- mac.mnames[mac.lastp] points here
|
||||
*
|
||||
* both the 2 char name (XX) and the descripton are null term and
|
||||
* follow one after the other.
|
||||
*/
|
||||
++mac.lastp;
|
||||
mac.mnames[mac.lastp] = mac.emb;
|
||||
strcpy (mac.emb, name);
|
||||
strcpy (mac.emb + strlen (name) + 1, p);
|
||||
mac.emb += strlen (name) + strlen (p) + 2;
|
||||
|
||||
return (OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* getmac
|
||||
*
|
||||
* Get (lookup) macro definition from namespace
|
||||
*/
|
||||
char *
|
||||
getmac (char *name) {
|
||||
int i;
|
||||
|
||||
/*
|
||||
* loop for all macros, starting with last one
|
||||
*/
|
||||
for (i = mac.lastp; i >= 0; --i) {
|
||||
/*
|
||||
* is this REALLY a macro?
|
||||
*/
|
||||
if (mac.mnames[i]) {
|
||||
/*
|
||||
* if it compares, return a ptr to it
|
||||
*/
|
||||
if (!strcmp (name, mac.mnames[i])) {
|
||||
#if 0 /* !!!debug */
|
||||
puts (mac.mnames[i]);
|
||||
#endif
|
||||
|
||||
if (mac.mnames[i][1] == EOS) {
|
||||
return (mac.mnames[i] + 2);
|
||||
} else {
|
||||
return (mac.mnames[i] + 3);
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* none found, return null
|
||||
*/
|
||||
return (NULL_CPTR);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* maceval
|
||||
*
|
||||
* Evaluate macro expansion from p into m
|
||||
*/
|
||||
void
|
||||
maceval (char *p, char *m) {
|
||||
register int i;
|
||||
char *argp[15];
|
||||
char c;
|
||||
int xc;
|
||||
|
||||
/*
|
||||
* replace command char with EOS
|
||||
*/
|
||||
*p++ = EOS;
|
||||
|
||||
/*
|
||||
* initialize argp array to substitute command
|
||||
* string for any undefined argument
|
||||
*
|
||||
* NO!!! this is fixed...
|
||||
*/
|
||||
#if 0
|
||||
for (i = 0; i < 10; ++i) {
|
||||
argp[i] = p;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* skip the command name
|
||||
*/
|
||||
p = skipwd (p);
|
||||
*p++ = EOS;
|
||||
|
||||
/*
|
||||
* loop for all $n variables...
|
||||
*/
|
||||
for (i = 0; i < 10; ++i) {
|
||||
/*
|
||||
* get to substituted param and if no more, reset remaining
|
||||
* args to NULL and stop. using "i" here IS ok...
|
||||
*/
|
||||
p = skipbl (p);
|
||||
if (*p == '\r' || *p == '\n' || *p == EOS) {
|
||||
DEBUGGING(("maceval: set_ireg(.$, %d, 0)", i));
|
||||
|
||||
set_ireg (".$", i, 0);
|
||||
for ( ; i < 10; i++) {
|
||||
argp[i] = NULL_CPTR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* ...otherwise, see if this param is quoted. if it is,
|
||||
* it is all one parameter, even with blanks (but not
|
||||
* newlines...). look for another "c" (which is the quote).
|
||||
*
|
||||
* if no quote, just read the arg as a single word and null
|
||||
* terminate it.
|
||||
*/
|
||||
if (*p == '\'' || *p == '"') {
|
||||
c = *p++;
|
||||
argp[i] = p;
|
||||
while (*p != c && *p != '\r' && *p != '\n' && *p != EOS) {
|
||||
++p;
|
||||
}
|
||||
*p++ = EOS;
|
||||
} else {
|
||||
argp[i] = p;
|
||||
p = skipwd (p);
|
||||
*p++ = EOS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* m contains text of the macro. p contained the input line.
|
||||
* here we start at the end of the macro def and see if there
|
||||
* are any $n thingies. go backwards.
|
||||
*/
|
||||
for (i = strlen (m) - 1; i >= 0; --i) {
|
||||
/*
|
||||
* found a $.
|
||||
*/
|
||||
if (i > 0 && m[i - 1] == '$') {
|
||||
if (!isdigit (m[i])) {
|
||||
/*
|
||||
* it wasn't a numeric replacement arg so
|
||||
* push this char back onto input stream
|
||||
*/
|
||||
PUTBAK(m[i]);
|
||||
} else {
|
||||
/*
|
||||
* it WAS a numeric replacement arg. so we
|
||||
* want to push back the appropriate macro
|
||||
* invocation arg. m[i]-'0' is the numerical
|
||||
* value of the $1 thru $9. if the arg is
|
||||
* not there, argp[n] will be (char *) 0
|
||||
* and pbstr will do nothing.
|
||||
*/
|
||||
xc = m[i] - '1';
|
||||
if (argp[xc]) {
|
||||
pbstr (argp[xc]);
|
||||
}
|
||||
--i;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* no $ so push back the char...
|
||||
*/
|
||||
PUTBAK(m[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* at this point, the iobuf will hold the new macro command, full
|
||||
* expanded for $n things. the return gets us right back to the
|
||||
* main loop in main() and we parse the (new) command just as if
|
||||
* it were read from a file.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* printmac
|
||||
* print macro data:
|
||||
* opt print
|
||||
* === =====
|
||||
* 0 name and size
|
||||
* 1 total size
|
||||
* 2 full information
|
||||
*/
|
||||
|
||||
void
|
||||
printmac (int opt) {
|
||||
register int i; /* was long, minix needs int */
|
||||
register long localSpace;
|
||||
register long totalspace;
|
||||
register char *pname;
|
||||
register char *pdef;
|
||||
|
||||
|
||||
localSpace = 0L;
|
||||
totalspace = 0L;
|
||||
|
||||
fflush (out_stream);
|
||||
fflush (err_stream);
|
||||
|
||||
for (i = mac.lastp; i >= 0; --i) {
|
||||
/*
|
||||
* is this REALLY a macro?
|
||||
*/
|
||||
if (mac.mnames[i]) {
|
||||
pname = (char *) (mac.mnames[i]);
|
||||
pdef = pname + 3;
|
||||
if (*(pname + 1) == '\0') {
|
||||
pdef = pname + 2;
|
||||
}
|
||||
|
||||
localSpace = (long) strlen (pdef);
|
||||
totalspace += localSpace;
|
||||
|
||||
switch (opt) {
|
||||
case 0:
|
||||
fprintf (err_stream, "%s %ld\n", pname, localSpace);
|
||||
break;
|
||||
case 2:
|
||||
fprintf (err_stream, "%s %ld\n", pname, localSpace);
|
||||
fprintf (err_stream, "%s\n", pdef);
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf (err_stream, "Total space: %ld\n", totalspace);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* putstr
|
||||
*
|
||||
* Put string definition into (macro) table
|
||||
*
|
||||
* NOTE: any expansions of things like number registers SHOULD
|
||||
* have been done already. strings and macros share mb buffer
|
||||
*/
|
||||
|
||||
int
|
||||
putstr (const char *name, const char *p) {
|
||||
|
||||
/*
|
||||
* any room left? (did we exceed max number of possible macros)
|
||||
*/
|
||||
if (mac.lastp >= MXMDEF) {
|
||||
return (ERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* will new one fit in big buffer?
|
||||
*/
|
||||
if (mac.emb + strlen (name) + strlen (p) + 1 > &mac.mb[MACBUF]) {
|
||||
return (ERR);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* add it...
|
||||
*
|
||||
* bump counter, set ptr to name, copy name, copy def.
|
||||
* finally increment end of macro buffer ptr (emb).
|
||||
*
|
||||
* string looks like this in mb:
|
||||
*
|
||||
* mac.mb[MACBUF] size of total buf
|
||||
* lastp < MXMDEF number of macros/strings possible
|
||||
* *mnames[MXMDEF] -> names, each max length
|
||||
* ...______________________________...____________________...
|
||||
* / / /|X|X|0|string definition |0| / / / / / / /
|
||||
* .../_/_/_|_|_|_|_________________...___|_|/_/_/_/_/_/_/_...
|
||||
* ^
|
||||
* |
|
||||
* \----- mac.mnames[mac.lastp] points here
|
||||
*
|
||||
* both the 2 char name (XX) and the descripton are null term and
|
||||
* follow one after the other.
|
||||
*/
|
||||
++mac.lastp;
|
||||
mac.mnames[mac.lastp] = mac.emb;
|
||||
strcpy (mac.emb, name);
|
||||
strcpy (mac.emb + strlen (name) + 1, p);
|
||||
mac.emb += strlen (name) + strlen (p) + 2;
|
||||
return (OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getstr
|
||||
* Get (lookup) string definition from namespace
|
||||
*/
|
||||
char *
|
||||
getstr (char *name) {
|
||||
int i;
|
||||
|
||||
/*
|
||||
* loop for all macros, starting with last one
|
||||
*/
|
||||
for (i = mac.lastp; i >= 0; --i) {
|
||||
/*
|
||||
* is this REALLY a macro?
|
||||
*/
|
||||
if (mac.mnames[i]) {
|
||||
/*
|
||||
* if it compares, return a ptr to it
|
||||
*/
|
||||
if (!strcmp (name, mac.mnames[i])) {
|
||||
#if 0 /* !!!debug */
|
||||
puts (mac.mnames[i]);
|
||||
#endif
|
||||
if (mac.mnames[i][1] == EOS) {
|
||||
return (mac.mnames[i] + 2);
|
||||
} else {
|
||||
return (mac.mnames[i] + 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* none found, return null
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NOT_USED
|
||||
|
||||
/*
|
||||
* putbak
|
||||
*
|
||||
* Push character back into input stream. we use the push-back buffer
|
||||
* stored with macros.
|
||||
*/
|
||||
void
|
||||
putbak (char c)
|
||||
{
|
||||
if (mac.ppb == NULL) { /* first time executing this code */
|
||||
mac.ppb = mac.pbb;
|
||||
*mac.ppb = c;
|
||||
} else if (mac.ppb < mac.pbb + MAXPBB) {
|
||||
mac.ppb++;
|
||||
*(mac.ppb) = c;
|
||||
} else {
|
||||
errx(-1, "push back buffer overflow (%d chars)", MAXPBB);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ngetc
|
||||
* get a character from the putback buffer or from <infp>
|
||||
*/
|
||||
int ngetc (FILE *infp)
|
||||
{
|
||||
register int c;
|
||||
|
||||
if (mac.ppb >= mac.pbb) {
|
||||
c = *mac.ppb--;
|
||||
} else {
|
||||
c = getc (infp);
|
||||
}
|
||||
return (c);
|
||||
}
|
||||
#endif /* NOT_USED */
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* $Id: macros.h,v 1.1 1997/03/14 06:22:27 gdr Exp $
|
||||
*
|
||||
* PUTBAK
|
||||
*
|
||||
* Push character back into input stream. we use the push-back buffer
|
||||
* stored with macros.
|
||||
*/
|
||||
#define PUTBAK(c) \
|
||||
{ \
|
||||
if (mac.ppb == NULL) { /* first time executing this code */ \
|
||||
mac.ppb = mac.pbb; \
|
||||
*mac.ppb = c; \
|
||||
} else if (mac.ppb < mac.pbb + MAXPBB) { \
|
||||
mac.ppb++; \
|
||||
*(mac.ppb) = c; \
|
||||
} else { \
|
||||
errx(-1, "push back buffer overflow (%d chars)", MAXPBB); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* NGETC -- get character from input file or push back buffer */
|
||||
#define NGETC(infp) ((mac.ppb >= mac.pbb) ? *mac.ppb-- : getc(infp))
|
||||
|
||||
typedef struct macros_t {
|
||||
char *mnames[MXMDEF]; /* table of ptrs to macro names */
|
||||
int lastp; /* index to last mname */
|
||||
char *emb; /* next char avail in macro defn buf */
|
||||
char mb[MACBUF]; /* table of macro definitions */
|
||||
char *ppb; /* pointer into push back buffer */
|
||||
char pbb[MAXPBB]; /* push back buffer */
|
||||
} macros_t;
|
||||
|
||||
|
||||
extern macros_t mac;
|
||||
|
||||
void initMacros (void);
|
||||
void defmac (char *line, FILE *infp);
|
||||
char *getmac (char *name);
|
||||
void maceval (char *p, char *m);
|
||||
void printmac (int opt);
|
||||
int putstr (const char *name, const char *p);
|
||||
char *getstr (char *name);
|
|
@ -0,0 +1,100 @@
|
|||
#
|
||||
# Makefile for nroff(1).
|
||||
#
|
||||
# $Id: makefile.mk,v 1.1 1997/03/14 06:22:28 gdr Exp $
|
||||
#
|
||||
|
||||
IIGS = FALSE # TRUE or FALSE
|
||||
USE_INSIGHT = FALSE # TRUE or FALSE
|
||||
|
||||
BINDIR = /usr/bin
|
||||
TMACDIR = /usr/lib/tmac
|
||||
MANDIR = /usr/man
|
||||
|
||||
#
|
||||
###### end of configuration
|
||||
#
|
||||
|
||||
PROFILE = # -pg
|
||||
|
||||
.IF $(IIGS) == TRUE
|
||||
DEFINES =
|
||||
OPTIMIZE =
|
||||
LDLIBS =
|
||||
.ELIF $(USE_INSIGHT) == TRUE
|
||||
CC = insight
|
||||
DEFINES =
|
||||
OPTIMIZE = -g
|
||||
LDLIBS = int.tqs -ltermcap
|
||||
.ELSE
|
||||
CC = gcc
|
||||
DEFINES = # -DDEBUG
|
||||
OPTIMIZE = $(PROFILE) -g
|
||||
LDLIBS = $(PROFILE) -ltermcap
|
||||
.END
|
||||
|
||||
.IF $(IIGS) == TRUE
|
||||
UX_SRC =
|
||||
UX_OBJ =
|
||||
.ELSE
|
||||
UX_SRC = err.c
|
||||
UX_OBJ = err.o
|
||||
.END
|
||||
|
||||
GCC_PARANOIA = \
|
||||
-Wstrict-prototypes \
|
||||
-Wmissing-prototypes \
|
||||
-Waggregate-return \
|
||||
-Wnested-externs \
|
||||
-fno-asm -fno-builtin -fno-inline
|
||||
|
||||
.IF $(CC) == gcc
|
||||
GCC_FLAGS = -Wall -funsigned-char $(GCC_PARANOIA)
|
||||
.ELSE
|
||||
GCC_FLAGS =
|
||||
.END
|
||||
|
||||
|
||||
CFLAGS = $(OPTIMIZE) $(GCC_FLAGS) $(DEFINES)
|
||||
|
||||
SUNOS_H = sunos.h
|
||||
OBJS = main.o command.o escape.o io.o low.o macros.o strings.o \
|
||||
text.o $(UX_OBJ)
|
||||
SRCS = main.c command.c escape.c io.c low.c macros.c strings.c \
|
||||
text.c $(UX_SRC)
|
||||
|
||||
default: nroff
|
||||
|
||||
nroff: $(OBJS)
|
||||
$(CC) -o $@ $(LDFLAGS) $(OBJS) $(LDLIBS)
|
||||
|
||||
clobber:
|
||||
$(RM) -f nroff $(OBJS)
|
||||
# $(RM) -f nroff $(OBJS) *~ core tca.* *.tqs insight.log
|
||||
|
||||
dep:
|
||||
gcc -MM $(CFLAGS) *.c > depend
|
||||
|
||||
callchart:
|
||||
cflow $(SRCS) > $@
|
||||
|
||||
install:
|
||||
$(INSTALL) -d $(BINDIR) $(TMACDIR) $(MANDIR)/man1 $(MANDIR)/man7
|
||||
$(INSTALL) -m755 nroff $(BINDIR)
|
||||
$(INSTALL) -m644 tmac.an $(TMACDIR)
|
||||
$(INSTALL) -m644 tmac.s $(TMACDIR)
|
||||
$(INSTALL) -m644 nroff.1 $(TMACDIR)/man1
|
||||
$(INSTALL) -m644 man.7 $(TMACDIR)/man7
|
||||
$(INSTALL) -m644 ms.7 $(TMACDIR)/man7
|
||||
|
||||
#
|
||||
# additional dependancies
|
||||
#
|
||||
command.o:: $(SUNOS_H) nroff.h config.h
|
||||
escape.o:: $(SUNOS_H) nroff.h config.h
|
||||
io.o:: $(SUNOS_H) nroff.h config.h macros.h io.h
|
||||
low.o:: $(SUNOS_H) nroff.h config.h
|
||||
macros.o:: $(SUNOS_H) nroff.h config.h macros.h
|
||||
main.o:: $(SUNOS_H) nroff.h config.h macros.h
|
||||
strings.o:: $(SUNOS_H) nroff.h config.h
|
||||
text.o:: $(SUNOS_H) nroff.h config.h io.h
|
|
@ -0,0 +1,248 @@
|
|||
.\" man(7) manpage by rosenkra@convex.com (Bill Rosenkranz, 7/22/90)
|
||||
.\"
|
||||
.TH MAN 7
|
||||
.SH NAME
|
||||
man - nroff macro package for manual pages
|
||||
.SH SYNOPSIS
|
||||
nroff -man file ...
|
||||
.SH DESCRIPTION
|
||||
These macros are used to lay out reference pages for manuals.
|
||||
.PP
|
||||
Any text argument
|
||||
t
|
||||
may be zero to six words.
|
||||
Quotes may be used to include blanks in a 'word'.
|
||||
Text
|
||||
can be empty, but unlike normal Unix macros, the next line is not used.
|
||||
.PP
|
||||
A prevailing indent distance is remembered between successive
|
||||
indented paragraphs, and is reset to default value upon
|
||||
reaching a non-indented paragraph (i.e. at .SH or .SS).
|
||||
In contrast with normal Unix procedure, all indents (tabs) are 8 spaces
|
||||
instead of 5.
|
||||
This can be changed by modifying tmac.an.
|
||||
.SH FILES
|
||||
.ec |
|
||||
\lib\tmac\tmac.an the macro library
|
||||
.ec \
|
||||
.SH SEE ALSO
|
||||
nroff(1), man(1)
|
||||
.SH "REQUEST SUMMARY"
|
||||
.nf
|
||||
.cc +
|
||||
Request Cause Explanation
|
||||
Break?
|
||||
|
||||
.B t no Text t is bold. Quote to imbed blanks.
|
||||
.I t no Text t is italic. Quote to imbed blanks.
|
||||
.IP x yes Set prevailing indent to 8. Begin
|
||||
indented paragraph with hanging tag
|
||||
given by first argument. Tag x is
|
||||
always placed on a separate line.
|
||||
.LP yes Same as .PP.
|
||||
.PP yes Begin paragraph. Set prevailing
|
||||
indent to 8.
|
||||
.RE yes End of relative indent. Set prevailing
|
||||
indent to amount of starting .RS.
|
||||
.RP x yes Like .IP, but use relative indent. Must
|
||||
end the section with .RE.
|
||||
.RS yes Start relative indent, move left margin
|
||||
in distance 8.
|
||||
.SH t yes Subhead. Quote to imbed blanks.
|
||||
.SS t yes Subsection. Quote to imbed blanks. No
|
||||
indent for t.
|
||||
.TH n s c v d yes Begin page named n of chapter s; c is
|
||||
the chapter name; d is the date of the
|
||||
most recent change; v is version number.
|
||||
Sets prevailing indent and tabs to 8.
|
||||
|
||||
+cc .
|
||||
.fi
|
||||
.ne 8
|
||||
.SH EXAMPLE
|
||||
The following illustrates some of the requests available
|
||||
with this macro package:
|
||||
.RS
|
||||
.nf
|
||||
.cc +
|
||||
|
||||
.\\\|" this is a comment
|
||||
.TH DEMO 1 "Commands Manual" "Version 1.0" "\\\|*\|(DA"
|
||||
.SH NAME
|
||||
demo - show how to use -man package \\\|" this is a comment
|
||||
.SH SYNOPSIS
|
||||
demo [options] file [...]
|
||||
.SH DESCRIPTION
|
||||
This is a test for showing how to use the
|
||||
.I nroff(1)
|
||||
man package.
|
||||
It shows how to use .TH, .SH, .PP, .I, and .IP commands.
|
||||
.PP
|
||||
This will be a new paragraph.
|
||||
You can also use normal
|
||||
.I nroff(1)
|
||||
commands in the text.
|
||||
.SS NROFF COMMANDS:
|
||||
.IP '\\\\\|"'
|
||||
This is the comment command.
|
||||
Note how you have to quote this sucker!
|
||||
You'll probably never have to write an
|
||||
.I nroff(1)
|
||||
manpage, so don't worry about it.
|
||||
.IP nf
|
||||
No fill mode (the normal mode is fill mode where things
|
||||
get justified right and left).
|
||||
.IP fi
|
||||
Re-enter fill mode.
|
||||
.IP br
|
||||
Break line here no matter what.
|
||||
.IP sp
|
||||
Vertical space (also causes a break to occur).
|
||||
.sp
|
||||
Note that to continue an indent and make a new paragraph (as
|
||||
is the case here), just put in a space (.sp).
|
||||
.PP
|
||||
Now we should be at a new paragraph.
|
||||
|
||||
+cc .
|
||||
.fi
|
||||
.RE
|
||||
.ne 8
|
||||
Executing 'nroff -man demo.man' results in the following output:
|
||||
.RS
|
||||
.nf
|
||||
.cc +
|
||||
|
||||
DEMO (1) Commands Manual DEMO (1)
|
||||
|
||||
NAME
|
||||
demo - show how to use -man package
|
||||
|
||||
SYNOPSIS
|
||||
demo [options] file [...]
|
||||
|
||||
DESCRIPTION
|
||||
This is a test for showing how to use the nroff(1)
|
||||
man package. It shows how to use .TH, .SH, .PP, .I,
|
||||
and .IP commands.
|
||||
|
||||
This will be a new paragraph. You can also use normal
|
||||
nroff(1) commands in the text.
|
||||
|
||||
NROFF COMMANDS:
|
||||
|
||||
\\\|"
|
||||
This is the comment command. Note how you have to
|
||||
quote this sucker! You'll probably never have to
|
||||
write an nroff(1) manpage, so don't worry about
|
||||
it.
|
||||
|
||||
nf
|
||||
No fill mode (the normal mode is fill mode where
|
||||
things get justified right and left).
|
||||
|
||||
fi
|
||||
Re-enter fill mode.
|
||||
|
||||
br
|
||||
Break line here no matter what.
|
||||
|
||||
sp
|
||||
Vertical space (also causes a break to occur).
|
||||
|
||||
Note that to continue an indent and make a new
|
||||
paragraph (as is the case here), just put in a
|
||||
space (.sp).
|
||||
|
||||
Now we should be at a new paragraph.
|
||||
|
||||
Version 1.0 23:33:57 2/25/90 1
|
||||
|
||||
|
||||
+cc .
|
||||
.fi
|
||||
.RE
|
||||
.ne 8
|
||||
.SH CONVENTIONS
|
||||
A typical manual page for a command or function is laid out as follows:
|
||||
.sp
|
||||
.RS
|
||||
.SS ".TH TITLE [1-8]"
|
||||
The name of the command or function in upper-case,
|
||||
which serves as the title of the manual page.
|
||||
This is followed by the number of the section in which it appears.
|
||||
.SS ".SH NAME"
|
||||
name - one-line summary
|
||||
.PP
|
||||
The name, or list of names, by which the command is called, followed by
|
||||
a dash and then a one-line summary of the action performed.
|
||||
All in roman font, this section contains no troff(1) commands or escapes,
|
||||
and no macro requests.
|
||||
It is used to generate the whatis(1) database.
|
||||
.SS ".SH SYNOPSIS"
|
||||
Commands:
|
||||
.sp
|
||||
.RS
|
||||
The syntax of the command and its arguments as typed on the command line.
|
||||
When in boldface, a word must be typed exactly as printed.
|
||||
When in italics, a word can be replaced with text that you supply.
|
||||
Syntactic symbols appear in roman face:
|
||||
.RP "[ ]"
|
||||
An argument, when surrounded by brackets is optional.
|
||||
.RE
|
||||
.RP |
|
||||
Arguments separated by a vertical bar are exclusive.
|
||||
You can supply only item from such a list.
|
||||
.RE
|
||||
.RP ...
|
||||
Arguments followed by an elipsis can be repeated.
|
||||
When an elipsis follows a bracketed set, the expression within the
|
||||
brackets can be repeated.
|
||||
.RE
|
||||
.RE
|
||||
.sp
|
||||
Functions:
|
||||
.sp
|
||||
.RS
|
||||
If required, the data declaration, or #include directive, is shown first,
|
||||
followed by the function declaration.
|
||||
Otherwise, the function declaration is shown.
|
||||
.RE
|
||||
.SS ".SH DESCRIPTION"
|
||||
A narrative description of the command or function in detail, including
|
||||
how it interacts with files or data, and how it handles the standard
|
||||
input, standard output and standard error.
|
||||
.PP
|
||||
Filenames, and references to commands or functions described elswhere
|
||||
in the manual, are italicised.
|
||||
The names of options, variables and other literal terms are
|
||||
in boldface.
|
||||
.SS ".SH OPTIONS"
|
||||
The list of options along with a description of how each affects the
|
||||
commands operation.
|
||||
.SS ".SH FILES"
|
||||
A list of files associated with the command or function.
|
||||
.SS '.SH "SEE ALSO"'
|
||||
A comma-separated list of related manual pages, followed by references
|
||||
to other published materials.
|
||||
This section contains no troff(1) escapes or commands, and no macro requests.
|
||||
.SS ".SH DIAGNOSTICS"
|
||||
A list of diagnostic messages and an explanation of each.
|
||||
.SS ".SH NOTES"
|
||||
Any additional notes such as installation-dependent functionality.
|
||||
.SS ".SH BUGS"
|
||||
A description of limitations, known defects, and possible problems
|
||||
associated with the command or function.
|
||||
.SS ".SH AUTHOR"
|
||||
The program's author and any pertinent release info.
|
||||
.SS ".SH VERSION"
|
||||
The program's current version number and release date.
|
||||
.RE
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
Adapted for Atari ST (TOS) and Minix by Bill Rosenkranz
|
||||
|
||||
net: rosenkra@convex.com
|
||||
CIS: 71460,17
|
||||
GENIE: W.ROSENKRANZ
|
||||
.fi
|
|
@ -0,0 +1,105 @@
|
|||
.\" ms(7) manpage by rosenkra@convex.com (Bill Rosenkranz, 7/22/90)
|
||||
.\"
|
||||
.TH MS 7
|
||||
.SH NAME
|
||||
ms - text formatting macros
|
||||
.SH SYNOPSIS
|
||||
nroff -ms [ options ] file ...
|
||||
.SH DESCRIPTION
|
||||
This package of nroff macro definitions provides a
|
||||
formatting facility for various styles of articles, theses, and books.
|
||||
All external -ms macros are defined below.
|
||||
.PP
|
||||
Note that this -ms macro package is a subset of the complete ms package
|
||||
since nroff(1) is not quite up to it yet.
|
||||
Still, it supports most of what is normally used, including the table
|
||||
of contents macros.
|
||||
.PP
|
||||
Some nroff requests may be unsafe in conjunction with this package.
|
||||
However, the first four requests below may be used with impunity after
|
||||
initialization, and the last two may be used even before initialization:
|
||||
.nf
|
||||
|
||||
.bp begin new page
|
||||
.br break output line
|
||||
.sp n insert n spacing lines
|
||||
.ce n center next n lines
|
||||
|
||||
.ls n line spacing: n=1 single, n=2 double space
|
||||
.na no alignment of right margin
|
||||
|
||||
.fi
|
||||
Font changes with \f are also allowed;
|
||||
for example, '\\fIword\\fR' will italicize word.
|
||||
.SH FILES
|
||||
.ec |
|
||||
\lib\tmac\tmac.s
|
||||
.ec \
|
||||
.SH REQUESTS
|
||||
.nf
|
||||
.cc +
|
||||
Macro Initial Break? Explanation
|
||||
Name Value Reset?
|
||||
.AB x - y begin abstract; if x=no don't label abstract
|
||||
.AE - y end abstract
|
||||
.AI - y author's institution, centered
|
||||
.AU - y author's name, centered
|
||||
.B x - n embolden x; if no x, switch to boldface
|
||||
.I x - n italicize x; if no x, switch to italics
|
||||
.IP x - y,y indented paragraph, with hanging tag x
|
||||
.LP - y,y left (block) paragraph.
|
||||
.NH x - y,y numbered header; x=level, x=0 resets
|
||||
.PP - y,y paragraph with first line indented
|
||||
.QP - y,y quoted paragraph (indented, shorter)
|
||||
.R on n return to Roman font
|
||||
.RE - y,y end level of relative indentation
|
||||
.RS 5n y,y right shift: start level of relative indent
|
||||
.SH - y,y section header, no numbering
|
||||
.TL - y title, centered
|
||||
.XP - y,y extended paragraph (biblio entry)
|
||||
.XS p - y begin index entry, p = page
|
||||
.XA p - y another index entry, p = page
|
||||
.XE - y end index entry
|
||||
.PX - y print index (ignored)
|
||||
|
||||
+cc .
|
||||
.fi
|
||||
.SH REGISTERS
|
||||
There are currently no user controlled registers in this implementation.
|
||||
.PP
|
||||
Here is a list of string registers available in -ms; they
|
||||
may be used anywhere in the text:
|
||||
.nf
|
||||
.ec |
|
||||
|
||||
Name String's Function
|
||||
|
||||
\*(DW weekday
|
||||
\*(MO month (month of the year)
|
||||
\*(DY day (current date)
|
||||
\*Q quote (" in nroff)
|
||||
\*U unquote (" in nroff)
|
||||
\*- dash (-- in nroff)
|
||||
|
||||
.ec \
|
||||
.fi
|
||||
.SH EXAMPLES
|
||||
For an example, see the test files (*.ms) included in the distribution.
|
||||
.SH BUGS
|
||||
Probably zillions, especially considering it is so incomplete.
|
||||
However, it is useful (better than nothing at all).
|
||||
I have used this package extensively at home to write reports for work.
|
||||
The results were nearly 100% compatible with Unix (BSD).
|
||||
No support for displays and keeps, tables, boxed text, multicolumn, other
|
||||
modes (e.g. thesis mode), footnotes, and beginning/end page traps.
|
||||
Indented paragraph with tag puts the tag on its own line regardless how
|
||||
long it is.
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
Adapted for Atari ST (TOS) and Minix by Bill Rosenkranz
|
||||
|
||||
net: rosenkra@convex.com
|
||||
CIS: 71460,17
|
||||
GENIE: W.ROSENKRANZ
|
||||
.fi
|
||||
|
|
@ -0,0 +1,766 @@
|
|||
.\" nroff(1) manpage by rosenkra@convex.com (Bill Rosenkranz, 7/22/90)
|
||||
.\"
|
||||
.TH NROFF 1
|
||||
.SH NAME
|
||||
nroff - text processor (Version 1.10)
|
||||
.SH SYNOPSIS
|
||||
nroff [options] file [...]
|
||||
.SH DESCRIPTION
|
||||
Nroff is a text processor and formatter based on the design
|
||||
provided in "Software Tools" by Kernighan and Plauger.
|
||||
It has been modified to closely resemble the Unix(tm) nroff command.
|
||||
The text and commands found in the file(s)
|
||||
are processed to generate formatted text.
|
||||
Note that one (and only one) of the files can be "-" which reads
|
||||
input from stdin at that point.
|
||||
The output always goes to stdout which can be redirected by the shell.
|
||||
.\" Using the command line option -l will cause the output to
|
||||
.\" be sent to the printer instead.
|
||||
The -o option lets you redirect error output to the specified
|
||||
file rather than stderr.
|
||||
Debugging information always goes to the file "nroff.dbg" and is
|
||||
generally used only for program development.
|
||||
.SH OPTIONS
|
||||
The following command line options are available:
|
||||
.IP -d
|
||||
Set debug mode.
|
||||
.IP -h
|
||||
Hold before exit (Atari TOS only).
|
||||
.IP -m<name>
|
||||
Process macro file tmac.<name>.
|
||||
Thus -man would cause the file tmac.an to be loaded.
|
||||
Note that files processed in this way should contain only macro definitions,
|
||||
no immediate output should be generated from this file (see ENVIRONMENT).
|
||||
.IP -o<file>
|
||||
Set error log file (default is stderr).
|
||||
.IP -raN
|
||||
Preset number register 'a' (single character) to N (decimal integer only).
|
||||
.IP -po<n>
|
||||
Shift output right n spaces (like .po).
|
||||
.IP -pn<n>
|
||||
Initial page number (like .pn).
|
||||
.IP -v
|
||||
Prints the version information to stdout.
|
||||
.IP +<n>
|
||||
Causes output to start with page n.
|
||||
.IP -<n>
|
||||
Causes output to stop after page n.
|
||||
.IP -
|
||||
Input from stdin.
|
||||
.sp
|
||||
.SH ENVIRONMENT
|
||||
Nroff recognizes the following environment variables from the shell:
|
||||
.IP TMACDIR
|
||||
An alternate directory to find the files tmac.* ("." for example).
|
||||
The default is c:\\lib\\tmac under TOS and /usr/lib/tmac under
|
||||
Minix or Unix(tm).
|
||||
.IP TMPDIR
|
||||
An alternate directory to place any temporary files.
|
||||
The default is the current directory.
|
||||
Note that nroff does not currently use any temporary files.
|
||||
.SH COMMANDS
|
||||
Commands typically are distinguished by a period in column one
|
||||
of the input
|
||||
followed by a two character abbreviation for the command funtion.
|
||||
The abbreviation may then be followed by an optional numeric or
|
||||
character argument.
|
||||
The numeric argument may be an absolute value such as setting
|
||||
the right margin to a particular column, or the argument may be
|
||||
preceded by a plus sign or a minus sign to indicate that the
|
||||
parameter should be modified relative to a previous setting.
|
||||
The following commands are recognized (those marked "extension"
|
||||
are requests added to the basic set provided by Unix(tm) nroff):
|
||||
.\"
|
||||
.IP .ad
|
||||
Begin line adjustment.
|
||||
If fill mode is not on, adjustment is defered until it is back on.
|
||||
If a type indicator is present, the adjustment type is changed as follows:
|
||||
.nf
|
||||
|
||||
Indicator Type
|
||||
l adjust left margin only
|
||||
r adjust right margin only
|
||||
c center
|
||||
b or n adjust both margins (default)
|
||||
absent unchanged
|
||||
.fi
|
||||
.\"
|
||||
.IP .af
|
||||
Assign format to number register.
|
||||
The available formats are:
|
||||
.nf
|
||||
|
||||
Format Numbering Sequence
|
||||
1 0,1,2,3,4,...
|
||||
001 000,001,002,...
|
||||
i 0,i,ii,iii,iv,v,...
|
||||
I 0,I,II,III,IV,V,...
|
||||
a 0,a,b,...,z,aa,ab,...zz,aaa,...
|
||||
A 0,A,B,...,Z,AA,AB,...ZZ,AAA,...
|
||||
|
||||
.fi
|
||||
The second format above indicates that the field width, i.e. number
|
||||
of digits, is specified by the number of digits in the format type.
|
||||
.\"
|
||||
.IP .bd
|
||||
Ignored by nroff.
|
||||
.\"
|
||||
.IP .bo (extension)
|
||||
Causes the following lines of text to appear in boldface.
|
||||
The optional argument specifies the number of lines to be typed in boldface.
|
||||
Boldface and underlining are mutually exclusive features.
|
||||
The appearance of a boldface command will cause any underlining to cease.
|
||||
.\"
|
||||
.IP .bp (extension)
|
||||
Causes succeeding text to appear at the top of a new page.
|
||||
The optional argument specifies the page number for the new page.
|
||||
The initial value is one and the default value is one more than
|
||||
the previous page number.
|
||||
.\"
|
||||
.IP .br
|
||||
Causes succeeding text to start on a new line at the current left margin.
|
||||
There is no numeric argument for this command.
|
||||
.\"
|
||||
.IP .bs (extension)
|
||||
Enables or disables the appearance of backspaces in the output text.
|
||||
Underlining and boldface options are implemented by inserting
|
||||
character - backspace - character combinations into the output buffer.
|
||||
This is fine for devices which properly recognize the backspace character.
|
||||
Some printers, however, do not recognize backspaces, so the option is
|
||||
provided to overprint one line buffer with another.
|
||||
The first line buffer is terminated with just a carriage return
|
||||
rather than the carriage return - linefeed combination.
|
||||
A zero argument or no argument to the backspace command removes
|
||||
backspaces from the output.
|
||||
A non-zero argument leaves them in the output.
|
||||
The default is to remove backspaces.
|
||||
.\"
|
||||
.IP .cc
|
||||
Changes the nroff command character to that specified by the
|
||||
character argument.
|
||||
If no argument is provided, the default is a period (\.).
|
||||
.\"
|
||||
.IP .ce
|
||||
Causes the next line of text to appear centered on the output.
|
||||
The optional argument specifies if more than one line is to be centered.
|
||||
.\"
|
||||
.IP .cs
|
||||
Ignored by nroff.
|
||||
.\"
|
||||
.IP .cu
|
||||
Causes the next line(s) of text to be continuously underlined.
|
||||
Unlike the underline command (see \.ul) which underlines only
|
||||
alphanumerics, continuous underlining underlines all printable characters.
|
||||
The optional argument specifies the number of lines of text to underlined.
|
||||
Any normal underlining or boldface commands currently in effect will be
|
||||
terminated.
|
||||
.\"
|
||||
.IP .c2
|
||||
Changes the nroff no break character to that specified by the
|
||||
character argument.
|
||||
If no argument is provided, the default is a single quote.
|
||||
.\"
|
||||
.IP .de
|
||||
Causes all text and commands following to be used to define a macro.
|
||||
The definition is terminated by a \.en command or the
|
||||
default \.\. terminator.
|
||||
The first two characters of the argument following the \.de
|
||||
command become the name of the new command.
|
||||
It should be noted that upper and lower case arguments are considered different.
|
||||
Thus, the commands \.PP and \.pp could define two different macros.
|
||||
Care should be exercised since existing commands may be redefined.
|
||||
.sp
|
||||
A macro may contain up to nine arguments.
|
||||
In the macro definition, the placement of arguments is designated by the
|
||||
two character sequences, $1, $2, ... $9.
|
||||
When the macro is invoked, each argument of the macro command line is
|
||||
substituted for its corresponding designator in the expansion.
|
||||
The first argument of the macro command is substituted for the $1
|
||||
in the expansion, the second argument for the $2, and so forth.
|
||||
Arguments are typically strings which do not contain blanks or tabs.
|
||||
If an argument is to contain blanks, then it should be surrounded by
|
||||
either single or double quotes.
|
||||
.\"
|
||||
.IP .ds
|
||||
Define a string.
|
||||
To initiate the string with a blank or include blanks
|
||||
in the string, start it with a single or double quite.
|
||||
The string
|
||||
can contain other defined strings or number registers as well as normal
|
||||
text.
|
||||
Strings are stored on the macro name space.
|
||||
.\"
|
||||
.IP .ec
|
||||
Changes the nroff escape character to that specified by the
|
||||
character argument.
|
||||
If no argument is provided, the default is a backslash.
|
||||
.\"
|
||||
.IP .ef (extension)
|
||||
Specifies the text for the footer on even numbered pages.
|
||||
The format is the same as for the footer command (see \.fo).
|
||||
.\"
|
||||
.IP .eh (extension)
|
||||
Specifies the text for the header on even numbered pages.
|
||||
The format is the same as for the footer command (see \.fo).
|
||||
.\"
|
||||
.IP .en (extension)
|
||||
Designates the end of a macro definition.
|
||||
.\"
|
||||
.IP .eo
|
||||
Turn the escape mechanism off.
|
||||
.\"
|
||||
.IP .ex
|
||||
Exit nroff at this point in the processing.
|
||||
Ex forces all files closed and flushes the output.
|
||||
.\"
|
||||
.IP .fi
|
||||
Causes the input text to be rearranged or filled to obtain the maximum
|
||||
word count possible between the previously set left and right margins.
|
||||
No argument is expected.
|
||||
.\"
|
||||
.IP .fl
|
||||
Causes the output buffer to be flushed immediately.
|
||||
.\"
|
||||
.IP .fo (extension)
|
||||
Specifies text to be used for a footer.
|
||||
The footer text contains three strings seperated by a delimiter character.
|
||||
The first non-blank character following the command is designated
|
||||
as the delimiter.
|
||||
The first text string is left justified to the current indentation
|
||||
value (specified by \.in).
|
||||
The second string is centered between the current indentation value
|
||||
and the current right margin value (specified by \.rm).
|
||||
The third string is right justified to the current right margin value.
|
||||
The absence of footer text will result in the footer being printed as
|
||||
one blank line.
|
||||
The presence of the page number character (set by \.pc) in the footer
|
||||
text results in the current page number being inserted at that position.
|
||||
Multiple occurrances of the page number character are allowed.
|
||||
.\"
|
||||
.IP .ft
|
||||
Changes the current font.
|
||||
The choices are R (Times Roman), I (Times Italic), B (Times Bold),
|
||||
S (math special), and P used to request the previous font.
|
||||
P resets the next previous font to be the one just changed, amounting to a swap.
|
||||
.\"
|
||||
.IP .he (extension)
|
||||
Specifies text to be used for a header.
|
||||
The format is the same as for the footer (see \.fo).
|
||||
.\"
|
||||
.IP .if
|
||||
Execute a command if the condition is true.
|
||||
Format is:
|
||||
.nf
|
||||
|
||||
.if c command
|
||||
.if !c command
|
||||
.if N command
|
||||
.if !N command
|
||||
.if "str1"str2" command
|
||||
.if !"str1"str2" command
|
||||
|
||||
.fi
|
||||
Here c is a single letter: n (true if nroff), t (true if troff), e (true
|
||||
if even page), or o (true if odd page).
|
||||
N is a numerical experssion and can include operators +, -, *, /, % (mod),
|
||||
>, <, >=, <=, = (or ==), & (and), or : (or).
|
||||
If the result is greater than 0, the condition evaluates true.
|
||||
Numbers in the expression can be either constants or contents of number
|
||||
registers.
|
||||
Strings are tested using delimeter / or " only at this time.
|
||||
Note that "block" conditionals like:
|
||||
.nf
|
||||
|
||||
.if c \\{\\
|
||||
...
|
||||
...
|
||||
... \\}
|
||||
|
||||
.fi
|
||||
are not yet supported.
|
||||
Also the .ie/.el conditional is not yet supported.
|
||||
.\"
|
||||
.IP .in
|
||||
Indents the left margin to the column value specified by the argument.
|
||||
The default left margin is set to zero.
|
||||
.\"
|
||||
.IP .ju (extension)
|
||||
Causes blanks to be inserted between words in a line of
|
||||
output in order to align or justify the right margin.
|
||||
The default is to justify.
|
||||
.\"
|
||||
.IP .lg
|
||||
Ignored by nroff.
|
||||
.\"
|
||||
.IP .ll
|
||||
Sets the current line length.
|
||||
The default is eighty.
|
||||
.\"
|
||||
.IP .ls
|
||||
Sets the line spacing to the value specified by the argument.
|
||||
The default is for single spacing.
|
||||
.\"
|
||||
.IP .lt
|
||||
Set length of three-part titles.
|
||||
Line length and title length
|
||||
are independent.
|
||||
Indents do not apply to titles but page offsets do.
|
||||
.\"
|
||||
.IP .m1 (extension)
|
||||
Specifies the number of lines in the header margin.
|
||||
This is the space from the physical top of page to and including
|
||||
the header text.
|
||||
A value of zero causes the header to not be printed.
|
||||
A value of one causes the header to appear at the physical top of page.
|
||||
Larger argument values cause the appropriate number of blank
|
||||
lines to appear before the header is printed.
|
||||
.\"
|
||||
.IP .m2 (extension)
|
||||
Specifies the number of blank lines to be printed between
|
||||
the header line and the first line of the processed text.
|
||||
.\"
|
||||
.IP .m3 (extension)
|
||||
Specifies the number of blank lines to be printed between
|
||||
the last line of processed text and the footer line.
|
||||
.\"
|
||||
.IP .m4 (extension)
|
||||
Specifies the number of lines in the footer margin.
|
||||
This command affects the footer the same way the \.m1
|
||||
command affects the header.
|
||||
.\"
|
||||
.IP .mc
|
||||
Margin character. The first argument is the character to use,
|
||||
the second is the distance to the right of the right margin
|
||||
to place the margin character. Useful for change bars.
|
||||
No arguments turns the capability off. Note that with this
|
||||
nroff, the margin character is always a single character only
|
||||
and this distance is prefered to be in inches (e.g. 0.2i).
|
||||
The default space is 0.2i (2 spaces).
|
||||
.\"
|
||||
.IP .na
|
||||
Noadjust.
|
||||
Ajdustment is turned off; the right margin is ragged.
|
||||
The adjustment type for \.ad is not changed.
|
||||
Output line filling still occurs if fill mode is on.
|
||||
.\"
|
||||
.IP .ne
|
||||
Specifies a number of lines which should not be broken across a page boundary.
|
||||
If the number of lines remaining on a page is less than the
|
||||
value needed, then a new output page is started.
|
||||
.\"
|
||||
.IP .nf
|
||||
Specifies that succeeding text should be printed without
|
||||
rearrangement, or with no fill.
|
||||
No argument is expected.
|
||||
.\"
|
||||
.IP .nj (extension)
|
||||
Specifies that no attempt should be made to align or justify the right margin.
|
||||
No argument is expected.
|
||||
.\"
|
||||
.IP .nr
|
||||
Causes the value of a number register to be set or modified.
|
||||
A total of twenty-six number registers are available designated
|
||||
\\na through \\nz (either upper or lower case is allowed).
|
||||
When the sequence \\nc is imbedded in the text, the current value
|
||||
of number register c replaces the sequence, thus, such things as
|
||||
paragraph numbering can be accomplished with relative ease.
|
||||
.\"
|
||||
.IP .of (extension)
|
||||
Specifies the text for the footer on odd numbered pages.
|
||||
The format is the same as the footer command (see \.fo).
|
||||
.\"
|
||||
.IP .oh (extension)
|
||||
Specifies the text for the header on odd numbered pages.
|
||||
The format is the same as the footer command (see \.fo).
|
||||
.\"
|
||||
.IP .pc
|
||||
Specifies the page number character to be used in headers and footers.
|
||||
The occurrance of this character in the header or footer text
|
||||
results in the current page number being printed.
|
||||
The default for this character is the percent sign (%).
|
||||
.\"
|
||||
.IP .pl
|
||||
Specifies the page length or the number of lines per output page.
|
||||
The default is sixty-six.
|
||||
.\"
|
||||
.IP .pm
|
||||
Print macros.
|
||||
The names and sizes of the macros are printed to stdout.
|
||||
This is useful when building a macro package to see how much of the
|
||||
total namespace is consumed by the package.
|
||||
.\"
|
||||
.IP .pn
|
||||
Changes the page number of the current page and all
|
||||
subsequent pages to its argument.
|
||||
If no argument is given, the command is ignored.
|
||||
.\"
|
||||
.IP .po
|
||||
Specifies a page offset value.
|
||||
This allows the formatted text to be shifted to the right by
|
||||
the number of spaces specified.
|
||||
This feature may also be invoked by a switch on the command line.
|
||||
.\"
|
||||
.IP .ps
|
||||
Ignored by nroff.
|
||||
.\"
|
||||
.IP .rr
|
||||
Removes a number register.
|
||||
.\"
|
||||
.IP .so
|
||||
Causes input to be retrieved from the file specified
|
||||
by the command's character string argument.
|
||||
The contents of the new file are inserted into the output
|
||||
stream until an EOF is detected.
|
||||
Processing of the original file is then resumed.
|
||||
Command nesting is allowed.
|
||||
.\"
|
||||
.IP .sp
|
||||
Specifies a number of blank lines to be output before
|
||||
printing the next line of text.
|
||||
.\"
|
||||
.IP .ss
|
||||
Ignored by nroff.
|
||||
.\"
|
||||
.IP .ti
|
||||
Temporarily alters the indentation or left margin value for a single
|
||||
succeeding input line.
|
||||
.\"
|
||||
.IP .tl
|
||||
Specifies text to be used for a page title.
|
||||
The format is the same as for the header (see \.he).
|
||||
.\"
|
||||
.IP .ul
|
||||
Causes the next line(s) of text to be underlined.
|
||||
Unlike the \.cu command, this command causes only alphanumerics
|
||||
to be underlined, skipping punctuation and white space.
|
||||
Underline and boldface are mutually exclusive.
|
||||
.PP
|
||||
The following nroff commands, normally available, are currently
|
||||
not implemented in this version:
|
||||
.cc +
|
||||
\.fp, \.mk, \.rt, \.vs, \.sv, \.os, \.ns, \.rs, \.am, \.as, \.rm, \.rn,
|
||||
\.di, \.da, \.wh, \.ch, \.dt, \.it, \.em, \.ta, \.tc, \.lc, \.fc, \.lg,
|
||||
\.uf, \.tr, \.nh, \.hy, \.hc, \.hw, \.nm, \.nn, \.ie, \.el, \.ev, \.rd,
|
||||
\.ex, \.nx, \.pi, \.tm, and \.ig.
|
||||
+cc .
|
||||
.\"
|
||||
.SH ESCAPE SEQUENCES
|
||||
Escape sequences are used to access special characters (such as Greek
|
||||
letters) which may be outside the normal printable ASCII character set.
|
||||
The are also used to toggle certain actions such as font selection.
|
||||
.PP
|
||||
.ne 5
|
||||
The escape sequences include:
|
||||
.sp
|
||||
.eo
|
||||
.\" .ec -
|
||||
.nf
|
||||
\\ backslash character
|
||||
\e printable version of escape character
|
||||
\' accute accent (equivalent to \\(aa)
|
||||
\` grave accent (equivalent to \\(ga)
|
||||
\- minus sign
|
||||
\. period
|
||||
\<space> a single, unpaddable space
|
||||
\0 digit-width space
|
||||
\| 1\6em space (zero space in nroff)
|
||||
\^ 1\12em space (zero space in nroff)
|
||||
\& non-printing zero-width character
|
||||
\" beginning of comment
|
||||
\% default hyphenation character
|
||||
\(xx special character named xx
|
||||
\*x,\*(xx interpolate string x or xx
|
||||
\fc font change (c = R,I,B,S,P)
|
||||
\nx interpolate number register x
|
||||
\t horizontal tab
|
||||
.fi
|
||||
.sp
|
||||
.ne 5
|
||||
The Atari ST (TOS) version of nroff includes the following special
|
||||
characters. NOTE: THESE ARE NOT AVAILABLE UNDER Minix OR Unix(tm)!
|
||||
.sp
|
||||
.nf
|
||||
\(co copyright
|
||||
\(rg registered
|
||||
\(tm trademark
|
||||
\(12 1/2
|
||||
\(14 1/4
|
||||
\(p2 exponent 2
|
||||
\(p3 exponent 3
|
||||
\(pn exponent n
|
||||
\(aa acute
|
||||
\(ga grave
|
||||
\(de degree
|
||||
\(dg dagger
|
||||
\(ct cent
|
||||
\(bu bullet
|
||||
\(pp paragraph
|
||||
\(^g ring bell
|
||||
\(ua up arrow
|
||||
\(da dn arrow
|
||||
\(-> rt arrow
|
||||
\(<- lf arrow
|
||||
\(di divide
|
||||
\(sr sq root
|
||||
\(== ==
|
||||
\(>= >=
|
||||
\(<= <=
|
||||
\(+- +-
|
||||
\(~= ~=
|
||||
\(ap approx
|
||||
\(no not
|
||||
\(mo memeber
|
||||
\(ca intersect
|
||||
\(cu union
|
||||
\(*a alpha
|
||||
\(*b beta
|
||||
\(*g gamma
|
||||
\(*d delta
|
||||
\(*s sigma
|
||||
\(*p pi
|
||||
\(*m mu
|
||||
.fi
|
||||
.ec
|
||||
.SH PREDEFINED GENERAL NUMBER REGISTERS
|
||||
The following number registers are available for both reading and writing.
|
||||
They are accessed with the \\n(xx and \\nx escape and can be set with .nr:
|
||||
.nf
|
||||
.ne 5
|
||||
|
||||
% current page number
|
||||
dw current day of the week (1-7)
|
||||
dy current day of the month (1-31)
|
||||
hh current hours (0-23)
|
||||
ln current line number
|
||||
mm current minutes (0-59)
|
||||
mo current month (1-12)
|
||||
ss current seconds (0-59)
|
||||
yr last 2 digits of current year
|
||||
.fi
|
||||
.sp
|
||||
The following number registers are available for reading only:
|
||||
.nf
|
||||
.cc +
|
||||
|
||||
.$ number of args available in current macro
|
||||
.A always 1 in nroff
|
||||
.H available horizontal resolution
|
||||
.T always 0 in nroff
|
||||
.V available vertical resolution
|
||||
.c number of lines read from current file
|
||||
.f current font (1-4)
|
||||
.i current indent
|
||||
.l current line length
|
||||
.o current page offset
|
||||
.p current page length
|
||||
.v current vertical spacing
|
||||
+cc .
|
||||
|
||||
.fi
|
||||
.SH NOTES
|
||||
There are several missing features, notably diversions, traps,
|
||||
conditionals, all the hard stuff.
|
||||
This means you can't use some existing macro packages (yet, I hope).
|
||||
There is no complete -ms and -me packages as a result.
|
||||
The goal is to make this nroff work with all the SunOS macro packages
|
||||
sometime before Unix becomes obsolete!
|
||||
.PP
|
||||
If you make additions to this code, please mail the changes to me so I
|
||||
can make formal distributions.
|
||||
.SH BUGS
|
||||
Undoubtedly more than I know about.
|
||||
Here are a few:
|
||||
.PP
|
||||
The ability to perform numerical calculations on registers is not
|
||||
implemented.
|
||||
.PP
|
||||
All dimensional units are in em's or inches only.
|
||||
.PP
|
||||
Lines with multiple string instances (i.e. \\*(xx) don't seem to work.
|
||||
.PP
|
||||
Lines with font changes (e.g. for italics) use vt52 escape sequences
|
||||
to go to highlight mode.
|
||||
This should read termcap/terminfo to do it right.
|
||||
.PP
|
||||
Some interpolations don't work properly.
|
||||
.PP
|
||||
The code uses statically allocated arrays for macros, strings, and registers.
|
||||
This should be changed to dynamically allocated buffers or
|
||||
write to intermediate files on small memory systems (i.e. Minix).
|
||||
.SH FILES
|
||||
.nf
|
||||
.ec |
|
||||
\lib\tmac\tmac.* predefined macros (see ENVIRONMENT)
|
||||
nroff.dbg debugging output
|
||||
stderr default error output stream
|
||||
stdout output stream
|
||||
|
||||
.ec \
|
||||
.fi
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
Adapted for Atari ST (TOS) and Minix by Bill Rosenkranz 11/89
|
||||
|
||||
net: rosenkra@convex.com
|
||||
CIS: 71460,17
|
||||
GENIE: W.ROSENKRANZ
|
||||
|
||||
Original author:
|
||||
|
||||
Stephen L. Browning
|
||||
5723 North Parker Avenue
|
||||
Indianapolis, Indiana 46220
|
||||
|
||||
.fi
|
||||
.SH HISTORY
|
||||
.nf
|
||||
Originally written in BDS C (by Stephen L. Browning?)
|
||||
Adapted for standard C by W. N. Paul
|
||||
Heavily hacked up to conform to the "real" nroff with numerous
|
||||
additions by Bill Rosenkranz 11/89
|
||||
Bug fixes (termcap) and Minix 1.5.5 compatibility by
|
||||
Wim 'Blue Baron' van Dorst (wsincc@tuerc3.urc.tue.nl)
|
||||
|
||||
.fi
|
||||
|
||||
.SH RECOMMENDATIONS
|
||||
I envisioned this rather limited version as a way of formatting
|
||||
man pages for my Atari ST system.
|
||||
It works just fine for that.
|
||||
The man macro package is certainly adequate for that purpose.
|
||||
However, it would be nice to have more.
|
||||
I suggest you limit
|
||||
yourself to things which would port easily to other environments.
|
||||
All the man macros available here should port without effort
|
||||
to a more complete Unix(tm) environment.
|
||||
.PP
|
||||
Nroff as it stands can certainly be useful.
|
||||
I recommend you don't
|
||||
use the commands marked "extension".
|
||||
Study the source for the man pages here (nroff(1), ms(7), and man(7)) as
|
||||
well as the macro packages (tmac.an and tmac.s) and the examples to find
|
||||
out the quirks.
|
||||
Some things may not quite work like they do under Unix(tm), but it is
|
||||
fairly close for what is here.
|
||||
.SH REFERENCES
|
||||
This document briefly describes the workings of nroff.
|
||||
It is certainly not the definitive work on text processing.
|
||||
I suggest you go out and get a good book (there are several on the market)
|
||||
or refer to the Unix(tm) manuals for more help.
|
||||
Nroff is just like a compiler and is much more complicated than (say) the C
|
||||
language which only has a handful of rules and is much more thoroughly
|
||||
documented.
|
||||
Good luck!
|
||||
.SH REQUEST SUMMARY
|
||||
The following table summarizes the nroff requests currently available:
|
||||
.nf
|
||||
.ne 8
|
||||
.cc +
|
||||
|
||||
Request Form Initial Default Notes Explanation
|
||||
-------------- ------- ------- ------- ----------------------
|
||||
Font and Character Size Control
|
||||
|
||||
.ps +-N 10pt prev E point size (ignored)
|
||||
.ss N 12/36em ignored E space size (ignored)
|
||||
.cs F N M off - P constant space mode (ign)
|
||||
.bd F N off - P embolden font F (ignored)
|
||||
.bd S F N off - P embolden special font
|
||||
.ft F Roman prev E change to font F
|
||||
|
||||
+ne 4
|
||||
Page Control
|
||||
|
||||
.pl +-N 11in 11in v page length
|
||||
.bp +-N N=1 - B,v eject page
|
||||
.pn +-N N=1 ignored - next page number N
|
||||
.po +-N 0 prev v page offset
|
||||
.ne N - N=1V D,v need N vertical space
|
||||
|
||||
+ne 4
|
||||
Text Filling, Adjusting, and Centering
|
||||
|
||||
.br - - B break
|
||||
.fi fill - B,E fill mode
|
||||
.nf fill - B,E no fill or adjust
|
||||
.ad c adj,both adjust E adjust output, mode c
|
||||
.na adjust - E no adjust
|
||||
.ce N off N=1 B,E center N lines
|
||||
|
||||
+ne 4
|
||||
Vertical Spacing
|
||||
|
||||
.ls N N=1 prev E output N-1 Vs
|
||||
.sp N - N=1V B,v space vertical
|
||||
|
||||
+ne 4
|
||||
Line Length and Indenting
|
||||
|
||||
.ll +-N 6.5i prev E,m line length
|
||||
.in +-N N=0 prev B,E,m indent
|
||||
.ti +-N - ignored B,E,m temporary indent
|
||||
|
||||
+ne 4
|
||||
Macros, Strings, Diversions, and Position Traps
|
||||
|
||||
.de xx yy - .yy=.. - define macro xx
|
||||
.ds xx str - ignored - define string xx
|
||||
|
||||
+ne 4
|
||||
Number Registers
|
||||
|
||||
.nr R +-N M - u define and set num reg
|
||||
.af R c arabic - - assign format to reg
|
||||
.rr R - - - remove register
|
||||
|
||||
+ne 4
|
||||
I/O Conventions and Character Translation
|
||||
|
||||
.ec c \ \ - set escape char
|
||||
.eo on - - turn off escape mech
|
||||
.lg N - - - ligature mode (ignored)
|
||||
.ul N off N=1 E underline N lines
|
||||
.cu N off N=1 E cont. underline
|
||||
.cc c . . E set control char
|
||||
.c2 c ' ' E set nobreak control char
|
||||
|
||||
+ne 4
|
||||
Three-part Titles
|
||||
|
||||
.tl 'l'c'r' - - three-part title
|
||||
.pc c % off - page number char
|
||||
.lt +-N 6.5in prev E,m length of title
|
||||
|
||||
+ne 4
|
||||
Conditional Acceptence of Input
|
||||
|
||||
.if c cmd - - if c true, accept cmd
|
||||
.if !c cmd - - if c false, accept cmd
|
||||
.if N cmd - - if N > 0, accept cmd
|
||||
.if !N cmd - - if N <= 0, accept cmd
|
||||
.if "s1"s2" cmd - - if strings same, accept cmd
|
||||
.if !"s1"s2" cmd - - if strings differ, accept cmd
|
||||
|
||||
+ne 4
|
||||
Input/Output File Switching
|
||||
|
||||
.so filename - - switch source file
|
||||
|
||||
+ne 4
|
||||
Miscellaneous
|
||||
|
||||
.mc c N - off E,m margin char c, seperation N
|
||||
.pm t - all - print macro names
|
||||
.fl - - B flush output buffer
|
||||
|
||||
+ne 4
|
||||
Notes
|
||||
|
||||
B causes a break
|
||||
D mode or parameters associated with current diversion level
|
||||
E relevant parameters are a part of the current environment
|
||||
O must stay in effect until logical output
|
||||
P mode must be still or again in effect at time of physical output
|
||||
v,p,m,u default scale indicators
|
||||
+cc
|
||||
.fi
|
|
@ -0,0 +1,991 @@
|
|||
/*
|
||||
* main.c - main for nroff word processor
|
||||
*
|
||||
* similar to Unix(tm) nroff or RSX-11M RNO. adaptation of text processor
|
||||
* given in "Software Tools", Kernighan and Plauger.
|
||||
*
|
||||
* adapted for atariST/TOS by Bill Rosenkranz 11/89
|
||||
* net: rosenkra@hall.cray.com
|
||||
* CIS: 71460,17
|
||||
* GENIE: W.ROSENKRANZ
|
||||
*
|
||||
* original author:
|
||||
*
|
||||
* Stephen L. Browning
|
||||
* 5723 North Parker Avenue
|
||||
* Indianapolis, Indiana 46220
|
||||
*
|
||||
* history:
|
||||
*
|
||||
* - Originally written in BDS C;
|
||||
* - Adapted for standard C by W. N. Paul
|
||||
* - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
|
||||
* - Heavily modified by Devin Reade to avoid memory trashing bugs.
|
||||
*
|
||||
* $Id: nroff.c,v 1.1 1997/03/14 06:22:27 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "main______";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __GNO__
|
||||
#include <err.h>
|
||||
#include <termcap.h>
|
||||
#else
|
||||
#include "err.h"
|
||||
#include "termcap.h"
|
||||
#endif
|
||||
|
||||
#ifdef sparc
|
||||
#include <memory.h>
|
||||
#include "sunos.h"
|
||||
#endif
|
||||
|
||||
#include "nroff.h"
|
||||
#include "macros.h"
|
||||
#include "io.h"
|
||||
|
||||
static void init (void);
|
||||
static void processFile (void);
|
||||
static int pswitch (char *p, int *q);
|
||||
static void usage (void);
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Global variables block. Keep them in main.c so that the IIgs'
|
||||
* debuggers can find them.
|
||||
*/
|
||||
|
||||
struct docctl dc;
|
||||
struct page pg;
|
||||
struct macros_t mac;
|
||||
struct regs rg[MAXREGS];
|
||||
FILE *out_stream;
|
||||
FILE *err_stream;
|
||||
FILE *dbg_stream;
|
||||
FILE *sofile[Nfiles+1];
|
||||
int ignoring; /* .ig vs .de */
|
||||
int hold_screen;
|
||||
int debugging;
|
||||
int stepping; /* paging */
|
||||
int mc_ing = 0; /* turned off */
|
||||
int mc_space = 2;
|
||||
char mc_char = '|';
|
||||
char tmpdir[256];
|
||||
char s_standout[20];
|
||||
char e_standout[20];
|
||||
char s_bold[20];
|
||||
char e_bold[20];
|
||||
char s_italic[20];
|
||||
char e_italic[20];
|
||||
char *dbgfile = "nroff.dbg";
|
||||
#ifdef GEMDOS
|
||||
char *printer = "prn:"; /* this WON'T work!!! */
|
||||
#else
|
||||
char *printer = ".ttyb"; /* this probably won't */
|
||||
#endif
|
||||
|
||||
static char termcap[1024]; /* _must_ be 1024 */
|
||||
static char *progname;
|
||||
static char *version = "(GNO) v1.2, 5 Mar 97 gdr";
|
||||
|
||||
/*
|
||||
* End of global variable definitions.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
int
|
||||
main (int argc, char *argv[]) {
|
||||
register int i;
|
||||
int swflg;
|
||||
int ifp = 0;
|
||||
char *ptmp;
|
||||
char *pterm;
|
||||
char capability[100];
|
||||
char *pcap;
|
||||
char *ps;
|
||||
|
||||
#ifdef __GNO__
|
||||
if (argc > 0) {
|
||||
progname = __prognameGS();
|
||||
} else {
|
||||
exit(1); /* not running from a shell? */
|
||||
}
|
||||
#else
|
||||
if (argc > 0) {
|
||||
progname = basename(argv[0]);
|
||||
} else {
|
||||
progname = "nroff";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* set up initial flags and file descriptors
|
||||
*/
|
||||
swflg = FALSE;
|
||||
ignoring = FALSE;
|
||||
hold_screen = FALSE;
|
||||
debugging = FALSE;
|
||||
stepping = FALSE;
|
||||
mc_ing = FALSE;
|
||||
out_stream = stdout;
|
||||
err_stream = stderr;
|
||||
dbg_stream = stderr;
|
||||
|
||||
|
||||
/*
|
||||
* this is for tmp files, if ever needed. it SHOULD start
|
||||
* out without the trailing slash. if not in env, use default
|
||||
*/
|
||||
if ((ptmp = getenv ("TMPDIR")) != NULL) {
|
||||
strcpy (tmpdir, ptmp);
|
||||
} else {
|
||||
strcpy (tmpdir, ".");
|
||||
}
|
||||
|
||||
/*
|
||||
* handle terminal for \fB, \fI
|
||||
*/
|
||||
s_standout[0] = '\0';
|
||||
e_standout[0] = '\0';
|
||||
s_bold[0] = '\0';
|
||||
e_bold[0] = '\0';
|
||||
s_italic[0] = '\0';
|
||||
e_italic[0] = '\0';
|
||||
|
||||
/*
|
||||
* get termcap information
|
||||
*/
|
||||
if ((pterm = getenv("TERM")) == NULL) {
|
||||
errx(1, "TERM environment variable not set");
|
||||
}
|
||||
switch (tgetent(termcap, pterm)) {
|
||||
case -1:
|
||||
errx(1, "couldn't open termcap database");
|
||||
/*NOTREACHED*/
|
||||
case 0:
|
||||
errx(1, "terminal type %s not found in termcap database", pterm);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* we currently use standout mode for all weirdness
|
||||
* like BOLD, italic, etc.
|
||||
*/
|
||||
pcap = capability;
|
||||
if ((ps = tgetstr ("so", &pcap)) != NULL) {
|
||||
/*
|
||||
* sun has padding in here. this is NOT portable.
|
||||
* better to use tputs() to strip it...
|
||||
*/
|
||||
/* while (*ps && *ps != 0x1b) ps++; */
|
||||
strcpy (s_standout, ps);
|
||||
strcpy (s_bold, ps);
|
||||
strcpy (s_italic, ps);
|
||||
} else {
|
||||
err(1, "couldn't get standout mode");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if ((ps = tgetstr ("se", &pcap)) != NULL) {
|
||||
/* while (*ps && *ps != 0x1b) ps++; */
|
||||
strcpy (e_standout, ps);
|
||||
strcpy (e_bold, ps);
|
||||
strcpy (e_italic, ps);
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize structures (defaults)
|
||||
*/
|
||||
init ();
|
||||
|
||||
/*
|
||||
* parse cmdline flags
|
||||
*/
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (*argv[i] == '-' || *argv[i] == '+') {
|
||||
if (pswitch (argv[i], &swflg) == ERR) {
|
||||
err_exit (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* loop on files
|
||||
*/
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (*argv[i] != '-' && *argv[i] != '+') {
|
||||
/*
|
||||
* open this file...
|
||||
*/
|
||||
if ((sofile[0] = fopen (argv[i], "r")) == NULL_FPTR) {
|
||||
err(-1, "unable to open file %s", argv[i]);
|
||||
} else {
|
||||
/*
|
||||
* do it for this file...
|
||||
*/
|
||||
ifp = 1;
|
||||
processFile ();
|
||||
fclose (sofile[0]);
|
||||
}
|
||||
} else if (*argv[i] == '-' && *(argv[i]+1) == 0) {
|
||||
/*
|
||||
* - means read stdin (anywhere in file list)
|
||||
*/
|
||||
sofile[0] = stdin;
|
||||
ifp = 1;
|
||||
sleep(1);
|
||||
processFile ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* if no files, usage (should really use stdin...)
|
||||
*/
|
||||
if ((ifp == 0 && swflg == FALSE) || argc <= 1) {
|
||||
usage ();
|
||||
err_exit (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* normal exit. this will fflush/fclose streams...
|
||||
*/
|
||||
err_exit (0);
|
||||
#if defined(__GNUC__) || defined(__INSIGHT__)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------*/
|
||||
/* usage */
|
||||
/*------------------------------*/
|
||||
static void
|
||||
usage (void) {
|
||||
/*
|
||||
* note: -l may not work correctly
|
||||
*/
|
||||
|
||||
fprintf(stderr, "Usage: %s [options] file [...]\n", progname);
|
||||
fputs("\t-a\tno font changes\n", stderr);
|
||||
fputs("\t-b\t\tbackspace\n", stderr);
|
||||
fputs("\t-d\t\tdebug mode (file: nroff.dbg)\n", stderr);
|
||||
#ifdef GEMDOS
|
||||
fputs("\t-h\t\thold screen before desktop\n", stderr);
|
||||
#endif
|
||||
#if 0
|
||||
fputs("\t-l\t\toutput to printer\n", stderr);
|
||||
#endif
|
||||
fputs("\t-m<name>\tmacro file (e.g. -man)\n", stderr);
|
||||
fputs("\t-o<file>\terror log file (stderr is default)\n", stderr);
|
||||
fputs("\t-po<n>\t\tpage offset\n", stderr);
|
||||
fputs("\t-pn<n>\t\tinitial page number\n", stderr);
|
||||
fputs("\t-pl<n>\t\tpage length\n", stderr);
|
||||
fputs("\t-s\t\tstep through pages\n", stderr);
|
||||
fputs("\t-v\t\tprint version only\n", stderr);
|
||||
fputs("\t+<n>\t\tfirst page to do\n", stderr);
|
||||
fputs("\t-<n>\t\tlast page to do\n", stderr);
|
||||
fputs("\t-\t\tuse stdin (in file list)\n", stderr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* init
|
||||
* initialize parameters for nro word processor
|
||||
*/
|
||||
static void
|
||||
init (void) {
|
||||
|
||||
|
||||
#ifdef MINIX
|
||||
register int i;
|
||||
#else
|
||||
register long i;
|
||||
#endif
|
||||
time_t tval;
|
||||
char *ctim;
|
||||
|
||||
/*
|
||||
* misc global flags, etc...
|
||||
*/
|
||||
mc_space = 2;
|
||||
mc_char = '|';
|
||||
tval = time (0L);
|
||||
ctim = ctime (&tval);
|
||||
|
||||
/*
|
||||
* basic document controls...
|
||||
*/
|
||||
dc.fill = YES;
|
||||
dc.dofnt = YES;
|
||||
dc.lsval = 1;
|
||||
dc.inval = 0;
|
||||
dc.rmval = PAGEWIDTH - 1;
|
||||
dc.llval = PAGEWIDTH - 1;
|
||||
dc.ltval = PAGEWIDTH - 1;
|
||||
dc.tival = 0;
|
||||
dc.ceval = 0;
|
||||
dc.ulval = 0;
|
||||
dc.cuval = 0;
|
||||
dc.juval = YES;
|
||||
dc.adjval = ADJ_BOTH;
|
||||
dc.boval = 0;
|
||||
dc.bsflg = FALSE;
|
||||
dc.prflg = TRUE;
|
||||
dc.sprdir = 0;
|
||||
dc.flevel = 0;
|
||||
dc.lastfnt = 1;
|
||||
dc.thisfnt = 1;
|
||||
dc.escon = YES;
|
||||
dc.pgchr = '%';
|
||||
dc.cmdchr = '.';
|
||||
dc.escchr = '\\';
|
||||
dc.nobrchr = '\'';
|
||||
for (i = 0; i < 26; ++i) {
|
||||
dc.nr[i] = 0;
|
||||
}
|
||||
for (i = 0; i < 26; ++i) {
|
||||
dc.nrauto[i] = 1;
|
||||
}
|
||||
for (i = 0; i < 26; ++i) {
|
||||
dc.nrfmt[i] = '1';
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize internal regs. first zero out...
|
||||
*/
|
||||
for (i = 0; i < MAXREGS; i++) {
|
||||
rg[i].rname[0] = EOS;
|
||||
rg[i].rname[1] = EOS;
|
||||
rg[i].rname[2] = EOS;
|
||||
rg[i].rname[3] = EOS;
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
}
|
||||
|
||||
/*
|
||||
* predefined regs. these are read/write:
|
||||
*/
|
||||
i = 0;
|
||||
|
||||
strcpy (rg[i].rname, "%"); /* current page */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "ct"); /* character type */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "dl"); /* width of last complete di */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "dn"); /* height of last complete di */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "dw"); /* day of week (1-7) */
|
||||
rg[i].rval = 0;
|
||||
if (!strncmp (&ctim[0], "Sun", 3)) rg[i].rval = 1;
|
||||
else if (!strncmp (&ctim[0], "Mon", 3)) rg[i].rval = 2;
|
||||
else if (!strncmp (&ctim[0], "Tue", 3)) rg[i].rval = 3;
|
||||
else if (!strncmp (&ctim[0], "Wed", 3)) rg[i].rval = 4;
|
||||
else if (!strncmp (&ctim[0], "Thu", 3)) rg[i].rval = 5;
|
||||
else if (!strncmp (&ctim[0], "Fri", 3)) rg[i].rval = 6;
|
||||
else if (!strncmp (&ctim[0], "Sat", 3)) rg[i].rval = 7;
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "dy"); /* day of month (1-31) */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = atoi (&ctim[8]);
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "hp"); /* current h pos on input */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "ln"); /* output line num */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "mo"); /* current month (1-12) */
|
||||
rg[i].rval = 0;
|
||||
if (!strncmp (&ctim[4], "Jan", 3)) rg[i].rval = 1;
|
||||
else if (!strncmp (&ctim[4], "Feb", 3)) rg[i].rval = 2;
|
||||
else if (!strncmp (&ctim[4], "Mar", 3)) rg[i].rval = 3;
|
||||
else if (!strncmp (&ctim[4], "Apr", 3)) rg[i].rval = 4;
|
||||
else if (!strncmp (&ctim[4], "May", 3)) rg[i].rval = 5;
|
||||
else if (!strncmp (&ctim[4], "Jun", 3)) rg[i].rval = 6;
|
||||
else if (!strncmp (&ctim[4], "Jul", 3)) rg[i].rval = 7;
|
||||
else if (!strncmp (&ctim[4], "Aug", 3)) rg[i].rval = 8;
|
||||
else if (!strncmp (&ctim[4], "Sep", 3)) rg[i].rval = 9;
|
||||
else if (!strncmp (&ctim[4], "Oct", 3)) rg[i].rval = 10;
|
||||
else if (!strncmp (&ctim[4], "Nov", 3)) rg[i].rval = 11;
|
||||
else if (!strncmp (&ctim[4], "Dec", 3)) rg[i].rval = 12;
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "nl"); /* v pos of last base-line */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "sb"); /* depth of str below base */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "st"); /* height of str above base */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "yr"); /* last 2 dig of current year*/
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = atoi (&ctim[22]);
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "hh"); /* current hour (0-23) */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = atoi (&ctim[11]);
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = 2 | 0x80;
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "mm"); /* current minute (0-59) */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = atoi (&ctim[14]);
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = 2 | 0x80;
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, "ss"); /* current second (0-59) */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = atoi (&ctim[17]);
|
||||
rg[i].rflag = RF_READ | RF_WRITE;
|
||||
rg[i].rfmt = 2 | 0x80;
|
||||
i++;
|
||||
|
||||
|
||||
/*
|
||||
* these are read only (by user):
|
||||
*/
|
||||
strcpy (rg[i].rname, ".$"); /* num args at current macro*/
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".A"); /* 1 for nroff */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 1;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".H"); /* hor resolution */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 1;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".T"); /* 1 for troff */
|
||||
rg[i].rauto = 0;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".V"); /* vert resolution */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 1;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".a");
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".c");
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".d");
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".f"); /* current font (1-4) */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 1;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".h");
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".i"); /* current indent */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".l"); /* current line length */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = PAGEWIDTH - 1;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".n");
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".o"); /* current offset */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".p"); /* current page len */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = PAGELEN;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".s"); /* current point size */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 1;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".t");
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".u");
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".v"); /* current v line spacing */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 1;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".w"); /* width of prev char */
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 1;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".x");
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".y");
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
i++;
|
||||
|
||||
strcpy (rg[i].rname, ".z");
|
||||
rg[i].rauto = 1;
|
||||
rg[i].rval = 0;
|
||||
rg[i].rflag = RF_READ;
|
||||
rg[i].rfmt = '1';
|
||||
|
||||
/*
|
||||
* page controls...
|
||||
*/
|
||||
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 = 30000;
|
||||
pg.ehead[0] = pg.ohead[0] = '\n';
|
||||
pg.efoot[0] = pg.ofoot[0] = '\n';
|
||||
memset(pg.ehead + 1, EOS, MAXLINE -1);
|
||||
memset(pg.ohead + 1, EOS, MAXLINE -1);
|
||||
memset(pg.efoot + 1, EOS, MAXLINE -1);
|
||||
memset(pg.ofoot + 1, EOS, MAXLINE -1);
|
||||
|
||||
#if 0
|
||||
for (i = 1; i < MAXLINE; ++i) {
|
||||
pg.ehead[i] = pg.ohead[i] = EOS;
|
||||
pg.efoot[i] = pg.ofoot[i] = EOS;
|
||||
}
|
||||
#endif
|
||||
pg.ehlim[LEFT] = pg.ohlim[LEFT] = dc.inval;
|
||||
pg.eflim[LEFT] = pg.oflim[LEFT] = dc.inval;
|
||||
pg.ehlim[RIGHT] = pg.ohlim[RIGHT] = dc.rmval;
|
||||
pg.eflim[RIGHT] = pg.oflim[RIGHT] = dc.rmval;
|
||||
|
||||
/*
|
||||
* output buffer controls...
|
||||
*/
|
||||
initOutbuf();
|
||||
|
||||
/*
|
||||
* macros...
|
||||
*/
|
||||
initMacros();
|
||||
|
||||
/*
|
||||
* file descriptors (for sourced files)
|
||||
*/
|
||||
for (i = 0; i < Nfiles+1; ++i) {
|
||||
sofile[i] = NULL_FPTR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pswitch
|
||||
*
|
||||
* process switch values from command line
|
||||
*/
|
||||
static int
|
||||
pswitch (char *p, int *q) {
|
||||
int swgood;
|
||||
char mfile[256];
|
||||
char *ptmac;
|
||||
int indx;
|
||||
int val;
|
||||
|
||||
swgood = TRUE;
|
||||
if (*p == '-') {
|
||||
/*
|
||||
* since is STILL use the goofy atari/dri xmain code, i
|
||||
* look for both upper and lower case. if you use dLibs
|
||||
* (and if its startup code does not ucase the cmd line),
|
||||
* you can probably look for just lower case. gulam and
|
||||
* other shells typically don't change case of cmd line.
|
||||
*/
|
||||
switch (*++p) {
|
||||
case 0: /* stdin */
|
||||
break;
|
||||
|
||||
case 'a': /* font changes */
|
||||
case 'A':
|
||||
dc.dofnt = NO;
|
||||
break;
|
||||
|
||||
case 'b': /* backspace */
|
||||
case 'B':
|
||||
dc.bsflg = TRUE;
|
||||
break;
|
||||
|
||||
case 'd': /* debug mode */
|
||||
case 'D':
|
||||
if ((dbg_stream = fopen (dbgfile, "w")) == NULL) {
|
||||
warn ("unable to open debug file %s, using stderr", dbgfile);
|
||||
dbg_stream = stderr;
|
||||
}
|
||||
debugging = TRUE;
|
||||
break;
|
||||
|
||||
case 'h': /* hold screen */
|
||||
case 'H':
|
||||
hold_screen = TRUE;
|
||||
break;
|
||||
|
||||
case 'l': /* to lpr (was P) */
|
||||
case 'L':
|
||||
#ifdef GEMDOS
|
||||
out_stream = (FILE *) 0;
|
||||
#else
|
||||
out_stream = fopen (printer, "w");
|
||||
#endif
|
||||
setPrinting(TRUE);
|
||||
break;
|
||||
|
||||
case 'm': /* macro file */
|
||||
case 'M':
|
||||
/*
|
||||
* build macro file name. start with lib
|
||||
*
|
||||
* put c:\lib\tmac in environment so we can
|
||||
* read it here. else use default. if you want
|
||||
* file from cwd, "setenv TMACDIR ." from shell.
|
||||
*
|
||||
* we want file names like "tmac.an" (for -man)
|
||||
*/
|
||||
if ((ptmac = getenv ("TMACDIR")) != NULL) {
|
||||
/*
|
||||
* this is the lib path (e.g. "c:\lib\tmac")
|
||||
*/
|
||||
strcpy (mfile, ptmac);
|
||||
|
||||
/*
|
||||
* this is the prefix (i.e. "\tmac.")
|
||||
*/
|
||||
strcat (mfile, TMACPRE);
|
||||
} else {
|
||||
/*
|
||||
* use default lib/prefix (i.e.
|
||||
* "c:\lib\tmac\tmac.")
|
||||
*/
|
||||
strcpy (mfile, TMACFULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* finally, add extension (e.g. "an")
|
||||
*/
|
||||
strcat (mfile, ++p);
|
||||
|
||||
/*
|
||||
* open file and read it
|
||||
*/
|
||||
if ((sofile[0] = fopen (mfile, "r")) == NULL_FPTR) {
|
||||
err(-1, "unable to open macro file %s", mfile);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
processFile ();
|
||||
fclose (sofile[0]);
|
||||
break;
|
||||
|
||||
case 'o': /* output error log */
|
||||
case 'O':
|
||||
if (!*(p+1)) {
|
||||
err(-1, "no error file specified");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if ((err_stream = fopen (p+1, "w")) == NULL) {
|
||||
err(-1, "unable to open error file %s", p+1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
err_set_file(err_stream);
|
||||
break;
|
||||
|
||||
case 'p': /* .po, .pn */
|
||||
case 'P':
|
||||
if (*(p+1) == 'o' || *(p+1) == 'O') { /* -po___ */
|
||||
p += 2;
|
||||
set (&pg.offset, ctod (p), '1', 0, 0, HUGE);
|
||||
set_ireg (".o", pg.offset, 0);
|
||||
} else if (*(p+1) == 'n' || *(p+1) == 'N') { /* -pn___ */
|
||||
p += 2;
|
||||
set (&pg.curpag, ctod (p) - 1, '1', 0, -HUGE, HUGE);
|
||||
pg.newpag = pg.curpag + 1;
|
||||
set_ireg ("%", pg.newpag, 0);
|
||||
} else if (*(p+1) == 'l' || *(p+1) == 'L') { /* -pl___ */
|
||||
p += 2;
|
||||
set (&pg.plval, ctod (p) - 1, '1', 0,
|
||||
pg.m1val + pg.m2val + pg.m3val + pg.m4val + 1,
|
||||
HUGE);
|
||||
set_ireg (".p", pg.plval, 0);
|
||||
pg.bottom = pg.plval - pg.m3val - pg.m4val;
|
||||
} else { /* -p___ */
|
||||
p++;
|
||||
set (&pg.offset, ctod (p), '1', 0, 0, HUGE);
|
||||
set_ireg (".o", pg.offset, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r': /* set number reg */
|
||||
case 'R':
|
||||
if (!isalpha (*(p+1))) {
|
||||
warnx("invalid number register name (%c)", *(p+1));
|
||||
} else {
|
||||
/*
|
||||
* indx is the user num register and val
|
||||
* is the final value.
|
||||
*/
|
||||
indx = tolower (*(p+1)) - 'a';
|
||||
val = atoi (p+2);
|
||||
set (&dc.nr[indx], val, '1', 0, -INFINITE, INFINITE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 's': /* page step mode */
|
||||
case 'S':
|
||||
stepping = TRUE;
|
||||
break;
|
||||
|
||||
case 'v': /* version */
|
||||
case 'V':
|
||||
printf ("%s %s\n", progname, version);
|
||||
*q = TRUE;
|
||||
break;
|
||||
|
||||
case '0': /* last page */
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
pg.lastpg = ctod (p);
|
||||
break;
|
||||
|
||||
default: /* illegal */
|
||||
swgood = FALSE;
|
||||
break;
|
||||
}
|
||||
} else if (*p == '+') { /* first page */
|
||||
pg.frstpg = ctod (++p);
|
||||
} else { /* illegal */
|
||||
swgood = FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (swgood == FALSE) {
|
||||
warnx("illegal option: %s", p);
|
||||
return (ERR);
|
||||
}
|
||||
|
||||
return (OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* processFile
|
||||
*
|
||||
* process input files from command line
|
||||
*/
|
||||
static void
|
||||
processFile (void) {
|
||||
|
||||
static char ibuf[MAXLINE];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* handle nesting of includes (.so). note that .so causes dc.flevel
|
||||
* to be increased...
|
||||
*/
|
||||
for (dc.flevel = 0; dc.flevel >= 0; dc.flevel -= 1) {
|
||||
while ((i = getlin (ibuf, sofile[dc.flevel])) != EOF) {
|
||||
/*
|
||||
* if line is a command or text
|
||||
*/
|
||||
if (ibuf[0] == dc.cmdchr) {
|
||||
comand (ibuf);
|
||||
} else {
|
||||
/*
|
||||
* this is a text line. first see if
|
||||
* first char is space. if it is, break
|
||||
* line.
|
||||
*/
|
||||
if (ibuf[0] == ' ') {
|
||||
robrk ();
|
||||
}
|
||||
text (ibuf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* close included file
|
||||
*/
|
||||
if (dc.flevel > 0) {
|
||||
fclose (sofile[dc.flevel]);
|
||||
}
|
||||
}
|
||||
if (pg.lineno > 0) {
|
||||
nroffSpace (HUGE);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma optimize 8
|
||||
#pragma debug 0
|
||||
|
||||
void
|
||||
debugMessage (const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
fprintf(err_stream, "%s: ", progname);
|
||||
vfprintf(err_stream, fmt, ap);
|
||||
va_end(ap);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
Name: nroff
|
||||
Version: 1.2 (17 Mar 97)
|
||||
Shell: ORCA/Shell, GNO/ME
|
||||
Author: Various. Maintained by Devin Reade.
|
||||
Contact: gdr@myrias.com
|
||||
Where: /usr/bin
|
||||
FTP: apple2.caltech.edu, ground.isca.uiowa.edu
|
||||
|
||||
Text Processing Typesetter
|
|
@ -0,0 +1,483 @@
|
|||
#ifndef NRO_H
|
||||
#define NRO_H
|
||||
|
||||
#include "config.h" /* os/compiler options */
|
||||
|
||||
#ifndef NEWLINE
|
||||
#define NEWLINE '\n'
|
||||
#endif
|
||||
|
||||
/*
|
||||
* nroff.h - stuff for nroff
|
||||
*
|
||||
* adapted for atariST/TOS by Bill Rosenkranz 10/89
|
||||
* net: rosenkra@hall.cray.com
|
||||
* CIS: 71460,17
|
||||
* GENIE: W.ROSENKRANZ
|
||||
*
|
||||
* things to look for here:
|
||||
* 1) TMAC definition for default macro package lib
|
||||
* 2) configuration sizes (see _STKSIZ below if alcyon/dri)
|
||||
* 3) libc should have getenv(), time(), and ctime()
|
||||
* 4) look in version.h for *printer file name (included below)
|
||||
*
|
||||
* all data is currently allocated in static arrays. the biggest
|
||||
* chunks are the parameters which control number registers and the
|
||||
* macro name space area. these are defined below: MAXREGS, MACBUF.
|
||||
* MACBUF is the larger. it holds all macros, strings, etc. if you
|
||||
* find yourself running out of macro space, increase MACBUF.
|
||||
*
|
||||
* original author:
|
||||
*
|
||||
* Stephen L. Browning
|
||||
* 5723 North Parker Avenue
|
||||
* Indianapolis, Indiana 46220
|
||||
*
|
||||
* history:
|
||||
*
|
||||
* - Originally written in BDS C;
|
||||
* - Adapted for standard C by W. N. Paul
|
||||
* - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* default prefix of macro files. files will be of the form "tmac.an"
|
||||
* (for -man), "tmac.s" (for -ms), "tmac.e" (for -me), etc. first
|
||||
* checks environment for TMACDIR which would be path (e.g. "c:\lib\tmac"
|
||||
* or ".", no trailing slash char!).
|
||||
*/
|
||||
#ifdef tmacfull
|
||||
# define TMACFULL tmacfull
|
||||
#endif
|
||||
#ifdef tmacpre
|
||||
# define TMACPRE tmacpre
|
||||
#endif
|
||||
|
||||
#ifdef GEMDOS
|
||||
# ifndef TMACFULL
|
||||
# define TMACFULL "c:\\lib\\tmac\\tmac."
|
||||
# endif
|
||||
# ifndef TMACPRE
|
||||
# define TMACPRE "\\tmac."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef MINIX
|
||||
# ifndef TMACFULL
|
||||
# define TMACFULL "/usr/lib/tmac/tmac."
|
||||
# endif
|
||||
# ifndef TMACPRE
|
||||
# define TMACPRE "/tmac."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef UNIX
|
||||
# ifndef TMACFULL
|
||||
# define TMACFULL "/usr/lib/tmac/tmac."
|
||||
# endif
|
||||
# ifndef TMACPRE
|
||||
# define TMACPRE "/tmac."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* command codes. indented defines are commands not yet implemented
|
||||
*/
|
||||
#undef PI
|
||||
#define MACRO 0 /* macro definition */
|
||||
#define BP 1 /* begin page */
|
||||
#define BR 2 /* break */
|
||||
#define CE 3 /* center */
|
||||
#define FI 4 /* fill */
|
||||
#define FO 5 /* footer */
|
||||
#define HE 6 /* header */
|
||||
#define IN 7 /* indent */
|
||||
#define LS 8 /* line spacing */
|
||||
#define NF 9 /* no fill */
|
||||
#define PL 10 /* page length */
|
||||
#define RM 11 /* remove macro */
|
||||
#define SP 12 /* line space */
|
||||
#define TI 13 /* temp indent */
|
||||
#define UL 14 /* underline */
|
||||
#define JU 15 /* justify */
|
||||
#define NJ 16 /* no justify */
|
||||
#define M1 17 /* top margin */
|
||||
#define M2 18 /* second top margin */
|
||||
#define M3 19 /* first bottom margin */
|
||||
#define M4 20 /* bottom-most margin */
|
||||
#define BS 21 /* allow/disallow '\b' in output */
|
||||
#define NE 22 /* need n lines */
|
||||
#define PC 23 /* page number character (%) */
|
||||
#define CC 24 /* control character (.) */
|
||||
#define PO 25 /* page offset */
|
||||
#define BO 26 /* bold face */
|
||||
#define EH 27 /* header for even numbered pages */
|
||||
#define OH 28 /* header for odd numbered pages */
|
||||
#define EF 29 /* footer for even numbered pages */
|
||||
#define OF 30 /* footer for odd numbered pages */
|
||||
#define SO 31 /* source file */
|
||||
#define CU 32 /* continuous underline */
|
||||
#define DE 33 /* define macro */
|
||||
#define EN 34 /* end macro definition */
|
||||
#define NR 35 /* set number register */
|
||||
#define EC 36 /* escape character (\) */
|
||||
#define FT 37 /* font change (R,B,I,S,P) */
|
||||
#define EO 38 /* turn escape parsing off */
|
||||
#define LL 39 /* line length (same as RM) */
|
||||
#define FL 40 /* flush output NOW */
|
||||
#define PN 41 /* page number for next page */
|
||||
#define RR 42 /* remove register */
|
||||
#define C2 43 /* nobreak char */
|
||||
# define TR 44 /* translate character */
|
||||
#define LT 45 /* length of title */
|
||||
# define FC 46 /* field delimeter */
|
||||
#define TL 47 /* like HE */
|
||||
#define AF 48 /* assign format to nr */
|
||||
#define AD 49 /* adjust line */
|
||||
#define NA 50 /* no adjust */
|
||||
#define DS 51 /* define string */
|
||||
#define PM 52 /* print macro names */
|
||||
#define IF 53 /* if */
|
||||
# define IE 54 /* if/else */
|
||||
# define EL 55 /* else */
|
||||
#define PS 56 /* point size (IGNORED in nroff) */
|
||||
#define SS 57 /* space char size (IGNORED in nroff) */
|
||||
#define CS 58 /* constant char space (IGNORED in nroff) */
|
||||
#define BD 59 /* embolden font (IGNORED in nroff) */
|
||||
# define FP 60 /* font position */
|
||||
# define MK 61 /* mark vertical place */
|
||||
# define RT 62 /* return to marked vert place */
|
||||
# define VS 63 /* vertical baseline spacing */
|
||||
# define SV 64 /* save vertical distance */
|
||||
# define OS 65 /* output saved vertical distance */
|
||||
# define NS 66 /* no-space mode */
|
||||
# define RS 67 /* restore spacing mode */
|
||||
# define AM 68 /* append to macro */
|
||||
# define AS 69 /* append to string */
|
||||
# define RN 70 /* rename */
|
||||
# define DI 71 /* divert to macro */
|
||||
# define DA 72 /* divert/append to macro */
|
||||
# define WH 73 /* set location trap */
|
||||
# define CH 74 /* change trap location */
|
||||
# define DT 75 /* set diversion trap */
|
||||
# define IT 76 /* set input line trap */
|
||||
# define EM 77 /* end macro */
|
||||
# define TA 78 /* tab settings */
|
||||
# define TC 79 /* tab repetition char */
|
||||
# define LC 80 /* leader repetition char */
|
||||
# define LG 81 /* ligature mode */
|
||||
# define UF 82 /* underline font */
|
||||
# define NH 83 /* no hyphenation */
|
||||
# define HY 84 /* hyphenate */
|
||||
# define HC 85 /* hyphenation indication char */
|
||||
# define HW 86 /* hyphenation exception words */
|
||||
# define NM 87 /* number mode */
|
||||
# define NN 88 /* no number next lines */
|
||||
# define EV 89 /* environment switch */
|
||||
# define RD 90 /* read insertion */
|
||||
# define EX 91 /* exit */
|
||||
# define NX 92 /* next file */
|
||||
# define PI 93 /* pipe to program */
|
||||
# define MC 94 /* set margin char */
|
||||
# define TM 95 /* print to terminal */
|
||||
#define IG 96 /* ignore */
|
||||
|
||||
#define COMMENT 1000 /* comment (.\") */
|
||||
#define UNKNOWN -1
|
||||
|
||||
|
||||
/*
|
||||
* MAXLINE is set to a value slightly larger than twice the longest
|
||||
* expected input line. Because of the way underlining is handled, the
|
||||
* input line which is to be underlined, can almost triple in length.
|
||||
* Unlike normal underlining and boldfacing, continuous underlining
|
||||
* affects all characters in the buffer, and represents the worst case
|
||||
* condition. If the distance between the left margin and the right
|
||||
* margin is greater than about 65 characters, and continuous underlining
|
||||
* is in effect, there is a high probability of buffer overflow.
|
||||
*/
|
||||
/* FIXME */
|
||||
#define MAXLINE 500 /*500*/ /* 200 */
|
||||
#define PAGELEN 66
|
||||
#define PAGEWIDTH 80
|
||||
#define HUGE 256
|
||||
#define INFINITE 32760
|
||||
#define LEFT 0 /* indecies into hdr margin lim arrays */
|
||||
#define RIGHT 1
|
||||
#define Nfiles 4 /* nesting depth for input files */
|
||||
|
||||
/*
|
||||
* The following parameters may be defined elsewhere so undef/def
|
||||
*/
|
||||
#undef min
|
||||
#undef max
|
||||
#undef YES
|
||||
#define YES 1
|
||||
#undef NO
|
||||
#define NO 0
|
||||
#undef ERR
|
||||
#define ERR -1
|
||||
#define EOS '\0'
|
||||
#undef FALSE
|
||||
#define FALSE 0
|
||||
#undef TRUE
|
||||
#define TRUE !FALSE
|
||||
#undef OK
|
||||
#define OK !ERR
|
||||
|
||||
/*
|
||||
* a rational way of dealing with the NULL thing...
|
||||
*/
|
||||
#define NULL_CPTR (char *) 0
|
||||
#define NULL_FPTR (FILE *) 0
|
||||
#define NULL_IPTR (int *) 0
|
||||
#define NULL_LPTR (long *) 0
|
||||
#define NULL_SPTR (short *) 0
|
||||
#define NULL_PTR (char *) 0
|
||||
#define NULLP(type) (type *) 0
|
||||
|
||||
|
||||
/*
|
||||
* for justification during line fill
|
||||
*/
|
||||
#define ADJ_OFF 0
|
||||
#define ADJ_LEFT 1
|
||||
#define ADJ_RIGHT 2
|
||||
#define ADJ_CENTER 3
|
||||
#define ADJ_BOTH 4
|
||||
|
||||
/*
|
||||
* Markers for various terminal/printer modes
|
||||
*/
|
||||
#define S_STANDOUT 128
|
||||
#define E_STANDOUT 129
|
||||
#define S_BOLD 130
|
||||
#define E_BOLD 131
|
||||
#define S_ITALIC 132
|
||||
#define E_ITALIC 133
|
||||
|
||||
/*
|
||||
* basic unit (b.u.) conversions. in nroff, all output is fixed spaced,
|
||||
* at least in THIS nroff. so unit conversion to b.u. amount to 1 Em per
|
||||
* character or 24 b.u. per character. thus 0.5i = 120 b.u. = 5 chars.
|
||||
* everything is rounded up to the nearest Em. it is highly recommended
|
||||
* to use inches for everything...
|
||||
*
|
||||
* to convert (say inches) to char spaces, do this:
|
||||
*
|
||||
* char_spaces = (int)(inches * (float) BU_INCH) / BU_EM;
|
||||
*/
|
||||
#define BU_INCH 240 /* 1.0i = 240 b.u. */
|
||||
#define BU_CM 945/10 /* 1.0c = 240*50/127 b.u. */
|
||||
#define BU_PICA 40 /* 1P = 240/6 b.u. */
|
||||
#define BU_EM 24 /* 1m = 240/10 b.u. (10 char/inch) */
|
||||
#define BU_EN 24 /* 1n = 240/10 b.u. */
|
||||
#define BU_POINT 240/72 /* 1p = 240/72 b.u. */
|
||||
#define BU_BU 1 /* 1 = 1 b.u. */
|
||||
|
||||
|
||||
/*
|
||||
* The parameter values selected for macro definitions are somewhat
|
||||
* arbitrary. MACBUF is the storage area for both macro names and
|
||||
* definitions. Since macro processing is handled by pushing back
|
||||
* the expansion into the input buffer, the longest possible expansion
|
||||
* would be MAXLINE characters. Allowing for argument expansion,
|
||||
* MXMLEN was chosen slightly less than MAXLINE. It is assumed that
|
||||
* most macro definitions will not exceed 20 characters, hence MXMDEF
|
||||
* of 150.
|
||||
*/
|
||||
#define MXMDEF 150 /* max no. of macro definitions */
|
||||
#define MACBUF 32000 /*100000*//* macro definition buffer size (32000) */
|
||||
#define MXMLEN 1000 /* max length of each macro definition (250) */
|
||||
#define MNLEN 10 /* max length of macro name */
|
||||
#define MAXREGS 100 /* max number of registers (2-char) */
|
||||
#define MAXPBB 5000 /* size of push back buffer */
|
||||
|
||||
|
||||
/*
|
||||
* number registers
|
||||
*/
|
||||
#define RF_READ 0x0001 /* register flags */
|
||||
#define RF_WRITE 0x0002
|
||||
|
||||
struct regs
|
||||
{
|
||||
char rname[4]; /* 2-char register name */
|
||||
int rauto; /* autoincrement value */
|
||||
int rval; /* current value of the register */
|
||||
int rflag; /* register flags */
|
||||
char rfmt; /* register format (1,a,A,i,I,...) */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* control parameters for nroff
|
||||
*/
|
||||
struct docctl
|
||||
{
|
||||
int fill; /* fill if YES, init = YES */
|
||||
int dofnt; /* handle font change, init = YES */
|
||||
int lsval; /* current line spacing, init = 1 */
|
||||
int inval; /* current indent, >= 0, init = 0 */
|
||||
int rmval; /* current right margin, init = 60 */
|
||||
int llval; /* current line length, init = 60 */
|
||||
int ltval; /* current title length, init = 60 */
|
||||
int tival; /* current temp indent, init = 0 */
|
||||
int ceval; /* number of lines to center, init = 0 */
|
||||
int ulval; /* number of lines to underline, init = 0 */
|
||||
int cuval; /* no lines to continuously uline, init = 0 */
|
||||
int juval; /* justify if YES, init = YES */
|
||||
int adjval; /* adjust type, init = ADJ_BOTH */
|
||||
int boval; /* number of lines to bold face, init = 0 */
|
||||
int bsflg; /* can output contain '\b', init = FALSE */
|
||||
int prflg; /* print on or off, init = TRUE */
|
||||
int sprdir; /* direction for spread(), init = 0 */
|
||||
int flevel; /* nesting depth for source cmd, init = 0 */
|
||||
int lastfnt; /* previous used font */
|
||||
int thisfnt; /* current font, init = 1 (1=R,2=I,3=B,4=S) */
|
||||
int escon; /* whether esc parsing is on, init = YES */
|
||||
int nr[26]; /* number registers */
|
||||
int nrauto[26]; /* number registers auto increment */
|
||||
char nrfmt[26]; /* number registers formats, init = '1' */
|
||||
/* input code how printed */
|
||||
/* 1 '1' 1,2,3,... */
|
||||
/* a 'a' a,b,c,...,aa,bb,cc,... */
|
||||
/* A 'A' A,B,C,...,AA,BB,CC,... */
|
||||
/* i 'i' i,ii,iii,iv,v... */
|
||||
/* I 'I' I,II,III,IV,V... */
|
||||
/* 01 2 01,02,03,... */
|
||||
/* 001 3 001,002,003,... */
|
||||
/* 0..1 8 00000001,00000002,... */
|
||||
char pgchr; /* page number character, init = '%' */
|
||||
char cmdchr; /* command character, init = '.' */
|
||||
char escchr; /* escape char, init = '\' */
|
||||
char nobrchr; /* nobreak char, init = '\'' */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* page control parameters
|
||||
*/
|
||||
struct page
|
||||
{
|
||||
int curpag; /* current output page number, init =0 */
|
||||
int newpag; /* next output page number, init = 1 */
|
||||
int lineno; /* next line to be printed, init = 0 */
|
||||
int plval; /* page length in lines, init = 66 */
|
||||
int m1val; /* margin before and including header */
|
||||
int m2val; /* margin after header */
|
||||
int m3val; /* margin after last text line */
|
||||
int m4val; /* bottom margin, including footer */
|
||||
int bottom; /* last live line on page
|
||||
= plval - m3val - m4val */
|
||||
int offset; /* page offset from left, init = 0 */
|
||||
int frstpg; /* first page to print, init = 0 */
|
||||
int lastpg; /* last page to print, init = 30000 */
|
||||
int ehlim[2]; /* left/right margins for headers/footers */
|
||||
int ohlim[2]; /* init = 0 and PAGEWIDTH */
|
||||
int eflim[2];
|
||||
int oflim[2];
|
||||
char ehead[MAXLINE]; /* top of page title, init = '\n' */
|
||||
char ohead[MAXLINE];
|
||||
char efoot[MAXLINE]; /* bottom of page title, init = '\n' */
|
||||
char ofoot[MAXLINE];
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* forward refs from nroff
|
||||
*/
|
||||
|
||||
/* main.c */
|
||||
void debugMessage (const char *fmt, ...);
|
||||
|
||||
/* command.c */
|
||||
void comand (char *p);
|
||||
int set_ireg (const char *name, int val, int opt);
|
||||
void set (int *param, int val, char type, int defval, int minval, int maxval);
|
||||
|
||||
/* low.c */
|
||||
int ctod (char *p);
|
||||
char *skipbl (char *p);
|
||||
char *skipwd (char *p);
|
||||
void nroffSpace (int n);
|
||||
char *getfield (char *p, char *q, char delim);
|
||||
int getwrd (char *src, char *dest);
|
||||
int countesc (char *p);
|
||||
int itoda (int value, char *p, int size);
|
||||
int itoROMAN (int value, char *p, int size);
|
||||
int itoroman (int value, char *p, int size);
|
||||
int itoLETTER (int value, char *p, int size);
|
||||
int itoletter (int value, char *p, int size);
|
||||
void err_exit (int code);
|
||||
|
||||
/* text.c */
|
||||
void initOutbuf (void);
|
||||
void pfoot (void);
|
||||
void phead (void);
|
||||
void robrk (void);
|
||||
void setPrinting (int val);
|
||||
void skip (int n);
|
||||
int strkovr (char *p, char *q);
|
||||
void text (char *p);
|
||||
|
||||
|
||||
/* strings.c */
|
||||
void defstr (char *line);
|
||||
|
||||
/*
|
||||
* Globals.
|
||||
*/
|
||||
extern struct docctl dc;
|
||||
extern struct page pg;
|
||||
extern struct regs rg[MAXREGS];
|
||||
extern FILE *out_stream;
|
||||
extern FILE *err_stream;
|
||||
extern FILE *dbg_stream;
|
||||
extern FILE *sofile[Nfiles+1];
|
||||
extern int ignoring;
|
||||
extern int hold_screen;
|
||||
extern int debugging;
|
||||
extern int stepping;
|
||||
extern int mc_ing;
|
||||
extern int mc_space;
|
||||
extern char mc_char;
|
||||
extern char tmpdir[];
|
||||
extern char s_standout[];
|
||||
extern char e_standout[];
|
||||
extern char s_italic[];
|
||||
extern char e_italic[];
|
||||
extern char s_bold[];
|
||||
extern char e_bold[];
|
||||
extern char *dbgfile;
|
||||
extern char *printer;
|
||||
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
#define DEBUGGING(args) \
|
||||
{ \
|
||||
if (debugging) { \
|
||||
debugMessage args; \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ASSERT(condition, args) \
|
||||
{ \
|
||||
if (!(condition)) { \
|
||||
printf("%s:%d: assertion failed (%s): ",__FILE__,__LINE__,#condition);\
|
||||
printf args; \
|
||||
abort(); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define ASSERT(condition, args)
|
||||
#endif
|
||||
|
||||
#endif /*NRO_H*/
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* $Id: nroff.rez,v 1.1 1997/03/14 06:22:29 gdr Exp $
|
||||
*/
|
||||
|
||||
#include "Types.Rez"
|
||||
|
||||
resource rVersion (0x1, purgeable3, nocrossbank) {
|
||||
|
||||
{ 1, 2, 0, /* version 1.2.0 */
|
||||
release, /* development|alpha|beta|final|release */
|
||||
0 /* non-final release number */
|
||||
},
|
||||
verBritain, /* close enough */
|
||||
"nroff",
|
||||
"Text Processing Typesetter\n"
|
||||
"Devin Reade <gdr@myrias.com>\n"
|
||||
"Canada"
|
||||
};
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* strings.c - String input/output processing for nroff word processor
|
||||
*
|
||||
* adapted for atariST/TOS by Bill Rosenkranz 11/89
|
||||
* net: rosenkra@hall.cray.com
|
||||
* CIS: 71460,17
|
||||
* GENIE: W.ROSENKRANZ
|
||||
*
|
||||
* original author:
|
||||
*
|
||||
* Stephen L. Browning
|
||||
* 5723 North Parker Avenue
|
||||
* Indianapolis, Indiana 46220
|
||||
*
|
||||
* history:
|
||||
*
|
||||
* - Originally written in BDS C;
|
||||
* - Adapted for standard C by W. N. Paul
|
||||
* - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
|
||||
* - Heavily modified by Devin Reade to avoid memory trashing bugs.
|
||||
*
|
||||
* $Id: strings.c,v 1.1 1997/03/14 06:22:29 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "strings___";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __GNO__
|
||||
#include <err.h>
|
||||
#else
|
||||
#include "err.h"
|
||||
#endif
|
||||
|
||||
#ifdef sparc
|
||||
#include "sunos.h"
|
||||
#endif
|
||||
|
||||
#include "nroff.h"
|
||||
#include "macros.h"
|
||||
|
||||
static int colstr (const char *src, char *dest, size_t len);
|
||||
|
||||
/*
|
||||
* defstr
|
||||
*
|
||||
* Define a string. top level, read from command line.
|
||||
*
|
||||
* we should read string without interpretation EXCEPT:
|
||||
*
|
||||
* 1) number registers are interpolated
|
||||
* 2) strings indicated by \* are interpolated
|
||||
* 3) arguments indicated by \$ are interpolated
|
||||
* 4) concealed newlines indicated by \(newline) are eliminated
|
||||
* 5) comments indicated by \" are eliminated
|
||||
* 6) \t and \a are interpreted as ASCII h tab and SOH.
|
||||
* 7) \\ is interpreted as backslash and \. is interpreted as a period.
|
||||
*
|
||||
* currently, we do only 3. a good place to do it would be here before
|
||||
* putstr, after colstr...
|
||||
*/
|
||||
void
|
||||
defstr (char *line) {
|
||||
register char *q;
|
||||
register int i;
|
||||
static char name[MNLEN];
|
||||
static char defn[MXMLEN+1];
|
||||
|
||||
name[0] = '\0';
|
||||
defn[0] = '\0';
|
||||
|
||||
#ifdef BORK
|
||||
fprintf(stderr, "DEBUG: %s:%d name = 0x%x\tdefn = 0x%x line=%s\n",
|
||||
__FILE__, __LINE__, name, defn, line);
|
||||
#endif
|
||||
/*
|
||||
* skip the .ds and get to the name...
|
||||
*/
|
||||
q = skipwd (line);
|
||||
q = skipbl (q);
|
||||
|
||||
/*
|
||||
* ok, name now holds the name. make sure it is valid (i.e. first
|
||||
* char is alpha...). getwrd returns the length of the word.
|
||||
*/
|
||||
i = getwrd (q, name);
|
||||
if (!name[0]) {
|
||||
errx(-1, "missing or illegal string definition name");
|
||||
}
|
||||
|
||||
/*
|
||||
* truncate to 2 char max name.
|
||||
*/
|
||||
if (i > 2) {
|
||||
name[2] = EOS;
|
||||
}
|
||||
|
||||
/*
|
||||
* skip the name to get to the string. it CAN start with a " to
|
||||
* have leading blanks...
|
||||
*/
|
||||
q = skipwd (q);
|
||||
q = skipbl (q);
|
||||
|
||||
/*
|
||||
* read rest of line from input stream and collect string into
|
||||
* temp buffer defn
|
||||
*/
|
||||
if ((i = colstr (q, defn, MXMLEN)) == ERR) {
|
||||
errx(-1, "string definition too long");
|
||||
}
|
||||
|
||||
/*
|
||||
* store the string
|
||||
*/
|
||||
if (putstr (name, defn) == ERR) {
|
||||
errx(-1, "string definition table full");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* colstr
|
||||
* Collect string definition from input stream
|
||||
*/
|
||||
static int
|
||||
colstr (const char *src, char *dest, size_t len) {
|
||||
const char *orgsrc;
|
||||
char *orgdest, *destlimit;
|
||||
|
||||
orgsrc = src;
|
||||
orgdest = dest;
|
||||
destlimit = dest + len; /* don't let dest go past this pointer */
|
||||
|
||||
#ifdef BORK
|
||||
fprintf(stderr,"DEBUG: %s:%d src=\"%s\"\n", __FILE__, __LINE__, src);
|
||||
#endif
|
||||
/*
|
||||
* if there is a " here, we have leading blanks (skipbl in caller
|
||||
* found it). just get past it...
|
||||
*/
|
||||
if (*src == '\"') {
|
||||
src++;
|
||||
}
|
||||
|
||||
while ((*src != '\n') && (*src != '\r') && (*src != '\0')
|
||||
&& (dest < destlimit - 1)) {
|
||||
|
||||
/*
|
||||
* If it's a comment, it ends terminates string collection
|
||||
*/
|
||||
if (*src == '\\' && *(src+1) == '\"') {
|
||||
/*
|
||||
* first back over any whitespace between the start of the
|
||||
* comment and the last non-whitespace character preceeding
|
||||
* the comment
|
||||
*/
|
||||
while (dest > orgdest && isspace(*dest)) {
|
||||
--dest;
|
||||
}
|
||||
|
||||
/* forward src until we hit newline or end of string */
|
||||
while (*src != '\n' && *src != '\r' && *src != '\0') {
|
||||
src++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* stop at the newline...
|
||||
*/
|
||||
if (*src == '\n' || *src == '\r') {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy it
|
||||
*/
|
||||
*dest++ = *src++;
|
||||
}
|
||||
*dest = '\0';
|
||||
|
||||
/* did we attempt to go over the allowed length for dest? */
|
||||
if (*src == '\0' || *src == '\n' || *src == '\r') {
|
||||
return dest - orgdest;
|
||||
} else {
|
||||
return ERR;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,849 @@
|
|||
#undef OLD_WAY
|
||||
/*
|
||||
* text.c - text output processing portion of nroff word processor
|
||||
*
|
||||
* adapted for atariST/TOS by Bill Rosenkranz 11/89
|
||||
* net: rosenkra@hall.cray.com
|
||||
* CIS: 71460,17
|
||||
* GENIE: W.ROSENKRANZ
|
||||
*
|
||||
* original author:
|
||||
*
|
||||
* Stephen L. Browning
|
||||
* 5723 North Parker Avenue
|
||||
* Indianapolis, Indiana 46220
|
||||
*
|
||||
* history:
|
||||
*
|
||||
* - Originally written in BDS C;
|
||||
* - Adapted for standard C by W. N. Paul
|
||||
* - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
|
||||
* - Heavily modified by Devin Reade to avoid memory trashing bugs.
|
||||
*
|
||||
* $Id: text.c,v 1.1 1997/03/14 06:22:29 gdr Exp $
|
||||
*/
|
||||
|
||||
#ifdef __ORCAC__
|
||||
segment "text______";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __GNO__
|
||||
#include <termcap.h>
|
||||
#else
|
||||
#include "termcap.h"
|
||||
#endif
|
||||
|
||||
#include "nroff.h"
|
||||
#include "io.h"
|
||||
#include "escape.h"
|
||||
|
||||
/*
|
||||
* output buffer control parameters
|
||||
*/
|
||||
static struct {
|
||||
int outp; /* next avail char pos in outbuf, init = 0 */
|
||||
int outw; /* width of text currently in buffer */
|
||||
int outwds; /* number of words in buffer, init = 0 */
|
||||
int lpr; /* output to printer, init = FALSE */
|
||||
int outesc; /* number of escape char on this line */
|
||||
char outbuf[MAXLINE];/* output of filled text */
|
||||
} co;
|
||||
|
||||
|
||||
static void bold (char *p0, char *p1, int size);
|
||||
static void center (char *p);
|
||||
static void expand (char *p0, char c, char *s);
|
||||
static void justcntr (char *p, char *q, int *limit);
|
||||
static void justleft (char *p, char *q, int limit);
|
||||
static void justrite (char *p, char *q, int limit);
|
||||
static void leadbl (char *p);
|
||||
static void puttl (char *p, int *lim, int pgno);
|
||||
static void putwrd (char *wrdbuf);
|
||||
static void spread (char *p, int outp, int nextra, int outwds,int escapes);
|
||||
static void underl (char *p0, char *p1, int size);
|
||||
static int width (char *s);
|
||||
static void do_mc (char *p);
|
||||
|
||||
|
||||
/*
|
||||
* text
|
||||
* main text processing
|
||||
*
|
||||
* Pre: <line> contains the line we wish to process (and print)
|
||||
* it is MAXLINE characters long, including the
|
||||
* terminating NULL character.
|
||||
*
|
||||
* Post:
|
||||
*/
|
||||
void
|
||||
text (char *line) {
|
||||
register int i;
|
||||
char wrdbuf[MAXLINE];
|
||||
|
||||
/*
|
||||
* skip over leading blanks if in fill mode. we indent later.
|
||||
* since leadbl does a robrk, do it if in .nf mode
|
||||
*/
|
||||
if (dc.fill == YES) {
|
||||
if (*line == ' ' || *line == '\n' || *line == '\r') {
|
||||
/* note that leadbl shifts <line> left as necessary */
|
||||
leadbl (line);
|
||||
}
|
||||
} else {
|
||||
robrk ();
|
||||
}
|
||||
|
||||
/*
|
||||
* expand escape sequences from <line> into <wrdbuf>
|
||||
*/
|
||||
expesc (line, wrdbuf, MAXLINE);
|
||||
|
||||
/*
|
||||
* test for how to output
|
||||
*/
|
||||
if (dc.ulval > 0) {
|
||||
/*
|
||||
* underline (.ul)
|
||||
*
|
||||
* Because of the way underlining is handled,
|
||||
* MAXLINE should be declared to be three times
|
||||
* larger than the longest expected input line
|
||||
* for underlining. Since many of the character
|
||||
* buffers use this parameter, a lot of memory
|
||||
* can be allocated when it may not really be
|
||||
* needed. A MAXLINE of 180 would allow about
|
||||
* 60 characters in the output line to be
|
||||
* underlined (remember that only alphanumerics
|
||||
* get underlined - no spaces or punctuation).
|
||||
*/
|
||||
underl (line, wrdbuf, MAXLINE);
|
||||
--dc.ulval;
|
||||
}
|
||||
if (dc.cuval > 0) {
|
||||
/*
|
||||
* continuous underline (.cu)
|
||||
*/
|
||||
underl (line, wrdbuf, MAXLINE);
|
||||
--dc.cuval;
|
||||
}
|
||||
if (dc.boval > 0) {
|
||||
/*
|
||||
* bold (.bo)
|
||||
*/
|
||||
bold (line, wrdbuf, MAXLINE);
|
||||
--dc.boval;
|
||||
}
|
||||
if (dc.ceval > 0) {
|
||||
/*
|
||||
* centered (.ce)
|
||||
*/
|
||||
center (line);
|
||||
do_mc (line);
|
||||
put (line);
|
||||
--dc.ceval;
|
||||
} else if ((*line == '\r' || *line == '\n') && dc.fill == NO) {
|
||||
/*
|
||||
* all blank line
|
||||
*/
|
||||
do_mc (line);
|
||||
put (line);
|
||||
} else if (dc.fill == NO) {
|
||||
/*
|
||||
* unfilled (.nf)
|
||||
*/
|
||||
do_mc (line);
|
||||
put (line);
|
||||
} else {
|
||||
/*
|
||||
* anything else...
|
||||
*
|
||||
* init escape char counter for this line...
|
||||
*/
|
||||
/* co.outesc = 0;*/
|
||||
|
||||
|
||||
/*
|
||||
* get a word and put it out. increment ptr to the next
|
||||
* word.
|
||||
*/
|
||||
while ((i = getwrd (line, wrdbuf)) > 0) {
|
||||
/* co.outesc += countesc (wrdbuf);*/
|
||||
|
||||
putwrd (wrdbuf);
|
||||
line += i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* bold
|
||||
* insert bold face text (by overstriking)
|
||||
*/
|
||||
static void
|
||||
bold (register char *p0, register char *p1, int size)
|
||||
{
|
||||
|
||||
register int i;
|
||||
register int j;
|
||||
|
||||
j = 0;
|
||||
for (i = 0; (p0[i] != '\n') && (j < size - 1); ++i)
|
||||
{
|
||||
if (isalpha (p0[i]) || isdigit (p0[i]))
|
||||
{
|
||||
p1[j++] = p0[i];
|
||||
p1[j++] = '\b';
|
||||
}
|
||||
p1[j++] = p0[i];
|
||||
}
|
||||
p1[j++] = '\n';
|
||||
p1[j] = EOS;
|
||||
while (*p1 != EOS)
|
||||
*p0++ = *p1++;
|
||||
*p0 = EOS;
|
||||
}
|
||||
|
||||
/*
|
||||
* center
|
||||
* center a line by setting tival
|
||||
*/
|
||||
static void
|
||||
center (register char *p) {
|
||||
int t;
|
||||
|
||||
t = (dc.rmval + dc.tival - width (p)) >> 1;
|
||||
dc.tival = MAX(t, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* expand
|
||||
* expand title buffer to include character string
|
||||
*/
|
||||
static void
|
||||
expand (register char *p0, char c, register char *s) {
|
||||
register char *p;
|
||||
register char *q;
|
||||
register char *r;
|
||||
char tmp[MAXLINE];
|
||||
|
||||
p = p0;
|
||||
q = tmp;
|
||||
while (*p != EOS) {
|
||||
if (*p == c) {
|
||||
r = s;
|
||||
while (*r != EOS) {
|
||||
*q++ = *r++;
|
||||
}
|
||||
} else {
|
||||
*q++ = *p;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
*q = EOS;
|
||||
strcpy (p0, tmp); /* copy it back */
|
||||
}
|
||||
|
||||
/*
|
||||
* justcntr
|
||||
* center title text into print buffer
|
||||
*/
|
||||
static void
|
||||
justcntr (register char *p, char *q, int *limit) {
|
||||
register int len;
|
||||
|
||||
len = width (p);
|
||||
q = &q[(limit[RIGHT] + limit[LEFT] - len) >> 1];
|
||||
while (*p != EOS) {
|
||||
*q++ = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* justleft
|
||||
* left justify title text into print buffer
|
||||
*/
|
||||
static void
|
||||
justleft (register char *p, char *q, int limit) {
|
||||
q = &q[limit];
|
||||
while (*p != EOS) {
|
||||
*q++ = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* justrite
|
||||
* right justify title text into print buffer
|
||||
*/
|
||||
static void
|
||||
justrite (register char *p, char *q, int limit) {
|
||||
register int len;
|
||||
|
||||
len = width (p);
|
||||
q = &q[limit - len];
|
||||
while (*p != EOS) {
|
||||
*q++ = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* leadbl
|
||||
* delete leading blanks, set tival
|
||||
*
|
||||
* REVIEWED
|
||||
*/
|
||||
static void
|
||||
leadbl (register char *p) {
|
||||
register char *q;
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* end current line and reset co struct
|
||||
*/
|
||||
robrk ();
|
||||
|
||||
/*
|
||||
* skip spaces
|
||||
*/
|
||||
for (i = 0; p[i] == ' ' || p[i] == '\t'; ++i);
|
||||
|
||||
/*
|
||||
* if not end of line, reset current temp indent
|
||||
*/
|
||||
if (p[i] != '\n' && p[i] != '\r') {
|
||||
dc.tival = i;
|
||||
}
|
||||
|
||||
/*
|
||||
* shift string
|
||||
*/
|
||||
q = &p[i];
|
||||
#ifdef DEBUG
|
||||
i = 0;
|
||||
#endif
|
||||
while (*q) {
|
||||
#ifdef DEBUG
|
||||
i++;
|
||||
ASSERT(i<MAXLINE, ("leadbl buffer overflow\n"));
|
||||
#endif
|
||||
*p++ = *q++;
|
||||
}
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pfoot
|
||||
* put out page footer
|
||||
*/
|
||||
void
|
||||
pfoot (void) {
|
||||
if (dc.prflg == TRUE) {
|
||||
skip (pg.m3val);
|
||||
if (pg.m4val > 0) {
|
||||
if ((pg.curpag % 2) == 0) {
|
||||
puttl (pg.efoot, pg.eflim, pg.curpag);
|
||||
} else {
|
||||
puttl (pg.ofoot, pg.oflim, pg.curpag);
|
||||
}
|
||||
skip (pg.m4val - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* phead
|
||||
* put out page header
|
||||
*/
|
||||
void
|
||||
phead (void) {
|
||||
pg.curpag = pg.newpag;
|
||||
if (pg.curpag >= pg.frstpg && pg.curpag <= pg.lastpg) {
|
||||
dc.prflg = TRUE;
|
||||
} else {
|
||||
dc.prflg = FALSE;
|
||||
}
|
||||
++pg.newpag;
|
||||
set_ireg ("%", pg.newpag, 0);
|
||||
if (dc.prflg == TRUE) {
|
||||
if (pg.m1val > 0) {
|
||||
skip (pg.m1val - 1);
|
||||
if ((pg.curpag % 2) == 0) {
|
||||
puttl (pg.ehead, pg.ehlim, pg.curpag);
|
||||
} else {
|
||||
puttl (pg.ohead, pg.ohlim, pg.curpag);
|
||||
}
|
||||
}
|
||||
skip (pg.m2val);
|
||||
}
|
||||
/*
|
||||
* initialize lineno for the next page
|
||||
*/
|
||||
pg.lineno = pg.m1val + pg.m2val + 1;
|
||||
set_ireg ("ln", pg.lineno, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* puttl
|
||||
* put out title or footer
|
||||
*/
|
||||
static void
|
||||
puttl (register char *p, int *lim, int pgno) {
|
||||
register int i;
|
||||
char pn[8];
|
||||
char t[MAXLINE];
|
||||
char h[MAXLINE];
|
||||
char delim;
|
||||
|
||||
itoda (pgno, pn, 6);
|
||||
for (i = 0; i < MAXLINE; ++i) {
|
||||
h[i] = ' ';
|
||||
}
|
||||
delim = *p++;
|
||||
p = getfield (p, t, delim);
|
||||
expand (t, dc.pgchr, pn);
|
||||
justleft (t, h, lim[LEFT]);
|
||||
p = getfield (p, t, delim);
|
||||
expand (t, dc.pgchr, pn);
|
||||
justcntr (t, h, lim);
|
||||
p = getfield (p, t, delim);
|
||||
expand (t, dc.pgchr, pn);
|
||||
justrite (t, h, lim[RIGHT]);
|
||||
for (i = MAXLINE - 4; h[i] == ' '; --i) {
|
||||
h[i] = EOS;
|
||||
}
|
||||
h[++i] = '\n';
|
||||
h[++i] = '\r';
|
||||
h[++i] = EOS;
|
||||
if (strlen (h) > 2) {
|
||||
for (i = 0; i < pg.offset; ++i) {
|
||||
PRCHAR2(' ', out_stream);
|
||||
}
|
||||
}
|
||||
putlin (h, out_stream);
|
||||
}
|
||||
|
||||
/*
|
||||
* putwrd
|
||||
* put word in output buffer
|
||||
*/
|
||||
|
||||
static void
|
||||
putwrd (register char *wrdbuf) {
|
||||
register char *p0;
|
||||
register char *p1;
|
||||
int w;
|
||||
int last;
|
||||
int llval;
|
||||
int nextra;
|
||||
|
||||
/*
|
||||
* check if this word puts us over the limit
|
||||
*/
|
||||
w = width (wrdbuf);
|
||||
last = strlen (wrdbuf) + co.outp;
|
||||
llval = dc.rmval - dc.tival;
|
||||
/* if (((co.outp > 0) && ((co.outw + w) > llval))*/
|
||||
co.outesc += countesc (wrdbuf);
|
||||
if (((co.outp > 0) && ((co.outw + w - co.outesc) > llval))
|
||||
||(last > MAXLINE)) {
|
||||
/*
|
||||
* last word exceeds limit so prepare to break line, print
|
||||
* it, and reset outbuf.
|
||||
*/
|
||||
last -= co.outp;
|
||||
if (dc.juval == YES) {
|
||||
nextra = llval - co.outw + 1;
|
||||
|
||||
/*
|
||||
* Do not take in the escape char of the
|
||||
* word that didn't fit on this line anymore
|
||||
*/
|
||||
co.outesc -= countesc (wrdbuf);
|
||||
|
||||
/*
|
||||
* Check whether last word was end of
|
||||
* sentence and modify counts so that
|
||||
* it is right justified.
|
||||
*/
|
||||
if (co.outbuf[co.outp - 2] == ' ') {
|
||||
--co.outp;
|
||||
++nextra;
|
||||
}
|
||||
#ifdef OLD_WAY
|
||||
spread (co.outbuf, co.outp - 1, nextra, co.outwds, co.outesc);
|
||||
if ((nextra > 0) && (co.outwds > 1)) {
|
||||
co.outp += (nextra - 1);
|
||||
}
|
||||
#if 0
|
||||
if (co.outesc > 0) {
|
||||
co.outp += co.outesc;
|
||||
}
|
||||
#endif /* 0 */
|
||||
#else /* OLD_WAY */
|
||||
spread (co.outbuf, co.outp - 1, nextra, co.outwds, co.outesc);
|
||||
if ((nextra + co.outesc > 0) && (co.outwds > 1)) {
|
||||
co.outp += (nextra + co.outesc - 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* break line, output it, and reset all co members. reset
|
||||
* esc count.
|
||||
*/
|
||||
robrk ();
|
||||
co.outesc = countesc (wrdbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy the current word to the out buffer which may have been
|
||||
* reset
|
||||
*/
|
||||
p0 = wrdbuf;
|
||||
p1 = co.outbuf + co.outp;
|
||||
while (*p0 != EOS) {
|
||||
*p1++ = *p0++;
|
||||
}
|
||||
|
||||
co.outp = last;
|
||||
co.outbuf[co.outp++] = ' ';
|
||||
co.outw += w + 1;
|
||||
co.outwds += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* skip
|
||||
* skips the number of lines specified by n.
|
||||
*/
|
||||
void
|
||||
skip (register int n) {
|
||||
register int i;
|
||||
register int j;
|
||||
|
||||
if (dc.prflg == TRUE && n > 0) {
|
||||
for (i = 0; i < n; ++i) {
|
||||
/*
|
||||
* handle blank line with changebar
|
||||
*/
|
||||
if (mc_ing == TRUE) {
|
||||
for (j = 0; j < pg.offset; ++j) {
|
||||
PRCHAR2(' ', out_stream);
|
||||
}
|
||||
for (j = 0; j < dc.rmval; ++j) {
|
||||
PRCHAR2(' ', out_stream);
|
||||
}
|
||||
for (j = 0; j < mc_space; j++) {
|
||||
PRCHAR2(' ', out_stream);
|
||||
}
|
||||
PRCHAR(mc_char, out_stream);
|
||||
}
|
||||
PRCHAR2('\n', out_stream);
|
||||
#if 0
|
||||
/* gdr: not required */
|
||||
prchar ('\r', out_stream);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* spread
|
||||
* spread words to justify right margin
|
||||
*/
|
||||
static void
|
||||
spread (register char *p, int outp, int nextra, int outwds, int escapes) {
|
||||
register int i;
|
||||
register int j;
|
||||
register int nb;
|
||||
register int ne;
|
||||
register int nholes;
|
||||
|
||||
|
||||
/*
|
||||
* quick sanity check...
|
||||
*/
|
||||
#ifdef OLDWAY
|
||||
if ((nextra <= 0) || (outwds <= 1)) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if ((nextra + escapes < 1) || (outwds < 2)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* set up for the spread and do it...
|
||||
*/
|
||||
dc.sprdir = ~dc.sprdir;
|
||||
#ifdef OLD_WAY
|
||||
ne = nextra;
|
||||
#else
|
||||
ne = nextra + escapes;
|
||||
#endif
|
||||
nholes = outwds - 1; /* holes between words */
|
||||
i = outp - 1; /* last non-blank character */
|
||||
j = MIN(MAXLINE - 3, i + ne); /* leave room for CR,LF,EOS */
|
||||
#if 0
|
||||
j += escapes;
|
||||
if (p[i-1] == 27) {
|
||||
j += 2;
|
||||
}
|
||||
j = MIN(j, MAXLINE - 3);
|
||||
#endif
|
||||
while (i < j) {
|
||||
p[j] = p[i];
|
||||
if (p[i] == ' ') {
|
||||
if (dc.sprdir == 0) {
|
||||
nb = (ne - 1) / nholes + 1;
|
||||
} else {
|
||||
nb = ne / nholes;
|
||||
}
|
||||
ne -= nb;
|
||||
--nholes;
|
||||
for (; nb > 0; --nb) {
|
||||
--j;
|
||||
p[j] = ' ';
|
||||
}
|
||||
}
|
||||
--i;
|
||||
--j;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* strkovr
|
||||
* split overstrikes (backspaces) into seperate buffer
|
||||
*/
|
||||
int
|
||||
strkovr (char *p, char *q) {
|
||||
register char *pp;
|
||||
int bsflg;
|
||||
|
||||
bsflg = FALSE;
|
||||
pp = p;
|
||||
while (*p != EOS) {
|
||||
*q = ' ';
|
||||
*pp = *p;
|
||||
++p;
|
||||
if (*p == '\b') {
|
||||
if (*pp >= ' ' && *pp <= '~') {
|
||||
bsflg = TRUE;
|
||||
*q = *pp;
|
||||
++p;
|
||||
*pp = *p;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
++q;
|
||||
++pp;
|
||||
}
|
||||
*q++ = NEWLINE;
|
||||
*q = *pp = EOS;
|
||||
|
||||
return bsflg;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* underl
|
||||
* underline a line
|
||||
*/
|
||||
static void
|
||||
underl (register char *p0, register char *p1, int size) {
|
||||
register int i;
|
||||
register int j;
|
||||
|
||||
j = 0;
|
||||
for (i = 0; (p0[i] != '\n') && (j < size - 1); ++i) {
|
||||
if (p0[i] >= ' ' &&
|
||||
p0[i] <= '~' &&
|
||||
(isalpha (p0[i]) || isdigit (p0[i]) || dc.cuval > 0))
|
||||
{
|
||||
p1[j++] = '_';
|
||||
p1[j++] = '\b';
|
||||
}
|
||||
p1[j++] = p0[i];
|
||||
}
|
||||
p1[j++] = '\n';
|
||||
p1[j] = EOS;
|
||||
while (*p1 != EOS) {
|
||||
*p0++ = *p1++;
|
||||
}
|
||||
*p0 = EOS;
|
||||
}
|
||||
|
||||
/*
|
||||
* width
|
||||
* compute width of character string
|
||||
*/
|
||||
static int
|
||||
width (char *s) {
|
||||
register int w;
|
||||
|
||||
w = 0;
|
||||
for (; *s != '\0'; s++) {
|
||||
ASSERT((*s != '\n' && *s != '\r'), ("\n"));
|
||||
if ((*s >= 32) && (*s < 127)) {
|
||||
++w;
|
||||
} else if (*s == '\b' || *s == 128) {
|
||||
--w;
|
||||
}
|
||||
/* ignore high-bit chars and other control chars */
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* do_mc
|
||||
* add margin char (change bar) for .nf and .ce lines.
|
||||
*
|
||||
* filled lines handled in robrk(). blank lines (.sp) handled in skip().
|
||||
* note: robrk() calls this routine, too.
|
||||
*/
|
||||
static void
|
||||
do_mc (char *p) {
|
||||
register char *ps;
|
||||
register int nspaces;
|
||||
register int i;
|
||||
register int has_cr;
|
||||
register int has_lf;
|
||||
int len;
|
||||
int nesc;
|
||||
|
||||
if (mc_ing == FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
len = strlen (p);
|
||||
|
||||
/*
|
||||
* get to the end...
|
||||
*/
|
||||
ps = p;
|
||||
while (*ps) {
|
||||
ps++;
|
||||
}
|
||||
|
||||
/*
|
||||
* check for cr and lf
|
||||
*/
|
||||
ps--;
|
||||
has_lf = 0;
|
||||
has_cr = 0;
|
||||
while (ps >= p && (*ps == '\r' || *ps == '\n')) {
|
||||
if (*ps == '\n') {
|
||||
has_lf++;
|
||||
} else {
|
||||
has_cr++;
|
||||
}
|
||||
len--;
|
||||
ps--;
|
||||
}
|
||||
if (has_lf < has_cr) {
|
||||
has_lf = has_cr;
|
||||
} else if (has_cr < has_lf) {
|
||||
has_cr = has_lf;
|
||||
}
|
||||
|
||||
/*
|
||||
* remove any trailing blanks here
|
||||
*/
|
||||
while (ps >= p && *ps == ' ') {
|
||||
ps--;
|
||||
len--;
|
||||
}
|
||||
*++ps = EOS;
|
||||
|
||||
|
||||
/*
|
||||
* add trailing spaces for short lines. count escapes, subtract
|
||||
* from len. use rmval for rigth margin (minus tival which is
|
||||
* added later in put).
|
||||
*/
|
||||
nesc = countesc (p);
|
||||
len -= nesc;
|
||||
nspaces = dc.rmval - dc.tival - len;
|
||||
for (i = 0; i < nspaces; i++, ps++) {
|
||||
*ps = ' ';
|
||||
}
|
||||
|
||||
/*
|
||||
* add the bar...
|
||||
*/
|
||||
for (i = 0; i < mc_space; i++, ps++) {
|
||||
*ps = ' ';
|
||||
}
|
||||
*ps++ = mc_char;
|
||||
|
||||
/*
|
||||
* replace cr, lf, and EOS
|
||||
*/
|
||||
while (has_lf--) {
|
||||
*ps++ = '\r';
|
||||
*ps++ = '\n';
|
||||
}
|
||||
*ps = EOS;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
initOutbuf (void) {
|
||||
co.outp = 0;
|
||||
co.outw = 0;
|
||||
co.outwds = 0;
|
||||
co.lpr = FALSE;
|
||||
co.outesc = 0;
|
||||
memset(co.outbuf, EOS, MAXLINE);
|
||||
#if 0
|
||||
for (i = 0; i < MAXLINE; ++i) {
|
||||
co.outbuf[i] = EOS;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* robrk
|
||||
*
|
||||
* End current filled line. References and modifies globals:
|
||||
* co
|
||||
*/
|
||||
void
|
||||
robrk (void) {
|
||||
if (co.outp > 0) {
|
||||
/*
|
||||
* handle margin char (change bar) here for all filled lines
|
||||
*/
|
||||
ASSERT(MAXLINE - co.outp > 2, ("output buffer overrun: >%d:%d:%d<\n",
|
||||
MAXLINE, co.outp, MAXLINE- co.outp));
|
||||
co.outbuf[co.outp] = '\r';
|
||||
co.outbuf[co.outp+1] = '\n';
|
||||
co.outbuf[co.outp+2] = EOS;
|
||||
|
||||
do_mc (co.outbuf);
|
||||
|
||||
put (co.outbuf);
|
||||
}
|
||||
co.outp = 0;
|
||||
co.outw = 0;
|
||||
co.outwds = 0;
|
||||
co.outesc = 0;
|
||||
}
|
||||
|
||||
void
|
||||
setPrinting(int val) {
|
||||
co.lpr = val;
|
||||
}
|
||||
|
|
@ -0,0 +1,335 @@
|
|||
.\" set this non-zero to turn on debugging
|
||||
.nr Z 1
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.\" -man package for nroff. not quite unix(tm), but adequate/working...
|
||||
.\"
|
||||
.\" usage: nroff -man file [...]
|
||||
.\"
|
||||
.\" included here are: TH, Th, SH, SS, IP, PP, LP, RS, RP, RE, I, B
|
||||
.\"
|
||||
.\" v1.10 7/22/90 rosenkra@convex.com (Bill Rosenkranz)
|
||||
.\" freely distributable (no copyright, etc.)
|
||||
.\"
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.\" some perdefined strings (quotes, etc)
|
||||
.\"
|
||||
.ds S s
|
||||
.ds ` "`
|
||||
.ds ' "'
|
||||
.ds lq ""
|
||||
.ds rq ""
|
||||
.\"
|
||||
.\" these are various predefined date and time strings
|
||||
.\"
|
||||
.\" DW day-of-week:
|
||||
.if \n(dw=1 .ds DW "Sun
|
||||
.if \n(dw=2 .ds DW "Mon
|
||||
.if \n(dw=3 .ds DW "Tue
|
||||
.if \n(dw=4 .ds DW "Wed
|
||||
.if \n(dw=5 .ds DW "Thu
|
||||
.if \n(dw=6 .ds DW "Fri
|
||||
.if \n(dw=7 .ds DW "Sat
|
||||
.\" Dy month day:
|
||||
.if \n(mo=1 .ds Dy "Jan \n(dy
|
||||
.if \n(mo=2 .ds Dy "Feb \n(dy
|
||||
.if \n(mo=3 .ds Dy "Mar \n(dy
|
||||
.if \n(mo=4 .ds Dy "Apr \n(dy
|
||||
.if \n(mo=5 .ds Dy "May \n(dy
|
||||
.if \n(mo=6 .ds Dy "Jun \n(dy
|
||||
.if \n(mo=7 .ds Dy "Jul \n(dy
|
||||
.if \n(mo=8 .ds Dy "Aug \n(dy
|
||||
.if \n(mo=9 .ds Dy "Sep \n(dy
|
||||
.if \n(mo=10 .ds Dy "Oct \n(dy
|
||||
.if \n(mo=11 .ds Dy "Nov \n(dy
|
||||
.if \n(mo=12 .ds Dy "Dec \n(dy
|
||||
.ds Da "\n(hh:\n(mm:\n(ss \n(mo/\n(dy/\n(yr
|
||||
.ds Yr "19\n(yr
|
||||
.ds DY "\*(Dy, \*(Yr
|
||||
.ds TM "\n(hh:\n(mm:\n(ss
|
||||
.ds DA "\*(TM \*(DY
|
||||
.ds CT "\*(DW \*(Dy \*(TM 19\n(yr
|
||||
.\"
|
||||
.\" they look like this:
|
||||
.\"
|
||||
.\" DW Sun
|
||||
.\" Dy Mar 4
|
||||
.\" DY Mar 4, 1990
|
||||
.\" Yr 1990
|
||||
.\" TM 16:34:00
|
||||
.\" DA 16:34:00 Mar 4, 1990
|
||||
.\" Da 16:34:00 2/4/90
|
||||
.\" CT Sun Mar 4 16:34:00 1990 like ctime(2)
|
||||
.\"
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.\" startup stuff...
|
||||
.\"
|
||||
.\" X is number register used internally here. it is initially 0. it gets
|
||||
.\" set to 1 in TH if ONLINE is set. it is used in the EX macro to force
|
||||
.\" an immediate exit at the end.
|
||||
.\"
|
||||
.in 0.0i
|
||||
.po 0.0i
|
||||
.lt 7.2i
|
||||
.ll 7.2i
|
||||
.m1 3
|
||||
.m2 3
|
||||
.m3 3
|
||||
.m4 3
|
||||
.nr X 0
|
||||
.\"
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.\" MACROS...
|
||||
.\"
|
||||
.\" ----------------------------------------------------------------------- TH
|
||||
.\" main page heading
|
||||
.\"
|
||||
.\" fields are usually: 1-name, 2-section, 3-section name, 4-version, 5-date
|
||||
.\" 1,2,3 are on header, 4,5 and page on footer. empty strings are skipped
|
||||
.\" by making the arg "". this must be first! there is an extra field at the
|
||||
.\" end ($6) which, if "ONLINE", prints the page without page breaks (i.e.
|
||||
.\" headers/footers).
|
||||
.\"
|
||||
.\" $1 $2 $3
|
||||
.\" | | |
|
||||
.\" v v v
|
||||
.\" NAME (1) Section NAME (1)
|
||||
.\" ...
|
||||
.\" Version Date Page n
|
||||
.\" ^ ^
|
||||
.\" | |
|
||||
.\" $4 $5
|
||||
.\"
|
||||
.\" .TH NAME 1 "Commands" "Version 1.0" "7 March 1990" ["ONLINE"]
|
||||
.\"
|
||||
.\" there is an extension here: if the 6th argument is "ONLINE" then the
|
||||
.\" resultant output does not have any headers/footers. this is useful for
|
||||
.\" making manpages for online use.
|
||||
.\"
|
||||
.de TH
|
||||
.\" define Se as default chapter name based on input chapter number
|
||||
.if $2=0 .ds Se "General Information
|
||||
.if $2=1 .ds Se "Commands and Applications
|
||||
.if $2=2 .ds Se "System Calls
|
||||
.if $2=3 .ds Se "Library Calls
|
||||
.if $2=4 .ds Se "Hardware and Special Files
|
||||
.if $2=5 .ds Se "File Formats
|
||||
.if $2=6 .ds Se "Games
|
||||
.if $2=7 .ds Se "Miscellaneous
|
||||
.if $2=8 .ds Se "Administation Commands
|
||||
.\" if the 6th arg is "ONLINE", set up for online docs output (no head/foot)
|
||||
.if !"$6"ONLINE" .pl 66
|
||||
.if "$6"ONLINE" .m1 0
|
||||
.if "$6"ONLINE" .m2 0
|
||||
.if "$6"ONLINE" .m3 0
|
||||
.if "$6"ONLINE" .m4 0
|
||||
.if !"$6"ONLINE" .tl |$1 ($2)|$3|$1 ($2)|
|
||||
.if !"$6"ONLINE" .if "$3"" .tl |$1 ($2)|\*(Se|$1 ($2)|
|
||||
.if !"$6"ONLINE" .fo |$4|$5|Page %|
|
||||
.if !"$6"ONLINE" .if "$4"" .fo |\*(CT|$5|Page %|
|
||||
.\" this is used by macro EX (exit)
|
||||
.if "$6"ONLINE" .nr X 1
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in 0.8i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- Th
|
||||
.\" alternate main page heading
|
||||
.\"
|
||||
.\" this prints no header/footer so it is good for creating online docs
|
||||
.\" for man(1). it ignores all args.
|
||||
.\"
|
||||
.\" .Th NAME 1
|
||||
.\"
|
||||
.de Th
|
||||
.m1 0
|
||||
.m2 0
|
||||
.m3 0
|
||||
.m4 0
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in 0.8i
|
||||
.nr X 1
|
||||
..
|
||||
.de UC
|
||||
.if t .ds ]W GNO/ME Version 1.0
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- EX
|
||||
.\" exit NOW! (no extra space at end of document)
|
||||
.\"
|
||||
.de EX
|
||||
.if \nX=1 .sp
|
||||
.if \nX=1 .ex
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- RS
|
||||
.\" start relative indent
|
||||
.\"
|
||||
.de RS
|
||||
.br
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in +0.8i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- RE
|
||||
.\" end relative indent
|
||||
.\"
|
||||
.de RE
|
||||
.br
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in -0.8i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- TP
|
||||
.\" indented paragraph with tag (no clue what the difference is)
|
||||
.\"
|
||||
.de TP
|
||||
.IP
|
||||
.\" .if \n(.$ \{ $1 $2 \}
|
||||
.\" .if !\n(.$ \{ \fBHAS NO ARGS\fR \}
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- IP
|
||||
.\" indented paragraph with tag (from this line)
|
||||
.\"
|
||||
.de IP
|
||||
.br
|
||||
.sp 1
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in 0.8i
|
||||
\&$1 $2 $3 $4 $5 $6 $7 $8 $9
|
||||
.br
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in +0.8i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- HP
|
||||
.\" indented paragraph without tag (from this line)
|
||||
.\"
|
||||
.de HP
|
||||
.br
|
||||
.sp 1
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in 0.8i
|
||||
.in +0.8i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- RP
|
||||
.\" relative indented paragraph with tag. MUST end with .RE
|
||||
.\"
|
||||
.de RP
|
||||
.br
|
||||
.sp 1
|
||||
.\".if !\\n(.i>8 .in 0.8i
|
||||
\&$1 $2 $3 $4 $5 $6 $7 $8 $9
|
||||
.br
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in +0.8i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- pp
|
||||
.\" start a new indented paragraph
|
||||
.\"
|
||||
.de pp
|
||||
.sp 1
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in 0.8i
|
||||
.ti +0.8i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- PP
|
||||
.\" start a new unindented paragraph
|
||||
.\"
|
||||
.de PP
|
||||
.sp 1
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in 0.8i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- LP
|
||||
.\" start a new unindented paragraph (same as PP)
|
||||
.\"
|
||||
.de LP
|
||||
.sp 1
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in 0.8i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- SH
|
||||
.\" main section heading
|
||||
.\"
|
||||
.de SH
|
||||
.sp 1
|
||||
.ne 3
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in 0.8i
|
||||
.ti -0.8i
|
||||
.\".bo
|
||||
\&$1 $2 $3 $4 $5 $6 $7 $8 $9
|
||||
.br
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- SS
|
||||
.\" subsection heading, same indent
|
||||
.\"
|
||||
.de SS
|
||||
.sp 1
|
||||
.ne 3
|
||||
.\" change to 0.5i for "normal" nroff output...
|
||||
.in 0.8i
|
||||
.\".bo
|
||||
\&$1 $2 $3 $4 $5 $6 $7 $8 $9
|
||||
.sp
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- I
|
||||
.\" italic text (must handle at least 2 args)
|
||||
.\"
|
||||
.de I
|
||||
\&\fI$1\fR$2
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- B
|
||||
.\" bold text (must handle at least 2 args)
|
||||
.\"
|
||||
.de B
|
||||
\&\fB$1\fR$2
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- R
|
||||
.\" Roman text
|
||||
.\"
|
||||
.de R
|
||||
\&\fR$1$2
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- IR
|
||||
.\" alternate italic and Roman text (must handle at least 6 args)
|
||||
.\"
|
||||
.de IR
|
||||
\&\fI$1\fR$2\fI$3\fR$4\fI$5\fR$6
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- RI
|
||||
.\" alternate Roman and italic text (must handle at least 6 args)
|
||||
.\"
|
||||
.de RI
|
||||
\&\fR$1\fI$2\fR$3\fI$4\fR$5\fI$6\fR
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- BR
|
||||
.\" alternate bold and Roman text (must handle at least 6 args)
|
||||
.\"
|
||||
.de BR
|
||||
\&\fB$1\fR$2\fB$3\fR$4\fB$5\fR$6
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- RB
|
||||
.\" alternate Roman and bold text (must handle at least 6 args)
|
||||
.\"
|
||||
.de RB
|
||||
\&\fR$1\fB$2\fR$3\fB$4\fR$5\fB$6\fR
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- SM
|
||||
.\" small text
|
||||
.\"
|
||||
.de SM
|
||||
\&\fB$1\fR
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- IX
|
||||
.\" make index entry (ignored by this nroff...)
|
||||
.\"
|
||||
.de IX
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- }D
|
||||
.\" debug. use (e.g. print current indent):
|
||||
.\"
|
||||
.\" .}D .br
|
||||
.\" .}D "** DEBUG ** before RS \n(.i"
|
||||
.\"
|
||||
.de }D
|
||||
.if \nZ>0 \&$1
|
||||
..
|
|
@ -0,0 +1,406 @@
|
|||
.\" set this non-zero to turn on debugging
|
||||
.nr Z 0
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.\" partial -ms package for nroff. macros for simple paper/report formats
|
||||
.\"
|
||||
.\" usage: nroff -ms file [...]
|
||||
.\"
|
||||
.\" included here are:
|
||||
.\"
|
||||
.\" TL, AU, AI, AB, AE, SH, NH, PP, LP, QP, XP, RS, RE, IP, I, B, R
|
||||
.\"
|
||||
.\" extensions include:
|
||||
.\"
|
||||
.\" TI (temp indent), EX (exit NOW)
|
||||
.\"
|
||||
.\" includes somewhat kludgy support for XS, XA, XE, PX (table of contents)
|
||||
.\"
|
||||
.\" v1.10 7/22/90 rosenkra@convex.com (Bill Rosenkranz)
|
||||
.\" freely distributable (no copyright, etc.)
|
||||
.\"
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.\" some perdefined strings (Quote, Unquote, dash, footer parts, etc):
|
||||
.\"
|
||||
.ds Q ""
|
||||
.ds U ""
|
||||
.ds - --
|
||||
.ds CF "ImPoSsIbLe
|
||||
.ds LF "\0
|
||||
.ds RF "\0
|
||||
.\"
|
||||
.\" these are various predefined date and time strings
|
||||
.\"
|
||||
.\" DW day-of-week:
|
||||
.if \n(dw=1 .ds DW "Sun
|
||||
.if \n(dw=2 .ds DW "Mon
|
||||
.if \n(dw=3 .ds DW "Tue
|
||||
.if \n(dw=4 .ds DW "Wed
|
||||
.if \n(dw=5 .ds DW "Thu
|
||||
.if \n(dw=6 .ds DW "Fri
|
||||
.if \n(dw=7 .ds DW "Sat
|
||||
.\" MO month:
|
||||
.if \n(mo=1 .ds MO "January
|
||||
.if \n(mo=2 .ds MO "February
|
||||
.if \n(mo=3 .ds MO "March
|
||||
.if \n(mo=4 .ds MO "April
|
||||
.if \n(mo=5 .ds MO "May
|
||||
.if \n(mo=6 .ds MO "June
|
||||
.if \n(mo=7 .ds MO "July
|
||||
.if \n(mo=8 .ds MO "August
|
||||
.if \n(mo=9 .ds MO "September
|
||||
.if \n(mo=10 .ds MO "October
|
||||
.if \n(mo=11 .ds MO "November
|
||||
.if \n(mo=12 .ds MO "December
|
||||
.\" make some composites:
|
||||
.ds Dy "\*(MO \n(dy
|
||||
.ds Da "\n(hh:\n(mm:\n(ss \n(mo/\n(dy/\n(yr
|
||||
.ds Yr "19\n(yr
|
||||
.ds dY "\*(Dy, \*(Yr
|
||||
.ds DY "\n(dy \*(MO \*(Yr
|
||||
.ds TM "\n(hh:\n(mm:\n(ss
|
||||
.ds DA "\*(TM \*(DY
|
||||
.ds CT "\*(DW \*(Dy \*(TM 19\n(yr
|
||||
.\"
|
||||
.\" they look like this:
|
||||
.\"
|
||||
.\" DW Sun
|
||||
.\" MO March
|
||||
.\" Dy March 4
|
||||
.\" dY March 4, 1990
|
||||
.\" DY 4 March 1990 <--- "normal" nroff form
|
||||
.\" Yr 1990
|
||||
.\" TM 16:34:00
|
||||
.\" DA 16:34:00 March 4, 1990
|
||||
.\" Da 16:34:00 2/4/90
|
||||
.\" CT Sun March 4 16:34:00 1990 almost like ctime(2)
|
||||
.\"
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.\" startup stuff...
|
||||
.\"
|
||||
.pl 66
|
||||
.ll 6.0i
|
||||
.lt 6.0i
|
||||
.m1 3
|
||||
.m2 2
|
||||
.m3 3
|
||||
.m4 3
|
||||
.\" no header line on first page! (set back in AB, SH, NH, LP, PP, QP)
|
||||
.tl ||||
|
||||
.\" this is the default footer (date, centered) unless string CF is defined
|
||||
.fo ||\*(DY||
|
||||
.\" these are for NH numbering (up to 5 levels, a la sun, X holds level)
|
||||
.nr A 0 1
|
||||
.af A 1
|
||||
.nr B 0 1
|
||||
.af B 1
|
||||
.nr C 0 1
|
||||
.af C 1
|
||||
.nr D 0 1
|
||||
.af D 1
|
||||
.nr E 0 1
|
||||
.af E 1
|
||||
.nr X 1 1
|
||||
.\"
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.\" MACROS...
|
||||
.\"
|
||||
.\" ---------------------------------------------------------------------- TL
|
||||
.\" title for document (optional)
|
||||
.\"
|
||||
.de TL
|
||||
.sp 4
|
||||
.ce 1000
|
||||
.\" reset footer. you MUST define CF, even to blank, to get the others!
|
||||
.if !"\*(CF"ImPoSsIbLe" .fo |\*(LF|\*(CF|\*(RF|
|
||||
..
|
||||
.\" ---------------------------------------------------------------------- AU
|
||||
.\" author(s) (optional, requires .TL)
|
||||
.\"
|
||||
.de AU
|
||||
.sp 2
|
||||
..
|
||||
.\" ---------------------------------------------------------------------- AI
|
||||
.\" author's institution (optional, requires .TL)
|
||||
.\"
|
||||
.de AI
|
||||
.sp 1
|
||||
..
|
||||
.\" ---------------------------------------------------------------------- AB
|
||||
.\" abstract (optional, requires .TL, .AE)
|
||||
.\"
|
||||
.de AB
|
||||
.br
|
||||
.sp 2
|
||||
.\" check for arg to AB. can be "no" or something like "SUMMARY". if "no",
|
||||
.\" no title above the abstract
|
||||
.if !"$1"no" .if "$1"" ABSTRACT
|
||||
.if !"$1"no" .if !"$1"" $1
|
||||
.if !"$1"no" .sp 1
|
||||
.\" set new line length...
|
||||
.ce 0
|
||||
.ll 5.5i
|
||||
.in 0.5i
|
||||
.tl ||- % -||
|
||||
..
|
||||
.\" ---------------------------------------------------------------------- AE
|
||||
.\" abstract end (optional, requires .TL)
|
||||
.\"
|
||||
.de AE
|
||||
.br
|
||||
.sp 1
|
||||
.\" reset...
|
||||
.ce 0
|
||||
.in 0.0i
|
||||
.ll 6.0i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- SH
|
||||
.\" section heading, no number (optional)
|
||||
.\"
|
||||
.de SH
|
||||
.\" reset...
|
||||
.ll 6.0i
|
||||
.in 0.0i
|
||||
.tl ||- % -||
|
||||
.\" see note in TL
|
||||
.if !"\*(CF"ImPoSsIbLe" .fo |\*(LF|\*(CF|\*(RF|
|
||||
.br
|
||||
.ce 0
|
||||
.sp 2
|
||||
.ne 4
|
||||
.\" section title goes here, fill mode only so far...
|
||||
..
|
||||
.\" ---------------------------------------------------------------------- NH
|
||||
.\" numbered section heading. arg (required) is the section level.
|
||||
.\" this would be MUCH simpler if the .if command supported "{...}". there is
|
||||
.\" a bug in nroff. i does not set the .$ number register correctly (number of
|
||||
.\" args for the current macro). that is the reason why level 1 must be set.
|
||||
.\"
|
||||
.de NH
|
||||
.\" do everything from SH...
|
||||
.SH
|
||||
.\" if ".NH 0", reset numbering
|
||||
.if $1=0 .nr A 1 1
|
||||
.if $1=0 .nr B 0 1
|
||||
.if $1=0 .nr C 0 1
|
||||
.if $1=0 .nr D 0 1
|
||||
.if $1=0 .nr E 0 1
|
||||
.if $1=0 .nr X 1 1
|
||||
.\" level 1 (two types here: ".NH" and ".NH 1"):
|
||||
.\" once .$ num reg is fixed, these 5 should be: .if \n(.$=0 .nr A +1 etc.
|
||||
.if "$1"" .nr A +1
|
||||
.if "$1"" .nr B 0 1
|
||||
.if "$1"" .nr C 0 1
|
||||
.if "$1"" .nr D 0 1
|
||||
.if "$1"" .nr E 0 1
|
||||
.if "$1"" .nr X 1 1
|
||||
.if "$1"1" .nr A +1
|
||||
.if "$1"1" .nr B 0 1
|
||||
.if "$1"1" .nr C 0 1
|
||||
.if "$1"1" .nr D 0 1
|
||||
.if "$1"1" .nr E 0 1
|
||||
.if "$1"1" .nr X 1 1
|
||||
.\" level 2 (increment B, reset lower levels):
|
||||
.if "$1"2" .nr B +1
|
||||
.if "$1"2" .nr C 0 1
|
||||
.if "$1"2" .nr D 0 1
|
||||
.if "$1"2" .nr E 0 1
|
||||
.if "$1"2" .nr X 2 1
|
||||
.\" level 3 (increment C, reset lower levels):
|
||||
.if "$1"3" .nr C +1
|
||||
.if "$1"3" .nr D 0 1
|
||||
.if "$1"3" .nr E 0 1
|
||||
.if "$1"3" .nr X 3 1
|
||||
.\" level 4 (increment D, reset lower levels):
|
||||
.if "$1"4" .nr D +1
|
||||
.if "$1"4" .nr E 0 1
|
||||
.if "$1"4" .nr X 4 1
|
||||
.\" level 5 (increment E, no more lower levels!):
|
||||
.if "$1"5" .nr E +1
|
||||
.if "$1"5" .nr X 5 1
|
||||
.\" print out the section number now, depending on current level...
|
||||
.if \nX=1 \nA.
|
||||
.if \nX=2 \nA.\nB.
|
||||
.if \nX=3 \nA.\nB.\nC.
|
||||
.if \nX=4 \nA.\nB.\nC.\nD.
|
||||
.if \nX=5 \nA.\nB.\nC.\nD.\nE.
|
||||
.\" section title goes here...
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- LP
|
||||
.\" start a new left block paragraph (either .LP or .PP required)
|
||||
.\"
|
||||
.de LP
|
||||
.br
|
||||
.\" reset...
|
||||
.tl ||- % -||
|
||||
.ce 0
|
||||
.sp 1
|
||||
.ll 6.0i
|
||||
.in 0.0i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- PP
|
||||
.\" start a new indented paragraph (either .LP or .PP required)
|
||||
.\"
|
||||
.de PP
|
||||
.\" do everything for LP, then make a temp indent...
|
||||
.LP
|
||||
.ti +0.5i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- XP
|
||||
.\" start a new extended paragraph (bibliography)
|
||||
.\"
|
||||
.de XP
|
||||
.br
|
||||
.\" reset...
|
||||
.tl ||- % -||
|
||||
.ce 0
|
||||
.sp 1
|
||||
.ll 6.0i
|
||||
.in 0.5i
|
||||
.ti -0.5i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- QP
|
||||
.\" start a new quoted paragraph (indented and shorter)
|
||||
.\"
|
||||
.de QP
|
||||
.br
|
||||
.tl ||- % -||
|
||||
.ce 0
|
||||
.sp 1
|
||||
.\" set new line length, indent. PP, LP, SH, and NH reset
|
||||
.ll 6.0i
|
||||
.in 0.0i
|
||||
.ll -0.5i
|
||||
.in +0.5i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- IP
|
||||
.\" indented paragraph with tag (relative)
|
||||
.\"
|
||||
.de IP
|
||||
.br
|
||||
.tl ||- % -||
|
||||
.ce 0
|
||||
.sp 1
|
||||
.if \n(.i>4 .in -0.5i
|
||||
.in +0.5i
|
||||
.}D "***DEBUG IP: indent before tag is: \n(.i"
|
||||
.}D .br
|
||||
.if !"$1"" .ti -0.5i
|
||||
.if !"$1"" \&$1
|
||||
.if !"$1"" .br
|
||||
.}D "***DEBUG IP: indent after tag is: \n(.i"
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- RS
|
||||
.\" start relative indent (requires .RE)
|
||||
.\"
|
||||
.de RS
|
||||
.ce 0
|
||||
.br
|
||||
.\" if there is arg, use that as indent, otherwise use +5
|
||||
.if \n(.$>0 .in +$1
|
||||
.if \n(.$=0 .in +0.5i
|
||||
.}D "***DEBUG RS: indent after RS is: \n(.i"
|
||||
.}D .br
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- RE
|
||||
.\" end relative indent
|
||||
.\"
|
||||
.de RE
|
||||
.ce 0
|
||||
.br
|
||||
.\" if there is arg, use that as unindent, otherwise use -5
|
||||
.if \n(.$>0 .in -$1
|
||||
.if \n(.$=0 .in -0.5i
|
||||
.if \n(.i<5 .in 0.0i
|
||||
.}D "***DEBUG RE: indent after RE is: \n(.i"
|
||||
.}D .br
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- XS
|
||||
.\" table of contents start
|
||||
.\"
|
||||
.de XS
|
||||
.bp
|
||||
.ce 1
|
||||
Table of Contents
|
||||
.ce 0
|
||||
.ll 8.0i
|
||||
.sp 1
|
||||
.\" \&123456789012345678901234567890123456789012345678901234567890
|
||||
\&NOTE: add/del "dots" until line ends here ---------------->| (del this line)
|
||||
.br
|
||||
.\" save the page number...
|
||||
.ds Xx "$1
|
||||
.\" first entry goes here...
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- XE
|
||||
.\" table of contents end
|
||||
.\"
|
||||
.de XE
|
||||
.\" dump last page number...
|
||||
\&\0........................... \*(Xx
|
||||
.br
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- XA
|
||||
.\" subsequent table of contents entry
|
||||
.\"
|
||||
.de XA
|
||||
.\" dump last page number...
|
||||
\&\0........................... \*(Xx
|
||||
.br
|
||||
.\" save next page number...
|
||||
.ds Xx "$1
|
||||
.\" next entry goes here...
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- PX
|
||||
.\" print table of contents
|
||||
.\"
|
||||
.de PX
|
||||
.\" this is a NOP without diversions...
|
||||
.ll 6.0i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- TI
|
||||
.\" temporary indent
|
||||
.\"
|
||||
.de TI
|
||||
.ce 0
|
||||
.ti +0.5i
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- EX
|
||||
.\" exit NOW! (no extra space at end of document)
|
||||
.\"
|
||||
.de EX
|
||||
.sp
|
||||
.ex
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- I
|
||||
.\" italic text
|
||||
.\"
|
||||
.de I
|
||||
\&\fI
|
||||
.if !"$1"" $1\fR$2
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- B
|
||||
.\" bold text
|
||||
.\"
|
||||
.de B
|
||||
\&\fB
|
||||
.if !"$1"" $1\fR$2
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- R
|
||||
.\" Roman (normal) text
|
||||
.\"
|
||||
.de R
|
||||
\&\fR
|
||||
..
|
||||
.\" ----------------------------------------------------------------------- }D
|
||||
.\" debug. use (e.g. print current indent):
|
||||
.\"
|
||||
.\" .}D .br
|
||||
.\" .}D "** DEBUG ** before RS \n(.i"
|
||||
.\"
|
||||
.de }D
|
||||
.if \nZ>0 \&$1
|
||||
..
|
|
@ -0,0 +1,167 @@
|
|||
/*-
|
||||
* Copyright (c) 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)err.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "err.h"
|
||||
|
||||
#if 0
|
||||
extern char *__progname; /* Program name, from crt0. */
|
||||
#else
|
||||
static char *__progname = "nroff";
|
||||
#endif
|
||||
|
||||
static FILE *err_file; /* file to use for error output */
|
||||
static void (*err_exit)(int);
|
||||
|
||||
extern void iic_error(int, const char *, ...);
|
||||
|
||||
void
|
||||
err_set_file(void *fp)
|
||||
{
|
||||
if (fp)
|
||||
err_file = fp;
|
||||
else
|
||||
err_file = stderr;
|
||||
}
|
||||
|
||||
void
|
||||
err_set_exit(void (*ef)(int))
|
||||
{
|
||||
err_exit = ef;
|
||||
}
|
||||
|
||||
void
|
||||
err(int eval, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verr(eval, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
verr(int eval, const char *fmt, va_list ap)
|
||||
{
|
||||
int sverrno;
|
||||
|
||||
sverrno = errno;
|
||||
if (! err_file)
|
||||
err_set_file((FILE *)0);
|
||||
(void)fprintf(err_file, "%s: ", __progname);
|
||||
if (fmt != NULL) {
|
||||
(void)vfprintf(err_file, fmt, ap);
|
||||
(void)fprintf(err_file, ": ");
|
||||
}
|
||||
(void)fprintf(err_file, "%s\n", strerror(sverrno));
|
||||
if(err_exit)
|
||||
err_exit(eval);
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
void
|
||||
errx(int eval, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
verrx(eval, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
verrx(int eval, const char *fmt, va_list ap)
|
||||
{
|
||||
if (! err_file)
|
||||
err_set_file((FILE *)0);
|
||||
(void)fprintf(err_file, "%s: ", __progname);
|
||||
if (fmt != NULL)
|
||||
(void)vfprintf(err_file, fmt, ap);
|
||||
(void)fprintf(err_file, "\n");
|
||||
if (err_exit)
|
||||
err_exit(eval);
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
void
|
||||
warn(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarn(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
vwarn(const char *fmt, va_list ap)
|
||||
{
|
||||
int sverrno;
|
||||
|
||||
sverrno = errno;
|
||||
if (! err_file)
|
||||
err_set_file((FILE *)0);
|
||||
(void)fprintf(err_file, "%s: ", __progname);
|
||||
if (fmt != NULL) {
|
||||
(void)vfprintf(err_file, fmt, ap);
|
||||
(void)fprintf(err_file, ": ");
|
||||
}
|
||||
(void)fprintf(err_file, "%s\n", strerror(sverrno));
|
||||
}
|
||||
|
||||
void
|
||||
warnx(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vwarnx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
vwarnx(const char *fmt, va_list ap)
|
||||
{
|
||||
if (! err_file)
|
||||
err_set_file((FILE *)0);
|
||||
(void)fprintf(err_file, "%s: ", __progname);
|
||||
if (fmt != NULL)
|
||||
(void)vfprintf(err_file, fmt, ap);
|
||||
(void)fprintf(err_file, "\n");
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
void err_set_file(void *fp);
|
||||
void err_set_exit(void (*ef)(int));
|
||||
void err(int eval, const char *fmt, ...);
|
||||
void verr(int eval, const char *fmt, va_list ap);
|
||||
void errx(int eval, const char *fmt, ...);
|
||||
void verrx(int eval, const char *fmt, va_list ap);
|
||||
void warn(const char *fmt, ...);
|
||||
void vwarn(const char *fmt, va_list ap);
|
||||
void warnx(const char *fmt, ...);
|
||||
void vwarnx(const char *fmt, va_list ap);
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* This is an interface file for use with Insight.
|
||||
*
|
||||
* $Id: int.c,v 1.1 1997/03/14 06:22:27 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "err.h"
|
||||
|
||||
void
|
||||
verr(int eval, const char *fmt, va_list ap)
|
||||
{
|
||||
iic_error(USER_ERROR, "verr traceback");
|
||||
verr(eval, fmt, ap);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
verrx(int eval, const char *fmt, va_list ap)
|
||||
{
|
||||
iic_error(USER_ERROR, "verrx traceback");
|
||||
verrx(eval, fmt, ap);
|
||||
}
|
||||
|
||||
void
|
||||
vwarn(const char *fmt, va_list ap)
|
||||
{
|
||||
iic_error(USER_ERROR, "dummy traceback");
|
||||
vwarn(fmt, ap);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vwarnx(const char *fmt, va_list ap)
|
||||
{
|
||||
iic_error(USER_ERROR, "dummy traceback");
|
||||
vwarnx(fmt, ap);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifdef SUNOS4
|
||||
|
||||
#ifdef FILE
|
||||
int _filbuf(FILE *);
|
||||
int _flsbuf(unsigned char, FILE *);
|
||||
int fclose (FILE *);
|
||||
int fflush (FILE *);
|
||||
int fprintf(FILE *, const char *, ...);
|
||||
#endif
|
||||
|
||||
#ifdef ITIMER_REAL
|
||||
time_t time (time_t *);
|
||||
#endif
|
||||
|
||||
int printf(const char *, ...);
|
||||
int tolower (int);
|
||||
|
||||
#endif /* SUNOS4 */
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
extern char PC, *BC, *UP;
|
||||
extern short ospeed;
|
||||
|
||||
int tgetent (char *bp, char *name);
|
||||
int tgetnum (char *id);
|
||||
int tgetflag (char *id);
|
||||
char * tgetstr (char *id, char **area);
|
||||
char * tgoto (char *cm, int destcol, int destline);
|
||||
int tputs (char *cp, int affcnt, int (*outc)(char));
|
Loading…
Reference in New Issue