Path: utzoo!attcan!uunet!convex!convex1.convex.com!rosenkra From: rosenkra@convex1.convex.com (William Rosencranz) Newsgroups: comp.os.minix Subject: nroff v1.10p3 (part04/05) Summary: new version Keywords: nroff conditionals ms man Message-ID: <104589@convex.convex.com> Date: 3 Aug 90 04:23:12 GMT Sender: news@convex.com Organization: Convex Computer Corporation; Richardson, TX Lines: 2627 --- part 4 of 5 shar files #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # If this archive is complete, you will see the following message at the end: # "End of archive 4 (of 5)." # # Contents: # man.man ms.man nroff.h patchlvl.h strings.c text.c tmac.an # # Wrapped by rosenkra%c1yankee@convex.com on Thu Aug 2 13:42:06 1990 # PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f man.man -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"man.man\" else echo shar: Extracting \"man.man\" \(7280 characters\) sed "s/^X//" >man.man <<'END_OF_man.man' X.\" man(7) manpage by rosenkra@convex.com (Bill Rosenkranz, 7/22/90) X.\" X.TH MAN 7 X.SH NAME Xman - nroff macro package for manual pages X.SH SYNOPSIS Xnroff -man file ... X.SH DESCRIPTION XThese macros are used to lay out reference pages for manuals. X.PP XAny text argument Xt Xmay be zero to six words. XQuotes may be used to include blanks in a 'word'. XText Xcan be empty, but unlike normal Unix macros, the next line is not used. X.PP XA prevailing indent distance is remembered between successive Xindented paragraphs, and is reset to default value upon Xreaching a non-indented paragraph (i.e. at .SH or .SS). XIn contrast with normal Unix procedure, all indents (tabs) are 8 spaces Xinstead of 5. XThis can be changed by modifying tmac.an. X.SH FILES X.ec | X\lib\tmac\tmac.an the macro library X.ec \ X.SH SEE ALSO Xnroff(1), man(1) X.SH "REQUEST SUMMARY" X.nf X.cc + XRequest Cause Explanation X Break? X X.B t no Text t is bold. Quote to imbed blanks. X.I t no Text t is italic. Quote to imbed blanks. X.IP x yes Set prevailing indent to 8. Begin X indented paragraph with hanging tag X given by first argument. Tag x is X always placed on a separate line. X.LP yes Same as .PP. X.PP yes Begin paragraph. Set prevailing X indent to 8. X.RE yes End of relative indent. Set prevailing X indent to amount of starting .RS. X.RP x yes Like .IP, but use relative indent. Must X end the section with .RE. X.RS yes Start relative indent, move left margin X in distance 8. X.SH t yes Subhead. Quote to imbed blanks. X.SS t yes Subsection. Quote to imbed blanks. No X indent for t. X.TH n s c v d yes Begin page named n of chapter s; c is X the chapter name; d is the date of the X most recent change; v is version number. X Sets prevailing indent and tabs to 8. X X+cc . X.fi X.ne 8 X.SH EXAMPLE XThe following illustrates some of the requests available Xwith this macro package: X.RS X.nf X.cc + X X.\\\|" this is a comment X.TH DEMO 1 "Commands Manual" "Version 1.0" "\\\|*\|(DA" X.SH NAME Xdemo - show how to use -man package \\\|" this is a comment X.SH SYNOPSIS Xdemo [options] file [...] X.SH DESCRIPTION XThis is a test for showing how to use the X.I nroff(1) Xman package. XIt shows how to use .TH, .SH, .PP, .I, and .IP commands. X.PP XThis will be a new paragraph. XYou can also use normal X.I nroff(1) Xcommands in the text. X.SS NROFF COMMANDS: X.IP '\\\\\|"' XThis is the comment command. XNote how you have to quote this sucker! XYou'll probably never have to write an X.I nroff(1) Xmanpage, so don't worry about it. X.IP nf XNo fill mode (the normal mode is fill mode where things Xget justified right and left). X.IP fi XRe-enter fill mode. X.IP br XBreak line here no matter what. X.IP sp XVertical space (also causes a break to occur). X.sp XNote that to continue an indent and make a new paragraph (as Xis the case here), just put in a space (.sp). X.PP XNow we should be at a new paragraph. X X+cc . X.fi X.RE X.ne 8 XExecuting 'nroff -man demo.man' results in the following output: X.RS X.nf X.cc + X XDEMO (1) Commands Manual DEMO (1) X XNAME X demo - show how to use -man package X XSYNOPSIS X demo [options] file [...] X XDESCRIPTION X This is a test for showing how to use the nroff(1) X man package. It shows how to use .TH, .SH, .PP, .I, X and .IP commands. X X This will be a new paragraph. You can also use normal X nroff(1) commands in the text. X X NROFF COMMANDS: X X \\\|" X This is the comment command. Note how you have to X quote this sucker! You'll probably never have to X write an nroff(1) manpage, so don't worry about X it. X X nf X No fill mode (the normal mode is fill mode where X things get justified right and left). X X fi X Re-enter fill mode. X X br X Break line here no matter what. X X sp X Vertical space (also causes a break to occur). X X Note that to continue an indent and make a new X paragraph (as is the case here), just put in a X space (.sp). X X Now we should be at a new paragraph. X XVersion 1.0 23:33:57 2/25/90 1 X X X+cc . X.fi X.RE X.ne 8 X.SH CONVENTIONS XA typical manual page for a command or function is laid out as follows: X.sp X.RS X.SS ".TH TITLE [1-8]" XThe name of the command or function in upper-case, Xwhich serves as the title of the manual page. XThis is followed by the number of the section in which it appears. X.SS ".SH NAME" Xname - one-line summary X.PP XThe name, or list of names, by which the command is called, followed by Xa dash and then a one-line summary of the action performed. XAll in roman font, this section contains no troff(1) commands or escapes, Xand no macro requests. XIt is used to generate the whatis(1) database. X.SS ".SH SYNOPSIS" XCommands: X.sp X.RS XThe syntax of the command and its arguments as typed on the command line. XWhen in boldface, a word must be typed exactly as printed. XWhen in italics, a word can be replaced with text that you supply. XSyntactic symbols appear in roman face: X.RP "[ ]" XAn argument, when surrounded by brackets is optional. X.RE X.RP | XArguments separated by a vertical bar are exclusive. XYou can supply only item from such a list. X.RE X.RP ... XArguments followed by an elipsis can be repeated. XWhen an elipsis follows a bracketed set, the expression within the Xbrackets can be repeated. X.RE X.RE X.sp XFunctions: X.sp X.RS XIf required, the data declaration, or #include directive, is shown first, Xfollowed by the function declaration. XOtherwise, the function declaration is shown. X.RE X.SS ".SH DESCRIPTION" XA narrative description of the command or function in detail, including Xhow it interacts with files or data, and how it handles the standard Xinput, standard output and standard error. X.PP XFilenames, and references to commands or functions described elswhere Xin the manual, are italicised. XThe names of options, variables and other literal terms are Xin boldface. X.SS ".SH OPTIONS" XThe list of options along with a description of how each affects the Xcommands operation. X.SS ".SH FILES" XA list of files associated with the command or function. X.SS '.SH "SEE ALSO"' XA comma-separated list of related manual pages, followed by references Xto other published materials. XThis section contains no troff(1) escapes or commands, and no macro requests. X.SS ".SH DIAGNOSTICS" XA list of diagnostic messages and an explanation of each. X.SS ".SH NOTES" XAny additional notes such as installation-dependent functionality. X.SS ".SH BUGS" XA description of limitations, known defects, and possible problems Xassociated with the command or function. X.SS ".SH AUTHOR" XThe program's author and any pertinent release info. X.SS ".SH VERSION" XThe program's current version number and release date. X.RE X.SH AUTHOR X.nf XAdapted for Atari ST (TOS) and Minix by Bill Rosenkranz X Xnet: rosenkra@convex.com XCIS: 71460,17 XGENIE: W.ROSENKRANZ X.fi END_OF_man.man if test 7280 -ne `wc -c ms.man <<'END_OF_ms.man' X.\" ms(7) manpage by rosenkra@convex.com (Bill Rosenkranz, 7/22/90) X.\" X.TH MS 7 X.SH NAME Xms - text formatting macros X.SH SYNOPSIS Xnroff -ms [ options ] file ... X.SH DESCRIPTION XThis package of nroff macro definitions provides a Xformatting facility for various styles of articles, theses, and books. XAll external -ms macros are defined below. X.PP XNote that this -ms macro package is a subset of the complete ms package Xsince nroff(1) is not quite up to it yet. XStill, it supports most of what is normally used, including the table Xof contents macros. X.PP XSome nroff requests may be unsafe in conjunction with this package. XHowever, the first four requests below may be used with impunity after Xinitialization, and the last two may be used even before initialization: X.nf X X .bp begin new page X .br break output line X .sp n insert n spacing lines X .ce n center next n lines X X .ls n line spacing: n=1 single, n=2 double space X .na no alignment of right margin X X.fi XFont changes with \f are also allowed; Xfor example, '\\fIword\\fR' will italicize word. X.SH FILES X.ec | X\lib\tmac\tmac.s X.ec \ X.SH REQUESTS X.nf X.cc + XMacro Initial Break? Explanation XName Value Reset? X.AB x - y begin abstract; if x=no don't label abstract X.AE - y end abstract X.AI - y author's institution, centered X.AU - y author's name, centered X.B x - n embolden x; if no x, switch to boldface X.I x - n italicize x; if no x, switch to italics X.IP x - y,y indented paragraph, with hanging tag x X.LP - y,y left (block) paragraph. X.NH x - y,y numbered header; x=level, x=0 resets X.PP - y,y paragraph with first line indented X.QP - y,y quoted paragraph (indented, shorter) X.R on n return to Roman font X.RE - y,y end level of relative indentation X.RS 5n y,y right shift: start level of relative indent X.SH - y,y section header, no numbering X.TL - y title, centered X.XP - y,y extended paragraph (biblio entry) X.XS p - y begin index entry, p = page X.XA p - y another index entry, p = page X.XE - y end index entry X.PX - y print index (ignored) X X+cc . X.fi X.SH REGISTERS XThere are currently no user controlled registers in this implementation. X.PP XHere is a list of string registers available in -ms; they Xmay be used anywhere in the text: X.nf X.ec | X X Name String's Function X X \*(DW weekday X \*(MO month (month of the year) X \*(DY day (current date) X \*Q quote (" in nroff) X \*U unquote (" in nroff) X \*- dash (-- in nroff) X X.ec \ X.fi X.SH EXAMPLES XFor an example, see the test files (*.ms) included in the distribution. X.SH BUGS XProbably zillions, especially considering it is so incomplete. XHowever, it is useful (better than nothing at all). XI have used this package extensively at home to write reports for work. XThe results were nearly 100% compatible with Unix (BSD). XNo support for displays and keeps, tables, boxed text, multicolumn, other Xmodes (e.g. thesis mode), footnotes, and beginning/end page traps. XIndented paragraph with tag puts the tag on its own line regardless how Xlong it is. X.SH AUTHOR X.nf XAdapted for Atari ST (TOS) and Minix by Bill Rosenkranz X Xnet: rosenkra@convex.com XCIS: 71460,17 XGENIE: W.ROSENKRANZ X.fi X END_OF_ms.man if test 3486 -ne `wc -c nroff.h <<'END_OF_nroff.h' X#ifndef NRO_H X#define NRO_H X X#include "config.h" /* os/compiler options */ X X/* X * nroff.h - stuff for nroff X * X * adapted for atariST/TOS by Bill Rosenkranz 10/89 X * net: rosenkra@hall.cray.com X * CIS: 71460,17 X * GENIE: W.ROSENKRANZ X * X * things to look for here: X * 1) TMAC definition for default macro package lib X * 2) configuration sizes (see _STKSIZ below if alcyon/dri) X * 3) libc should have getenv(), time(), and ctime() X * 4) look in version.h for *printer file name (included below) X * X * all data is currently allocated in static arrays. the biggest X * chunks are the parameters which control number registers and the X * macro name space area. these are defined below: MAXREGS, MACBUF. X * MACBUF is the larger. it holds all macros, strings, etc. if you X * find yourself running out of macro space, increase MACBUF. X * X * original author: X * X * Stephen L. Browning X * 5723 North Parker Avenue X * Indianapolis, Indiana 46220 X * X * history: X * X * - Originally written in BDS C; X * - Adapted for standard C by W. N. Paul X * - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz X */ X X#include X X/* X * default prefix of macro files. files will be of the form "tmac.an" X * (for -man), "tmac.s" (for -ms), "tmac.e" (for -me), etc. first X * checks environment for TMACDIR which would be path (e.g. "c:\lib\tmac" X * or ".", no trailing slash char!). X */ X#ifdef tmacfull X# define TMACFULL tmacfull X#endif X#ifdef tmacpre X# define TMACPRE tmacpre X#endif X X#ifdef GEMDOS X# ifndef TMACFULL X# define TMACFULL "c:\\lib\\tmac\\tmac." X# endif X# ifndef TMACPRE X# define TMACPRE "\\tmac." X# endif X#endif X X#ifdef MINIX X# ifndef TMACFULL X# define TMACFULL "/usr/lib/tmac/tmac." X# endif X# ifndef TMACPRE X# define TMACPRE "/tmac." X# endif X#endif X X#ifdef UNIX X# ifndef TMACFULL X# define TMACFULL "/usr/lib/tmac/tmac." X# endif X# ifndef TMACPRE X# define TMACPRE "/tmac." X# endif X#endif X X/* X * command codes. indented defines are commands not yet implemented X */ X#undef PI X#define MACRO 0 /* macro definition */ X#define BP 1 /* begin page */ X#define BR 2 /* break */ X#define CE 3 /* center */ X#define FI 4 /* fill */ X#define FO 5 /* footer */ X#define HE 6 /* header */ X#define IN 7 /* indent */ X#define LS 8 /* line spacing */ X#define NF 9 /* no fill */ X#define PL 10 /* page length */ X#define RM 11 /* remove macro */ X#define SP 12 /* line space */ X#define TI 13 /* temp indent */ X#define UL 14 /* underline */ X#define JU 15 /* justify */ X#define NJ 16 /* no justify */ X#define M1 17 /* top margin */ X#define M2 18 /* second top margin */ X#define M3 19 /* first bottom margin */ X#define M4 20 /* bottom-most margin */ X#define BS 21 /* allow/disallow '\b' in output */ X#define NE 22 /* need n lines */ X#define PC 23 /* page number character (%) */ X#define CC 24 /* control character (.) */ X#define PO 25 /* page offset */ X#define BO 26 /* bold face */ X#define EH 27 /* header for even numbered pages */ X#define OH 28 /* header for odd numbered pages */ X#define EF 29 /* footer for even numbered pages */ X#define OF 30 /* footer for odd numbered pages */ X#define SO 31 /* source file */ X#define CU 32 /* continuous underline */ X#define DE 33 /* define macro */ X#define EN 34 /* end macro definition */ X#define NR 35 /* set number register */ X#define EC 36 /* escape character (\) */ X#define FT 37 /* font change (R,B,I,S,P) */ X#define EO 38 /* turn escape parsing off */ X#define LL 39 /* line length (same as RM) */ X#define FL 40 /* flush output NOW */ X#define PN 41 /* page number for next page */ X#define RR 42 /* remove register */ X#define C2 43 /* nobreak char */ X# define TR 44 /* translate character */ X#define LT 45 /* length of title */ X# define FC 46 /* field delimeter */ X#define TL 47 /* like HE */ X#define AF 48 /* assign format to nr */ X#define AD 49 /* adjust line */ X#define NA 50 /* no adjust */ X#define DS 51 /* define string */ X#define PM 52 /* print macro names */ X#define IF 53 /* if */ X# define IE 54 /* if/else */ X# define EL 55 /* else */ X#define PS 56 /* point size (IGNORED in nroff) */ X#define SS 57 /* space char size (IGNORED in nroff) */ X#define CS 58 /* constant char space (IGNORED in nroff) */ X#define BD 59 /* embolden font (IGNORED in nroff) */ X# define FP 60 /* font position */ X# define MK 61 /* mark vertical place */ X# define RT 62 /* return to marked vert place */ X# define VS 63 /* vertical baseline spacing */ X# define SV 64 /* save vertical distance */ X# define OS 65 /* output saved vertical distance */ X# define NS 66 /* no-space mode */ X# define RS 67 /* restore spacing mode */ X# define AM 68 /* append to macro */ X# define AS 69 /* append to string */ X# define RN 70 /* rename */ X# define DI 71 /* divert to macro */ X# define DA 72 /* divert/append to macro */ X# define WH 73 /* set location trap */ X# define CH 74 /* change trap location */ X# define DT 75 /* set diversion trap */ X# define IT 76 /* set input line trap */ X# define EM 77 /* end macro */ X# define TA 78 /* tab settings */ X# define TC 79 /* tab repetition char */ X# define LC 80 /* leader repetition char */ X# define LG 81 /* ligature mode */ X# define UF 82 /* underline font */ X# define NH 83 /* no hyphenation */ X# define HY 84 /* hyphenate */ X# define HC 85 /* hyphenation indication char */ X# define HW 86 /* hyphenation exception words */ X# define NM 87 /* number mode */ X# define NN 88 /* no number next lines */ X# define EV 89 /* environment switch */ X# define RD 90 /* read insertion */ X# define EX 91 /* exit */ X# define NX 92 /* next file */ X# define PI 93 /* pipe to program */ X# define MC 94 /* set margin char */ X# define TM 95 /* print to terminal */ X#define IG 96 /* ignore */ X X#define COMMENT 1000 /* comment (.\") */ X#define UNKNOWN -1 X X X/* X * MAXLINE is set to a value slightly larger than twice the longest X * expected input line. Because of the way underlining is handled, the X * input line which is to be underlined, can almost triple in length. X * Unlike normal underlining and boldfacing, continuous underlining X * affects all characters in the buffer, and represents the worst case X * condition. If the distance between the left margin and the right X * margin is greater than about 65 characters, and continuous underlining X * is in effect, there is a high probability of buffer overflow. X */ X#define MAXLINE 500 /* 200 */ X#define PAGELEN 66 X#define PAGEWIDTH 80 X#define HUGE 256 X#define INFINITE 32760 X#define LEFT 0 /* indecies into hdr margin lim arrays */ X#define RIGHT 1 X#define Nfiles 4 /* nesting depth for input files */ X X/* X * The following parameters may be defined elsewhere so undef/def X */ X#undef min X#undef max X#undef YES X#define YES 1 X#undef NO X#define NO 0 X#undef ERR X#define ERR -1 X#define EOS '\0' X#undef FALSE X#define FALSE 0 X#undef TRUE X#define TRUE !FALSE X#undef OK X#define OK !ERR X X/* X * a rational way of dealing with the NULL thing... X */ X#define NULL_CPTR (char *) 0 X#define NULL_FPTR (FILE *) 0 X#define NULL_IPTR (int *) 0 X#define NULL_LPTR (long *) 0 X#define NULL_SPTR (short *) 0 X#define NULL_PTR (char *) 0 X#define NULLP(type) (type *) 0 X X X/* X * for justification during line fill X */ X#define ADJ_OFF 0 X#define ADJ_LEFT 1 X#define ADJ_RIGHT 2 X#define ADJ_CENTER 3 X#define ADJ_BOTH 4 X X X/* X * basic unit (b.u.) conversions. in nroff, all output is fixed spaced, X * at least in THIS nroff. so unit conversion to b.u. amount to 1 Em per X * character or 24 b.u. per character. thus 0.5i = 120 b.u. = 5 chars. X * everything is rounded up to the nearest Em. it is highly recommended X * to use inches for everything... X * X * to convert (say inches) to char spaces, do this: X * X * char_spaces = (int)(inches * (float) BU_INCH) / BU_EM; X */ X#define BU_INCH 240 /* 1.0i = 240 b.u. */ X#define BU_CM 945/10 /* 1.0c = 240*50/127 b.u. */ X#define BU_PICA 40 /* 1P = 240/6 b.u. */ X#define BU_EM 24 /* 1m = 240/10 b.u. (10 char/inch) */ X#define BU_EN 24 /* 1n = 240/10 b.u. */ X#define BU_POINT 240/72 /* 1p = 240/72 b.u. */ X#define BU_BU 1 /* 1 = 1 b.u. */ X X X/* X * The parameter values selected for macro definitions are somewhat X * arbitrary. MACBUF is the storage area for both macro names and X * definitions. Since macro processing is handled by pushing back X * the expansion into the input buffer, the longest possible expansion X * would be MAXLINE characters. Allowing for argument expansion, X * MXMLEN was chosen slightly less than MAXLINE. It is assumed that X * most macro definitions will not exceed 20 characters, hence MXMDEF X * of 150. X */ X X#define MXMDEF 150 /* max no. of macro definitions */ X#define MACBUF 100000 /* macro definition buffer size (32000) */ X#define MXMLEN 2000 /* max length of each macro definition (250) */ X#define MNLEN 10 /* max length of macro name */ X#define MAXREGS 100 /* max number of registers (2-char) */ X#define MAXPBB 5000 /* size of push back buffer */ X Xstruct macros X{ X char *mnames[MXMDEF]; /* table of ptrs to macro names */ X int lastp; /* index to last mname */ X char *emb; /* next char avail in macro defn buf */ X char mb[MACBUF]; /* table of macro definitions */ X char *ppb; /* pointer into push back buffer */ X char pbb[MAXPBB]; /* push back buffer */ X}; X X X/* X * number registers X */ X#define RF_READ 0x0001 /* register flags */ X#define RF_WRITE 0x0002 X Xstruct regs X{ X char rname[4]; /* 2-char register name */ X int rauto; /* autoincrement value */ X int rval; /* current value of the register */ X int rflag; /* register flags */ X char rfmt; /* register format (1,a,A,i,I,...) */ X}; X X X X/* X * control parameters for nroff X */ Xstruct docctl X{ X int fill; /* fill if YES, init = YES */ X int dofnt; /* handle font change, init = YES */ X int lsval; /* current line spacing, init = 1 */ X int inval; /* current indent, >= 0, init = 0 */ X int rmval; /* current right margin, init = 60 */ X int llval; /* current line length, init = 60 */ X int ltval; /* current title length, init = 60 */ X int tival; /* current temp indent, init = 0 */ X int ceval; /* number of lines to center, init = 0 */ X int ulval; /* number of lines to underline, init = 0 */ X int cuval; /* no lines to continuously uline, init = 0 */ X int juval; /* justify if YES, init = YES */ X int adjval; /* adjust type, init = ADJ_BOTH */ X int boval; /* number of lines to bold face, init = 0 */ X int bsflg; /* can output contain '\b', init = FALSE */ X int prflg; /* print on or off, init = TRUE */ X int sprdir; /* direction for spread(), init = 0 */ X int flevel; /* nesting depth for source cmd, init = 0 */ X int lastfnt; /* previous used font */ X int thisfnt; /* current font, init = 1 (1=R,2=I,3=B,4=S) */ X int escon; /* whether esc parsing is on, init = YES */ X int nr[26]; /* number registers */ X int nrauto[26]; /* number registers auto increment */ X char nrfmt[26]; /* number registers formats, init = '1' */ X /* input code how printed */ X /* 1 '1' 1,2,3,... */ X /* a 'a' a,b,c,...,aa,bb,cc,... */ X /* A 'A' A,B,C,...,AA,BB,CC,... */ X /* i 'i' i,ii,iii,iv,v... */ X /* I 'I' I,II,III,IV,V... */ X /* 01 2 01,02,03,... */ X /* 001 3 001,002,003,... */ X /* 0..1 8 00000001,00000002,... */ X char pgchr; /* page number character, init = '%' */ X char cmdchr; /* command character, init = '.' */ X char escchr; /* escape char, init = '\' */ X char nobrchr; /* nobreak char, init = '\'' */ X}; X X X/* X * output buffer control parameters X */ Xstruct cout X{ X int outp; /* next avail char pos in outbuf, init = 0 */ X int outw; /* width of text currently in buffer */ X int outwds; /* number of words in buffer, init = 0 */ X int lpr; /* output to printer, init = FALSE */ X int outesc; /* number of escape char on this line */ X char outbuf[MAXLINE];/* output of filled text */ X}; X X X/* X * page control parameters X */ Xstruct page X{ X int curpag; /* current output page number, init =0 */ X int newpag; /* next output page number, init = 1 */ X int lineno; /* next line to be printed, init = 0 */ X int plval; /* page length in lines, init = 66 */ X int m1val; /* margin before and including header */ X int m2val; /* margin after header */ X int m3val; /* margin after last text line */ X int m4val; /* bottom margin, including footer */ X int bottom; /* last live line on page X = plval - m3val - m4val */ X int offset; /* page offset from left, init = 0 */ X int frstpg; /* first page to print, init = 0 */ X int lastpg; /* last page to print, init = 30000 */ X int ehlim[2]; /* left/right margins for headers/footers */ X int ohlim[2]; /* init = 0 and PAGEWIDTH */ X int eflim[2]; X int oflim[2]; X char ehead[MAXLINE]; /* top of page title, init = '\n' */ X char ohead[MAXLINE]; X char efoot[MAXLINE]; /* bottom of page title, init = '\n' */ X char ofoot[MAXLINE]; X}; X X X X/* X * forward refs from libc X */ Xchar *getenv (); Xchar *ctime (); Xlong time (); X#ifdef UNIX Xchar *tgetstr (); /* from termcap/terminfo */ X#endif X#ifdef MINIX_ST Xchar *tgetstr (); X#endif X#ifdef MINIX_PC Xchar *tgetstr (); X#endif X X X/* X * forward refs from nroff X */ Xchar *getmac (); Xchar *getstr (); Xchar *skipwd (); Xchar *skipbl (); Xchar *getfield (); X Xint do_mc (); Xint comand (); Xint comtyp (); Xint gettl (); Xint getval (); Xint set (); Xint expesc (); Xint specialchar (); Xint fontchange (); Xint getlin (); Xint ngetc (); Xint pbstr (); Xint putbak (); Xint prchar (); Xint put (); Xint putlin (); Xint atod (); Xint robrk (); Xint ctod (); Xint space (); Xint getwrd (); Xint countesc (); Xint itoda (); Xint itoROMAN (); Xint itoroman (); Xint itoLETTER (); Xint itoletter (); Xint min (); Xint max (); Xint defmac (); Xint colmac (); Xint putmac (); Xint maceval (); Xint main (); Xint usage (); Xint init (); Xint pswitch (); Xint profile (); Xint text (); Xint bold (); Xint center (); Xint expand (); Xint justcntr (); Xint justleft (); Xint justrite (); Xint leadbl (); Xint pfoot (); Xint phead (); Xint puttl (); Xint putwrd (); Xint skip (); Xint spread (); Xint strkovr (); Xint underl (); Xint width (); Xint inptobu (); /* convert input units to b.u. */ Xint butochar (); /* convert b.u. to char spaces */ X Xint findreg (); Xint set_ireg (); X X X X/* X * globals. define NRO_MAIN in main.c to define globals there. else X * you get extern. X */ X#ifdef NRO_MAIN X Xstruct docctl dc; Xstruct page pg; Xstruct cout co; Xstruct macros mac; Xstruct regs rg[MAXREGS]; XFILE *out_stream; XFILE *err_stream; XFILE *dbg_stream; XFILE *sofile[Nfiles+1]; Xint ignoring; /* .ig vs .de */ Xint hold_screen; Xint debugging; Xint stepping; /* paging */ Xint mc_ing = 0; /* turned off */ Xint mc_space = 2; Xchar mc_char = '|'; Xchar tmpdir[256]; Xchar termcap[1030]; Xchar s_standout[20]; Xchar e_standout[20]; Xchar s_bold[20]; Xchar e_bold[20]; Xchar s_italic[20]; Xchar e_italic[20]; Xchar *dbgfile = "nroff.dbg"; X#ifdef GEMDOS Xchar *printer = "prn:"; /* this WON'T work!!! */ X#else Xchar *printer = "/dev/lp"; /* this probably won't */ X#endif X X X#include "version.h" /* for myname and version */ X X X#ifdef ALCYON X/* X * this SHOULD be big enough for most needs. only used by startup X * code (gemstart.o or crt0.o) X */ Xlong _STKSIZ = 16384L; X#endif X X X#else /*NRO_MAIN*/ X Xextern struct docctl dc; Xextern struct page pg; Xextern struct cout co; Xextern struct macros mac; Xextern struct regs rg[MAXREGS]; Xextern FILE *out_stream; Xextern FILE *err_stream; Xextern FILE *dbg_stream; Xextern FILE *sofile[Nfiles+1]; Xextern int ignoring; Xextern int hold_screen; Xextern int debugging; Xextern int stepping; Xextern int mc_ing; Xextern int mc_space; Xextern char mc_char; Xextern char tmpdir[]; Xextern char termcap[]; Xextern char s_standout[]; Xextern char e_standout[]; Xextern char s_italic[]; Xextern char e_italic[]; Xextern char *dbgfile; Xextern char *printer; Xextern char *myname; Xextern char *version; Xextern int patchlevel; X X#endif /*NRO_MAIN*/ X X#endif /*NRO_H*/ X END_OF_nroff.h if test 15981 -ne `wc -c patchlvl.h <<'END_OF_patchlvl.h' X#define PATCHLEVEL 3 END_OF_patchlvl.h if test 21 -ne `wc -c strings.c <<'END_OF_strings.c' X/* X * strings.c - String input/output processing for nroff word processor X * X * adapted for atariST/TOS by Bill Rosenkranz 11/89 X * net: rosenkra@hall.cray.com X * CIS: 71460,17 X * GENIE: W.ROSENKRANZ X * X * original author: X * X * Stephen L. Browning X * 5723 North Parker Avenue X * Indianapolis, Indiana 46220 X * X * history: X * X * - Originally written in BDS C; X * - Adapted for standard C by W. N. Paul X * - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz X */ X X#undef NRO_MAIN /* extern globals */ X X#include X#include "nroff.h" X X X X/*------------------------------*/ X/* defstr */ X/*------------------------------*/ Xdefstr (p) Xregister char *p; X{ X X/* X * Define a string. top level, read from command line. X * X * we should read string without interpretation EXCEPT: X * X * 1) number registers are interpolated X * 2) strings indicated by \* are interpolated X * 3) arguments indicated by \$ are interpolated X * 4) concealed newlines indicated by \(newline) are eliminated X * 5) comments indicated by \" are eliminated X * 6) \t and \a are interpreted as ASCII h tab and SOH. X * 7) \\ is interpreted as backslash and \. is interpreted as a period. X * X * currently, we do only 3. a good place to do it would be here before X * putstr, after colstr... X */ X X register char *q; X register int i; X char name[MNLEN]; X char defn[MXMLEN]; X X X X name[0] = '\0'; X defn[0] = '\0'; X X X /* X * skip the .ds and get to the name... X */ X q = skipwd (p); X q = skipbl (q); X X /* X * ok, name now holds the name. make sure it is valid (i.e. first X * char is alpha...). getwrd returns the length of the word. X */ X i = getwrd (q, name); X if (!name[0]) X { X fprintf (err_stream, X "***%s: missing or illegal string definition name\n", X myname); X err_exit (-1); X } X X /* X * truncate to 2 char max name. X */ X if (i > 2) X name[2] = EOS; X X X /* X * skip the name to get to the string. it CAN start with a " to X * have leading blanks... X */ X q = skipwd (q); X q = skipbl (q); X X X X /* X * read rest of line from input stream and collect string into X * temp buffer defn X */ X if ((i = colstr (q, defn)) == ERR) X { X fprintf (err_stream, X "***%s: string definition too long\n", myname); X err_exit (-1); X } X X X /* X * store the string X */ X if (putstr (name, defn) == ERR) X { X fprintf (err_stream, X "***%s: string definition table full\n", myname); X err_exit (-1); X } X} X X X X X X/*------------------------------*/ X/* colstr */ X/*------------------------------*/ Xcolstr (p, d) Xregister char *p; Xchar *d; X{ X X/* X * Collect string definition from input stream X */ X X register int i = 0; X char *pstart = p; X X X X /* X * if there is a " here, we have leading blanks (skipbl in caller X * found it). just get past it... X */ X if (*p == '\"') X p++; X X X while (*p != EOS) X { X /* X * are we over the length limit for a single string? X */ X if (i >= MXMLEN - 1) X { X d[i - 1] = EOS; X return (ERR); X } X X /* X * "i break for comments..." X */ X if (*p == '\\' && *(p+1) == '\"') X { X /* X * first back over any whitespace between comment X * start and last character in line. remember to X * decrement counter i, too... X */ X p--; X while (isspace (*p) && p > pstart && i > 0) X { X p--; X i--; X } X X /* X * now skip over the comment until we reach the X * trailing newline X */ X while (*p != EOS) X { X if (*p == '\n' || *p == '\r') X break; X p++; X } X } X X /* X * stop at the newline... X */ X if (*p == '\n' || *p == '\r') X break; X X /* X * copy it X */ X d[i++] = *p++; X } X d[i] = EOS; X return (i); X} X X X X X X/*------------------------------*/ X/* putstr */ X/*------------------------------*/ Xputstr (name, p) Xregister char *name; Xregister char *p; X{ X X/* X * Put string definition into (macro) table X * X * NOTE: any expansions of things like number registers SHOULD X * have been done already. strings and macros share mb buffer X */ X X X /* X * any room left? (did we exceed max number of possible macros) X */ X if (mac.lastp >= MXMDEF) X return (ERR); X X /* X * will new one fit in big buffer? X */ X if (mac.emb + strlen (name) + strlen (p) + 1 > &mac.mb[MACBUF]) X { X return (ERR); X } X X X /* X * add it... X * X * bump counter, set ptr to name, copy name, copy def. X * finally increment end of macro buffer ptr (emb). X * X * string looks like this in mb: X * X * mac.mb[MACBUF] size of total buf X * lastp < MXMDEF number of macros/strings possible X * *mnames[MXMDEF] -> names, each max length X * ...______________________________...____________________... X * / / /|X|X|0|string definition |0| / / / / / / / X * .../_/_/_|_|_|_|_________________...___|_|/_/_/_/_/_/_/_... X * ^ X * | X * \----- mac.mnames[mac.lastp] points here X * X * both the 2 char name (XX) and the descripton are null term and X * follow one after the other. X */ X ++mac.lastp; X mac.mnames[mac.lastp] = mac.emb; X strcpy (mac.emb, name); X strcpy (mac.emb + strlen (name) + 1, p); X mac.emb += strlen (name) + strlen (p) + 2; X return (OK); X} X X X X X X X/*------------------------------*/ X/* getstr */ X/*------------------------------*/ Xchar *getstr (name) Xregister char *name; X{ X X/* X * Get (lookup) string definition from namespace X */ X X register int i; X X /* X * loop for all macros, starting with last one X */ X for (i = mac.lastp; i >= 0; --i) X { X /* X * is this REALLY a macro? X */ X if (mac.mnames[i]) X { X /* X * if it compares, return a ptr to it X */ X if (!strcmp (name, mac.mnames[i])) X { X/*!!!debug puts (mac.mnames[i]);*/ X X if (mac.mnames[i][1] == EOS) X return (mac.mnames[i] + 2); X else X return (mac.mnames[i] + 3); X } X } X } X X /* X * none found, return null X */ X return (NULL_CPTR); X} X X X X X X END_OF_strings.c if test 5761 -ne `wc -c text.c <<'END_OF_text.c' X#undef OLD_WAY X/* X * text.c - text output processing portion of nroff word processor X * X * adapted for atariST/TOS by Bill Rosenkranz 11/89 X * net: rosenkra@hall.cray.com X * CIS: 71460,17 X * GENIE: W.ROSENKRANZ X * X * original author: X * X * Stephen L. Browning X * 5723 North Parker Avenue X * Indianapolis, Indiana 46220 X * X * history: X * X * - Originally written in BDS C; X * - Adapted for standard C by W. N. Paul X * - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz X */ X X#undef NRO_MAIN /* extern globals */ X X#include X#include "nroff.h" X X X/*------------------------------*/ X/* text */ X/*------------------------------*/ Xtext (p) Xregister char *p; X{ X X/* X * main text processing X */ X X register int i; X char wrdbuf[MAXLINE]; X X X /* X * skip over leading blanks if in fill mode. we indent later. X * since leadbl does a robrk, do it if in .nf mode X */ X if (dc.fill == YES) X { X if (*p == ' ' || *p == '\n' || *p == '\r') X leadbl (p); X } X else X robrk (); X X X /* X * expand escape sequences X */ X expesc (p, wrdbuf); X X X /* X * test for how to output X */ X if (dc.ulval > 0) X { X /* X * underline (.ul) X * X * Because of the way underlining is handled, X * MAXLINE should be declared to be three times X * larger than the longest expected input line X * for underlining. Since many of the character X * buffers use this parameter, a lot of memory X * can be allocated when it may not really be X * needed. A MAXLINE of 180 would allow about X * 60 characters in the output line to be X * underlined (remember that only alphanumerics X * get underlined - no spaces or punctuation). X */ X underl (p, wrdbuf, MAXLINE); X --dc.ulval; X } X if (dc.cuval > 0) X { X /* X * continuous underline (.cu) X */ X underl (p, wrdbuf, MAXLINE); X --dc.cuval; X } X if (dc.boval > 0) X { X /* X * bold (.bo) X */ X bold (p, wrdbuf, MAXLINE); X --dc.boval; X } X if (dc.ceval > 0) X { X /* X * centered (.ce) X */ X center (p); X do_mc (p); X put (p); X --dc.ceval; X } X else if ((*p == '\r' || *p == '\n') && dc.fill == NO) X { X /* X * all blank line X */ X do_mc (p); X put (p); X } X else if (dc.fill == NO) X { X /* X * unfilled (.nf) X */ X do_mc (p); X put (p); X } X else X { X /* X * anything else... X * X * init escape char counter for this line... X */ X/* co.outesc = 0;*/ X X X /* X * get a word and put it out. increment ptr to the next X * word. X */ X while ((i = getwrd (p, wrdbuf)) > 0) X { X/* co.outesc += countesc (wrdbuf);*/ X X putwrd (wrdbuf); X p += i; X } X } X} X X X X X/*------------------------------*/ X/* bold */ X/*------------------------------*/ Xbold (p0, p1, size) Xregister char *p0; Xregister char *p1; Xint size; X{ X X/* X * insert bold face text (by overstriking) X */ X X register int i; X register int j; X X j = 0; X for (i = 0; (p0[i] != '\n') && (j < size - 1); ++i) X { X if (isalpha (p0[i]) || isdigit (p0[i])) X { X p1[j++] = p0[i]; X p1[j++] = '\b'; X } X p1[j++] = p0[i]; X } X p1[j++] = '\n'; X p1[j] = EOS; X while (*p1 != EOS) X *p0++ = *p1++; X *p0 = EOS; X} X X X X X X X/*------------------------------*/ X/* center */ X/*------------------------------*/ Xcenter (p) Xregister char *p; X{ X X/* X * center a line by setting tival X */ X X dc.tival = max ((dc.rmval + dc.tival - width (p)) >> 1, 0); X} X X X X X/*------------------------------*/ X/* expand */ X/*------------------------------*/ Xexpand (p0, c, s) Xregister char *p0; Xchar c; Xregister char *s; X{ X X/* X * expand title buffer to include character string X */ X X register char *p; X register char *q; X register char *r; X char tmp[MAXLINE]; X X p = p0; X q = tmp; X while (*p != EOS) X { X if (*p == c) X { X r = s; X while (*r != EOS) X *q++ = *r++; X } X else X *q++ = *p; X ++p; X } X *q = EOS; X strcpy (p0, tmp); /* copy it back */ X} X X X X X/*------------------------------*/ X/* justcntr */ X/*------------------------------*/ Xjustcntr (p, q, limit) Xregister char *p; Xchar *q; Xint *limit; X{ X X/* X * center title text into print buffer X */ X X register int len; X X len = width (p); X q = &q[(limit[RIGHT] + limit[LEFT] - len) >> 1]; X while (*p != EOS) X *q++ = *p++; X} X X X X X X/*------------------------------*/ X/* justleft */ X/*------------------------------*/ Xjustleft (p, q, limit) Xregister char *p; Xchar *q; Xint limit; X{ X X/* X * left justify title text into print buffer X */ X X q = &q[limit]; X while (*p != EOS) X *q++ = *p++; X} X X X X X/*------------------------------*/ X/* justrite */ X/*------------------------------*/ Xjustrite (p, q, limit) Xregister char *p; Xchar *q; Xint limit; X{ X X/* X * right justify title text into print buffer X */ X X register int len; X X len = width (p); X q = &q[limit - len]; X while (*p != EOS) X *q++ = *p++; X} X X X X X X X/*------------------------------*/ X/* leadbl */ X/*------------------------------*/ Xleadbl (p) Xregister char *p; X{ X X/* X * delete leading blanks, set tival X */ X X register int i; X register int j; X X /* X * end current line and reset co struct X */ X robrk (); X X /* X * skip spaces X */ X for (i = 0; p[i] == ' ' || p[i] == '\t'; ++i) X ; X X /* X * if not end of line, reset current temp indent X */ X if (p[i] != '\n' && p[i] != '\r') X dc.tival = i; X X /* X * shift string X */ X for (j = 0; p[i] != EOS; ++j) X p[j] = p[i++]; X p[j] = EOS; X} X X X X X X/*------------------------------*/ X/* pfoot */ X/*------------------------------*/ Xpfoot () X{ X X/* X * put out page footer X */ X X if (dc.prflg == TRUE) X { X skip (pg.m3val); X if (pg.m4val > 0) X { X if ((pg.curpag % 2) == 0) X { X puttl (pg.efoot, pg.eflim, pg.curpag); X } X else X { X puttl (pg.ofoot, pg.oflim, pg.curpag); X } X skip (pg.m4val - 1); X } X } X} X X X X X X/*------------------------------*/ X/* phead */ X/*------------------------------*/ Xphead () X{ X X/* X * put out page header X */ X X pg.curpag = pg.newpag; X if (pg.curpag >= pg.frstpg && pg.curpag <= pg.lastpg) X { X dc.prflg = TRUE; X } X else X { X dc.prflg = FALSE; X } X ++pg.newpag; X set_ireg ("%", pg.newpag, 0); X if (dc.prflg == TRUE) X { X if (pg.m1val > 0) X { X skip (pg.m1val - 1); X if ((pg.curpag % 2) == 0) X { X puttl (pg.ehead, pg.ehlim, pg.curpag); X } X else X { X puttl (pg.ohead, pg.ohlim, pg.curpag); X } X } X skip (pg.m2val); X } X /* X * initialize lineno for the next page X */ X pg.lineno = pg.m1val + pg.m2val + 1; X set_ireg ("ln", pg.lineno, 0); X} X X X X X/*------------------------------*/ X/* puttl */ X/*------------------------------*/ Xputtl (p, lim, pgno) Xregister char *p; Xint *lim; Xint pgno; X{ X X/* X * put out title or footer X */ X X register int i; X char pn[8]; X char t[MAXLINE]; X char h[MAXLINE]; X char delim; X X itoda (pgno, pn, 6); X for (i = 0; i < MAXLINE; ++i) X h[i] = ' '; X delim = *p++; X p = getfield (p, t, delim); X expand (t, dc.pgchr, pn); X justleft (t, h, lim[LEFT]); X p = getfield (p, t, delim); X expand (t, dc.pgchr, pn); X justcntr (t, h, lim); X p = getfield (p, t, delim); X expand (t, dc.pgchr, pn); X justrite (t, h, lim[RIGHT]); X for (i = MAXLINE - 4; h[i] == ' '; --i) X h[i] = EOS; X h[++i] = '\n'; X h[++i] = '\r'; X h[++i] = EOS; X if (strlen (h) > 2) X { X for (i = 0; i < pg.offset; ++i) X prchar (' ', out_stream); X } X putlin (h, out_stream); X} X X X X X X/*------------------------------*/ X/* putwrd */ X/*------------------------------*/ Xputwrd (wrdbuf) Xregister char *wrdbuf; X{ X X/* X * put word in output buffer X */ X X register char *p0; X register char *p1; X int w; X int last; X int llval; X int nextra; X X X X /* X * check if this word puts us over the limit X */ X w = width (wrdbuf); X last = strlen (wrdbuf) + co.outp; X llval = dc.rmval - dc.tival; X/* if (((co.outp > 0) && ((co.outw + w) > llval))*/ X co.outesc += countesc (wrdbuf); X if (((co.outp > 0) && ((co.outw + w - co.outesc) > llval)) X || (last > MAXLINE)) X { X /* X * last word exceeds limit so prepare to break line, print X * it, and reset outbuf. X */ X last -= co.outp; X if (dc.juval == YES) X { X nextra = llval - co.outw + 1; X X /* X * Do not take in the escape char of the X * word that didn't fit on this line anymore X */ X co.outesc -= countesc (wrdbuf); X X /* X * Check whether last word was end of X * sentence and modify counts so that X * it is right justified. X */ X if (co.outbuf[co.outp - 2] == ' ') X { X --co.outp; X ++nextra; X } X#ifdef OLD_WAY X spread (co.outbuf, co.outp - 1, nextra, co.outwds, co.outesc); X if ((nextra > 0) && (co.outwds > 1)) X { X co.outp += (nextra - 1); X } X/* if (co.outesc > 0) X { X co.outp += co.outesc; X } X*/ X#else X spread (co.outbuf, co.outp - 1, nextra, X co.outwds, co.outesc); X if ((nextra + co.outesc > 0) && (co.outwds > 1)) X { X co.outp += (nextra + co.outesc - 1); X } X#endif X } X X /* X * break line, output it, and reset all co members. reset X * esc count. X */ X robrk (); X X co.outesc = countesc (wrdbuf); X } X X X /* X * copy the current word to the out buffer which may have been X * reset X */ X p0 = wrdbuf; X p1 = co.outbuf + co.outp; X while (*p0 != EOS) X *p1++ = *p0++; X X co.outp = last; X co.outbuf[co.outp++] = ' '; X co.outw += w + 1; X co.outwds += 1; X} X X X X X/*------------------------------*/ X/* skip */ X/*------------------------------*/ Xskip (n) Xregister int n; X{ X X/* X * skips the number of lines specified by n. X */ X X register int i; X register int j; X X X if (dc.prflg == TRUE && n > 0) X { X for (i = 0; i < n; ++i) X { X /* X * handle blank line with changebar X */ X if (mc_ing == TRUE) X { X for (j = 0; j < pg.offset; ++j) X prchar (' ', out_stream); X for (j = 0; j < dc.rmval; ++j) X prchar (' ', out_stream); X for (j = 0; j < mc_space; j++) X prchar (' ', out_stream); X prchar (mc_char, out_stream); X } X prchar ('\n', out_stream); X prchar ('\r', out_stream); X } X } X} X X X X X X/*------------------------------*/ X/* spread */ X/*------------------------------*/ Xspread (p, outp, nextra, outwds, escapes) Xregister char *p; Xint outp; Xint nextra; Xint outwds; Xint escapes; X{ X X/* X * spread words to justify right margin X */ X X register int i; X register int j; X register int nb; X register int ne; X register int nholes; X int jmin; X X X /* X * quick sanity check... X */ X#ifdef OLDWAY X if ((nextra <= 0) || (outwds <= 1)) X return; X#else X if ((nextra + escapes < 1) || (outwds < 2)) X return; X#endif X X X/*fflush (out_stream); fprintf (err_stream, "in spread: escapes = %d\n", escapes); fflush (err_stream);*/ X X X /* X * set up for the spread and do it... X */ X dc.sprdir = ~dc.sprdir; X#ifdef OLD_WAY X ne = nextra; X#else X ne = nextra + escapes; X#endif X nholes = outwds - 1; /* holes between words */ X i = outp - 1; /* last non-blank character */ X j = min (MAXLINE - 3, i + ne); /* leave room for CR,LF,EOS */ X/* X j += escapes; X if (p[i-1] == 27) X j += 2; X j = min (j, MAXLINE - 3); X*/ X while (i < j) X { X p[j] = p[i]; X if (p[i] == ' ') X { X if (dc.sprdir == 0) X nb = (ne - 1) / nholes + 1; X else X nb = ne / nholes; X ne -= nb; X --nholes; X for (; nb > 0; --nb) X { X --j; X p[j] = ' '; X } X } X --i; X --j; X } X} X X X X X X/*------------------------------*/ X/* strkovr */ X/*------------------------------*/ Xstrkovr (p, q) Xregister char *p; Xregister char *q; X{ X X/* X * split overstrikes (backspaces) into seperate buffer X */ X X register char *pp; X int bsflg; X X bsflg = FALSE; X pp = p; X while (*p != EOS) X { X *q = ' '; X *pp = *p; X ++p; X if (*p == '\b') X { X if (*pp >= ' ' && *pp <= '~') X { X bsflg = TRUE; X *q = *pp; X ++p; X *pp = *p; X ++p; X } X } X ++q; X ++pp; X } X *q++ = '\r'; X *q = *pp = EOS; X X return (bsflg); X} X X X X X X/*------------------------------*/ X/* underl */ X/*------------------------------*/ Xunderl (p0, p1, size) Xregister char *p0; Xregister char *p1; Xint size; X{ X X/* X * underline a line X */ X X register int i; X register int j; X X j = 0; X for (i = 0; (p0[i] != '\n') && (j < size - 1); ++i) X { X if (p0[i] >= ' ' && p0[i] <= '~') X { X if (isalpha (p0[i]) || isdigit (p0[i]) || dc.cuval > 0) X { X p1[j++] = '_'; X p1[j++] = '\b'; X } X } X p1[j++] = p0[i]; X } X p1[j++] = '\n'; X p1[j] = EOS; X while (*p1 != EOS) X *p0++ = *p1++; X *p0 = EOS; X} X X X X X/*------------------------------*/ X/* width */ X/*------------------------------*/ Xwidth (s) Xregister char *s; X{ X X/* X * compute width of character string X */ X X register int w; X X w = 0; X while (*s != EOS) X { X if (*s == '\b') X --w; X else if (*s != '\n' && *s != '\r') X ++w; X ++s; X } X X return (w); X} X X X X X/*------------------------------*/ X/* do_mc */ X/*------------------------------*/ Xdo_mc (p) Xchar *p; X{ X X/* X * add margin char (change bar) for .nf and .ce lines. X * X * filled lines handled in robrk(). blank lines (.sp) handled in skip(). X * note: robrk() calls this routine, too. X */ X X register char *ps; X register int nspaces; X register int i; X register int has_cr; X register int has_lf; X int len; X int nesc; X X X if (mc_ing == FALSE) X return; X X X len = strlen (p); X X X /* X * get to the end... X */ X ps = p; X while (*ps) X ps++; X X X /* X * check for cr and lf X */ X ps--; X has_lf = 0; X has_cr = 0; X while (ps >= p && (*ps == '\r' || *ps == '\n')) X { X if (*ps == '\n') X has_lf++; X else X has_cr++; X X len--; X ps--; X } X if (has_lf < has_cr) X has_lf = has_cr; X else if (has_cr < has_lf) X has_cr = has_lf; X X X /* X * remove any trailing blanks here X */ X while (ps >= p && *ps == ' ') X { X ps--; X len--; X } X *++ps = EOS; X X X /* X * add trailing spaces for short lines. count escapes, subtract X * from len. use rmval for rigth margin (minus tival which is X * added later in put). X */ X nesc = countesc (p); X len -= nesc; X nspaces = dc.rmval - dc.tival - len; X for (i = 0; i < nspaces; i++, ps++) X *ps = ' '; X X X /* X * add the bar... X */ X for (i = 0; i < mc_space; i++, ps++) X *ps = ' '; X *ps++ = mc_char; X X X /* X * replace cr, lf, and EOS X */ X while (has_lf--) X { X *ps++ = '\r'; X *ps++ = '\n'; X } X *ps = EOS; X X X return; X} END_OF_text.c if test 13950 -ne `wc -c tmac.an <<'END_OF_tmac.an' X.\" set this non-zero to turn on debugging X.nr Z 0 X.\" ************************************************************************** X.\" X.\" -man package for nroff. not quite unix(tm), but adequate/working... X.\" X.\" usage: nroff -man file [...] X.\" X.\" included here are: TH, Th, SH, SS, IP, PP, LP, RS, RP, RE, I, B X.\" X.\" v1.10 7/22/90 rosenkra@convex.com (Bill Rosenkranz) X.\" freely distributable (no copyright, etc.) X.\" X.\" ************************************************************************** X.\" X.\" some perdefined strings (quotes, etc) X.\" X.ds S s X.ds ` "` X.ds ' "' X.ds lq "" X.ds rq "" X.\" X.\" these are various predefined date and time strings X.\" X.\" DW day-of-week: X.if \n(dw=1 .ds DW "Sun X.if \n(dw=2 .ds DW "Mon X.if \n(dw=3 .ds DW "Tue X.if \n(dw=4 .ds DW "Wed X.if \n(dw=5 .ds DW "Thu X.if \n(dw=6 .ds DW "Fri X.if \n(dw=7 .ds DW "Sat X.\" Dy month day: X.if \n(mo=1 .ds Dy "Jan \n(dy X.if \n(mo=2 .ds Dy "Feb \n(dy X.if \n(mo=3 .ds Dy "Mar \n(dy X.if \n(mo=4 .ds Dy "Apr \n(dy X.if \n(mo=5 .ds Dy "May \n(dy X.if \n(mo=6 .ds Dy "Jun \n(dy X.if \n(mo=7 .ds Dy "Jul \n(dy X.if \n(mo=8 .ds Dy "Aug \n(dy X.if \n(mo=9 .ds Dy "Sep \n(dy X.if \n(mo=10 .ds Dy "Oct \n(dy X.if \n(mo=11 .ds Dy "Nov \n(dy X.if \n(mo=12 .ds Dy "Dec \n(dy X.ds Da "\n(hh:\n(mm:\n(ss \n(mo/\n(dy/\n(yr X.ds Yr "19\n(yr X.ds DY "\*(Dy, \*(Yr X.ds TM "\n(hh:\n(mm:\n(ss X.ds DA "\*(TM \*(DY X.ds CT "\*(DW \*(Dy \*(TM 19\n(yr X.\" X.\" they look like this: X.\" X.\" DW Sun X.\" Dy Mar 4 X.\" DY Mar 4, 1990 X.\" Yr 1990 X.\" TM 16:34:00 X.\" DA 16:34:00 Mar 4, 1990 X.\" Da 16:34:00 2/4/90 X.\" CT Sun Mar 4 16:34:00 1990 like ctime(2) X.\" X.\" ************************************************************************** X.\" X.\" startup stuff... X.\" X.\" X is number register used internally here. it is initially 0. it gets X.\" set to 1 in TH if ONLINE is set. it is used in the EX macro to force X.\" an immediate exit at the end. X.\" X.in 0.0i X.po 0.0i X.lt 7.2i X.ll 7.2i X.m1 3 X.m2 3 X.m3 3 X.m4 3 X.nr X 0 X.\" X.\" ************************************************************************** X.\" X.\" MACROS... X.\" X.\" ----------------------------------------------------------------------- TH X.\" main page heading X.\" X.\" fields are usually: 1-name, 2-section, 3-section name, 4-version, 5-date X.\" 1,2,3 are on header, 4,5 and page on footer. empty strings are skipped X.\" by making the arg "". this must be first! there is an extra field at the X.\" end ($6) which, if "ONLINE", prints the page without page breaks (i.e. X.\" headers/footers). X.\" X.\" $1 $2 $3 X.\" | | | X.\" v v v X.\" NAME (1) Section NAME (1) X.\" ... X.\" Version Date Page n X.\" ^ ^ X.\" | | X.\" $4 $5 X.\" X.\" .TH NAME 1 "Commands" "Version 1.0" "7 March 1990" ["ONLINE"] X.\" X.\" there is an extension here: if the 6th argument is "ONLINE" then the X.\" resultant output does not have any headers/footers. this is useful for X.\" making manpages for online use. X.\" X.de TH X.\" define Se as default chapter name based on input chapter number X.if $2=0 .ds Se "General Information X.if $2=1 .ds Se "Commands and Applications X.if $2=2 .ds Se "System Calls X.if $2=3 .ds Se "Library Calls X.if $2=4 .ds Se "Hardware and Special Files X.if $2=5 .ds Se "File Formats X.if $2=6 .ds Se "Games X.if $2=7 .ds Se "Miscellaneous X.if $2=8 .ds Se "Administation Commands X.\" if the 6th arg is "ONLINE", set up for online docs output (no head/foot) X.if !"$6"ONLINE" .pl 66 X.if "$6"ONLINE" .m1 0 X.if "$6"ONLINE" .m2 0 X.if "$6"ONLINE" .m3 0 X.if "$6"ONLINE" .m4 0 X.if !"$6"ONLINE" .tl |$1 ($2)|$3|$1 ($2)| X.if !"$6"ONLINE" .if "$3"" .tl |$1 ($2)|\*(Se|$1 ($2)| X.if !"$6"ONLINE" .fo |$4|$5|Page %| X.if !"$6"ONLINE" .if "$4"" .fo |\*(CT|$5|Page %| X.\" this is used by macro EX (exit) X.if "$6"ONLINE" .nr X 1 X.\" change to 0.5i for "normal" nroff output... X.in 0.8i X.. X.\" ----------------------------------------------------------------------- Th X.\" alternate main page heading X.\" X.\" this prints no header/footer so it is good for creating online docs X.\" for man(1). it ignores all args. X.\" X.\" .Th NAME 1 X.\" X.de Th X.m1 0 X.m2 0 X.m3 0 X.m4 0 X.\" change to 0.5i for "normal" nroff output... X.in 0.8i X.nr X 1 X.. X.\" ----------------------------------------------------------------------- EX X.\" exit NOW! (no extra space at end of document) X.\" X.de EX X.if \nX=1 .sp X.if \nX=1 .ex X.. X.\" ----------------------------------------------------------------------- RS X.\" start relative indent X.\" X.de RS X.br X.\" change to 0.5i for "normal" nroff output... X.in +0.8i X.. X.\" ----------------------------------------------------------------------- RE X.\" end relative indent X.\" X.de RE X.br X.\" change to 0.5i for "normal" nroff output... X.in -0.8i X.. X.\" ----------------------------------------------------------------------- IP X.\" indented paragraph with tag (from this line) X.\" X.de IP X.br X.sp 1 X.\" change to 0.5i for "normal" nroff output... X.in 0.8i X\&$1 $2 $3 $4 $5 $6 $7 $8 $9 X.br X.\" change to 0.5i for "normal" nroff output... X.in +0.8i X.. X.\" ----------------------------------------------------------------------- HP X.\" indented paragraph without tag (from this line) X.\" X.de HP X.br X.sp 1 X.\" change to 0.5i for "normal" nroff output... X.in 0.8i X.in +0.8i X.. X.\" ----------------------------------------------------------------------- RP X.\" relative indented paragraph with tag. MUST end with .RE X.\" X.de RP X.br X.sp 1 X.\".if !\\n(.i>8 .in 0.8i X\&$1 $2 $3 $4 $5 $6 $7 $8 $9 X.br X.\" change to 0.5i for "normal" nroff output... X.in +0.8i X.. X.\" ----------------------------------------------------------------------- pp X.\" start a new indented paragraph X.\" X.de pp X.sp 1 X.\" change to 0.5i for "normal" nroff output... X.in 0.8i X.ti +0.8i X.. X.\" ----------------------------------------------------------------------- PP X.\" start a new unindented paragraph X.\" X.de PP X.sp 1 X.\" change to 0.5i for "normal" nroff output... X.in 0.8i X.. X.\" ----------------------------------------------------------------------- LP X.\" start a new unindented paragraph (same as PP) X.\" X.de LP X.sp 1 X.\" change to 0.5i for "normal" nroff output... X.in 0.8i X.. X.\" ----------------------------------------------------------------------- SH X.\" main section heading X.\" X.de SH X.sp 1 X.ne 3 X.\" change to 0.5i for "normal" nroff output... X.in 0.8i X.ti -0.8i X.\".bo X\&$1 $2 $3 $4 $5 $6 $7 $8 $9 X.br X.. X.\" ----------------------------------------------------------------------- SS X.\" subsection heading, same indent X.\" X.de SS X.sp 1 X.ne 3 X.\" change to 0.5i for "normal" nroff output... X.in 0.8i X.\".bo X\&$1 $2 $3 $4 $5 $6 $7 $8 $9 X.sp X.. X.\" ----------------------------------------------------------------------- I X.\" italic text (must handle at least 2 args) X.\" X.de I X\&\fI$1\fR$2 X.. X.\" ----------------------------------------------------------------------- B X.\" bold text (must handle at least 2 args) X.\" X.de B X\&\fB$1\fR$2 X.. X.\" ----------------------------------------------------------------------- R X.\" Roman text X.\" X.de R X\&\fR$1$2 X.. X.\" ----------------------------------------------------------------------- IR X.\" alternate italic and Roman text (must handle at least 6 args) X.\" X.de IR X\&\fI$1\fR$2\fI$3\fR$4\fI$5\fR$6 X.. X.\" ----------------------------------------------------------------------- RI X.\" alternate Roman and italic text (must handle at least 6 args) X.\" X.de RI X\&\fR$1\fI$2\fR$3\fI$4\fR$5\fI$6\fR X.. X.\" ----------------------------------------------------------------------- BR X.\" alternate bold and Roman text (must handle at least 6 args) X.\" X.de BR X\&\fB$1\fR$2\fB$3\fR$4\fB$5\fR$6 X.. X.\" ----------------------------------------------------------------------- RB X.\" alternate Roman and bold text (must handle at least 6 args) X.\" X.de RB X\&\fR$1\fB$2\fR$3\fB$4\fR$5\fB$6\fR X.. X.\" ----------------------------------------------------------------------- SM X.\" small text X.\" X.de SM X\&\fB$1\fR X.. X.\" ----------------------------------------------------------------------- IX X.\" make index entry (ignored by this nroff...) X.\" X.de IX X.. X.\" ----------------------------------------------------------------------- }D X.\" debug. use (e.g. print current indent): X.\" X.\" .}D .br X.\" .}D "** DEBUG ** before RS \n(.i" X.\" X.de }D X.if \nZ>0 \&$1 X.. X END_OF_tmac.an if test 8405 -ne `wc -c