home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume21
/
ro
/
part01
next >
Wrap
Text File
|
1990-02-05
|
56KB
|
2,124 lines
Subject: v21i003: A text formatter with some nroff-like capabilities, Part01/03
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: tcamp@dukeac.UUCP (Ted A. Campbell)
Posting-number: Volume 21, Issue 3
Archive-name: ro/part01
ro is a text formatter with many of the capabilities of nroff. It is
based on a long line of CP/M and MSDOS formatters, going back to the ROFF
formatter described in Kernigan and Plauger's <Software Tools.> Makefiles
are included for DOS and Unix. Freeware.
#--------------------------------CUT HERE-------------------------------------
#! /bin/sh
#
# This is a shell archive. Save this into a file, edit it
# and delete all lines above this comment. Then give this
# file to sh by executing the command "sh file". The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-r--r-- 1 tcamp users 2644 Nov 24 13:07 README
# -rw-r--r-- 1 tcamp users 14206 Nov 24 12:50 ro.h
# -rw-r--r-- 1 tcamp users 15015 Nov 24 12:49 ro.c
# -rw-r--r-- 1 tcamp users 7405 Nov 24 12:50 ro_proc.c
# -rw-r--r-- 1 tcamp users 11762 Nov 24 12:50 ro_macr.c
#
echo 'x - README'
if test -f README; then echo 'shar: not overwriting README'; else
sed 's/^X//' << '________This_Is_The_END________' > README
Xro version 1.00 -- Release of Source Code
X-----------------------------------------
X
X
XDescription:
X-----------
X
X"ro" is a text formatter with some of the capabilities
Xof the Unix (tm, AT&T) "nroff" text formatter. It is
Xbased on an honorable tradition of CP/M and DOS formatters
Xwhich go back to the ROFF formatter described in Kernigan
Xand Plauger's <Software Tools>. It is copyrighted and
Xdistributed as "freeware," i.e., you can use it for any
Xpurpose as long as you don't make money off of it, or
Xtry to claim that you wrote it.
X
XThe "ro.qrf" file will give an overview of the capabilities
Xof the formatter.
X
XThe sourcecode has been compiled on an XT clone using
Xthe Microsoft QuickC (tm) compiler, and on the AT&T
XUnix PC and 3B15 computers using the stock Unix C
Xcompilers.
X
X
XFiles:
X-----
X
X ro.h general include file
X ro.c main program module
X ro_proc.c various procedures
X ro_macr.c macro procedures
X ro_dive.c diversion procedures
X ro_word.c word-handling procedures
X ro_text.c text-handling procedures
X ro_setp.c parameter setting procedures
X ro_outp.c output procedures
X
X Makefile Unix makefile
X ro.mak QuickC makefile
X
X term.h include file for filters
X termnull.c null filter -- strips out all printer codes
X termansi.c ANSI filter -- sets printer codes for ANSI terminal
X termnx10.c NX10 filter -- sets printer codes for NX 10 printer
X
X ro.doc primary documentation in "ro" format
X ro.qrf quick reference guide
X tmac.m a macro package
X test.doc test document showing use of end-note macros
X README this document
X
X
XReading and printing the manual:
X-------------------------------
X
XThe manual (file "ro.doc") is in "ro" format, and must be read
Xusing "ro" and a filter program. If you have the Unix or DOS
Xpager "more" installed in your path, you can read it page-by-
Xpage with the command
X
X ro ro.doc | termnull | more
X
XIf your DOS computer has ANSI.SYS installed, or your Unix terminal
Xsupports ANSI escape sequences, the following command will show
Xbold as bold and italics as underline:
X
X ro ro.doc | termansi | more
X
XThe manual can br printed to any printer with the command(s):
X
X ro ro.doc | termnull | lp (Unix)
X ro ro.doc | termnull >prn (DOS)
X
XWith the Star Micronics NX10 printer, you may substitute
X"termnx10" for "termnull" in the above command lines. Instructions
Xfor creating filters for other printers are included in "ro.doc".
X
XBinaries:
X-----------
X
XPC-compatible binaries have been posted to comp.binaries.ibm.pc.
X
X
XCommunications:
X--------------
X
XTed A. Campbell
XBywater Software
XBox 4023
XDuke Station
XDurham, NC 27706
X
XInternet: tcamp@dukeac.ac.duke.edu
XGENIE: T.CAMPBELL1
________This_Is_The_END________
if test `wc -l < README` -ne 95; then
echo 'shar: README was damaged during transit (should have been 95 bytes)'
fi
fi ; : end of overwriting check
echo 'x - ro.h'
if test -f ro.h; then echo 'shar: not overwriting ro.h'; else
sed 's/^X//' << '________This_Is_The_END________' > ro.h
X/********************************************************/
X/* */
X/* ro.h General header file for ro */
X/* */
X/* ro version 1.00 */
X/* */
X/* Portions copyright (c) 1989 by Ted A. Campbell */
X/* Bywater Software */
X/* P. O. Box 4023 */
X/* Duke Station */
X/* Durham, NC 27706 */
X/* */
X/* Contains portions of ROFF4, Version 1.60 */
X/* (c) 1983, 4 by Ernest E. Bergmann */
X/* Physics, Building #16 */
X/* Lehigh University */
X/* Bethlehem, Pa. 18015 */
X/* */
X/* Contains portions of ROFF4, Version 1.61 */
X/* (c) 1985 by Konrad Kwok */
X/* 20 3rd Street, Section M */
X/* Fariview Park, */
X/* Hong Kong */
X/* */
X/* ro and its predecessor ROFF4 are based on */
X/* the ROFF text processor described in Kernigan */
X/* and Plauger's now-classic text <Software Tools> */
X/* */
X/* Permission is hereby granted for all commercial and */
X/* non-commercial reproduction and distribution of this */
X/* material provided this notice is included. */
X/* */
X/********************************************************/
X
X/************* INCLUDE FILES ****************************/
X
X#include "stdio.h"
X#include "ctype.h"
X#include "time.h"
X
X#ifdef __STDC__
X#include "stdlib.h"
X#include "malloc.h"
X#else
X#define size_t int
X#define time_t long
X#endif
X
X/****** PROGRAM DEFINITIONS *****************************/
X
X/*** User-Definable Options ***/
X
X#define NONROFF /* allow non-nroff-standard features */
X
X/*** End of User-Definable Options ***/
X
X#define ro_ X /* shorten names for limited compilers */
X
X#define MAXLINE 255
X#define TRUE 1
X#define FALSE 0
X#define ERROR (-1)
X#define OK 0
X
X#define TBUFSIZE 4096 /* Size of temporary holding buffer */
X#define BACKSIZE 4096 /* Size of backup buffer */
X#define STKSIZ 4
X#define DEBUG ( debug != 0 )
X#define HUGE 135 /* generally large number */
X#define LSZ 511 /* line buffer size*/
X#define COMMAND '.' /* all commands starts with this */
X
X#define UNKNOWN -1 /* returned if doesn't recg. command */
X#define NO_VAL -32760 /* returned when no argument w/commad */
X#define WE_HAVE_A_WORD 1 /* returned by getwrd func. */
X#define NO 0
X#define YES 1
X#define UNDERLINE '\137'
X
X/*** Character Definitions */
X
X#define CR 0x0D
X#define BACKSPACE '\b'
X#define BELL '\007'
X#define NUMSIGN '#' /* for title strings */
X#define NEWLINE '\n'
X#define TAB '\t'
X#define BLANK ' '
X#define FORMF 0x0C /* formfeed for printer */
X#define ESCAPE 0x1b /* escape character */
X#define SQUOTE 0x27 /* single quote */
X#define DQUOTE 0x22 /* double quote */
X#define BACKSLASH 0x5c /* backslash */
X#define PASSBACK 0xeee /* a random large number to pass a literal
X backslash back into the input stream */
X
X/** Single-character printer code designations ***/
X
X#define ROMAN 'R' /* Restore "roman" or "regular" font */
X /* Should turn off Bold and Italic */
X#define ITALIC 'I' /* Switch to italics or underline */
X#define BOLD 'B' /* Switch to bold */
X#define HALFUP 'u' /* Half-line up */
X#define HALFDOWN 'd' /* Half-line down */
X
X#define TRANSLATE 2 /* May 23, 1983*/
X#define BLACK 1
X#define WHITE 0
X#define CONTROL -1
X#define SENTINEL -2
X#define HTAB -3
X#define OTHERS -4
X#define XCHAR '-'
X#define UCHAR '_'
X
X/* defaults for global parameters */
X
X#define FI_DEF 1
X#define LS_DEF 1
X#define IN_DEF 0
X#define RM_DEF 70
X#define TI_DEF 0
X#define CE_DEF 1
X#define UL_DEF -1
X#define M1_DEF 2
X#define M2_DEF 2
X#define M3_DEF 2
X#define M4_DEF 2
X#define PL_DEF 66
X#define FF_DEF YES /* .ff defaults to "on" */
X#define FF_INI NO /* initial setting*/
X#define SC_INI BLANK
X#define TS_DEF 8 /*standard tabsize*/
X#define TC_DEF '~' /*translation flag default*/
X#define CF_DEF '^' /*Dec 4*/
X#define IC_DEF '\\'
X#define CW_DEF 12 /* 12/120" */
X#define JU_INI YES /* right adjust (justification) */
X#define PO_DEF 0 /* page offset */
X#define REGDEF 0 /*default for register var.*/
X /*when .rg has no numeric arg*/
X
X#define REVSCROLL FALSE
X#define CANBS FALSE
X
X#define FMAX 8 /* # of additional files open*/
X
X/* defaults for global parameters */
X
X#define FI_DEF 1
X#define LS_DEF 1
X#define IN_DEF 0
X#define RM_DEF 70
X#define TI_DEF 0
X#define CE_DEF 1
X#define UL_DEF -1
X#define M1_DEF 2
X#define M2_DEF 2
X#define M3_DEF 2
X#define M4_DEF 2
X#define PL_DEF 66
X#define FF_DEF YES /* .ff defaults to "on" */
X#define FF_INI NO /* initial setting*/
X#define SC_INI BLANK
X#define TS_DEF 8 /*standard tabsize*/
X#define TC_DEF '~' /*translation flag default*/
X#define CF_DEF '^' /*Dec 4*/
X#define IC_DEF '\\'
X#define CW_DEF 12 /* 12/120" */
X#define JU_INI YES /*right justification*/
X#define REGDEF 0 /*default for register var.*/
X /*when .rg has no numeric arg*/
X
X#define REVSCROLL FALSE
X#define CANBS FALSE
X
X#define FMAX 8 /* # of additional files open*/
X
X#define FI 1 /* fill lines */
X#define TI 2 /* temporary indent */
X#define BP 3 /* begin page */
X#define BR 4 /* causes break */
X#define CE 5 /* center line(s) */
X#define IN 7 /* left indent */
X#define LS 8 /* line spacing */
X#define NF 9 /* no fill */
X#define PL 10 /* set page length */
X#define LL 11 /* set line length (right margin) */
X#define SP 12 /* add blank line(s) */
X#define ST 13 /* stop(pause) at page start?*/
X#define FO 14 /* footer title */
X#define HE 15 /* header title */
X#define M1 16 /* top margin */
X#define M2 17 /* second top margin */
X#define M3 18 /* first bottom margin */
X#define M4 19 /* bottom-most margin */
X#define IG 20 /* "ignore";comments,Nov 6,82*/
X#define NE 21 /* "need";Nov 7,82*/
X#define FF 22 /* "formfeed";Nov 10*/
X#define SC 23 /* "space character";Nov13*/
X#define TA 25 /* "tabsize";Nov 13*/
X#define EH 26 /* "even headers";Nov 14*/
X#define OH 27 /* "odd headers"*/
X#define EF 28 /* "even footers"*/
X#define OF 29 /* "odd footers"*/
X#define EX 30 /* exit ("abort") */
X#define DB 31 /* "debug"*/
X#define TC 32 /* "translation flag char"*/
X#define TR 33 /* "def translation string"*/
X#define CF 34 /* Dec 4:control flag char*/
X#define IC 35 /* insert character */
X#define AD 37 /* adjust (justify) output lines */
X#define NA 38 /* no adjust of output lines */
X#define WH 39 /* whole line spacing code */
X#define FR 40 /* fractional spacing,code */
X#define DS 41 /* define string*/
X#define DE 42 /* define macro*/
X#define EM 43 /* end macro*/
X#define NR 44 /* register variable*/
X#define DI 45 /* diversion*/
X#define SO 47 /* "source", include*/
X#define PC 48 /* printer control definition*/
X#define TM 49 /* send inline msg to terminal */
X#define BJ 50 /* break with right justification
X of current line */
X#define PM 51 /* print macro names */
X#define FT 52 /* set font */
X#define PO 53 /* page offset */
X#define SS 54 /* show strings */
X#define SR 55 /* show registers */
X
X/****** GLOBAL VARIABLES ********************************/
X
XFILE *_dobuf, *instream; /* i/o buffer used for direction */
Xint debug; /* Boolean: debug mode on/off */
Xint ro_verbose; /* Boolean: verbose mode on/off */
Xint ro_pagestop;
Xint ro_adjust;
Xint ro_useff;
Xint ro_firstpage, ro_lastpage; /* for selectively printing output*/
Xint ro_suppress; /* if true,no output is passed by putchar()*/
Xint ro_tival; /* temporary indent -> default 0 */
Xint ro_ceval; /* set equal to number of lines to be centered */
Xint ro_spval; /* blank lines to be spaced down */
Xint ro_curpag; /* current output page number; init = 0 */
Xint ro_newpag; /* next output page number; init = 1 */
Xint ro_vlineno; /* virtual (intended) line advances on page,
X see vadv()*/
Xint ro_vflineno; /* + line fraction */
Xint ro_plineno; /* printer's actual line advances on page,
X see padv()*/
Xint ro_pflineno; /* + line fraction */
Xint ro_bottom; /* end of text area in lines;start of M3+M4 */
Xint ro_sentence; /* Nov 20*/
Xint ro_poval; /* page offset */
X
X/*** Stack variables
X
X The following variables are assigned to a stack and when
X a new value is assigned, it is "pushed" onto the stack,
X and when read, "popped" off. The stack is read from
X the bottom. ***/
X
Xint ro_fill[STKSIZ]; /* set to YES or NO */
Xint ro_lsval[STKSIZ]; /* line spacing value -> default will be 1 */
Xint ro_inval[STKSIZ]; /* left indent -> default 0 */
Xint ro_rmval[STKSIZ]; /* right margin -> default PAGEWIDTH */
Xint ro_tcval[STKSIZ]; /* translation flag char */
Xint ro_plval[STKSIZ]; /* page length in lines */
Xint ro_m1val[STKSIZ]; /* margin before& including header in lines */
Xint ro_m2val[STKSIZ]; /* margin after header in lines */
Xint ro_m3val[STKSIZ]; /* margin after last text line in lines */
Xint ro_m4val[STKSIZ]; /* bottom margin, including footer in lines */
Xint ro_scval[STKSIZ]; /* space character */
Xint ro_tabsiz[STKSIZ]; /* spacing of tabstops */
Xint ro_cfval[STKSIZ]; /* Dec 4:control flag character value */
Xint ro_icval[STKSIZ]; /* insert character */
X
Xchar ro_curline[ LSZ ]; /*input line buffer, Nov 26 */
Xchar ro_ehead[ LSZ ], ro_eh2[ LSZ ], ro_eh3[ LSZ ]; /* even header title */
Xchar ro_ohead[ LSZ ], ro_oh2[ LSZ ], ro_oh3[ LSZ ]; /* odd header title */
Xchar ro_efoot[ LSZ ], ro_ef2[ LSZ ], ro_ef3[ LSZ ]; /* even footer title */
Xchar ro_ofoot[ LSZ ], ro_of2[ LSZ ], ro_of3[ LSZ ]; /* even footer title */
X
Xstruct divfd /* diversion file descriptor */
X {
X char nm[ 36 ]; /* name */
X char fn[ 64 ]; /* name of diversion file (not source file) */
X int cs; /* character count */
X int ls; /* line count */
X int val; /* value for register */
X char *mstr; /* pointer to macro character string */
X FILE *bf; /* to instream if open, FALSE otherwise */
X struct divfd *prev;
X };
X
Xchar tbuf[ TBUFSIZE ]; /* a temporary buffer */
Xint ro_dir; /* for "spreading" of lines */
Xint ro_outwrds; /* no. words in ro_outbuf; init = 0 */
Xchar ro_outbuf[ LSZ ]; /*lines to be filled collected here */
Xint ro_outw; /*current display width of ro_outbuf */
Xint ro_outpos; /* =strlen(ro_outbuf) */
Xint ro_wtop, ro_ltop, ro_outtop; /*zero|negative;levels of subscripts */
Xint ro_wbot, ro_lbot, ro_outbot; /*zero|positive;levels of subscripts */
Xint ro_oldln; /*position of previous main line */
Xint ro_oldbot; /*ro_outbot for previous line;reset
X each page */
Xint ro_frq, ro_frval; /* fractional line?, what fraction size */
Xchar *ro_frstring; /* ^ to code for fractional spacing */
Xchar *ro_whstring; /* ^ to code for whole line spacing */
Xchar *ro_cptr[128-' ']; /*pointer table for print control */
Xchar *ro_tptr[128-' ']; /*pointer table for translation strings
X for char; initialize to null */
X
Xstruct divfd *dlink; /* points to head of diversion list */
Xstruct divfd *rlink; /* points to head of register variable list */
Xstruct divfd *slink; /* points to head of linked string list */
Xstruct divfd *mlink; /* points to head of linked macro list */
X
X/*following added for buffered and formatted output: */
X
Xchar ro_out2buf[LSZ]; /*for line to be output in fancy fmt */
Xint ro_bpos, ro_cp, ro_pp; /*buffer,column,printer positions */
Xchar ro_xbuf[LSZ]; /*strikout buffer */
Xint ro_xf, ro_xcol; /* " flag and column */
Xchar ro_ubuf[LSZ]; /*underline buffer */
Xint ro_uf, ro_ucol; /* " flag and column */
Xint ro_first; /*flag for first pass */
Xchar ro_dbuf[LSZ]; /*double strike buffer */
Xint ro_dpos;
Xint ro_ocnt;
Xint ro_mcnt;
Xint ro_blkcnt;
X
Xint ro_newxf, ro_newuf, ro_newmcnt; /* 3rd Mar,85 ; Conrad Kwok */
Xchar ro_lastch; /* 5th Mar,85 ; Conrad Kwok */
X
Xchar ro_backbuf[BACKSIZE]; /* Backup buffer */
Xint ro_binp; /* Position in above;init to 0 */
Xchar ro_keybd; /*boolean & prompt for keyboard input */
Xchar ro_kline[MAXLINE]; /*keyboard line input buffer */
Xchar *ro_kptr; /*pointer for above */
X
Xint ro_fptr;
XFILE *ro_fstack[FMAX];
Xint ro_tflag;/*added for start(), complete() */
Xint ro_xf2, ro_uf2, ro_mcnt2;
X
X/****** DECLARATIONS FOR EXTERNAL FUNCTIONS ************ */
X
X/* Declarations of externals
X *
X *
X */
X
X#ifndef __STDC__
Xextern char *malloc();
X#endif
Xextern char *macq();
Xextern struct divfd * find2();
Xextern char ro_getch();
X
X/******** END OF FILE ***********************************/
X
X
________This_Is_The_END________
if test `wc -l < ro.h` -ne 365; then
echo 'shar: ro.h was damaged during transit (should have been 365 bytes)'
fi
fi ; : end of overwriting check
echo 'x - ro.c'
if test -f ro.c; then echo 'shar: not overwriting ro.c'; else
sed 's/^X//' << '________This_Is_The_END________' > ro.c
X/********************************************************/
X/* */
X/* ro.c main program file for ro */
X/* */
X/* ro version 1.00 */
X/* */
X/* Portions copyright (c) 1989 by Ted A. Campbell */
X/* Bywater Software */
X/* P. O. Box 4023 */
X/* Duke Station */
X/* Durham, NC 27706 */
X/* */
X/* Contains portions of ROFF4, Version 1.60 */
X/* (c) 1983, 4 by Ernest E. Bergmann */
X/* Physics, Building #16 */
X/* Lehigh University */
X/* Bethlehem, Pa. 18015 */
X/* */
X/* Contains portions of ROFF4, Version 1.61 */
X/* (c) 1985 by Konrad Kwok */
X/* 20 3rd Street, Section M */
X/* Fariview Park, */
X/* Hong Kong */
X/* */
X/* ro and its predecessor ROFF4 are based on */
X/* the ROFF text processor described in Kernigan */
X/* and Plauger's now-classic text <Software Tools> */
X/* */
X/* Permission is hereby granted for all commercial and */
X/* non-commercial reproduction and distribution of this */
X/* material provided this notice is included. */
X/* */
X/********************************************************/
X
X#include "ro.h"
X
Xextern char *ro_gets();
X
Xint ro_iline = 0;
Xint ro_deno = 0;
X
X/*****************MAIN************MAIN*********/
X
Xmain( argc, argv )
X int argc;
X char **argv;
X {
X register int n;
X int fs;
X char option, *pc;
X char filename[20];
X struct divfd *pd;
X
X ro_lastch = NULL;
X debug = FALSE;
X ro_verbose = FALSE;
X
X init_defaults();
X
X /*** First process any flags ***/
X
X for ( n = 1; n < argc; ++n )
X {
X strcpy( filename, argv[ n ] );
X
X if ( filename[0] == '-' )
X {
X option = filename[1];
X if ( option == 's' ) ro_pagestop = TRUE;
X else if ( option == 'o' ) range( &filename[2] );
X else if ( option == 'f' ) ro_useff = TRUE;
X else if ( option == 'x' )
X {
X debug = TRUE;
X ro_verbose = TRUE;
X }
X else if ( option == 'v' ) ro_verbose = TRUE;
X continue;
X }
X }
X
X if ( ro_verbose == TRUE )
X {
X fprintf( stderr, "ro, version 1.00 \n" );
X }
X
X if DEBUG
X {
X fprintf( stderr, "DEBUG: initial .ls setting is %d. \n",
X ro_lsval[0] );
X }
X
X /* Now process all files named */
X
X fs = 0;
X
X for ( n = 1; n < argc; ++n )
X {
X strcpy( filename, argv[ n ] );
X if ( filename[0] != '-' )
X {
X
X if( pd = find2( filename, dlink ))
X {
X dclose( pd );
X }
X
X if (( instream = fopen( filename, "r" )) == NULL )
X {
X fprintf( stderr, "Can't open <%s> for input.\n", filename );
X }
X else
X {
X ++fs; /* inc. number of files */
X if ( ro_verbose == TRUE )
X {
X fprintf( stderr, "Processing <%s>\n", filename );
X }
X dolns();
X }
X }
X }
X
X /* No files opened; take input from stdin */
X
X if ( fs == 0 )
X {
X if ( ro_verbose && ro_pagestop )
X {
X fprintf( stderr, "ERROR: one cannot use -s (page stop) with standard input. \n" );
X }
X ro_pagestop = FALSE; /* Cannot use page stop if stdin */
X instream = stdin;
X dolns();
X }
X
X ro_brk();
X ro_vlineno = ro_plval[ 0 ];
X padv();
X if ( ro_useff ) putchar( FORMF );
X dsclose(); /* Close all diversions */
X } /* end main() */
X
X/****************************************/
X/* do processing of lines */
X/****************************************/
X
Xdolns()
X {
X char *pc;
X struct divfd *sptr;
X static char name[ 12 ];
X ro_binp = 0;
X
X while ( !feof( instream ) | ro_fptr | ro_binp )
X {
X ro_gets( ro_curline );
X ++ro_iline;
X
X if DEBUG
X {
X fprintf( stderr, "DEBUG: input line # %d <%s> \n",
X ro_iline, ro_curline );
X fprintf( stderr, "DEBUG: ro_curline[0] is <%c> (0x%x)\n",
X ro_curline[0], ro_curline[0] );
X }
X
X if ( ro_curline[ 0 ] == COMMAND )
X {
X name[ 0 ] = ro_curline[ 1 ];
X if ( class( ro_curline[ 2 ] ) == BLACK )
X {
X name[ 1 ] = ro_curline[ 2 ];
X name[ 2 ] = '\0';
X }
X else
X {
X name[ 1 ] = '\0';
X }
X if ( ( pc = macq( ro_curline )) != NULL )
X {
X pbmac( pc, ro_curline );
X }
X else if ( ( sptr = find2( name, dlink )) != NULL )
X {
X read_div( sptr );
X }
X else
X {
X command( ro_curline );
X }
X }
X else
X {
X text( ro_curline );
X }
X if ( feof( instream) )
X {
X endso();
X }
X }
X }
X
Xchar *
Xro_gets( line )
X char *line;
X {
X char *l;
X
X l = line;
X do
X {
X *l = ro_getch();
X ++l;
X }
X while( *(l - 1) != '\n' );
X
X *( l - 1 ) = '\0';
X
X if DEBUG
X {
X fprintf( stderr, "DEBUG: ro_gets() <%s> \n", line );
X }
X
X return line;
X }
X
Xchar
Xro_getch()
X {
X register int c;
X static int bflag = FALSE; /* was last character BACKSLASH? */
X
X while ( TRUE )
X {
X if ( ro_binp == 0 )
X {
X if ( feof( instream ))
X {
X return '\n';
X }
X c = fgetc( instream );
X }
X else
X {
X c = ro_backbuf[ ro_binp-- ];
X }
X switch ( c )
X {
X case EOF:
X bflag = FALSE;
X return '\n';
X break;
X case '\r':
X bflag = FALSE;
X break;
X case BACKSLASH:
X if ( !bflag )
X {
X bflag = TRUE;
X if ( ro_expand() == PASSBACK )
X {
X return BACKSLASH;
X }
X else
X {
X return ro_getch();
X }
X }
X else
X {
X bflag = FALSE;
X return c;
X }
X break;
X default:
X bflag = FALSE;
X return c;
X break;
X }
X }
X }
X
X/**************************************************************
Xinitializes the global variables governing the execution of the
X format commands.
X**************************************************************/
X
Xinit_defaults()
X {
X static time_t now;
X struct tm *ltime;
X
X initsk( ro_fill, FI_DEF); /* yes we want filled lines */
X initsk( ro_lsval, LS_DEF); /* line spacing = 1 */
X initsk( ro_inval, IN_DEF); /* left margin indent 0 */
X initsk( ro_rmval, RM_DEF); /* right margin = page width */
X initsk( ro_tcval, TC_DEF);
X initsk( ro_plval, PL_DEF);
X initsk( ro_m1val, M1_DEF);
X initsk( ro_m2val, M2_DEF);
X initsk( ro_m3val, M3_DEF);
X initsk( ro_m4val, M4_DEF);
X initsk( ro_scval, SC_INI);
X initsk( ro_tabsiz, TS_DEF);
X initsk( ro_cfval, CF_DEF);
X initsk( ro_icval, IC_DEF);
X
X ro_tival = IN_DEF; /* left margin temporary indent 0 */
X ro_ceval = 0; /* next n lines to be centered - 0 */
X ro_pagestop = FALSE;
X ro_useff = FF_INI;
X ro_firstpage = 1;
X ro_lastpage = 30000; /*infinite*/
X ro_adjust = JU_INI;
X ro_poval = PO_DEF;
X
X ro_curpag = 0;
X ro_newpag = 1;
X ro_frq = 0;
X ro_frstring = ro_whstring = NULL;
X ro_frval = 1;
X ro_vflineno = ro_pflineno = ro_plineno = 0;
X ro_vlineno = -1;
X ro_bottom = ro_plval[0] - ro_m3val[0] - ro_m4val[0];
X ro_outw = ro_outpos = ro_outtop = ro_outbot = ro_oldln = ro_oldbot = ro_outwrds = 0;
X ro_outbuf [0] = '\0';
X ro_dir = 0;
X ro_eh2[0] = ro_eh3[0] = ro_ehead[0] = '\0';
X ro_oh2[0] = ro_oh3[0] = ro_ohead[0] = '\0';
X ro_ef2[0] = ro_ef3[0] = ro_efoot[0] = '\0';
X ro_of2[0] = ro_of3[0] = ro_ofoot[0] = '\0';
X memfill( ro_cptr, 2*(128-' '), 0);
X memfill( ro_tptr, 2*(128-' '), 0);
X
X ro_out2buf[ 0 ] = ro_bpos = 0;
X initxu(); /* Initialize overstrike and other variables */
X ro_mcnt=1;
X ro_uf = ro_xf = FALSE;
X memfill( ro_dbuf, LSZ, FALSE);
X ro_dpos = -1;
X ro_fptr = 0;
X mlink = dlink = rlink = slink = NULL;
X ro_kptr = ro_kline;
X *ro_kline=0;
X ro_keybd=FALSE;
X
X /*** now set up some pre-defined registers ***/
X
X time( &now );
X ltime = localtime( &now );
X preregister( "dy", ltime->tm_mday );
X preregister( "mo", ltime->tm_mon );
X preregister( "yr", ltime->tm_year );
X preregister( "%", ro_curpag );
X }
X
X/**************************************************************
Xperforms the formatting command returned by comtyp -sets global
X variables ( indenting, underlining, etc. )
X**************************************************************/
X
Xcommand( line )
X char *line;
X {
X int c_type; /* command type */
X int arg_val; /* argument value, if any */
X static int arg_typ; /* relative (+ or -) or absolute */
X char wbuf[20], *l;
X register int i;
X
X c_type = comtyp (line);
X
X if DEBUG
X {
X fprintf( stderr, "DEBUG: command is %d \n", c_type );
X }
X
X if ( c_type == UNKNOWN )
X {
X if ( ro_verbose )
X fprintf( stderr, "%s: unknown command \n", line);
X return;
X }
X arg_val = get_val( line, &arg_typ );
X
X if DEBUG
X {
X fprintf( stderr, "DEBUG: get_val returned arg_val = %d, arg_typ = %c\n",
X arg_val, arg_typ );
X fprintf( stderr, "DEBUG: c_type is now %d \n", c_type );
X }
X
X switch ( c_type )
X {
X case EM :
X case IG :
X break; /* ignore remark */
X
X case FI : /* filled lines */
X ro_brk();
X ro_fill[0] = YES;
X break;
X
X case NF: /* non-filled lines */
X ro_brk();
X ro_fill[0] = NO;
X break;
X
X case AD : /* adjusted (justified) lines */
X ro_adjust = TRUE;
X break;
X
X case NA : /* non-adjusted lines */
X ro_adjust = FALSE;
X break;
X
X case BR : /* just cause a break */
X ro_brk();
X break;
X
X case LS : /* set line spacing value */
X setS( ro_lsval, arg_val, arg_typ, LS_DEF, 1, HUGE );
X break;
X
X case TI : /* set temporary left indent */
X ro_brk();
X set( &ro_tival, arg_val, arg_typ, TI_DEF, 0, ro_rmval );
X break;
X
X case IN : /* set left indent */
X setS( ro_inval, arg_val, arg_typ, IN_DEF, 0, ro_rmval-1 );
X ro_tival = ro_inval[0];
X break;
X
X case LL : /* set line length (right margin) */
X setS( ro_rmval, arg_val, arg_typ, RM_DEF, ro_tival+1, 256 );
X break;
X
X case CE : /* center next arg_val lines */
X ro_brk();
X set( &ro_ceval, arg_val, arg_typ, CE_DEF, 0, HUGE);
X break;
X
X case SP : /* space down arg_val blank lines */
X set( &ro_spval, arg_val, arg_typ, 1, 0, HUGE);
X do_space ( ro_spval );
X break;
X
X case BP : /* set pageno arg_val - begin page */
X ro_brk();
X if(((ro_vlineno<=0)||(ro_vlineno>=ro_bottom))&&
X (arg_val==NO_VAL))
X {
X break;
X }
X if ( ro_vlineno > 0 )
X {
X do_space (HUGE);
X }
X set( &ro_curpag, arg_val, arg_typ, ro_curpag+1, 0, 9999);
X ro_newpag = ro_curpag;
X break;
X
X case NE : /*"need"*/
X if ( arg_val == NO_VAL )
X {
X arg_val = 2; /*default*/
X }
X need( arg_val );
X break;
X
X case PL : /* set page length */
X setS( ro_plval, arg_val, arg_typ, PL_DEF,
X ro_m1val[0]+ro_m2val[0]+ro_m3val[0]+ro_m4val[0]+1, HUGE);
X ro_bottom = ro_plval[0] - ro_m3val[0] - ro_m4val[0];
X break;
X
X case TA : /*tabsize*/
X setS( ro_tabsiz, arg_val, '0', TS_DEF, 1, HUGE);
X break;
X
X case TC : /* tab character */
X if ( arg_typ )
X {
X arg_val=arg_typ;
X }
X setS( ro_tcval, arg_val, '0', TC_DEF, BLANK+1, 127);
X break;
X
X case FT : /* Set font */
X switch( arg_typ )
X {
X case 'R':
X putback( '\n' );
X putback( ROMAN );
X putback( ESCAPE );
X break;
X case 'I':
X putback( '\n' );
X putback( ITALIC );
X putback( ESCAPE );
X break;
X case 'B':
X putback( '\n' );
X putback( BOLD );
X putback( ESCAPE );
X break;
X default:
X if ( ro_verbose )
X {
X fprintf( stderr,
X "ft: unrecognized font name \"%c\". \n",
X arg_typ );
X }
X }
X break;
X
X case TR : /*translation string defined here*/
X gettr();
X break;
X
X case DS : /*define string*/
X insert();
X break;
X
X case DE : /*define macro*/
X ++ro_deno;
X if DEBUG
X {
X fprintf( stderr, "DEBUG: .de number %d \n",
X ro_deno );
X }
X minsert();
X break;
X
X case NR : /*register variable*/
X dovar();
X break;
X
X case DI : /*diversion to file*/
X dodiv();
X break;
X
X case SO : /*source from file*/
X source();
X break;
X
X case PM : /* print macro definitions */
X showm();
X break;
X
X case PO : /* page offset */
X set( &ro_poval, arg_val, arg_typ, 1, 0, HUGE );
X break;
X
X case TM : /* send message to terminal */
X getwrd(ro_curline, wbuf); /*skip command*/
X skip_blanks(ro_curline);
X trunc_bl(ro_curline);
X fprintf( stderr, "<%s>\n", ro_curline);
X break;
X
X#ifdef NONROFF
X
X case M1: /* set topmost margin */
X setS( ro_m1val, arg_val, arg_typ, M1_DEF, 0, HUGE);
X break;
X
X case M2: /* set second top margin */
X setS( ro_m2val, arg_val, arg_typ, M2_DEF, 0, HUGE);
X break;
X
X case M3: /* set first bottom margin */
X setS( ro_m3val, arg_val, arg_typ, M3_DEF, 0, HUGE);
X ro_bottom = ro_plval[0] - ro_m3val[0] - ro_m4val[0];
X break;
X
X case M4: /* set bottom-most margin */
X setS( ro_m4val, arg_val, arg_typ, M4_DEF, 0, HUGE);
X ro_bottom = ro_plval[0] - ro_m3val[0] - ro_m4val[0];
X break;
X
X case HE : /* get header title for pages */
X gettl3 ( line, ro_ehead, ro_eh2, ro_eh3 );
X gettl3 ( line, ro_ohead, ro_oh2, ro_oh3 );
X break;
X
X case OH : /*get odd header title*/
X gettl3 ( line, ro_ohead, ro_oh2, ro_oh3 );
X break;
X
X case EH : /*get even header title*/
X gettl3 ( line, ro_ehead, ro_eh2, ro_eh3 );
X break;
X
X case FO : /* get footer title for pages */
X gettl3 ( line, ro_efoot, ro_ef2, ro_ef3 );
X gettl3 ( line, ro_ofoot, ro_of2, ro_of3 );
X break;
X
X case OF : /* get odd page footer title*/
X gettl3 ( line, ro_ofoot, ro_of2, ro_of3 );
X break;
X
X case EF : /* get even page footer title*/
X gettl3 ( line, ro_efoot, ro_ef2, ro_ef3 );
X break;
X
X case ST : /* stop(pause) at each page?*/
X set( &ro_pagestop, arg_val, '0', YES, NO, YES);
X break;
X
X case BJ : /*break with right justification*/
X if(ro_fill)/*not applicable otherwise*/
X {
X spread(ro_outbuf,
X ro_min(ro_rmval-ro_tival, MAXLINE-1)-ro_outw+1,
X ro_outwrds);
X ro_brk();
X }
X break;
X
X case FF : /*formfeed*/
X set( &ro_useff, arg_val, '0', FF_DEF, NO, YES);
X break;
X
X case SC : /*space character*/
X if ( arg_typ )
X {
X arg_val=arg_typ;
X }
X setS( ro_scval, arg_val, '0', SC_INI, BLANK, 127);
X break;
X
X case EX : /* exit (abort) */
X if ( ro_verbose )
X fprintf( stderr, ".ex: user abort. \n");
X exit(-1); /* tac */
X
X case CF : /*translate character flag*/
X if ( arg_typ )
X {
X arg_val=arg_typ;
X }
X setS( ro_cfval, arg_val, '0', CF_DEF, BLANK+1, 127);
X break;
X
X case IC : /* insert character for macro replace */
X if ( arg_typ )
X {
X arg_val = arg_typ;
X }
X setS( ro_icval, arg_val, '0', IC_DEF, BLANK+1, 127 );
X break;
X
X case SR : /* print register definitions */
X showr();
X break;
X
X case SS : /* print string definitions */
X showit();
X break;
X
X case DB : /* debug */
X set( &debug, arg_val, '0', NO, NO, YES);
X if DEBUG
X {
X fprintf( stderr, "Debug on...\n");
X }
X else
X {
X fprintf( stderr, "...end of debug. \n");
X }
X break;
X#endif
X
X default :
X if ( ro_verbose )
X {
X fprintf( stderr, "Command %d not found.\n", c_type );
X fprintf( stderr, " line: <%s> \n", line );
X }
X break;
X }
X }
X
Xrange( s )
X char *s;
X {
X int num;
X num=0;
X while(isdigit(*s)) num=num*10+(*(s++)-'0');
X if(num) ro_firstpage=num;
X if(*s=='-')
X {
X s++;
X num=0;
X while(isdigit(*s)) num=num*10+(*(s++)-'0');
X if(num) ro_lastpage=num;
X }
X else ro_lastpage = ro_firstpage;
X }
X
Xro_min( n1, n2 )
X int n1, n2;
X {
X if ( n1 > n2 )
X {
X return n2;
X }
X else
X {
X return n1;
X }
X }
X
Xro_max( n1, n2 )
X int n1, n2;
X {
X if ( n1 < n2 )
X {
X return n2;
X }
X else
X {
X return n1;
X }
X }
X
Xmemfill( b, n, c )
X char *b;
X int n;
X char c;
X {
X register int x;
X char *y;
X
X y = b;
X for ( x = 0; x < n; ++x )
X {
X *y = c;
X }
X }
X
________This_Is_The_END________
if test `wc -l < ro.c` -ne 745; then
echo 'shar: ro.c was damaged during transit (should have been 745 bytes)'
fi
fi ; : end of overwriting check
echo 'x - ro_proc.c'
if test -f ro_proc.c; then echo 'shar: not overwriting ro_proc.c'; else
sed 's/^X//' << '________This_Is_The_END________' > ro_proc.c
X/********************************************************/
X/* */
X/* ro_proc.c various procedures for ro */
X/* */
X/* ro version 1.00 */
X/* */
X/* Portions copyright (c) 1989 by Ted A. Campbell */
X/* Bywater Software */
X/* P. O. Box 4023 */
X/* Duke Station */
X/* Durham, NC 27706 */
X/* */
X/* Contains portions of ROFF4, Version 1.60 */
X/* (c) 1983, 4 by Ernest E. Bergmann */
X/* Physics, Building #16 */
X/* Lehigh University */
X/* Bethlehem, Pa. 18015 */
X/* */
X/* Contains portions of ROFF4, Version 1.61 */
X/* (c) 1985 by Konrad Kwok */
X/* 20 3rd Street, Section M */
X/* Fariview Park, */
X/* Hong Kong */
X/* */
X/* ro and its predecessor ROFF4 are based on */
X/* the ROFF text processor described in Kernigan */
X/* and Plauger's now-classic text <Software Tools> */
X/* */
X/* Permission is hereby granted for all commercial and */
X/* non-commercial reproduction and distribution of this */
X/* material provided this notice is included. */
X/* */
X/********************************************************/
X
X#include "ro.h"
X
X/**********************************************************
XRemoves white-space characters at start of string.
X***********************************************************/
X
Xskip_blanks ( string )
X char *string; /* cursor to original string */
X {
X char *p; /* cursor to 'final' string */
X for(p=string;*string==BLANK||*string==TAB||*string==NEWLINE;
X string++);
X while(*(p++) = *(string++));
X }
X
X/*************************************************************/
X
Xint comtyp (line)
X char *line;
X {
X char let1, let2;
X let1 = line[1];
X let2 = line[2];
X
X if ( let1==COMMAND ) return( EM ); /* end macro or comment */
X if ( let1=='f' && let2=='i') return( FI ); /* fill */
X if ( let1=='t' && let2=='i') return( TI ); /* temp. left indent */
X if ( let1=='b' && let2=='p') return( BP ); /* break, page # */
X if ( let1=='b' && let2=='r') return( BR ); /* break */
X if ( let1=='c' && let2=='e') return( CE ); /* center line(s) */
X if ( let1=='i' && let2=='n') return( IN ); /* left indent */
X if ( let1=='l' && let2=='l') return( LL ); /* right margin */
X if ( let1=='l' && let2=='s') return( LS ); /* line spacing */
X if ( let1=='n' && let2=='f') return( NF ); /* no fill */
X if ( let1=='p' && let2=='l') return( PL ); /* page length */
X if ( let1=='s' && let2=='p') return( SP ); /* output blank lines */
X if ( let1=='n' && let2=='e') return( NE ); /* need vertical spaces */
X if ( let1=='t' && let2=='a') return( TA ); /* tab size */
X if ( let1=='t' && let2=='c') return( TC ); /* tab character */
X if ( let1=='t' && let2=='r') return( TR ); /* translate chars */
X if ( let1=='a' && let2=='d') return( AD ); /* adjust output lines */
X if ( let1=='n' && let2=='a') return( NA ); /* no adjust output */
X if ( let1=='e' && let2=='m') return( EM ); /* end macro */
X if ( let1=='d' && let2=='e') return( DE ); /* define macro */
X if ( let1=='d' && let2=='s') return( DS ); /* define string */
X if ( let1=='n' && let2=='r') return( NR ); /* number register */
X if ( let1=='d' && let2=='i') return( DI ); /* divert output */
X if ( let1=='s' && let2=='o') return( SO ); /* source from file */
X if ( let1=='p' && let2=='m') return( PM ); /* print macros */
X if ( let1=='e' && let2=='x') return( EX ); /* exit (abort) */
X if ( let1=='i' && let2=='g') return( IG ); /* ignore -- comment */
X if ( let1=='t' && let2=='m') return( TM ); /* message to terminal */
X if ( let1=='f' && let2=='t') return( FT ); /* set font */
X if ( let1=='p' && let2=='o') return( PO ); /* page offset */
X
X#ifdef NOTYET
X if ( let1=='w' && let2=='h') return( WH ); /* set trap */
X#endif
X
X#ifdef NONROFF
X if ( let1=='F' && let2=='O') return( FO ); /* footer for title */
X if ( let1=='H' && let2=='E') return( HE ); /* header for title */
X if ( let1=='S' && let2=='T') return( ST ); /* stop between pages */
X if ( let1=='F' && let2=='F') return( FF ); /* form feed */
X if ( let1=='S' && let2=='C') return( SC ); /* space character */
X if ( let1=='O' && let2=='H') return( OH ); /* odd-page header */
X if ( let1=='O' && let2=='F') return( OF ); /* odd-page footer */
X if ( let1=='E' && let2=='H') return( EH ); /* even-page header */
X if ( let1=='E' && let2=='F') return( EF ); /* even-page footer */
X if ( let1=='C' && let2=='F') return( CF ); /* trans. char. flag */
X if ( let1=='I' && let2=='C') return( IC ); /* insert character */
X if ( let1=='B' && let2=='J') return( BJ ); /* break, justified */
X if ( let1=='S' && let2=='S') return( SS ); /* show strings */
X if ( let1=='S' && let2=='R') return( SR ); /* show registers */
X if ( let1=='M')
X {
X if (let2=='1') return( M1 );
X if (let2=='2') return( M2 );
X if (let2=='3') return( M3 );
X if (let2=='4') return( M4 );
X }
X if ( let1=='D' && let2=='B') return( DB ); /* debug on */
X#endif
X
X return( UNKNOWN ); /* no match */
X }
X
X/*************************************************************
Xgets the number ( if any ) associated with any command
X*************************************************************/
X
Xget_val( line, typ )
X char *line;
X int *typ;
X {
X int i;
X char local[ MAXLINE ];
X strcpy (local, line); /* local copy */
X
X /* skip over the command line */
X for(i=1; local[i]!=' '&&local[i]!='\t'&&local[i]!='\n'
X &&local[i]!=0; i++);
X
X skip_blanks (&local[i]); /* find the number */
X *typ = local[i]; /* relative or absolute */
X if ( *typ=='+' || *typ=='-' )
X {
X i++;
X }
X else if ( !isdigit( *typ ) )
X {
X return( NO_VAL );
X }
X return ( atoi( &local[i] ));
X }
X
X/*************************************************************
X sets a non-stacked global parameter like ro_spval, ro_pagestop, etc.
X Also checks that the new value is within the range of that
X parameter. Assigns the default for that parameter if no value
X is specified.
X*************************************************************/
X
Xset( param, val, arg_typ, defval, minval, maxval )
X int *param, val, defval, minval, maxval;
X int arg_typ;
X {
X if ( val == NO_VAL )
X {
X *param = defval; /* defaulted */
X }
X else if (arg_typ == '+')
X {
X *param += val; /* relative + */
X }
X else if ( arg_typ == '-' )
X {
X *param -= val; /* relative - */
X }
X else
X {
X *param = val; /* absolute */
X }
X *param = ro_min (*param, maxval);
X *param = ro_max (*param, minval);
X
X if DEBUG fprintf( stderr,"DEBUG: set() *param = %d\n", *param);
X }
X
X/*************************************************************
X end current filled line
X**************************************************************/
X
Xro_brk()
X {
X int l;
X if DEBUG
X {
X fprintf( stderr,"DEBUG: ro_brk(): ro_outbuf=<%s>\n", ro_outbuf);
X }
X
X if (ro_outpos)
X {
X put( ro_outbuf );
X }
X ro_outw = ro_outpos = ro_outtop = ro_outbot = ro_outwrds = 0;
X ro_outbuf[0] = '\0';
X }
X
X/**************************************************/
X
Xinitxu() /*initialize underline,overstrike variables*/
X {
X ro_xcol = ro_ucol = -1;
X memfill(ro_xbuf,LSZ,' ');
X memfill(ro_ubuf,LSZ,' ');
X }
X
X/****************************************/
X
Xneed(n) /*test for space before footer*/
X int n; /*whole lines*/
X {
X if (( ro_vlineno >= (ro_bottom-n) ) && ( ro_bottom >= ro_vlineno ) )
X {
X do_space( HUGE );
X ro_newpag = ++ro_curpag;
X }
X }
X
________This_Is_The_END________
if test `wc -l < ro_proc.c` -ne 224; then
echo 'shar: ro_proc.c was damaged during transit (should have been 224 bytes)'
fi
fi ; : end of overwriting check
echo 'x - ro_macr.c'
if test -f ro_macr.c; then echo 'shar: not overwriting ro_macr.c'; else
sed 's/^X//' << '________This_Is_The_END________' > ro_macr.c
X/********************************************************/
X/* */
X/* ro_macr.c macro and diversion routines */
X/* for ro */
X/* */
X/* ro version 1.00 */
X/* */
X/* Portions copyright (c) 1989 by Ted A. Campbell */
X/* Bywater Software */
X/* P. O. Box 4023 */
X/* Duke Station */
X/* Durham, NC 27706 */
X/* */
X/* Contains portions of ROFF4, Version 1.60 */
X/* (c) 1983, 4 by Ernest E. Bergmann */
X/* Physics, Building #16 */
X/* Lehigh University */
X/* Bethlehem, Pa. 18015 */
X/* */
X/* Contains portions of ROFF4, Version 1.61 */
X/* (c) 1985 by Konrad Kwok */
X/* 20 3rd Street, Section M */
X/* Fariview Park, */
X/* Hong Kong */
X/* */
X/* ro and its predecessor ROFF4 are based on */
X/* the ROFF text processor described in Kernigan */
X/* and Plauger's now-classic text <Software Tools> */
X/* */
X/* Permission is hereby granted for all commercial and */
X/* non-commercial reproduction and distribution of this */
X/* material provided this notice is included. */
X/* */
X/********************************************************/
X
X#include "ro.h"
X
X/********************************************/
X/* insert() -- process .ds command */
X/* takes a command line in ro_curline and adds its
Xentry to the table */
X
Xinsert()
X {
X static char name[ LSZ ];
X register int n;
X char c, *l;
X struct divfd *sptr;
X
X /*pass over command*/
X
X l = ro_curline;
X for ( c = *l; c != ' ' && c != '\n' && c != '\t'; l++ )
X {
X c = *l;
X }
X
X /*advance to first non-blank */
X
X for ( ; c == ' ' || c == '\t'; l++ )
X {
X c = *l;
X }
X if ( c == '\n' )
X {
X if ( ro_verbose == TRUE )
X {
X fprintf( stderr, ".ds: no arguments \n" );
X }
X return -1;
X }
X
X /* get the name of the macro into the buffer */
X
X n = 0;
X --l;
X do
X {
X name[ n ] = *l;
X ++l;
X ++n;
X }
X while( *l != ' ' && *l != '\t' && *l != '\n' );
X name[ n ] = '\0'; /* terminate name with \0 */
X
X if ( strlen( name ) > 2 )
X {
X name[ 2 ] = '\0';
X if ( ro_verbose == TRUE )
X {
X fprintf( stderr, ".ds: string name over two characters, shortened to <%s>. \n",
X name );
X }
X }
X
X /*advance to first non-blank */
X
X c = *l;
X for ( ; c == ' ' || c == '\t'; l++ )
X {
X c = *l;
X }
X if ( c == '\n' )
X {
X if ( ro_verbose == TRUE )
X {
X fprintf( stderr, ".ds: no string argument \n" );
X }
X return -1;
X }
X
X /* now get the string itself into the tbuf buffer */
X
X if ( c == '\"' )
X {
X n = 0;
X do
X {
X tbuf[ n ] = *l;
X ++l;
X ++n;
X }
X while( *l != c );
X tbuf[ n ] = '\0'; /* terminate name with \0 */
X }
X else
X {
X n = 0;
X do
X {
X tbuf[ n ] = *l;
X ++l;
X ++n;
X }
X while( *l != ' ' && *l != '\t' && *l != '\n' );
X tbuf[ n ] = '\0'; /* terminate name with \0 */
X }
X
X /* see if it is already defined */
X
X if( ( sptr = find2( name, slink )) != NULL )
X {
X if ( ro_verbose == TRUE )
X {
X fprintf( stderr, "%cWarning: <%s> was defined to be <%s>\n",
X BELL, name, sptr->mstr );
X fprintf( stderr, "...now it is defined to be <%s>\n", tbuf );
X }
X }
X
X else
X {
X if ( ( sptr = (struct divfd *) malloc( (size_t) sizeof( struct divfd ))) == NULL )
X {
X fprintf( stderr, "Fatal error: cannot allocate memory for insertion structure. \n" );
X exit ( -1 );
X }
X
X /* allocation succeeded, set up links */
X
X sptr->prev = slink; /* save previous link */
X slink = sptr; /* reset link */
X strcpy( sptr->nm, name );
X sptr->mstr = NULL;
X }
X
X /* allocate memory for the new string if it is longer
X than the current string */
X
X if ( strlen( tbuf ) > strlen( sptr->mstr ) )
X {
X if ( ( sptr->mstr = malloc( (size_t) strlen( tbuf ) + 1 )) == NULL )
X {
X fprintf( stderr, "Fatal error: failed to allocate memory for string. \n" );
X exit( -1 );
X }
X }
X
X /* copy the string to the new memory */
X
X strcpy( sptr->mstr, tbuf );
X
X }
X
X/****************************************/
X
Xshowit() /* displays the list of entries in the string
X substitution table pointed to by HEAD. */
X {
X struct divfd *pw;
X fprintf( stderr, "Strings defined:\n");
X dashes();
X pw = slink;
X while( pw != NULL )
X {
X fprintf( stderr, "%s:\t<%s> \n", pw->nm, pw->mstr );
X pw = pw->prev;
X }
X dashes();
X }
X
X/****************************************/
X
Xputback( c ) /*cf K & P, p256*/
X char c;
X {
X if ( ++ro_binp >= BACKSIZE )
X {
X fprintf( stderr, "Fatal error: too many characters pushed back\n");
X exit( -1 );
X }
X ro_backbuf[ ro_binp ] = c;
X }
X
X/** add by Conrad Kwok. 9th Sept.,84 ****/
X
Xpbmac( s, sl ) /* s = pointer to macro text */
X char s[], sl[]; /* sl = current line */
X {
X static char *parms[10], dupln[LSZ];
X register int i;
X
X strcpy( dupln, sl ); /* get a copy of the current line */
X setparm( dupln, parms );
X for ( i = strlen(s)-1; i >= 0; )
X {
X if ( isdigit( s[i] ))
X {
X if ( i > 0 && s[ i - 1 ] == '$' )
X {
X pbstr( parms[ s[i--] & 0x0f ]);
X --i;
X }
X else
X {
X putback( s[i--] );
X }
X }
X else
X {
X putback( s[i--] );
X }
X }
X }
X
Xsetparm( sl, parms)
X char *sl, *parms[];
X {
X char a,c;
X int nuparm;
X for ( c = *sl; c != ' ' && c != '\n' && c != '\t'; )
X {
X c = *++sl;
X }
X
X while ( c == ' ' || c == '\t' )
X {
X c = *++sl;
X }
X
X for ( nuparm = 0; nuparm < 10; )
X {
X if (!(isalnum(c) || (c=='+') || (c=='-')))
X {
X sl++;
X }
X else
X {
X c = ' ';
X }
X parms[ nuparm++ ] = sl;
X
X for ( a = *sl; a != c && a != '\n' && a != '\0'; )
X {
X if ( c == ' ' && a == '\t' )
X {
X break;
X }
X
X else
X {
X a = *++sl;
X }
X }
X *sl = '\0';
X c = a;
X if ( a != '\0' && a != '\n')
X {
X while ( c == ' ' || c == '\t')
X {
X c = *++sl;
X }
X }
X }
X }
X
X/****************************************/
X
Xpbstr( s ) /*put back string on input; cf K&P,p257*/
X char s[LSZ];
X {
X int i;
X for ( i = strlen(s); i > 0; )
X {
X putback( s[--i] );
X }
X }
X
Xro_expand()
X {
X char c, d, name[ 36 ];
X register int n;
X struct divfd *sptr;
X
X c = ro_getch();
X switch( c )
X {
X case BACKSLASH:
X return PASSBACK;
X break;
X case '*': /* expand defined string */
X d = ro_getch();
X if ( d == '(' ) /* two-letter name */
X {
X name[ 0 ] = ro_getch();
X name[ 1 ] = ro_getch();
X name[ 2 ] = '\0';
X }
X else /* one-character name */
X {
X name[ 0 ] = d;
X name[ 1 ] = '\0';
X }
X if ( ( sptr = find2( name, slink )) == NULL )
X {
X if ( ro_verbose == TRUE )
X {
X fprintf( stderr, "ro: failed to find string name <%s> \n",
X name );
X }
X }
X else
X {
X n = strlen( sptr->mstr ) - 1;
X while( n >= 0 )
X {
X putback( sptr->mstr[ n ] );
X --n;
X }
X }
X break;
X case 'n': /* expand number register */
X d = ro_getch();
X if ( d == '(' ) /* two-letter name */
X {
X name[ 0 ] = ro_getch();
X name[ 1 ] = ro_getch();
X name[ 2 ] = '\0';
X }
X else /* one-character name */
X {
X name[ 0 ] = d;
X name[ 1 ] = '\0';
X }
X if ( ( sptr = find2( name, rlink )) == NULL )
X {
X if ( ro_verbose == TRUE )
X {
X fprintf( stderr, "ro: failed to find register name <%s> \n",
X name );
X }
X }
X else
X {
X sprintf( tbuf, "%d", sptr->val );
X n = strlen( tbuf ) - 1;
X while( n >= 0 )
X {
X putback( tbuf[ n ] );
X --n;
X }
X }
X break;
X case 'u': /* Half-line up */
X putback( HALFUP );
X putback( ESCAPE );
X break;
X case 'd': /* Half-line down */
X putback( HALFDOWN );
X putback( ESCAPE );
X break;
X case 'f': /* switch font */
X d = ro_getch();
X switch( d )
X {
X case 'R':
X putback( ROMAN );
X putback( ESCAPE );
X break;
X case 'I':
X putback( ITALIC );
X putback( ESCAPE );
X break;
X case 'B':
X putback( BOLD );
X putback( ESCAPE );
X break;
X default:
X if ( ro_verbose == TRUE )
X {
X fprintf( stderr,
X "ro: unrecognized font name \"%c\" in input stream. \n",
X d );
X }
X }
X break;
X default:
X putback( c );
X break;
X }
X return TRUE;
X }
X
X/****************************************/
X/* takes a .de and following lines and places
Xthe information in the table; no macro
Xdefinition nesting permitted */
X
Xminsert()
X {
X register int n;
X static char c, *src, *dst;
X int keepon;
X struct divfd *sptr;
X
X if DEBUG
X {
X fprintf( stderr, "DEBUG: enter minsert() \n" );
X }
X
X /* pass over command and following white space */
X
X for ( src = ro_curline, c = *src; (c != ' ' ) && (c!='\n') && (c!='\t'); src++ )
X {
X c = *src;
X }
X for ( ; (c == ' ') || (c == '\t'); src++ )
X {
X c = *src;
X }
X
X /* Check to see if there is a name for the macro */
X
X if ( ( c == '\n' ) || ( c == '\0' ))
X {
X if ( ro_verbose )
X {
X fprintf( stderr, "ERROR: .de: no name given. \n");
X }
X return -1;
X }
X
X /* Name detected, proceed to store the name */
X
X else
X {
X if DEBUG
X {
X fprintf( stderr, "DEBUG: macro name found; prepare to allocate memory. \n" );
X }
X
X if ( ( sptr = (struct divfd *) malloc( (size_t) sizeof( struct divfd ))) == NULL )
X {
X fprintf( stderr, "FATAL ERROR: cannot allocate memory for macro definition structure. \n" );
X exit ( -1 );
X }
X
X if DEBUG
X {
X fprintf( stderr, "DEBUG: memory allocated for macro.\n" );
X }
X
X sptr->prev = mlink; /* save previous link */
X mlink = sptr; /* set mlink to this */
X n = 0;
X while( class( c ) == BLACK ) /* Store each character */
X { /* of the macro name */
X sptr->nm[ n++ ] = c;
X c = *( src++ );
X }
X sptr->nm[ n ] = '\0';
X
X if DEBUG
X {
X fprintf( stderr, "DEBUG: new macro name is <%s> \n",
X sptr->nm );
X }
X
X }
X
X /* Now read from instream until end of macro or EOF */
X
X dst = tbuf;
X keepon = 1;
X while( keepon == 1 )
X {
X ro_gets( ro_curline );
X src = ro_curline;
X
X /* Check for end of macro */
X
X if (( ro_curline[0] == COMMAND) && ( comtyp( ro_curline ) == EM ))
X {
X keepon = 0;
X }
X else /* Not end; transfer to buffer */
X {
X transfer( &src, &dst, (char) '\0' );
X *(dst - 1) = '\n'; /* put a LF at the end */
X *dst = 0; /* and a temp. delimiter */
X }
X
X if DEBUG
X {
X fprintf( stderr, "DEBUG: minsert() current line <%s> \n",
X tbuf );
X }
X
X }
X *( dst ) = '\0'; /* Terminate with \0 */
X
X if DEBUG
X {
X fprintf( stderr, "DEBUG: text of new macro is <%s> \n", tbuf );
X }
X
X /* allocate memory for this macro string and transfer the string to
X the new location */
X
X if ( ( sptr->mstr = malloc( (size_t) strlen( tbuf ) + 1 )) == NULL )
X {
X fprintf( stderr, "Fatal error: failed to allocate memory for macro string. \n" );
X exit( -1 );
X }
X strcpy( sptr->mstr, tbuf );
X
X }
X
X/****************************************/
X
Xshowm() /*lists macro definitions*/
X {
X struct divfd *pw;
X char *pc;
X fprintf( stderr, "MACROS DEFINED:\n");
X pw = mlink;
X while ( pw != NULL )
X {
X fprintf( stderr, "\t.%s\t<%s>\n", pw->nm, pw->mstr );
X pw = pw->prev;
X }
X dashes();
X }
X
X/****************************************/
X
Xchar *macq( line ) /*looks up name to see if it is a macro
X definition. If it is, returns the
X corresponding string, else returns
X FALSE.
X */
X char *line;
X {
X char c, *pc, wb[ LSZ ];
X struct divfd *pstr;
X
X pc = wb;
X while ( class( c = *( ++line )) == BLACK )
X {
X *( pc++ ) = c;
X }
X *pc='\0';
X
X pstr = find2( wb, mlink );
X if ( pstr == NULL )
X {
X return NULL;
X }
X else
X {
X return ( pstr->mstr );
X }
X }
X
X/****************************************/
X
Xstruct divfd *
Xfind2( s, link) /* finds or doesn't find s in table
X of substitutions pointed to by link */
X char *s;
X struct divfd *link;
X {
X struct divfd *l;
X char *pc;
X
X l = link;
X while ( l != NULL )
X {
X if ( !strcmp( s, l->nm ) )
X {
X return( l ); /* return structure pointer */
X }
X l = l->prev;
X }
X
X return( NULL ); /* failed */
X }
X
X/****************************************/
X
________This_Is_The_END________
if test `wc -l < ro_macr.c` -ne 620; then
echo 'shar: ro_macr.c was damaged during transit (should have been 620 bytes)'
fi
fi ; : end of overwriting check
exit 0