add directory study

This commit is contained in:
gohigh
2024-02-19 00:25:23 -05:00
parent b1306b38b1
commit f3774e2f8c
4001 changed files with 2285787 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
# Makefile for nroff
CFLAGS=-D_MINIX -D_POSIX_SOURCE -F
OBJS = main.s command.s text.s io.s macros.s strings.s escape.s low.s
nroff: $(OBJS) nroff.h
cc -i -o nroff $(OBJS)
clean:
@rm -f *.bak *.s nroff

View File

@@ -0,0 +1,52 @@
-----------------------------------------
nroff (TOS, Minix) v0.99 BETA 2/26/90 wjr
-----------------------------------------
This is an improved release of a version of nroff for both Minix and the
atariST. It was written under TOS and 4BSD unix but should port easily to
Minix ST as well. Unfortunately I have no access to Minix (hopefully
someone did test this before sending it out...ast?).
Much of this works. The things that (still) don't are all the hard things:
diversions, traps, conditionals, etc. See the man pages for what is not
supported (yet). Font switching, underlining, etc. are limited to reverse
video on the screen, though stdout will contain underlines as "_^H" for
printers.
There is a crude man package included (tmac.an) which is still not right
but is better and needs diversions to become right. It should handle most
common man tasks, though. It gets installed in /usr/lib/tmac under Minix
unless you change the location in nroff.h. For testing, you can
% setenv TMACDIR .
% nroff -man file
to use tmac.an (say) in the cwd.
For porting info, look in nroff.h and the makefile. The termcap library
is used to get standout capabilites for doing bold and italics to the
screen. Minix and BSD have termcap(3) and S5R3 has terminfo, which I
believe also includes the tgetent/tgetnum/tgetflag/tgetstr functions for
compatibility.
If you want to try and use nroff for printer output, the termcap library
looks for TERMCAP in your environment (a file) so that you could do:
% env TERMCAP=printfile nroff -man file
and substitute your own file with so (standout) for your printer. This
assumes your system has env, but you get the idea.
The program is small enough to work under Minix. It does not have a large
stack, but does store all macros and strings in a common namespace. Look
in nroff.h for the size.
If you do hack away, I would appreciate you sending me the changes
so I can keep this centralized.
The future holds increased capabilites, though I find it pretty useful
as it is. Most man things are possible and you can do reports and resumes
and such without much problem. See the example files included (ex[12].nr).
-Bill Rosenkranz
rosenkra@hall.cray.com

View File

@@ -0,0 +1,75 @@
/* nroff/config.h
* Adapted for compatibility with Minix 1.5.5 nroff/Makefile
* by Wim 'Blue Baron' van Dorst (wsincc@tuerc3.urc.tue.nl)
*/
#ifndef CONFIG_H
#define CONFIG_H
/*
* for different 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 -DatariST ... (ST minix)
* cc -D_MINIX ... (PC minix)
*
* for unix, do: cc -Dunix ... (generic)
* cc -Dunix -DBSD... (BSD)
*
* 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.
*/
#ifdef ALCYON
# ifndef tos
# define tos
# 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
# define register
# ifdef atariST
# define MINIX_ST
# else
# define MINIX_PC
# endif
#endif
#ifdef unix
# define register
# undef tos
# undef minix
# undef GEMDOS
# undef MINIX_ST
# undef MINIX_PC
# ifndef UNIX
# define UNIX
# endif
#endif
#endif /*CONFIG_H*/

View File

@@ -0,0 +1,96 @@
.\" example 1. execute with: nroff ex1.nr
.\"
.\" we first set up basic page parameters (left offset, line length,
.\" title length, and where titles and footers go. we define a macro
.\" to handle paragraphs. it just breaks the last line (.sp does this),
.\" spaces down 2 lines, and temprarily indents the next line (.ti).
.\" the .ti has a "+" so this means add to the current indent. then
.\" we center the title and redefine the page header after the first
.\" line of text to keep the page header off the first page. invoke
.\" the paragraph macro (.IP) at every paragraph.
.\"
.pl 66 \" page length (lines)
.po 5 \" page offset (left margin)
.ll 65 \" line length
.lt 65 \" title length
.m1 3 \" lines from page top to header
.m2 3 \" lines from header to text
.m3 3 \" lines from text to footer
.m4 3 \" lines from footer to page botton
.fo ||- % -|| \" page footer (just page number)
.de IP \" define a macro
.sp 2 \" 2 spaces
.ti +5 \" indent next line 5 spaces
.. \" end macro
.ce 6 \" center next 6 lines
NROFF Report Formatting
by
Bill Rosenkranz
rosenkra@hall.cray.com
.\"
.\"
.tl ||NROFF Report Formatting|| \" page header (centered)
.IP \" invoke our macro
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.
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.
.IP
Nroff recognizes the following environment variables from the shell.
.IP
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
An alternate directory to place any temporary files.
The default is the current directory.
.IP
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
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:
.ne 7 \" need 7 lines without a break
.nf \" nofill for the table
Indicator Type
l adjust left margin only
r adjust right margin only
c center
b or n adjust both margins (default)
absent unchanged
.fi \" back to fill mode
.IP
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
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.
.\"
.\" the end...

View File

@@ -0,0 +1,83 @@
.\" example 2. execute with: nroff ex2.nr
.\"
.\" this is set up similar to ex1 except we show how to use number
.\" registers for section numbers. sections will be: I.00, I.01,...,
.\" II.00, II.01,... etc. the advantage is that you can add/remove
.\" sections without keeping track of the numbers. try it...
.\"
.pl 66 \" page length (lines)
.po 5 \" page offset (left margin)
.ll 60 \" line length
.lt 60 \" title length
.m1 3 \" lines from page top to header
.m2 3 \" lines from header to text
.m3 3 \" lines from text to footer
.m4 3 \" lines from footer to page botton
.tl |Using Number Registers For Sections|||
.fo |||Page %| \" page footer (just page number)
.in 5 \" basic text indent (not header or major)
.nr A 0 1 \" define reg A for major number
.af A I \" it will be upcase roman numerals
.nr B 0 1 \" define reg B for minor number
.af B 01 \" it will be 2 dig number (leading 0)
.\"
.\" start a major section. increase major number, reset minor number.
.\" first (and only) arg is the section name (text). we force a negative
.\" indent (temporary) back to the po for this title. make sure to quote
.\" multi-word titles...
.\"
.de MA
.nr A +1
.nr B 0 1
.sp 2
.ne 4
.ti -5
.\" print section title
\nA. $1
.sp 1
..
.\"
.\" start minor section. similar to MA except just increase minor number.
.\"
.de MI
.nr B +1
.sp 2
.ne 4
.\" print section title
\nA.\nB $1
.sp 1
..
.\"
.\"
.\" start text...
.\"
.MA "Major Section"
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
.MI "Minor Section"
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
.MI "Minor Section"
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
.MI "Minor Section"
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
.MA "Major Section"
.MI "Minor Section"
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
.MI "Minor Section"
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.
.MA "Major Section"
Blah blah blah blah blah blah blah blah blah blah.
Blah blah blah blah blah blah blah blah blah blah.

View File

@@ -0,0 +1,272 @@
/*
* 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
*/
#undef NRO_MAIN /* extern globals */
#include <stdio.h>
#include "nroff.h"
/*------------------------------*/
/* getlin */
/*------------------------------*/
getlin (p, in_buf)
char *p;
FILE *in_buf;
{
/*
* retrieve one line of input text
*/
register char *q;
register int i;
int c;
int nreg;
q = p;
for (i = 0; i < MAXLINE - 1; ++i)
{
c = ngetc (in_buf);
if (c == EOF)
{
*q = EOS;
c = strlen (p);
return (c == 0 ? EOF : c);
}
*q++ = c;
if (c == '\n')
break;
}
*q = EOS;
nreg = findreg (".c");
if (nreg > 0)
set_ireg (".c", rg[nreg].rval + 1, 0);
return (strlen (p));
}
/*------------------------------*/
/* ngetc */
/*------------------------------*/
ngetc (infp)
FILE *infp;
{
/*
* get character from input file or push back buffer
*/
register int c;
if (mac.ppb >= &mac.pbb[0])
c = *mac.ppb--;
else
c = getc (infp);
return (c);
}
/*------------------------------*/
/* pbstr */
/*------------------------------*/
pbstr (p)
char *p;
{
/*
* Push back string into input stream
*/
register int i;
/*
* if string is null, we do nothing
*/
if (p == NULL_CPTR)
return;
if (p[0] == EOS)
return;
for (i = strlen (p) - 1; i >= 0; --i)
{
putbak (p[i]);
}
}
/*------------------------------*/
/* putbak */
/*------------------------------*/
putbak (c)
char c;
{
/*
* Push character back into input stream. we use the push-back buffer
* stored with macros.
*/
if (mac.ppb < &(mac.pbb[0]))
{
mac.ppb = &(mac.pbb[0]);
*mac.ppb = c;
}
else
{
if (mac.ppb >= &mac.pbb[MAXLINE - 1])
{
fprintf (err_stream,
"***%s: push back buffer overflow\n", myname);
err_exit (-1);
}
*++(mac.ppb) = c;
}
}
/*------------------------------*/
/* prchar */
/*------------------------------*/
prchar (c, fp)
char c;
FILE *fp;
{
/*
* print character with test for printer
*/
if (fp == stdout)
putc (c, fp);
else
putc_lpr (c, fp);
}
/*------------------------------*/
/* put */
/*------------------------------*/
put (p)
char *p;
{
/*
* put out line with proper spacing and indenting
*/
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)
prchar (' ', out_stream);
for (j = 0; j < dc.tival; ++j)
prchar (' ', out_stream);
putlin (os, out_stream);
}
}
for (j = 0; j < pg.offset; ++j)
prchar (' ', out_stream);
for (j = 0; j < dc.tival; ++j)
prchar (' ', 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 ();
if (stepping)
wait_for_char ();
}
}
/*------------------------------*/
/* putlin */
/*------------------------------*/
putlin (p, pbuf)
register char *p;
FILE *pbuf;
{
/*
* output a null terminated string to the file
* specified by pbuf.
*/
while (*p != EOS)
prchar (*p++, pbuf);
}
/*------------------------------*/
/* putc_lpr */
/*------------------------------*/
#ifdef GEMDOS
#include <osbind.h>
#endif
putc_lpr (c, fp)
char c;
FILE *fp;
{
/*
* write char to printer
*/
#ifdef GEMDOS
Bconout (0, (int) c & 0x00FF);
#else
putc (c, fp);
#endif
}

View File

@@ -0,0 +1,876 @@
/*
* 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
* - Adapted to have it recognize also VT100 escape codes (e.g. ESC[7m)
* by Wim 'Blue Baron' van Dorst (wsincc@tuerc3.urc.tue.nl)
*/
#undef NRO_MAIN /* extern globals */
#include <stdio.h>
#include "nroff.h"
/*------------------------------*/
/* atod */
/*------------------------------*/
atod (c)
char c;
{
/*
* convert ascii character to decimal.
*/
return (((c < '0') || (c > '9')) ? -1 : c - '0');
}
/*------------------------------*/
/* robrk */
/*------------------------------*/
robrk ()
{
/*
* end current filled line
*/
if (co.outp > 0)
{
#ifdef GEMDOS
co.outbuf[co.outp] = '\r';
co.outbuf[co.outp+1] = '\n';
co.outbuf[co.outp+2] = EOS;
#else
co.outbuf[co.outp] = '\n';
co.outbuf[co.outp+1] = EOS;
co.outbuf[co.outp+2] = EOS;
#endif
put (co.outbuf);
}
co.outp = 0;
co.outw = 0;
co.outwds = 0;
co.outesc = 0;
}
/*------------------------------*/
/* ctod */
/*------------------------------*/
ctod (p)
register char *p;
{
/*
* convert string to decimal.
* processes only positive values.
*/
register int val;
register int d;
val = 0;
while (*p != EOS)
{
d = atod (*p);
p++;
if (d == -1)
return (val);
val = 10 * val + d;
}
return (val);
}
/*------------------------------*/
/* inptobu */
/*------------------------------*/
inptobu (ps)
char *ps;
{
/*
* convert input units to b.u.
*/
return;
}
/*------------------------------*/
/* butochar */
/*------------------------------*/
butochar (ps)
char *ps;
{
/*
* convert b.u. to char spaces
*/
return;
}
/*------------------------------*/
/* skipbl */
/*------------------------------*/
char *skipbl (p)
register char *p;
{
/*
* 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.
* also increments the arg ptr (side effect).
*/
while ((*p != EOS) && (*p == ' ' || *p == '\t'))
++p;
return (p);
}
/*------------------------------*/
/* skipwd */
/*------------------------------*/
char *skipwd (p)
register char *p;
{
/*
* skip over word and punctuation. anything but space,\t,\r,\n, and EOS
* is skipped. return ptr to the first of these found. also increments
* the arg ptr (side effect).
*/
while (*p != ' ' && *p != '\t' && *p != '\r' && *p != '\n' && *p != EOS)
++p;
return (p);
}
/*------------------------------*/
/* space */
/*------------------------------*/
space (n)
int n;
{
/*
* space vertically n lines. this does header and footer also.
*/
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 */
/*------------------------------*/
char *getfield (p, q, delim)
register char *p;
register char *q;
char delim;
{
/*
* get field from title
*/
while (*p != delim && *p != '\r' && *p != '\n' && *p != EOS)
{
*q++ = *p++;
}
*q = EOS;
if (*p == delim)
++p;
return (p);
}
/*------------------------------*/
/* getwrd */
/*------------------------------*/
getwrd (p0, p1)
register char *p0;
register char *p1;
{
/*
* get non-blank word from p0 into p1.
* return number of characters processed.
*/
register int i;
register char *p;
char c;
/*
* init counter...
*/
i = 0;
/*
* skip leading whitespace
*/
while (*p0 && (*p0 == ' ' || *p0 == '\t'))
{
++i;
++p0;
}
/*
* set ptr and start to look for end of word
*/
p = p0;
while (*p0 != ' ' && *p0 != EOS && *p0 != '\t')
{
if (*p0 == '\n' || *p0 == '\r')
break;
*p1 = *p0++;
++p1;
++i;
}
c = *(p1 - 1);
if (c == '"')
c = *(p1 - 2);
if (c == '?' || c == '!')
{
*p1++ = ' ';
++i;
}
if (c == '.' && (*p0 == '\n' || *p0 == '\r' || islower (*p)))
{
*p1++ = ' ';
++i;
}
*p1 = EOS;
return (i);
}
/*------------------------------*/
/* countesc */
/*------------------------------*/
#define ESC 27
countesc (p)
register char *p;
{
/*
* count escape sequence characters in given null-terminated
* string
*/
register char *pp;
register int num;
pp = p;
num = 0;
while (*pp != EOS)
{
if (*pp == ESC)
{
/*
* count escape char (vt52 and vt100)
*/
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 */
/*------------------------------*/
itoda (value, p, size)
int value;
register char *p;
register int size;
{
/*
* convert integer to decimal ascii string
*/
register int i;
register int j;
register int k;
register int 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);
}
/*------------------------------*/
/* itoROMAN */
/*------------------------------*/
itoROMAN (value, p, size)
int value;
register char *p;
register int size;
{
/*
* convert integer to upper roman. must be positive
*/
register int i;
register int j;
register int k;
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 */
/*------------------------------*/
itoroman (value, p, size)
int value;
char *p;
int size;
{
/*
* convert integer to lower roman
*/
register int i;
register int len;
register int aval;
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 */
/*------------------------------*/
itoLETTER (value, p, size)
int value;
register char *p;
register int size;
{
/*
* convert integer to upper letter value: 0,A,B,C,...,AA,AB,AC,...
*/
register int i;
register int j;
register int k;
register int aval;
int rem;
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 */
/*------------------------------*/
itoletter (value, p, size)
int value;
register char *p;
register int size;
{
/*
* convert integer to upper letter value: 0,a,b,c,...,aa,ab,ac,...
*/
register int i;
register int j;
register int k;
register int aval;
char c[20];
int rem;
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);
}
/*------------------------------*/
/* min */
/*------------------------------*/
#ifdef min
#undef min
#endif
min (v1, v2)
register int v1;
register int v2;
{
/*
* find minimum of two integer ONLY
*/
return ((v1 < v2) ? v1 : v2);
}
/*------------------------------*/
/* max */
/*------------------------------*/
#ifdef max
#undef max
#endif
max (v1, v2)
register int v1;
register int v2;
{
/*
* find maximum of two integers ONLY
*/
return ((v1 > v2) ? v1 : v2);
}
/*------------------------------*/
/* err_exit */
/*------------------------------*/
err_exit (code)
{
/*
* exit cleanly on fatal error (close files, etc). also handles normal
* exit.
*/
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);
}
if (hold_screen)
{
wait_for_char ();
}
exit (code);
}
/*------------------------------*/
/* wait_for_char */
/*------------------------------*/
#ifdef GEMDOS
#include <osbind.h>
#endif
wait_for_char ()
{
#ifdef GEMDOS
printf ("enter any key..."); fflush (stdout);
Cconin ();
#endif
}

View File

@@ -0,0 +1,517 @@
/*
* 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
* - Changed array index i from type long to type int (32000 is the
* largest value anyhow) to prevent compiler warnings
* by Wim 'Blue Baron' van Dorst (wsincc@tuerc3.urc.tue.nl)
*/
#undef NRO_MAIN /* extern globals */
#include <stdio.h>
#include "nroff.h"
/*------------------------------*/
/* defmac */
/*------------------------------*/
defmac (p, infp)
register char *p;
FILE *infp;
{
/*
* 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...
*/
register char *q;
register int i;
char name[MNLEN];
char defn[MXMLEN];
char newend[10];
/*
* skip the .de and get to the name...
*/
q = skipwd (p);
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 (!isprint (*name))
{
fprintf (err_stream,
"***%s: missing or illegal macro definition name\n",
myname);
err_exit (-1);
}
/*
* 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 (p);
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 (p, infp) != EOF)
{
if (p[0] == dc.cmdchr && newend[0] != EOS
&& p[1] == newend[0] && p[2] == newend[1])
{
/*
* replacement end found
*/
break;
}
if (p[0] == dc.cmdchr && p[1] == 'e' && p[2] == 'n')
{
/*
* .en found
*/
break;
}
if (p[0] == dc.cmdchr && p[1] == dc.cmdchr)
{
/*
* .. found
*/
break;
}
/*
* collect macro from the line we just read. all this does
* is put it in the string defn.
*/
if ((i = colmac (p, defn, i)) == ERR)
{
fprintf (err_stream,
"***%s: macro definition too long\n", myname);
err_exit (-1);
}
}
/*
* store the macro
*/
if (!ignoring)
{
if (putmac (name, defn) == ERR)
{
fprintf (err_stream,
"***%s: macro definition table full\n", myname);
err_exit (-1);
}
}
}
/*------------------------------*/
/* colmac */
/*------------------------------*/
colmac (p, d, i)
register char *p;
char *d;
register int i;
{
/*
* Collect macro definition from input stream
*/
while (*p != EOS)
{
if (i >= MXMLEN - 1)
{
d[i - 1] = EOS;
return (ERR);
}
d[i++] = *p++;
}
d[i] = EOS;
return (i);
}
/*------------------------------*/
/* putmac */
/*------------------------------*/
putmac (name, p)
char *name;
char *p;
{
/*
* Put macro definition into table
*
* NOTE: any expansions of things like number registers SHOULD
* have been done already.
*/
/*
* 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).
*
* 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 */
/*------------------------------*/
char *getmac (name)
register char *name;
{
/*
* Get (lookup) macro definition from namespace
*/
register 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]))
{
/*!!!debug puts (mac.mnames[i]);*/
if (mac.mnames[i][1] == EOS)
return (mac.mnames[i] + 2);
else
return (mac.mnames[i] + 3);
}
}
}
/*
* none found, return null
*/
return (NULL_CPTR);
}
/*------------------------------*/
/* maceval */
/*------------------------------*/
maceval (p, m)
register char *p;
char *m;
{
/*
* Evaluate macro expansion
*/
register int i;
register int j;
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...
*/
/* for (i = 0; i < 10; ++i)
argp[i] = p;
*/
/*
* 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)
{
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 */
/*------------------------------*/
printmac (opt)
int opt; /* 0=name&size,1=total size,2=full */
{
/*
* print all macros and strings and tabulate sizes
*/
register int i;
register long space;
register long totalspace;
register char *pname;
register char *pdef;
space = 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;
space = (long) strlen (pdef);
totalspace += space;
switch (opt)
{
case 0:
fprintf (err_stream, "%s %ld\n", pname, space);
break;
case 2:
fprintf (err_stream, "%s %ld\n", pname, space);
fprintf (err_stream, "%s\n", pdef);
break;
case 1:
default:
break;
}
}
}
fprintf (err_stream, "Total space: %ld\n", totalspace);
}

View File

@@ -0,0 +1,247 @@
.\" man(7) manpage by rosenkra@hall.cray.com (Bill Rosenkranz)
.\"
.TH MAN 7 "Misc. Stuff" "Version 0.99" "February 26, 1990"
.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).
.SH FILES
/usr/lib/tmac/tmac.an
.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 5. 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 5.
.RE yes End of relative indent. Set prevailing
indent to amount of starting .RS.
.RS yes Start relative indent, move left margin
in distance 5.
.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 5.
+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:
.nf
.cc +
.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.
.SH NAME
name - one-line summary
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 sec-
tion contains no troff(1) commands or escapes, and no
macro requests. It is used to generate the whatis(1)
database.
.SH SYNOPSIS
Commands:
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:
[ ] An argument, when surrounded by brackets is
optional.
| Arguments separated by a vertical bar are
exclusive. You can supply only item from
such a list.
... Arguments followed by an elipsis can be
repeated. When an elipsis follows a brack-
eted set, the expression within the brackets
can be repeated.
Functions:
If required, the data declaration, or #include
directive, is shown first, followed by the func-
tion declaration. Otherwise, the function declara-
tion is shown.
.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.
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.
.SH OPTIONS
The list of options along with a description of how
each affects the commands operation.
.SH FILES
A list of files associated with the command or func-
tion.
.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.
.SH DIAGNOSTICS
A list of diagnostic messages and an explanation of
each.
.SH NOTES
Any additional notes such as installation-dependent
functionality.
.SH BUGS
A description of limitations, known defects, and possi-
ble problems associated with the command or function.
.SH AUTHOR
The program's author and any pertinent release info.
.SH VERSION
The program's current version number and release date.
+cc .
.fi

View File

@@ -0,0 +1,580 @@
#ifndef NRO_H
#define NRO_H
#include "config.h" /* os/compiler options */
/*
* 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>
#ifdef _MINIX
# ifdef tolower
# undef tolower
# endif
# define tolower(x) (isupper(x)?((x)-'A'+'a'):(x))
#endif
#ifdef UNIX
# ifdef tolower
# undef tolower
# endif
# define tolower(x) (isupper(x)?((x)-'A'+'a'):(x))
#endif
/*
* 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.
*/
#define MAXLINE 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
/*
* 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 /* macro definition buffer size */
#define MXMLEN 250 /* max length of each macro definition */
#define MNLEN 10 /* max length of macro name */
#define MAXREGS 100 /* max number of registers (2-char) */
struct macros
{
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[MAXLINE]; /* 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 = '\'' */
};
/*
* output buffer control parameters
*/
struct cout
{
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 */
};
/*
* 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 libc
*/
char *getenv ();
char *ctime ();
long time ();
#ifdef UNIX
char *tgetstr (); /* from termcap/terminfo */
#endif
#ifdef MINIX_ST
char *tgetstr ();
#endif
#ifdef MINIX_PC
char *tgetstr ();
#endif
/*
* forward refs from nroff
*/
char *getmac ();
char *getstr ();
char *skipwd ();
char *skipbl ();
char *getfield ();
int comand ();
int comtyp ();
int gettl ();
int getval ();
int set ();
int expesc ();
int specialchar ();
int fontchange ();
int getlin ();
int ngetc ();
int pbstr ();
int putbak ();
int prchar ();
int put ();
int putlin ();
int atod ();
int robrk ();
int ctod ();
int space ();
int getwrd ();
int countesc ();
int itoda ();
int itoROMAN ();
int itoroman ();
int itoLETTER ();
int itoletter ();
int min ();
int max ();
int defmac ();
int colmac ();
int putmac ();
int maceval ();
int main ();
int usage ();
int init ();
int pswitch ();
int profile ();
int text ();
int bold ();
int center ();
int expand ();
int justcntr ();
int justleft ();
int justrite ();
int leadbl ();
int pfoot ();
int phead ();
int puttl ();
int putwrd ();
int skip ();
int spread ();
int strkovr ();
int underl ();
int width ();
int inptobu (); /* convert input units to b.u. */
int butochar (); /* convert b.u. to char spaces */
int findreg ();
int set_ireg ();
/*
* globals. define NRO_MAIN in main.c to define globals there. else
* you get extern.
*/
#ifdef NRO_MAIN
struct docctl dc;
struct page pg;
struct cout co;
struct macros 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 */
char tmpdir[256];
char termcap[1030];
char s_standout[20];
char e_standout[20];
char s_italic[20];
char e_italic[20];
char s_bold[20];
char e_bold[20];
char *dbgfile = "nroff.dbg";
#ifdef GEMDOS
char *printer = "prn:"; /* this WON'T work!!! */
#else
char *printer = "/dev/lp"; /* this probably won't */
#endif
#include "version.h" /* for myname and version */
#ifdef ALCYON
/*
* this SHOULD be big enough for most needs. only used by startup
* code (gemstart.o or crt0.o)
*/
long _STKSIZ = 16384L;
#endif
#else /*NRO_MAIN*/
extern struct docctl dc;
extern struct page pg;
extern struct cout co;
extern struct macros mac;
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 char tmpdir[];
extern char termcap[];
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;
extern char *myname;
extern char *version;
#endif /*NRO_MAIN*/
#endif /*NRO_H*/

View File

@@ -0,0 +1,273 @@
/*
* 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
*/
#undef NRO_MAIN /* extern globals */
#include <stdio.h>
#include "nroff.h"
/*------------------------------*/
/* defstr */
/*------------------------------*/
defstr (p)
register char *p;
{
/*
* 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...
*/
register char *q;
register int i;
char name[MNLEN];
char defn[MXMLEN];
name[0] = '\0';
defn[0] = '\0';
/*
* skip the .ds and get to the name...
*/
q = skipwd (p);
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])
{
fprintf (err_stream,
"***%s: missing or illegal string definition name\n",
myname);
err_exit (-1);
}
/*
* 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)) == ERR)
{
fprintf (err_stream,
"***%s: string definition too long\n", myname);
err_exit (-1);
}
/*
* store the string
*/
if (putstr (name, defn) == ERR)
{
fprintf (err_stream,
"***%s: string definition table full\n", myname);
err_exit (-1);
}
}
/*------------------------------*/
/* colstr */
/*------------------------------*/
colstr (p, d)
register char *p;
char *d;
{
/*
* Collect string definition from input stream
*/
register int i = 0;
if (*p == '\"')
p++;
while (*p != EOS)
{
if (i >= MXMLEN - 1)
{
d[i - 1] = EOS;
return (ERR);
}
d[i++] = *p++;
}
d[i] = EOS;
return (i);
}
/*------------------------------*/
/* putstr */
/*------------------------------*/
putstr (name, p)
register char *name;
register char *p;
{
/*
* 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
*/
/*
* 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 */
/*------------------------------*/
char *getstr (name)
register char *name;
{
/*
* Get (lookup) string definition from namespace
*/
register 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]))
{
/*!!!debug puts (mac.mnames[i]);*/
if (mac.mnames[i][1] == EOS)
return (mac.mnames[i] + 2);
else
return (mac.mnames[i] + 3);
}
}
}
/*
* none found, return null
*/
return (NULL_CPTR);
}

View File

@@ -0,0 +1,42 @@
.TH TEST 0 "Test Suite" "Today's Date:" "\*(DA"
.SH NAME
test - test for nroff(1) man package
.SH SYNOPSIS
.nf
nroff -man test.1
or
make test
.fi
.SH DESCRIPTION
You should get a manpage-like output from this test.
The last word in this sentence should be
.I italic.
The last word in this sentence should be
.B BOLD.
They may be printed in standout mode (i.e. reverse video).
That's ok.
If they appear normal, check the termcap file (if Unix or minix)
which is /etc/termcap.
It should have an entry for "so" which may look like this: \\E[7m.
.PP
For more tests, try and print the man pages ("man.man" and "nroff.man")
by doing:
.nf
% nroff -man man.man
% nroff -man nroff.man
.fi
You might also what to test the example files ("ex1.nr" and "ex2.nr")
by doing:
.nf
% nroff ex1.nr
% nroff ex2.nr
.fi
.SH FILES
.nf
test.0, ex1.nr, ex2.nr test/example files

View File

@@ -0,0 +1,783 @@
/*
* 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
* - Adapted the justification of lines with escape codes
* by Wim 'Blue Baron' van Dorst (wsincc@tuerc3.urc.tue.nl)
*/
#undef NRO_MAIN /* extern globals */
#include <stdio.h>
#include "nroff.h"
/*------------------------------*/
/* text */
/*------------------------------*/
text (p)
register char *p;
{
/*
* main text processing
*/
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 (*p == ' ' || *p == '\n' || *p == '\r')
leadbl (p);
}
else
robrk ();
/*
* expand escape sequences
*/
expesc (p, wrdbuf);
/*
* 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 (p, wrdbuf, MAXLINE);
--dc.ulval;
}
if (dc.cuval > 0)
{
/*
* continuous underline (.cu)
*/
underl (p, wrdbuf, MAXLINE);
--dc.cuval;
}
if (dc.boval > 0)
{
/*
* bold (.bo)
*/
bold (p, wrdbuf, MAXLINE);
--dc.boval;
}
if (dc.ceval > 0)
{
/*
* centered (.ce)
*/
center (p);
put (p);
--dc.ceval;
}
else if ((*p == '\r' || *p == '\n') && dc.fill == NO)
{
/*
* all blank line
*/
put (p);
}
else if (dc.fill == NO)
{
/*
* unfilled (.nf)
*/
put (p);
}
else
{
/*
* anything else...
*/
/*
* get a word and put it out. increment ptr to the next
* word.
*/
while ((i = getwrd (p, wrdbuf)) > 0)
{
putwrd (wrdbuf);
p += i;
}
}
}
/*------------------------------*/
/* bold */
/*------------------------------*/
bold (p0, p1, size)
register char *p0;
register char *p1;
int size;
{
/*
* insert bold face text (by overstriking)
*/
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 (p)
register char *p;
{
/*
* center a line by setting tival
*/
dc.tival = max ((dc.rmval + dc.tival - width (p)) >> 1, 0);
}
/*------------------------------*/
/* expand */
/*------------------------------*/
expand (p0, c, s)
register char *p0;
char c;
register char *s;
{
/*
* expand title buffer to include character string
*/
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 */
/*------------------------------*/
justcntr (p, q, limit)
register char *p;
char *q;
int *limit;
{
/*
* center title text into print buffer
*/
register int len;
len = width (p);
q = &q[(limit[RIGHT] + limit[LEFT] - len) >> 1];
while (*p != EOS)
*q++ = *p++;
}
/*------------------------------*/
/* justleft */
/*------------------------------*/
justleft (p, q, limit)
register char *p;
char *q;
int limit;
{
/*
* left justify title text into print buffer
*/
q = &q[limit];
while (*p != EOS)
*q++ = *p++;
}
/*------------------------------*/
/* justrite */
/*------------------------------*/
justrite (p, q, limit)
register char *p;
char *q;
int limit;
{
/*
* right justify title text into print buffer
*/
register int len;
len = width (p);
q = &q[limit - len];
while (*p != EOS)
*q++ = *p++;
}
/*------------------------------*/
/* leadbl */
/*------------------------------*/
leadbl (p)
register char *p;
{
/*
* delete leading blanks, set tival
*/
register int i;
register int j;
/*
* 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
*/
#ifdef GEMDOS
if (p[i] != '\n' && p[i] != '\r')
dc.tival = i;
#else
if (p[i] != '\n' && p[i] != '\r')
dc.tival = i;
#endif
/*
* shift string
*/
for (j = 0; p[i] != EOS; ++j)
p[j] = p[i++];
p[j] = EOS;
}
/*------------------------------*/
/* pfoot */
/*------------------------------*/
pfoot ()
{
/*
* put out page footer
*/
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 */
/*------------------------------*/
phead ()
{
/*
* put out page header
*/
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 */
/*------------------------------*/
puttl (p, lim, pgno)
register char *p;
int *lim;
int pgno;
{
/*
* put out title or footer
*/
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';
#ifdef GEMDOS
h[++i] = '\r';
#endif
h[++i] = EOS;
if (strlen (h) > 2)
{
for (i = 0; i < pg.offset; ++i)
prchar (' ', out_stream);
}
putlin (h, out_stream);
}
/*------------------------------*/
/* putwrd */
/*------------------------------*/
putwrd (wrdbuf)
register char *wrdbuf;
{
/*
* put word in output buffer
*/
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;
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;
}
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);
}
}
/*
* 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 */
/*------------------------------*/
skip (n)
register int n;
{
/*
* skips the number of lines specified by n.
*/
register int i;
if (dc.prflg == TRUE && n > 0)
{
for (i = 0; i < n; ++i)
{
prchar ('\n', out_stream);
}
#ifdef GEMDOS
prchar ('\r', out_stream);
#endif
}
}
/*------------------------------*/
/* spread */
/*------------------------------*/
spread (p, outp, nextra, outwds, escapes)
register char *p;
int outp;
int nextra;
int outwds;
int escapes;
{
/*
* spread words to justify right margin
*/
register int i;
register int j;
register int nb;
register int ne;
register int nholes;
int jmin;
/*
* quick sanity check...
*/
if ((nextra + escapes < 1) || (outwds < 2))
return;
/*
* set up for the spread and do it...
*/
dc.sprdir = ~dc.sprdir;
ne = nextra + escapes;
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 */
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 */
/*------------------------------*/
strkovr (p, q)
register char *p;
register char *q;
{
/*
* split overstrikes (backspaces) into seperate buffer
*/
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++ = '\r';
*q = *pp = EOS;
return (bsflg);
}
/*------------------------------*/
/* underl */
/*------------------------------*/
underl (p0, p1, size)
register char *p0;
register char *p1;
int size;
{
/*
* underline a line
*/
register int i;
register int j;
j = 0;
for (i = 0; (p0[i] != '\n') && (j < size - 1); ++i)
{
if (p0[i] >= ' ' && p0[i] <= '~')
{
if (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 */
/*------------------------------*/
width (s)
register char *s;
{
/*
* compute width of character string
*/
register int w;
w = 0;
while (*s != EOS)
{
if (*s == '\b')
--w;
else if (*s != '\n' && *s != '\r')
++w;
++s;
}
return (w);
}

View File

@@ -0,0 +1,252 @@
.\" **************************************************************************
.\"
.\" -man package for nroff. not quite unix(tm), but working...
.\"
.\" usage: nroff -man file [...]
.\"
.\" note to hackers: if you add things here, make sure there are no blank
.\" lines. they will find their way into the text. use comments (.\") to
.\" make space.
.\"
.\" included here are: TH, SH, SS, IP, PP, LP, RS, RE, I, B, BI,
.\"
.\" see end of this file for usage example
.\"
.\" v0.99 2/25/90 rosenkra@hall.cray.com (Bill Rosenkranz)
.\" freely distributable (no copyright, etc.)
.\"
.\" **************************************************************************
.\"
.\" this is a date string (e.g. 22:20:37 2/25/90) accessible via \*(DA in
.\" the text
.\"
.ds DA "\n(hh:\n(mm:\n(ss \n(mo/\n(dy/\n(yr"
.ds S s
.ds ` "`"
.ds ' "'"
.\"
.\" --------------------------------------------------------------------------
.\" 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 "".
.\"
.de TH
.m1 1
.in 0
.po 0
.lt 65
.ll 65
.tl |$1 ($2)|$3|$1 ($2)|
.fo |$4|$5|%|
.in 5
.ll 65
..
.\" --------------------------------------------------------------------------
.\" start relative indent (always 5 spaces...sorry)
.\"
.de RS
.sp
.in +5
..
.\" --------------------------------------------------------------------------
.\" end relative indent
.\"
.de RE
.sp
.in -5
..
.\" --------------------------------------------------------------------------
.\" indented paragraph with tag (from this line)
.\"
.de IP
.br
.sp 1
.in 5
\&$1 $2 $3 $4 $5 $6 $7 $8 $9
.br
.in +5
..
.\" --------------------------------------------------------------------------
.\" start a new indented paragraph
.\"
.de pp
.sp 1
.in 5
.ti +5
..
.\" --------------------------------------------------------------------------
.\" start a new unindented paragraph
.\"
.de PP
.sp 1
.in 5
..
.\" --------------------------------------------------------------------------
.\" start a new unindented paragraph (same as PP)
.\"
.de LP
.sp 1
.in 5
..
.\" --------------------------------------------------------------------------
.\" main section heading
.\"
.de SH
.sp 1
.ne 3
.in 5
.ti -5
.\".bo
\&$1 $2 $3 $4 $5 $6 $7 $8 $9
.br
..
.\" --------------------------------------------------------------------------
.\" subsection heading, same indent
.\"
.de SS
.sp 1
.ne 3
.in 5
.\".bo
\&$1 $2 $3 $4 $5 $6 $7 $8 $9
.br
..
.\" --------------------------------------------------------------------------
.\" Italic text
.\"
.de I
\&\fI$1\fR
..
.\" --------------------------------------------------------------------------
.\" Bold text
.\"
.de B
\&\fB$1\fR
..
.\" --------------------------------------------------------------------------
.\" Italic Roman text
.\"
.de IR
\&\fI$1\fR$2
..
.\" --------------------------------------------------------------------------
.\" Bold Roman text
.\"
.de BR
\&\fB$1\fR$2
..
.\" --------------------------------------------------------------------------
.\" Bold Italic text
.\"
.de BI
\&\fB$1\fI$2\fR
..
.\" --------------------------------------------------------------------------
.\" small text
.\"
.de SM
\&\fB$1\fR
..
.\" **************************************************************************
.\" example:
.\"
.\" .\" this is a comment...
.\" .TH MYCMD 1 "Commands Manual" "Version 1.0" "\*(DA"
.\" .SH NAME
.\" mycmd - something unix-like \" this is a comment...
.\" .SH SYNOPSIS
.\" mycmd [options] file [...]
.\" .SH 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.
.\" .PP
.\" This will be a new paragraph. You can also use normal
.\" nroff(1)
.\" commands in the text. Most used ones are:
.\" .IP '\\\\\|"'
.\" 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.
.\" .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.
.\" .PP
.\" Now we should be at a new paragraph.
.\" .PP
.\" And now we should be at a another new paragraph.
.\" .SH AUTHOR
.\" .nf
.\" Bill Rosenkranz
.\" rosenkra@hall.cray.com
.\" .fi
.\"
.\" here is the output of "nroff -man mycmd.man":
.\"
.\"
.\" MYCMD (1) Commands Manual MYCMD (1)
.\"
.\"
.\"
.\" NAME
.\" mycmd - something unix-like
.\"
.\" SYNOPSIS
.\" mycmd [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. Most used ones are:
.\"
.\" \"
.\" 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.
.\"
.\" Now we should be at a new paragraph.
.\"
.\" And now we should be at a another new paragraph.
.\"
.\" AUTHOR
.\" Bill Rosenkranz
.\" rosenkra@hall.cray.com
.\"
.\" [blank spaces removed here...]
.\"
.\" Version 1.0 22:20:37 2/25/90 1
.\"

View File

@@ -0,0 +1,11 @@
#ifndef VERSION_H
#define VERSION_H
/*
* to get around no valid argv[0] with some compilers...
*/
char *myname = "nroff";
char *version = "nroff v0.99 BETA 02/25/90 wjr";
#endif /*VERSION_H*/