rosenkra@convex1.convex.com (William Rosencranz) (08/03/90)
--- this is the file POST.MNX from the distribution. please read it and the readme before you flame me! ---------------------------------------------------------------------------- This is a new version of nroff(1), a text processor similar to Unix(tm) nroff, though not 100% compatible (not all the commands are available and the macro packages here will not work with unix nroff, though the macro commands in text files will). This is version 1.10 and was written on a 4 MB atari ST under TOS, not minix. I have NOT tested it under minix because I do not have minix operational on my "spare" ST (yet?). NOTE: there was a patch to 0.99 for the termcap stuff in main.c. unfortunately, i lost it in my last "career move" so you may need to fix this for terminal support for bold, italic, and/or standout modes. If you do, pls send me the patch (diff -c oldfile.c newfile.f is fine). I made the Makefile as compatible as I could for minix. The original (TOS) makefile is also included. You _SHOULD_ just be able to say: % make all and it will compile. I would suggest you look at the Makefile first before trying "make install". At least do "make -n install" to see what would happen (assuming, of course, that minix make has a unix-like "-n" flag). This version adds 2 things: 1) support (partial) for the ".if" command (look at the tmac.* files to see how it can be used), and 2) a working though hardly complete -ms (manuscript) package. I also added the ".mc" command to make changebars in documents possible. oh, i added the "-raN" command line switch (to preset a user number register). This post is equivalent to TOS nroff, v1.10, patchlevel 3. v1.10 was posted to c.s.atari.st and c.b.atari.st up to patchlevel 2. pl 3 only makes it possible to specify margin char location with the .mc command which is like 4-5 lines of code. This is what I am currently using as of this writing. I suggest you use the macro packages rather than raw nroff commands as they may not always work as you would expect. vertical displacements are generally in "units" rather than inches though horizontal distances should be ok with inches, though you will need floating point support. nroff does not yet support complicated things like: .in \nA+\n(.l/2 just single numbers (no arithmetic on args). use the existing macro packages (tmac.an and tmac.s) and the test programs (in tests.uu) as a guide for using nroff or for writing/expanding macro packages. Futures: I eventually hope to finish the .if command (to accept block input as in: .if something \{\ ... ... \} and add support for .ie/.el (if/else) within the next few months. I'd also like to add at least .wh traps and possibly diversions within 6 months, depending on what little free time I have. Note that there is a GNU troff on prep.ai.mit.edu (ftp access). I have NOT ported that to minix since i seriously doubt it would fit. It would take forever to run on my 8 Mhz ST anyway. My nroff is a single pass nroff while "real" nroff is at least 2 pass, I think, and though no speed demon itself, this nroff is probably faster than what the full nroff would do on these tiny systems. Anyway, have fun. I use this all the time to write -ms and -man docs on my atari, then move them (without changes) to other unix systems (currently convex). The -ms package has all the basics: TL,AU,AI,AB,AE, SH,NH,PP,LP,QP,XP,RS,RE,IP(buggy),I,B,R which will easily let you make nice looking documents. Check the test cases in tests.uu (this is a uuencoded shar file). Note that there is no support for displays, keeps, footnotes, tables, etc. in the -ms package. It is pretty basic. The -man package supports TH,SH,SS,PP,RS,RE,IP,I,B,IR,BR, etc. Enjoy... -Bill Rosenkranz rosenkra%c1yankee@convex.com Bill Rosenkranz |UUCP: {uunet,texsun}!convex!c1yankee!rosenkra Convex Computer Corp. |ARPA: rosenkra%c1yankee@convex.com
rosenkra@convex1.convex.com (William Rosencranz) (08/03/90)
--- part 1 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 1 (of 5)." # # Contents: # MANIFEST Makefile Makefile.tos POST.MNX README nroff.man # # Wrapped by rosenkra%c1yankee@convex.com on Thu Aug 2 13:39:42 1990 # PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f MANIFEST -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"MANIFEST\" else echo shar: Extracting \"MANIFEST\" \(1400 characters\) sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST' XManifest: X Xmacro libraries: X-rw-r--r-- 1 rosenkra 8405 Jul 29 14:59 tmac.an (install in /usr/lib/tmac) X-rw-r--r-- 1 rosenkra 9432 Jul 29 14:59 tmac.s X Xsource code: X-rw-r--r-- 1 rosenkra 8221 Jul 29 15:36 Makefile (read this before make) X-rw-r--r-- 1 rosenkra 8118 Jul 30 00:19 Makefile.tos X-rw-r--r-- 1 rosenkra 30522 Jul 29 15:34 command.c X-rw-r--r-- 1 rosenkra 1819 Jul 29 15:34 config.h X-rw-r--r-- 1 rosenkra 18010 Jul 29 15:34 escape.c X-rw-r--r-- 1 rosenkra 4007 Jul 29 15:34 io.c X-rw-r--r-- 1 rosenkra 13787 Jul 29 15:34 low.c X-rw-r--r-- 1 rosenkra 10226 Jul 29 15:34 macros.c X-rw-r--r-- 1 rosenkra 19776 Jul 29 15:34 main.c X-rw-r--r-- 1 rosenkra 15981 Jul 29 15:39 nroff.h X-rw-r--r-- 1 rosenkra 21 Jul 29 15:34 patchlvl.h X-rw-r--r-- 1 rosenkra 5761 Jul 29 15:34 strings.c X-rw-r--r-- 1 rosenkra 13950 Jul 29 15:34 text.c X-rw-r--r-- 1 rosenkra 534 Jul 29 15:38 version.h X Xothers X-rw-r--r-- 1 rosenkra 3657 Jul 29 14:59 README (please read this first) X-rw-r--r-- 1 rosenkra 1212 Jul 30 00:20 MANIFEST (this file) X-rw-r--r-- 1 rosenkra 3574 Aug 2 13:22 POST.MNX (read this, too) X Xman pages: X-rw-r--r-- 1 rosenkra 7280 Jul 29 15:09 man.man (manpage sources) X-rw-r--r-- 1 rosenkra 3486 Jul 29 15:09 ms.man X-rw-r--r-- 1 rosenkra 25302 Jul 29 15:18 nroff.man X Xtests: X-rw-r--r-- 1 rosenkra 32307 Jul 29 15:27 tests.uu (uuencoded compressed shar) END_OF_MANIFEST if test 1400 -ne `wc -c <MANIFEST`; then echo shar: \"MANIFEST\" unpacked with wrong size! fi # end of overwriting check fi if test -f Makefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Makefile\" else echo shar: Extracting \"Makefile\" \(8221 characters\) sed "s/^X//" >Makefile <<'END_OF_Makefile' X#---------------------------------------------------------------------------- X# makefile for nroff 07/21/90 wjr. this makefile _SHOULD_ handle minix, tos, X# and unix. PLEASE READ THE ENTIRE MAKEFILE BEFORE YOU MAKE! X# X# this makefile was designed for my own make(1) and may not work correctly X# with minix. but then i don't have to worry about 64k limits so it can be X# more robust. it should work with any reasonable make, though. nothing fancy X# here... X# X# note that i have set this up for minix, based on the old makefile but X# it has not been tested... X# X# please look at the makefile first to customize it to your environment. X#---------------------------------------------------------------------------- X# X# MACRO DEFINITIONS: X# X X# version (3 digits max): X# XVER = 110 X X# compiler: X# XCC = cc X X# rename: X# XRENAME = cp X X# install: X# XINSTALL = cp X X# X# main target: X# X# for tos, make this ".ttp", otherwise blank X# XEXTN = X X# for testing, use "x", otherwise blank X# XXTST = XTARGET = $(XTST)nroff$(EXTN) X X# manual page names: X# X# section of the manual (generally always "1") X# XSECTN = 1 XMANSRC = nroff.man XCATPAGE = nroff.cat XMANPAGE = nroff.$(SECTN) XSECTN_an = 7 XMANSRC_an = man.man XCATPAGE_an = man.cat XMANPAGE_an = man.$(SECTN_an) XSECTN_s = 7 XMANSRC_s = ms.man XCATPAGE_s = ms.cat XMANPAGE_s = ms.$(SECTN_s) X X# compile flags: X# X# for different versions, use only one of the following sets in VERSFLAGS: X# tos: -Dtos -Dalcyon X# minix ST: -Dminix -DatariST X# minix PC: -Dminix X# unix: -Dunix X# X# DEBUG can be "-g" under unix and OPTIMIZE can be "-O" X# note that minix may need other flags as well (i don't have minix) X# XVERSFLAGS = -D_MINIX -D_POSIX_SOURCE XDEFS = -F XDEBUG = XOPTIMIZE = XCFLAGS = $(DEFS) $(VERSFLAGS) $(DEBUG) $(OPTIMIZE) X X# link flags: X# X# for tos, i use "-s -stksiz", others may vary X# XLDFLAGS = -i X X# source files: X# XHEADERS = config.h nroff.h version.h XSRCS1 = main.c command.c text.c io.c XSRCS2 = macros.c strings.c escape.c low.c XSRCS = $(SRCS1) $(SRCS2) X X# object targets: X# X# for normal systems (i.e. sun,apollo,hp,ibm,cray,etc): O=o X# for minix (ACK is right!): O=s (SHEESH!!!) XO =s XOBJS = main.$O command.$O text.$O io.$O macros.$O strings.$O \ X escape.$O low.$O X X# other files in the distribution: X# XTESTS = test.0 XOTHERS = README MANIFEST Makefile nroff.man man.man ms.man \ X tmac.an tmac.s $(TESTS) X X# linked libraries: X# X# for tos, i use "-lterm" X# XLIBS = X X# arc archive: X# XARCFILE = nroff$(VER).arc X X# executable uuencoded: X# XUUEFILE = nroff$(VER).uue X X# shar files: X# XSHARFLG = -a XSHARF1 = nroff$(VER).01 XSHARF2 = nroff$(VER).02 XSHARF3 = nroff$(VER).03 XSHARF4 = nroff$(VER).04 XSHARF5 = nroff$(VER).05 XSHARFILE = nroff$(VER).shr X X# macro library files: X# XMAN_MACRO = tmac.an XMS_MACRO = tmac.s X#ME_MACRO = tmac.e X X# final locations for things: X# X# set these as per your system (for "make install") X# tos: TMACDIR = c:\lib\tmac (for tmac.an) X# BINDIR = c:\bin (for nroff) X# MANDIR = c:\man\man$(SECTN) (for nroff.1) X# minix: TMACDIR = /usr/lib/tmac X# BINDIR = /usr/bin X# MANDIR = /usr/man/man$(SECTN) X# unix: TMACDIR = /usr/local/lib/tmac X# BINDIR = /usr/local/bin X# MANDIR = /usr/local/man/man$(SECTN) X# XTMACDIR = /usr/lib/tmac XBINDIR = /bin XMANDIR = /usr/man/man$(SECTN) XMANDIR_an = /usr/man/man$(SECTN_an) XMANDIR_s = /usr/man/man$(SECTN_s) X X# system path seperator: X# X# note that my make under tos uses <space>\ for line continuation so i can't X# put a space after the "=". X# for tos, use: S=\ (NO SPACES!!!) X# for minix, unix, use: S=/ X# XS =/ X X# testing: X# X# make sure to "setenv TMACDIR ." first... X# XRUNPARM = -man test.0 XRUNOUT = >test.out X X# a non-objecting rm command: X# X# unix/minix: RM = rm -f XRM = rm -f X X X#---------------------------------------------------------------------------- X# X# ACTIONS: X# X X X# directions for making things is default target... X# Xdirections: X @echo Please read the README file first. Also review makefile. X @echo Type "make all" to build $(TARGET) X @echo Type "make manpage" to build $(MANPAGE) X @echo Type "make install" to build/install $(TARGET) X @echo Type "make test" to test $(TARGET) X @echo Type "make clean" to remove objects X @echo Type "make clobber" to remove objects and $(TARGET) X @echo Type "make arc" to make source archive $(ARCFILE) X @echo Type "make shar" to make source shar file $(SHARFILE) X @echo Type "make uue" to make uuencoded $(TARGET) $(UUEFILE) X X X X# make main target... X# Xall: $(TARGET) X X$(TARGET): $(OBJS) X $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) X @echo "done making $(TARGET)" X X X X# make installable manpage... X# X# you may have to change this. i keep my manpages pre-nroffed so i use X# CATPAGE as my manpage. your man(1) may use nroff to display manpages, X# so you may want to do this instead: X# X# manpage: $(MANPAGE) $(MANPAGE_an) X# X# $(MANPAGE): $(MANSRC) X# $(RENAME) $(MANSRC) $(MANPAGE) X# X# $(MANPAGE_an): $(MANSRC_an) X# $(RENAME) $(MANSRC_an) $(MANPAGE_an) X# Xmanpage: $(MANPAGE) $(MANPAGE_an) $(MANPAGE_s) X @echo "done making manpages" X X$(MANPAGE): $(CATPAGE) X $(RENAME) $(CATPAGE) $(MANPAGE) X X$(MANPAGE_an): $(CATPAGE_an) X $(RENAME) $(CATPAGE_an) $(MANPAGE_an) X X$(MANPAGE_s): $(CATPAGE_s) X $(RENAME) $(CATPAGE_s) $(MANPAGE_s) X X$(CATPAGE): $(MANSRC) # note: uses built-in .man.cat rule!!!!! X X$(CATPAGE_an): $(MANSRC_an) X X$(CATPAGE_s): $(MANSRC_s) X X X X# to test run it... X# Xtest: $(TARGET) X $(TARGET) $(RUNPARM) $(RUNOUT) X @echo "done with test" X X X# install target, manpage, and lib stuff... X# Xinstall: install_bin install_man install_tmac X @echo "install complete" X Xinstall_bin: $(TARGET) X $(INSTALL) $(TARGET) $(BINDIR)$S$(TARGET) X @echo "done installing $(TARGET)" X Xinstall_man: $(MANPAGE) $(MANPAGE_an) $(MANPAGE_s) X $(INSTALL) $(MANPAGE) $(MANDIR)$S$(MANPAGE) X $(INSTALL) $(MANPAGE_an) $(MANDIR_an)$S$(MANPAGE_an) X $(INSTALL) $(MANPAGE_s) $(MANDIR_s)$S$(MANPAGE_s) X @echo "done installing manpages" X Xinstall_tmac: X $(INSTALL) $(MAN_MACRO) $(TMACDIR)$S$(MAN_MACRO) X $(INSTALL) $(MS_MACRO) $(TMACDIR)$S$(MS_MACRO) X# $(INSTALL) $(ME_MACRO) $(TMACDIR)$S$(ME_MACRO) X @echo "done installing macro packages" X X X X# clean up... X# Xclean: X $(RM) $(OBJS) X Xclobber: X $(RM) $(OBJS) X $(RM) $(TARGET) X Xcleansrc: X $(RM) $(SRCS) $(HEADERS) X Xcleandocs: X $(RM) docs.arc readme bugs $(MANPAGE) $(MAN_MACRO) $(MS_MACRO) X X X X# various archives... X# Xuue: X $(UUENCODE) $(TARGET) X @echo done making $(UUEFILE) X Xshar: uue X $(SHAR) $(SHARFLG) $(OTHERS) >$(SHARF1) X $(SHAR) $(SHARFLG) $(SRCS1) >$(SHARF2) X $(SHAR) $(SHARFLG) $(SRCS2) >$(SHARF3) X $(SHAR) $(SHARFLG) $(HEADERS) >$(SHARF4) X $(SHAR) $(SHARFLG) $(UUEFILE) >$(SHARF5) X @echo done making $(SHARF1) $(SHARF2) $(SHARF3) $(SHARF4) $(SHARF5) X Xarc: X $(ARC) a $(ARCFILE) $(OTHERS) X $(ARC) a $(ARCFILE) $(HEADERS) X $(ARC) a $(ARCFILE) $(SRCS) X @echo done making $(ARCFILE) X X X X# the following actions i use while developing so i can save disk space. X X# use this to save space on disk X# Xbackup: objs.arc srcs.arc docs.arc X Xobjs.arc: X $(ARC) a objs.arc $(OBJS) $(TARGET) X @echo done making objs.arc. consider "make clean" X Xsrcs.arc: X $(ARC) a srcs.arc $(HEADERS) X $(ARC) a srcs.arc $(SRCS) X @echo done making srcs.arc. consider "make cleansrc" X Xdocs.arc: X $(ARC) a docs.arc readme bugs $(MANPAGE) $(MAN_MACRO) $(MS_MACRO) X @echo done making docs.arc. consider "make cleandocs" X X# use this to go back to work after "make backup" X# Xrestore: X $(ARC) x srcs.arc $(HEADERS) X $(ARC) x srcs.arc $(SRCS) X $(ARC) x docs.arc $(MANPAGE) $(MAN_MACRO) $(MS_MACRO) X $(ARC) x objs.arc $(OBJS) X $(ARC) x objs.arc $(TARGET) X @echo done with restore...ok to continue to hack X @echo be sure to setenv TMACDIR during testing X X X#---------------------------------------------------------------------------- X# X# DEPENDENCIES: X# X# note: nroff.h includes version.h and config.h. all sources include nroff.h X# and in addition, main.c includes config.h as well (first thing). X Xversion.h: patchlvl.h X touch version.h X Xnroff.h: version.h config.h X touch nroff.h X Xmain.$O: main.c nroff.h Xcommand.$O: command.c nroff.h Xtext.$O: text.c nroff.h Xio.$O: io.c nroff.h Xmacros.$O: macros.c nroff.h Xstrings.$O: strings.c nroff.h Xescape.$O: escape.c nroff.h Xlow.$O: low.c nroff.h X X# the end... END_OF_Makefile if test 8221 -ne `wc -c <Makefile`; then echo shar: \"Makefile\" unpacked with wrong size! fi # end of overwriting check fi if test -f Makefile.tos -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Makefile.tos\" else echo shar: Extracting \"Makefile.tos\" \(8118 characters\) sed "s/^X//" >Makefile.tos <<'END_OF_Makefile.tos' X#---------------------------------------------------------------------------- X# makefile for nroff 07/21/90 wjr. this makefile _SHOULD_ handle minix, tos, X# and unix. PLEASE READ THE ENTIRE MAKEFILE BEFORE YOU MAKE! X# X# this makefile was designed for my own make(1) and may not work correctly X# with minix. but then i don't have to worry about 64k limits so it can be X# more robust. it should work with any reasonable make, though. nothing fancy X# here... X# X# please look at the makefile first to customize it to your environment. X#---------------------------------------------------------------------------- X# X# MACRO DEFINITIONS: X# X X# version (3 digits max): X# XVER = 110 X X# compiler: X# XCC = cc X X# rename: X# XRENAME = cp X X# install: X# XINSTALL = cp X X# X# main target: X# X# for tos, make this ".ttp", otherwise blank X# XEXTN = .ttp X X# for testing, use "x", otherwise blank X# XXTST = XTARGET = $(XTST)nroff$(EXTN) X X# manual page names: X# X# section of the manual (generally always "1") X# XSECTN = 1 XMANSRC = nroff.man XCATPAGE = nroff.cat XMANPAGE = nroff.$(SECTN) XSECTN_an = 7 XMANSRC_an = man.man XCATPAGE_an = man.cat XMANPAGE_an = man.$(SECTN_an) XSECTN_s = 7 XMANSRC_s = ms.man XCATPAGE_s = ms.cat XMANPAGE_s = ms.$(SECTN_s) X X# compile flags: X# X# for different versions, use only one of the following sets in VERSFLAGS: X# tos: -Dtos -Dalcyon X# minix ST: -Dminix -DatariST X# minix PC: -Dminix X# unix: -Dunix X# X# DEBUG can be "-g" under unix and OPTIMIZE can be "-O" X# note that minix may need other flags as well (i don't have minix) X# XVERSFLAGS = -Dalcyon -Dtos XDEFS = XDEBUG = XOPTIMIZE = XCFLAGS = $(DEFS) $(VERSFLAGS) $(DEBUG) $(OPTIMIZE) X X# link flags: X# X# for tos, i use "-s -stksiz", others may vary X# XLDFLAGS = -s -stksiz X X# source files: X# XHEADERS = config.h nroff.h version.h XSRCS1 = main.c command.c text.c io.c XSRCS2 = macros.c strings.c escape.c low.c XSRCS = $(SRCS1) $(SRCS2) X X# object targets: X# X# for normal systems (i.e. sun,apollo,hp,ibm,cray,etc): O=o X# for minix (ACK is right!): O=s (SHEESH!!!) XO =o XOBJS = main.$O command.$O text.$O io.$O macros.$O strings.$O \ X escape.$O low.$O X X# other files in the distribution: X# XTESTS = test.0 XOTHERS = README MANIFEST Makefile nroff.man man.man ms.man \ X tmac.an tmac.s $(TESTS) X X# linked libraries: X# X# for tos, i use "-lc" X# XLIBS = -lterm -ltime -lc X X# arc archive: X# XARCFILE = nroff$(VER).arc X X# executable uuencoded: X# XUUEFILE = nroff$(VER).uue X X# shar files: X# XSHARFLG = -a XSHARF1 = nroff$(VER).01 XSHARF2 = nroff$(VER).02 XSHARF3 = nroff$(VER).03 XSHARF4 = nroff$(VER).04 XSHARF5 = nroff$(VER).05 XSHARFILE = nroff$(VER).shr X X# macro library files: X# XMAN_MACRO = tmac.an XMS_MACRO = tmac.s X#ME_MACRO = tmac.e X X# final locations for things: X# X# set these as per your system (for "make install") X# tos: TMACDIR = c:\lib\tmac (for tmac.an) X# BINDIR = c:\bin (for nroff) X# MANDIR = c:\man\man$(SECTN) (for nroff.1) X# minix: TMACDIR = /usr/lib/tmac X# BINDIR = /usr/bin X# MANDIR = /usr/man/man$(SECTN) X# unix: TMACDIR = /usr/local/lib/tmac X# BINDIR = /usr/local/bin X# MANDIR = /usr/local/man/man$(SECTN) X# XTMACDIR = c:\lib\tmac XBINDIR = c:\bin XMANDIR = c:\man\man$(SECTN) XMANDIR_an = c:\man\man$(SECTN_an) XMANDIR_s = c:\man\man$(SECTN_s) X X# system path seperator: X# X# note that my make under tos uses <space>\ for line continuation so i can't X# put a space after the "=". X# for tos, use: S=\ (NO SPACES!!!) X# for minix, unix, use: S=/ X# XS =\ X X# testing: X# X# make sure to "setenv TMACDIR ." first... X# XRUNPARM = -man test.0 XRUNOUT = >test.out X X# a non-objecting rm command: X# X# unix/minix: RM = rm -f XRM = rm X X X#---------------------------------------------------------------------------- X# X# ACTIONS: X# X X X# directions for making things is default target... X# Xdirections: X @echo Please read the README file first. Also review makefile. X @echo Type "make all" to build $(TARGET) X @echo Type "make manpage" to build $(MANPAGE) X @echo Type "make install" to build/install $(TARGET) X @echo Type "make test" to test $(TARGET) X @echo Type "make clean" to remove objects X @echo Type "make clobber" to remove objects and $(TARGET) X @echo Type "make arc" to make source archive $(ARCFILE) X @echo Type "make shar" to make source shar file $(SHARFILE) X @echo Type "make uue" to make uuencoded $(TARGET) $(UUEFILE) X X X X# make main target... X# Xall: $(TARGET) X X$(TARGET): $(OBJS) X $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) X @echo "done making $(TARGET)" X X X X# make installable manpage... X# X# you may have to change this. i keep my manpages pre-nroffed so i use X# CATPAGE as my manpage. your man(1) may use nroff to display manpages, X# so you may want to do this instead: X# X# manpage: $(MANPAGE) $(MANPAGE_an) X# X# $(MANPAGE): $(MANSRC) X# $(RENAME) $(MANSRC) $(MANPAGE) X# X# $(MANPAGE_an): $(MANSRC_an) X# $(RENAME) $(MANSRC_an) $(MANPAGE_an) X# Xmanpage: $(MANPAGE) $(MANPAGE_an) $(MANPAGE_s) X @echo "done making manpages" X X$(MANPAGE): $(CATPAGE) X $(RENAME) $(CATPAGE) $(MANPAGE) X X$(MANPAGE_an): $(CATPAGE_an) X $(RENAME) $(CATPAGE_an) $(MANPAGE_an) X X$(MANPAGE_s): $(CATPAGE_s) X $(RENAME) $(CATPAGE_s) $(MANPAGE_s) X X$(CATPAGE): $(MANSRC) # use built-in .man.cat rule X X$(CATPAGE_an): $(MANSRC_an) X X$(CATPAGE_s): $(MANSRC_s) X X X X# to test run it... X# Xtest: $(TARGET) X $(TARGET) $(RUNPARM) $(RUNOUT) X @echo "done with test" X X X# install target, manpage, and lib stuff... X# Xinstall: install_bin install_man install_tmac X @echo "install complete" X Xinstall_bin: $(TARGET) X $(INSTALL) $(TARGET) $(BINDIR)$S$(TARGET) X @echo "done installing $(TARGET)" X Xinstall_man: $(MANPAGE) $(MANPAGE_an) $(MANPAGE_s) X $(INSTALL) $(MANPAGE) $(MANDIR)$S$(MANPAGE) X $(INSTALL) $(MANPAGE_an) $(MANDIR_an)$S$(MANPAGE_an) X $(INSTALL) $(MANPAGE_s) $(MANDIR_s)$S$(MANPAGE_s) X @echo "done installing manpages" X Xinstall_tmac: X $(INSTALL) $(MAN_MACRO) $(TMACDIR)$S$(MAN_MACRO) X $(INSTALL) $(MS_MACRO) $(TMACDIR)$S$(MS_MACRO) X# $(INSTALL) $(ME_MACRO) $(TMACDIR)$S$(ME_MACRO) X @echo "done installing macro packages" X X X X# clean up... X# Xclean: X $(RM) $(OBJS) errs X Xclobber: X $(RM) $(OBJS) X $(RM) $(TARGET) X Xcleansrc: X $(RM) $(SRCS) $(HEADERS) X Xcleandocs: X $(RM) docs.arc readme bugs $(MANPAGE) $(MAN_MACRO) $(MS_MACRO) X X X X# various archives... X# Xuue: X $(UUENCODE) $(TARGET) X @echo done making $(UUEFILE) X Xshar: uue X $(SHAR) $(SHARFLG) $(OTHERS) >$(SHARF1) X $(SHAR) $(SHARFLG) $(SRCS1) >$(SHARF2) X $(SHAR) $(SHARFLG) $(SRCS2) >$(SHARF3) X $(SHAR) $(SHARFLG) $(HEADERS) >$(SHARF4) X $(SHAR) $(SHARFLG) $(UUEFILE) >$(SHARF5) X @echo done making $(SHARF1) $(SHARF2) $(SHARF3) $(SHARF4) $(SHARF5) X Xarc: X $(ARC) a $(ARCFILE) $(OTHERS) X $(ARC) a $(ARCFILE) $(HEADERS) X $(ARC) a $(ARCFILE) $(SRCS) X @echo done making $(ARCFILE) X X X X# the following actions i use while developing so i can save disk space. X X# use this to save space on disk X# Xbackup: objs.arc srcs.arc docs.arc X Xobjs.arc: X $(ARC) a objs.arc $(OBJS) $(TARGET) X @echo done making objs.arc. consider "make clean" X Xsrcs.arc: X $(ARC) a srcs.arc $(HEADERS) X $(ARC) a srcs.arc $(SRCS) X @echo done making srcs.arc. consider "make cleansrc" X Xdocs.arc: X $(ARC) a docs.arc readme bugs $(MANPAGE) $(MAN_MACRO) $(MS_MACRO) X @echo done making docs.arc. consider "make cleandocs" X X# use this to go back to work after "make backup" X# Xrestore: X $(ARC) x srcs.arc $(HEADERS) X $(ARC) x srcs.arc $(SRCS) X $(ARC) x docs.arc $(MANPAGE) $(MAN_MACRO) $(MS_MACRO) X $(ARC) x objs.arc $(OBJS) X $(ARC) x objs.arc $(TARGET) X @echo done with restore...ok to continue to hack X @echo be sure to setenv TMACDIR during testing X X X#---------------------------------------------------------------------------- X# X# DEPENDENCIES: X# X# note: nroff.h includes version.h and config.h. all sources include nroff.h X# and in addition, main.c includes config.h as well (first thing). X Xversion.h: patchlvl.h X touch version.h X Xnroff.h: version.h config.h X touch nroff.h X Xmain.$O: main.c nroff.h Xcommand.$O: command.c nroff.h Xtext.$O: text.c nroff.h Xio.$O: io.c nroff.h Xmacros.$O: macros.c nroff.h Xstrings.$O: strings.c nroff.h Xescape.$O: escape.c nroff.h Xlow.$O: low.c nroff.h X X# the end... END_OF_Makefile.tos if test 8118 -ne `wc -c <Makefile.tos`; then echo shar: \"Makefile.tos\" unpacked with wrong size! fi # end of overwriting check fi if test -f POST.MNX -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"POST.MNX\" else echo shar: Extracting \"POST.MNX\" \(3574 characters\) sed "s/^X//" >POST.MNX <<'END_OF_POST.MNX' XThis is a new version of nroff(1), a text processor similar to Unix(tm) Xnroff, though not 100% compatible (not all the commands are available and Xthe macro packages here will not work with unix nroff, though the macro Xcommands in text files will). This is version 1.10 and was written on Xa 4 MB atari ST under TOS, not minix. I have NOT tested it under minix Xbecause I do not have minix operational on my "spare" ST (yet?). X XNOTE: there was a patch to 0.99 for the termcap stuff in main.c. Xunfortunately, i lost it in my last "career move" so you may need to Xfix this for terminal support for bold, italic, and/or standout modes. XIf you do, pls send me the patch (diff -c oldfile.c newfile.f is fine). X XI made the Makefile as compatible as I could for minix. The original X(TOS) makefile is also included. You _SHOULD_ just be able to say: X X % make all X Xand it will compile. I would suggest you look at the Makefile first Xbefore trying "make install". At least do "make -n install" to see what Xwould happen (assuming, of course, that minix make has a unix-like "-n" Xflag). X XThis version adds 2 things: 1) support (partial) for the ".if" command X(look at the tmac.* files to see how it can be used), and 2) a working Xthough hardly complete -ms (manuscript) package. I also added the ".mc" Xcommand to make changebars in documents possible. oh, i added the "-raN" Xcommand line switch (to preset a user number register). X XThis post is equivalent to TOS nroff, v1.10, patchlevel 3. v1.10 was Xposted to c.s.atari.st and c.b.atari.st up to patchlevel 2. pl 3 only Xmakes it possible to specify margin char location with the .mc command Xwhich is like 4-5 lines of code. This is what I am currently using Xas of this writing. X XI suggest you use the macro packages rather than raw nroff commands as Xthey may not always work as you would expect. vertical displacements Xare generally in "units" rather than inches though horizontal distances Xshould be ok with inches, though you will need floating point support. Xnroff does not yet support complicated things like: X X .in \nA+\n(.l/2 X Xjust single numbers (no arithmetic on args). use the existing macro Xpackages (tmac.an and tmac.s) and the test programs (in tests.uu) as Xa guide for using nroff or for writing/expanding macro packages. X XFutures: I eventually hope to finish the .if command (to accept block Xinput as in: X X .if something \{\ X ... X ... \} X Xand add support for .ie/.el (if/else) within the next few months. I'd Xalso like to add at least .wh traps and possibly diversions within X6 months, depending on what little free time I have. X XNote that there is a GNU troff on prep.ai.mit.edu (ftp access). I have XNOT ported that to minix since i seriously doubt it would fit. It would Xtake forever to run on my 8 Mhz ST anyway. My nroff is a single pass Xnroff while "real" nroff is at least 2 pass, I think, and though no Xspeed demon itself, this nroff is probably faster than what the full Xnroff would do on these tiny systems. X XAnyway, have fun. I use this all the time to write -ms and -man docs Xon my atari, then move them (without changes) to other unix systems X(currently convex). The -ms package has all the basics: TL,AU,AI,AB,AE, XSH,NH,PP,LP,QP,XP,RS,RE,IP(buggy),I,B,R which will easily let you make Xnice looking documents. Check the test cases in tests.uu (this is a Xuuencoded shar file). Note that there is no support for displays, keeps, Xfootnotes, tables, etc. in the -ms package. It is pretty basic. The -man Xpackage supports TH,SH,SS,PP,RS,RE,IP,I,B,IR,BR, etc. X XEnjoy... X X-Bill Rosenkranz Xrosenkra%c1yankee@convex.com X END_OF_POST.MNX if test 3574 -ne `wc -c <POST.MNX`; then echo shar: \"POST.MNX\" unpacked with wrong size! fi # end of overwriting check fi if test -f README -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"README\" else echo shar: Extracting \"README\" \(3657 characters\) sed "s/^X//" >README <<'END_OF_README' X------------------------------------ Xnroff (TOS, Minix) v1.10 7/22/90 wjr X------------------------------------ X XThis is an improved release of a version of nroff for both TOS and Unix X(Minix and BSD). It was written under TOS and 4BSD unix but has been Xreleased with Minix 1.5.5 as well. Unfortunately I have no access to Minix Xso I do not know if this particular version will work correctly under Minix. XIt does run under both SunOS and Convex, both BSD, so i feel pretty confident Xthat it should run under Minix. You will need to change the makefile Xregardless. I use Alcyon and my own cc(1). X XBesides small bug fixes, these are some new features since v0.99 (BETA): X X - added .if command which makes it possible to make a reasonable X ms package X X - fixed the bug where line filling on lines containing standout X would not fill properly X X - added a -ms package which is not half bad X X - enhanced the -man package X XMuch of this works. The things that (still) don't are all the hard things: Xdiversions, traps, conditionals, etc. See the man pages for what is not Xsupported (yet). Font switching, underlining, etc. are limited to reverse Xvideo on the screen (TOS). X XThere are decent man and ms packages included (tmac.an and tmac.s) which are Xnot perfect but then they are not half bad either. To make them better, nroff Xneeds diversions and traps, something that I will eventually do. They should Xhandle most common man tasks, though. They get installed in /usr/lib/tmac Xunder Minix and c:\lib\tmac under atari TOS, unless you change the location Xin nroff.h. For testing, you can X X % setenv TMACDIR . X % nroff -man file X Xto use tmac.an (say) in the cwd. X XFor porting info, look in config.h, nroff.h and the makefile. The termcap Xlibrary is used to get standout capabilites for doing bold and italics to Xthe screen (Minix and Unix). The TOS version has these hardwired to the Xvt52 escapes. Minix and BSD have termcap(3) and S5R3 has terminfo, which I Xbelieve also includes the tgetent/tgetnum/tgetflag/tgetstr functions for Xcompatibility. Note that the Sun /etc/termcap includes padding in some of Xthe definitions which I strip out. See main.c. X XIf you want to try and use nroff for printer output, the termcap library X(Minix and Unix only) looks for TERMCAP in your environment (a file) so Xthat you could do: X X % env TERMCAP=printer_termcap_file nroff -man file X Xand substitute your own file with "so" (standout) for your printer. This Xassumes your system has env, but you get the idea. X XThe program is small enough to work under Minix. It does not have a large Xstack, but does store all macros and strings in a common namespace. Look Xin nroff.h for the size. X XIf you do hack away, I would appreciate you sending me the changes so I can Xkeep this centralized. X XThe future holds increased capabilites, though I find it pretty useful Xas it is. Most man things are possible and you can do reports and resumes Xand such without much problem. See the example files included as well as Xthe manpage sources (nroff.man, man.man, ms.man) and the macro libraries X(tmac.an and tmac.s) for more help. Most people do not write macro libraries Xbut rather use the predefined macros (-man and -ms) which are supported Xpretty well at this point. X XThings to do include: X X - support for "block" if's, i.e. X X .if condition \{\ X ... X ... X ... \} X X - support for .ie/.el (if/else) X X - traps, diversions X X - vertical motions X X - two-character user number registers X X - tabs, leaders, and fields X X - hyphenation X X - environment switching X XIf anyone has a few spare minutes, maybe you could add these? Just kidding! X X XEnjoy... X X X-Bill Rosenkranz Xrosenkra%c1yankee@convex.com END_OF_README if test 3657 -ne `wc -c <README`; then echo shar: \"README\" unpacked with wrong size! fi # end of overwriting check fi if test -f nroff.man -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"nroff.man\" else echo shar: Extracting \"nroff.man\" \(25302 characters\) sed "s/^X//" >nroff.man <<'END_OF_nroff.man' X.\" nroff(1) manpage by rosenkra@convex.com (Bill Rosenkranz, 7/22/90) X.\" X.TH NROFF 1 X.SH NAME Xnroff - text processor (Version 1.10) X.SH SYNOPSIS Xnroff [options] file [...] X.SH DESCRIPTION XNroff is a text processor and formatter based on the design Xprovided in "Software Tools" by Kernighan and Plauger. XIt has been modified to closely resemble the Unix(tm) nroff command. XThe text and commands found in the file(s) Xare processed to generate formatted text. XNote that one (and only one) of the files can be "-" which reads Xinput from stdin at that point. XThe output always goes to stdout which can be redirected by the shell. X.\" Using the command line option -l will cause the output to X.\" be sent to the printer instead. XThe -o option lets you redirect error output to the specified Xfile rather than stderr. XDebugging information always goes to the file "nroff.dbg" and is Xgenerally used only for program development. X.SH OPTIONS XThe following command line options are available: X.IP -d XSet debug mode. X.IP -h XHold before exit (Atari TOS only). X.IP -m<name> XProcess macro file tmac.<name>. XThus -man would cause the file tmac.an to be loaded. XNote that files processed in this way should contain only macro definitions, Xno immediate output should be generated from this file (see ENVIRONMENT). X.IP -o<file> XSet error log file (default is stderr). X.IP -raN XPreset number register 'a' (single character) to N (decimal integer only). X.IP -po<n> XShift output right n spaces (like .po). X.IP -pn<n> XInitial page number (like .pn). X.IP -v XPrints the version information to stdout. X.IP +<n> XCauses output to start with page n. X.IP -<n> XCauses output to stop after page n. X.IP - XInput from stdin. X.sp X.SH ENVIRONMENT XNroff recognizes the following environment variables from the shell: X.IP TMACDIR XAn alternate directory to find the files tmac.* ("." for example). XThe default is c:\\lib\\tmac under TOS and /usr/lib/tmac under XMinix or Unix(tm). X.IP TMPDIR XAn alternate directory to place any temporary files. XThe default is the current directory. XNote that nroff does not currently use any temporary files. X.SH COMMANDS XCommands typically are distinguished by a period in column one Xof the input Xfollowed by a two character abbreviation for the command funtion. XThe abbreviation may then be followed by an optional numeric or Xcharacter argument. XThe numeric argument may be an absolute value such as setting Xthe right margin to a particular column, or the argument may be Xpreceded by a plus sign or a minus sign to indicate that the Xparameter should be modified relative to a previous setting. XThe following commands are recognized (those marked "extension" Xare requests added to the basic set provided by Unix(tm) nroff): X.\" X.IP .ad XBegin line adjustment. XIf fill mode is not on, adjustment is defered until it is back on. XIf a type indicator is present, the adjustment type is changed as follows: X.nf X X Indicator Type X l adjust left margin only X r adjust right margin only X c center X b or n adjust both margins (default) X absent unchanged X.fi X.\" X.IP .af XAssign format to number register. XThe available formats are: X.nf X X Format Numbering Sequence X 1 0,1,2,3,4,... X 001 000,001,002,... X i 0,i,ii,iii,iv,v,... X I 0,I,II,III,IV,V,... X a 0,a,b,...,z,aa,ab,...zz,aaa,... X A 0,A,B,...,Z,AA,AB,...ZZ,AAA,... X X.fi XThe second format above indicates that the field width, i.e. number Xof digits, is specified by the number of digits in the format type. X.\" X.IP .bd XIgnored by nroff. X.\" X.IP .bo (extension) XCauses the following lines of text to appear in boldface. XThe optional argument specifies the number of lines to be typed in boldface. XBoldface and underlining are mutually exclusive features. XThe appearance of a boldface command will cause any underlining to cease. X.\" X.IP .bp (extension) XCauses succeeding text to appear at the top of a new page. XThe optional argument specifies the page number for the new page. XThe initial value is one and the default value is one more than Xthe previous page number. X.\" X.IP .br XCauses succeeding text to start on a new line at the current left margin. XThere is no numeric argument for this command. X.\" X.IP .bs (extension) XEnables or disables the appearance of backspaces in the output text. XUnderlining and boldface options are implemented by inserting Xcharacter - backspace - character combinations into the output buffer. XThis is fine for devices which properly recognize the backspace character. XSome printers, however, do not recognize backspaces, so the option is Xprovided to overprint one line buffer with another. XThe first line buffer is terminated with just a carriage return Xrather than the carriage return - linefeed combination. XA zero argument or no argument to the backspace command removes Xbackspaces from the output. XA non-zero argument leaves them in the output. XThe default is to remove backspaces. X.\" X.IP .cc XChanges the nroff command character to that specified by the Xcharacter argument. XIf no argument is provided, the default is a period (\.). X.\" X.IP .ce XCauses the next line of text to appear centered on the output. XThe optional argument specifies if more than one line is to be centered. X.\" X.IP .cs XIgnored by nroff. X.\" X.IP .cu XCauses the next line(s) of text to be continuously underlined. XUnlike the underline command (see \.ul) which underlines only Xalphanumerics, continuous underlining underlines all printable characters. XThe optional argument specifies the number of lines of text to underlined. XAny normal underlining or boldface commands currently in effect will be Xterminated. X.\" X.IP .c2 XChanges the nroff no break character to that specified by the Xcharacter argument. XIf no argument is provided, the default is a single quote. X.\" X.IP .de XCauses all text and commands following to be used to define a macro. XThe definition is terminated by a \.en command or the Xdefault \.\. terminator. XThe first two characters of the argument following the \.de Xcommand become the name of the new command. XIt should be noted that upper and lower case arguments are considered different. XThus, the commands \.PP and \.pp could define two different macros. XCare should be exercised since existing commands may be redefined. X.sp XA macro may contain up to nine arguments. XIn the macro definition, the placement of arguments is designated by the Xtwo character sequences, $1, $2, ... $9. XWhen the macro is invoked, each argument of the macro command line is Xsubstituted for its corresponding designator in the expansion. XThe first argument of the macro command is substituted for the $1 Xin the expansion, the second argument for the $2, and so forth. XArguments are typically strings which do not contain blanks or tabs. XIf an argument is to contain blanks, then it should be surrounded by Xeither single or double quotes. X.\" X.IP .ds XDefine a string. XTo initiate the string with a blank or include blanks Xin the string, start it with a single or double quite. XThe string Xcan contain other defined strings or number registers as well as normal Xtext. XStrings are stored on the macro name space. X.\" X.IP .ec XChanges the nroff escape character to that specified by the Xcharacter argument. XIf no argument is provided, the default is a backslash. X.\" X.IP .ef (extension) XSpecifies the text for the footer on even numbered pages. XThe format is the same as for the footer command (see \.fo). X.\" X.IP .eh (extension) XSpecifies the text for the header on even numbered pages. XThe format is the same as for the footer command (see \.fo). X.\" X.IP .en (extension) XDesignates the end of a macro definition. X.\" X.IP .eo XTurn the escape mechanism off. X.\" X.IP .ex XExit nroff at this point in the processing. XEx forces all files closed and flushes the output. X.\" X.IP .fi XCauses the input text to be rearranged or filled to obtain the maximum Xword count possible between the previously set left and right margins. XNo argument is expected. X.\" X.IP .fl XCauses the output buffer to be flushed immediately. X.\" X.IP .fo (extension) XSpecifies text to be used for a footer. XThe footer text contains three strings seperated by a delimiter character. XThe first non-blank character following the command is designated Xas the delimiter. XThe first text string is left justified to the current indentation Xvalue (specified by \.in). XThe second string is centered between the current indentation value Xand the current right margin value (specified by \.rm). XThe third string is right justified to the current right margin value. XThe absence of footer text will result in the footer being printed as Xone blank line. XThe presence of the page number character (set by \.pc) in the footer Xtext results in the current page number being inserted at that position. XMultiple occurrances of the page number character are allowed. X.\" X.IP .ft XChanges the current font. XThe choices are R (Times Roman), I (Times Italic), B (Times Bold), XS (math special), and P used to request the previous font. XP resets the next previous font to be the one just changed, amounting to a swap. X.\" X.IP .he (extension) XSpecifies text to be used for a header. XThe format is the same as for the footer (see \.fo). X.\" X.IP .if XExecute a command if the condition is true. XFormat is: X.nf X X .if c command X .if !c command X .if N command X .if !N command X .if "str1"str2" command X .if !"str1"str2" command X X.fi XHere c is a single letter: n (true if nroff), t (true if troff), e (true Xif even page), or o (true if odd page). XN is a numerical experssion and can include operators +, -, *, /, % (mod), X>, <, >=, <=, = (or ==), & (and), or : (or). XIf the result is greater than 0, the condition evaluates true. XNumbers in the expression can be either constants or contents of number Xregisters. XStrings are tested using delimeter / or " only at this time. XNote that "block" conditionals like: X.nf X X .if c \\{\\ X ... X ... X ... \\} X X.fi Xare not yet supported. XAlso the .ie/.el conditional is not yet supported. X.\" X.IP .in XIndents the left margin to the column value specified by the argument. XThe default left margin is set to zero. X.\" X.IP .ju (extension) XCauses blanks to be inserted between words in a line of Xoutput in order to align or justify the right margin. XThe default is to justify. X.\" X.IP .lg XIgnored by nroff. X.\" X.IP .ll XSets the current line length. XThe default is eighty. X.\" X.IP .ls XSets the line spacing to the value specified by the argument. XThe default is for single spacing. X.\" X.IP .lt XSet length of three-part titles. XLine length and title length Xare independent. XIndents do not apply to titles but page offsets do. X.\" X.IP .m1 (extension) XSpecifies the number of lines in the header margin. XThis is the space from the physical top of page to and including Xthe header text. XA value of zero causes the header to not be printed. XA value of one causes the header to appear at the physical top of page. XLarger argument values cause the appropriate number of blank Xlines to appear before the header is printed. X.\" X.IP .m2 (extension) XSpecifies the number of blank lines to be printed between Xthe header line and the first line of the processed text. X.\" X.IP .m3 (extension) XSpecifies the number of blank lines to be printed between Xthe last line of processed text and the footer line. X.\" X.IP .m4 (extension) XSpecifies the number of lines in the footer margin. XThis command affects the footer the same way the \.m1 Xcommand affects the header. X.\" X.IP .mc XMargin character. The first argument is the character to use, Xthe second is the distance to the right of the right margin Xto place the margin character. Useful for change bars. XNo arguments turns the capability off. Note that with this Xnroff, the margin character is always a single character only Xand this distance is prefered to be in inches (e.g. 0.2i). XThe default space is 0.2i (2 spaces). X.\" X.IP .na XNoadjust. XAjdustment is turned off; the right margin is ragged. XThe adjustment type for \.ad is not changed. XOutput line filling still occurs if fill mode is on. X.\" X.IP .ne XSpecifies a number of lines which should not be broken across a page boundary. XIf the number of lines remaining on a page is less than the Xvalue needed, then a new output page is started. X.\" X.IP .nf XSpecifies that succeeding text should be printed without Xrearrangement, or with no fill. XNo argument is expected. X.\" X.IP .nj (extension) XSpecifies that no attempt should be made to align or justify the right margin. XNo argument is expected. X.\" X.IP .nr XCauses the value of a number register to be set or modified. XA total of twenty-six number registers are available designated X\\na through \\nz (either upper or lower case is allowed). XWhen the sequence \\nc is imbedded in the text, the current value Xof number register c replaces the sequence, thus, such things as Xparagraph numbering can be accomplished with relative ease. X.\" X.IP .of (extension) XSpecifies the text for the footer on odd numbered pages. XThe format is the same as the footer command (see \.fo). X.\" X.IP .oh (extension) XSpecifies the text for the header on odd numbered pages. XThe format is the same as the footer command (see \.fo). X.\" X.IP .pc XSpecifies the page number character to be used in headers and footers. XThe occurrance of this character in the header or footer text Xresults in the current page number being printed. XThe default for this character is the percent sign (%). X.\" X.IP .pl XSpecifies the page length or the number of lines per output page. XThe default is sixty-six. X.\" X.IP .pm XPrint macros. XThe names and sizes of the macros are printed to stdout. XThis is useful when building a macro package to see how much of the Xtotal namespace is consumed by the package. X.\" X.IP .pn XChanges the page number of the current page and all Xsubsequent pages to its argument. XIf no argument is given, the command is ignored. X.\" X.IP .po XSpecifies a page offset value. XThis allows the formatted text to be shifted to the right by Xthe number of spaces specified. XThis feature may also be invoked by a switch on the command line. X.\" X.IP .ps XIgnored by nroff. X.\" X.IP .rr XRemoves a number register. X.\" X.IP .so XCauses input to be retrieved from the file specified Xby the command's character string argument. XThe contents of the new file are inserted into the output Xstream until an EOF is detected. XProcessing of the original file is then resumed. XCommand nesting is allowed. X.\" X.IP .sp XSpecifies a number of blank lines to be output before Xprinting the next line of text. X.\" X.IP .ss XIgnored by nroff. X.\" X.IP .ti XTemporarily alters the indentation or left margin value for a single Xsucceeding input line. X.\" X.IP .tl XSpecifies text to be used for a page title. XThe format is the same as for the header (see \.he). X.\" X.IP .ul XCauses the next line(s) of text to be underlined. XUnlike the \.cu command, this command causes only alphanumerics Xto be underlined, skipping punctuation and white space. XUnderline and boldface are mutually exclusive. X.PP XThe following nroff commands, normally available, are currently Xnot implemented in this version: X.cc + X\.fp, \.mk, \.rt, \.vs, \.sv, \.os, \.ns, \.rs, \.am, \.as, \.rm, \.rn, X\.di, \.da, \.wh, \.ch, \.dt, \.it, \.em, \.ta, \.tc, \.lc, \.fc, \.lg, X\.uf, \.tr, \.nh, \.hy, \.hc, \.hw, \.nm, \.nn, \.ie, \.el, \.ev, \.rd, X\.ex, \.nx, \.pi, \.tm, and \.ig. X+cc . X.\" X.SH ESCAPE SEQUENCES XEscape sequences are used to access special characters (such as Greek Xletters) which may be outside the normal printable ASCII character set. XThe are also used to toggle certain actions such as font selection. X.PP X.ne 5 XThe escape sequences include: X.sp X.eo X.\" .ec - X.nf X\\ backslash character X\e printable version of escape character X\' accute accent (equivalent to \\(aa) X\` grave accent (equivalent to \\(ga) X\- minus sign X\. period X\<space> a single, unpaddable space X\0 digit-width space X\| 1\6em space (zero space in nroff) X\^ 1\12em space (zero space in nroff) X\& non-printing zero-width character X\" beginning of comment X\% default hyphenation character X\(xx special character named xx X\*x,\*(xx interpolate string x or xx X\fc font change (c = R,I,B,S,P) X\nx interpolate number register x X\t horizontal tab X.fi X.sp X.ne 5 XThe Atari ST (TOS) version of nroff includes the following special Xcharacters. NOTE: THESE ARE NOT AVAILABLE UNDER Minix OR Unix(tm)! X.sp X.nf X\(co copyright X\(rg registered X\(tm trademark X\(12 1/2 X\(14 1/4 X\(p2 exponent 2 X\(p3 exponent 3 X\(pn exponent n X\(aa acute X\(ga grave X\(de degree X\(dg dagger X\(ct cent X\(bu bullet X\(pp paragraph X\(^g ring bell X\(ua up arrow X\(da dn arrow X\(-> rt arrow X\(<- lf arrow X\(di divide X\(sr sq root X\(== == X\(>= >= X\(<= <= X\(+- +- X\(~= ~= X\(ap approx X\(no not X\(mo memeber X\(ca intersect X\(cu union X\(*a alpha X\(*b beta X\(*g gamma X\(*d delta X\(*s sigma X\(*p pi X\(*m mu X.fi X.ec X.SH PREDEFINED GENERAL NUMBER REGISTERS XThe following number registers are available for both reading and writing. XThey are accessed with the \\n(xx and \\nx escape and can be set with .nr: X.nf X.ne 5 X X% current page number Xdw current day of the week (1-7) Xdy current day of the month (1-31) Xhh current hours (0-23) Xln current line number Xmm current minutes (0-59) Xmo current month (1-12) Xss current seconds (0-59) Xyr last 2 digits of current year X.fi X.sp XThe following number registers are available for reading only: X.nf X.cc + X X.$ number of args available in current macro X.A always 1 in nroff X.H available horizontal resolution X.T always 0 in nroff X.V available vertical resolution X.c number of lines read from current file X.f current font (1-4) X.i current indent X.l current line length X.o current page offset X.p current page length X.v current vertical spacing X+cc . X X.fi X.SH NOTES XThere are several missing features, notably diversions, traps, Xconditionals, all the hard stuff. XThis means you can't use some existing macro packages (yet, I hope). XThere is no complete -ms and -me packages as a result. XThe goal is to make this nroff work with all the SunOS macro packages Xsometime before Unix becomes obsolete! X.PP XIf you make additions to this code, please mail the changes to me so I Xcan make formal distributions. X.SH BUGS XUndoubtedly more than I know about. XHere are a few: X.PP XThe ability to perform numerical calculations on registers is not Ximplemented. X.PP XAll dimensional units are in em's or inches only. X.PP XLines with multiple string instances (i.e. \\*(xx) don't seem to work. X.PP XLines with font changes (e.g. for italics) use vt52 escape sequences Xto go to highlight mode. XThis should read termcap/terminfo to do it right. X.PP XSome interpolations don't work properly. X.PP XThe code uses statically allocated arrays for macros, strings, and registers. XThis should be changed to dynamically allocated buffers or Xwrite to intermediate files on small memory systems (i.e. Minix). X.SH FILES X.nf X.ec | X\lib\tmac\tmac.* predefined macros (see ENVIRONMENT) Xnroff.dbg debugging output Xstderr default error output stream Xstdout output stream X X.ec \ X.fi X.SH AUTHOR X.nf XAdapted for Atari ST (TOS) and Minix by Bill Rosenkranz 11/89 X Xnet: rosenkra@convex.com XCIS: 71460,17 XGENIE: W.ROSENKRANZ X XOriginal author: X XStephen L. Browning X5723 North Parker Avenue XIndianapolis, Indiana 46220 X X.fi X.SH HISTORY X.nf XOriginally written in BDS C (by Stephen L. Browning?) XAdapted for standard C by W. N. Paul XHeavily hacked up to conform to the "real" nroff with numerous Xadditions by Bill Rosenkranz 11/89 XBug fixes (termcap) and Minix 1.5.5 compatibility by XWim 'Blue Baron' van Dorst (wsincc@tuerc3.urc.tue.nl) X X.fi X X.SH RECOMMENDATIONS XI envisioned this rather limited version as a way of formatting Xman pages for my Atari ST system. XIt works just fine for that. XThe man macro package is certainly adequate for that purpose. XHowever, it would be nice to have more. XI suggest you limit Xyourself to things which would port easily to other environments. XAll the man macros available here should port without effort Xto a more complete Unix(tm) environment. X.PP XNroff as it stands can certainly be useful. XI recommend you don't Xuse the commands marked "extension". XStudy the source for the man pages here (nroff(1), ms(7), and man(7)) as Xwell as the macro packages (tmac.an and tmac.s) and the examples to find Xout the quirks. XSome things may not quite work like they do under Unix(tm), but it is Xfairly close for what is here. X.SH REFERENCES XThis document briefly describes the workings of nroff. XIt is certainly not the definitive work on text processing. XI suggest you go out and get a good book (there are several on the market) Xor refer to the Unix(tm) manuals for more help. XNroff is just like a compiler and is much more complicated than (say) the C Xlanguage which only has a handful of rules and is much more thoroughly Xdocumented. XGood luck! X.SH REQUEST SUMMARY XThe following table summarizes the nroff requests currently available: X.nf X.ne 8 X.cc + X XRequest Form Initial Default Notes Explanation X-------------- ------- ------- ------- ---------------------- XFont and Character Size Control X X.ps +-N 10pt prev E point size (ignored) X.ss N 12/36em ignored E space size (ignored) X.cs F N M off - P constant space mode (ign) X.bd F N off - P embolden font F (ignored) X.bd S F N off - P embolden special font X.ft F Roman prev E change to font F X X+ne 4 XPage Control X X.pl +-N 11in 11in v page length X.bp +-N N=1 - B,v eject page X.pn +-N N=1 ignored - next page number N X.po +-N 0 prev v page offset X.ne N - N=1V D,v need N vertical space X X+ne 4 XText Filling, Adjusting, and Centering X X.br - - B break X.fi fill - B,E fill mode X.nf fill - B,E no fill or adjust X.ad c adj,both adjust E adjust output, mode c X.na adjust - E no adjust X.ce N off N=1 B,E center N lines X X+ne 4 XVertical Spacing X X.ls N N=1 prev E output N-1 Vs X.sp N - N=1V B,v space vertical X X+ne 4 XLine Length and Indenting X X.ll +-N 6.5i prev E,m line length X.in +-N N=0 prev B,E,m indent X.ti +-N - ignored B,E,m temporary indent X X+ne 4 XMacros, Strings, Diversions, and Position Traps X X.de xx yy - .yy=.. - define macro xx X.ds xx str - ignored - define string xx X X+ne 4 XNumber Registers X X.nr R +-N M - u define and set num reg X.af R c arabic - - assign format to reg X.rr R - - - remove register X X+ne 4 XI/O Conventions and Character Translation X X.ec c \ \ - set escape char X.eo on - - turn off escape mech X.lg N - - - ligature mode (ignored) X.ul N off N=1 E underline N lines X.cu N off N=1 E cont. underline X.cc c . . E set control char X.c2 c ' ' E set nobreak control char X X+ne 4 XThree-part Titles X X.tl 'l'c'r' - - three-part title X.pc c % off - page number char X.lt +-N 6.5in prev E,m length of title X X+ne 4 XConditional Acceptence of Input X X.if c cmd - - if c true, accept cmd X.if !c cmd - - if c false, accept cmd X.if N cmd - - if N > 0, accept cmd X.if !N cmd - - if N <= 0, accept cmd X.if "s1"s2" cmd - - if strings same, accept cmd X.if !"s1"s2" cmd - - if strings differ, accept cmd X X+ne 4 XInput/Output File Switching X X.so filename - - switch source file X X+ne 4 XMiscellaneous X X.mc c N - off E,m margin char c, seperation N X.pm t - all - print macro names X.fl - - B flush output buffer X X+ne 4 XNotes X XB causes a break XD mode or parameters associated with current diversion level XE relevant parameters are a part of the current environment XO must stay in effect until logical output XP mode must be still or again in effect at time of physical output Xv,p,m,u default scale indicators X X+cc X.fi END_OF_nroff.man if test 25302 -ne `wc -c <nroff.man`; then echo shar: \"nroff.man\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 1 \(of 5\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 4 5 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 5 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 Bill Rosenkranz |UUCP: {uunet,texsun}!convex!c1yankee!rosenkra Convex Computer Corp. |ARPA: rosenkra%c1yankee@convex.com
rosenkra@convex1.convex.com (William Rosencranz) (08/03/90)
--- part 2 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 2 (of 5)." # # Contents: # command.c config.h escape.c # # Wrapped by rosenkra%c1yankee@convex.com on Thu Aug 2 13:40:07 1990 # PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f command.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"command.c\" else echo shar: Extracting \"command.c\" \(30522 characters\) sed "s/^X//" >command.c <<'END_OF_command.c' X/* X * command.c - command input parser/processor for nroff text 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 <stdio.h> X#include "nroff.h" X X#define iscond(x) ((x)=='>'||(x)=='<'||(x)=='=') X#define isoper(x) ((x)=='+'||(x)=='-'||(x)=='*'||(x)=='/'||(x)=='%') X X/*------------------------------*/ X/* comand */ X/*------------------------------*/ Xcomand (p) Xregister char *p; X{ X X/* X * main command processor X */ X X static int in_if_cond = 0; X X register int i; X register int ct; X register int val; X register int indx; X int newval; X int spval; X int not_cond; X char argtyp; X char name[MAXLINE]; X char macexp[MXMLEN]; X int tmp; X char *pfs; X char fs[20]; X char c; X char *ps1; X char *ps2; X X X if (debugging) X fprintf (err_stream, X "***%s.comand: enter, p=|%s|\n",myname,p); X X /* X * get command code X */ X ct = comtyp (p, macexp); X X /* X * error? X */ X if (ct == UNKNOWN) X { X fprintf (err_stream, X "***%s: unrecognized command %s\n", myname, p); X return; X } X X /* X * ignore comments X */ X if (ct == COMMENT) X return; X X X /* X * do escape expansion on command line args X */ X expesc (p, name); X X X /* X * get value of command X */ X/* val = getval (p, &argtyp);*/ X X X /* X * do the command X */ X switch (ct) X { X /* set (¶m, val, type, defval, minval, maxval) */ X case FC: X /* X * field delim/pad chars X * X * .fc [delim] [pad] X */ X fprintf (err_stream, "***%s: .fc not available\n", myname); X break; X case TR: X /* X * translate X * X * .tr ab... X */ X fprintf (err_stream, "***%s: .tr not available\n", myname); X break; X X X X X case AD: X /* X * adjust X * X * .ad [mode] X */ X val = getval (p, &argtyp); X p = skipwd (p); X p = skipbl (p); X X switch (*p) X { X case 'l': X dc.adjval = ADJ_LEFT; X dc.juval = YES; X break; X case 'r': X dc.adjval = ADJ_RIGHT; X dc.juval = YES; X break; X case 'c': X dc.adjval = ADJ_CENTER; X dc.juval = YES; X break; X case 'b': X case 'n': X dc.adjval = ADJ_BOTH; X dc.juval = YES; X break; X default: X break; X } X break; X case AF: X /* X * assign format to number reg X * X * .af R {1,a,A,i,I,0...1} X */ X val = getval (p, &argtyp); X p = skipwd (p); X p = skipbl (p); X if (!isalpha (*p)) X { X fprintf (err_stream, X "***%s: invalid or missing number register name\n", X myname); X } X else X { X /* X * number register format is 1,a,A,i,I,0...1 X * default is 1. for 0001 format, store num dig X * or'ed with 0x80, up to 8 digits. X */ X indx = tolower (*p) - 'a'; X p = skipwd (p); X p = skipbl (p); X if (*p == '1') X dc.nrfmt[indx] = '1'; X else if (*p == 'a') X dc.nrfmt[indx] = 'a'; X else if (*p == 'A') X dc.nrfmt[indx] = 'A'; X else if (*p == 'i') X dc.nrfmt[indx] = 'i'; X else if (*p == 'I') X dc.nrfmt[indx] = 'I'; X else if (*p == '0') X { X for (i = 0; isdigit (p[i]); i++) X ; X dc.nrfmt[indx] = (char) (i); X if (dc.nrfmt[indx] <= 0) X dc.nrfmt[indx] = '1'; X else if (dc.nrfmt[indx] > 8) X { X dc.nrfmt[indx] = 8; X dc.nrfmt[indx] |= 0x80; X } X else X dc.nrfmt[indx] |= 0x80; X X } X else X dc.nrfmt[indx] = '1'; X } X break; X case BD: X /* X * embolden font (IGNORED) X * X * .bd [S] F N X */ X break; X case BO: X /* X * bold face X * X * .bo [N] X */ X val = getval (p, &argtyp); X set (&dc.boval, val, argtyp, 1, 0, HUGE); X dc.cuval = dc.ulval = 0; X break; X case BP: X /* X * begin page X * X * .bp [+/-N] X */ X val = getval (p, &argtyp); X if (pg.lineno > 0) X space (HUGE); X set (&pg.curpag, val, argtyp, pg.curpag + 1, -HUGE, HUGE); X pg.newpag = pg.curpag; X set_ireg ("%", pg.newpag, 0); X break; X case BR: X /* X * break (page) X * X * .br X */ X robrk (); X break; X case BS: X /* X * backspc in output X * X * .bs [N] X */ X val = getval (p, &argtyp); X set (&dc.bsflg, val, argtyp, 1, 0, 1); X break; X case C2: X /* X * nobreak char X * X * .c2 [c='] X */ X val = getval (p, &argtyp); X if (argtyp == '\r' || argtyp == '\n') X dc.nobrchr = '\''; X else X dc.nobrchr = argtyp; X break; X case CC: X /* X * command character X * X * .cc [c=.] X */ X val = getval (p, &argtyp); X if (argtyp == '\r' || argtyp == '\n') X dc.cmdchr = '.'; X else X dc.cmdchr = argtyp; X break; X case CE: X /* X * center X * X * .ce [N] X */ X val = getval (p, &argtyp); X robrk (); X set (&dc.ceval, val, argtyp, 1, 0, HUGE); X break; X case CS: X /* X * constant space char (IGNORED) X * X * .cs F N M X */ X break; X case CU: X /* X * continuous underline X * X * .cu [N] X */ X val = getval (p, &argtyp); X set (&dc.cuval, val, argtyp, 1, 0, HUGE); X dc.ulval = dc.boval = 0; X break; X case DE: X /* X * define macro X * X * .de name [end] X */ X val = getval (p, &argtyp); X ignoring = FALSE; X defmac (p, sofile[dc.flevel]); X break; X case DS: X /* X * define string X * X * .ds name string X */ X val = getval (p, &argtyp); X defstr (p); X break; X case EC: X /* X * escape char X * X * .ec [c=\] X */ X val = getval (p, &argtyp); X if (argtyp == '\r' || argtyp == '\n') X dc.escchr = '\\'; X else X dc.escchr = argtyp; X dc.escon = YES; X break; X case EF: X /* X * even footer X * X * .ef "a" "b" "c" X */ X val = getval (p, &argtyp); X gettl (p, pg.efoot, &pg.eflim[0]); X break; X case EH: X /* X * even header X * X * .eh "a" "b" "c" X */ X val = getval (p, &argtyp); X gettl (p, pg.ehead, &pg.ehlim[0]); X break; X case EN: X /* X * end macro def (should not get one here...) X * X * .en or .. X */ X fprintf (err_stream, "***%s: missing .de command\n", myname); X break; X case EO: X /* X * escape off X * X * .eo X */ X dc.escon = NO; X break; X case EX: X /* X * exit X * X * .ex X */ X if (sofile[0] != stdin) X fclose (sofile[0]); X for (i = 1; i <= Nfiles; i++) X { X if (sofile[i] != NULL_FPTR) X fclose (sofile[i]); X } X err_exit (0); X break; X case FI: X /* X * fill X * X * .fi X */ X robrk (); X dc.fill = YES; X break; X case FL: X /* X * flush NOW X * X * .fl X */ X fflush (out_stream); X break; X case FO: X /* X * footer X * X * .fo "a" "b" "c" X */ X val = getval (p, &argtyp); X gettl (p, pg.efoot, &pg.eflim[0]); X gettl (p, pg.ofoot, &pg.oflim[0]); X break; X case FT: X /* X * font change X * X * .ft {R,I,B,S,P} X * X * the way it's implemented here, it causes a break X * rather than be environmental... X */ X val = getval (p, &argtyp); X p = skipwd (p); X p = skipbl (p); X if (!isalpha (*p)) X { X fprintf (err_stream, X "***%s: invalid or missing font name\n", X myname); X } X else X { X pfs = &fs[0]; X X fontchange (*p, pfs); X X robrk (); X fflush (out_stream); X fprintf (out_stream, "%s", pfs); X fflush (out_stream); X } X break; X case TL: X case HE: X /* X * header (both are currently identical. .he is -me) X * X * .tl "a" "b" "c" X * .he "a" "b" "c" X */ X val = getval (p, &argtyp); X gettl (p, pg.ehead, &pg.ehlim[0]); X gettl (p, pg.ohead, &pg.ohlim[0]); X break; X case IE: X /* X * if of if/else conditional X * X * .ie condition anything X * .el anything X * X * .ie condition \{\ X * ... X * ... \} X * .el \{\ X * ... X * ... \} X */ X fprintf (err_stream, "***%s: .ie not available\n", myname); X break; X case EL: X /* X * else of if/else conditional X * X * .ie condition anything X * .el anything X * X * .ie condition \{\ X * ... X * ... \} X * .el \{\ X * ... X * ... \} X */ X fprintf (err_stream, "***%s: .el not available\n", myname); X break; X case IF: X /* X * conditional X * X * .if c command [c=n(roff),t(roff),e(ven),o(dd)] X * .if !c command X * .if 's1's2' command [s1 == s2] X * .if !'s1's2' command [s1 != s2] X * .if N command [N > 0] X * .if !N command [N <= 0] X * X * .if cond \{\ X * command X * ... \} X */ X p = skipwd (p); X p = skipbl (p); X not_cond = 0; X if (*p == '!') X { X p++; X not_cond = 1; X } X if (islower (*p) && isspace (*(p+1))) X { X /* X * single char: n=nroff,t=troff,e=evenpage,o=oddpage X */ X c = *p; X switch (c) X { X case 'n': /* if nroff... (always T) */ X p = skipwd (p); X p = skipbl (p); X X if (debugging) X fprintf (err_stream, X "***%s.comand: p=|%s|\n",myname, p); X X if (*p != EOS && not_cond == 0) X { X if (*p == '\\' && *(p+1) == '{') X { X read_if (); X } X else X { X if (*p == dc.cmdchr) X comand (p); X else X { X if (*p == '\"') X p++; X if (*p == ' ') X robrk (); X text (p); X } X } X } X break; X case 't': /* if troff... (always F) */ X p = skipwd (p); X p = skipbl (p); X X if (debugging) X fprintf (err_stream, X "***%s.comand: p=|%s|\n",myname, p); X X if (*p != EOS && not_cond != 0) X { X if (*p == '\\' && *(p+1) == '{') X { X read_if (); X } X else X { X if (*p == dc.cmdchr) X comand (p); X else X { X if (*p == '\"') X p++; X if (*p == ' ') X robrk (); X text (p); X } X } X } X break; X case 'e': /* if even page... */ X p = skipwd (p); X p = skipbl (p); X X if (debugging) X fprintf (err_stream, X "***%s.comand: p=|%s|\n",myname, p); X X X if (((pg.curpag % 2) == 0 && not_cond == 0) X || ((pg.curpag % 2) != 0 && not_cond != 0)) X { /* could be newpag, too */ X if (*p == '\\' && *(p+1) == '{') X { X read_if (); X } X else X { X if (*p == dc.cmdchr) X comand (p); X else X { X if (*p == '\"') X p++; X if (*p == ' ') X robrk (); X text (p); X } X } X } X break; X case 'o': /* if odd page... */ X p = skipwd (p); X p = skipbl (p); X X if (debugging) X fprintf (err_stream, X "***%s.comand: p=|%s|\n",myname, p); X X X if (((pg.curpag % 2) == 1 && not_cond == 0) X || ((pg.curpag % 2) != 1 && not_cond != 0)) X { X if (*p == '\\' && *(p+1) == '{') X { X read_if (); X } X else X { X if (*p == dc.cmdchr) X comand (p); X else X { X if (*p == '\"') X p++; X if (*p == ' ') X robrk (); X text (p); X } X } X } X break; X } X } X else if (*p == '\'' || *p == '/' || *p == '\"') X { X /* X * compare strings. we need to interpolate here X */ X c = *p; X ps1 = ++p; X while (*p != EOS && *p != c) X p++; X *p = EOS; X ps2 = ++p; X while (*p != EOS && *p != c) X p++; X *p = EOS; X X if (debugging) X fprintf (err_stream, X "***%s.comand: strcmp (ps1=|%s|,ps2=|%s|)\n", X myname, ps1, ps2); X X if ((!strcmp (ps1, ps2) && not_cond == 0) X || ( strcmp (ps1, ps2) && not_cond != 0)) X { X p++; X p = skipbl (p); X X if (*p == '\\' && *(p+1) == '{') X { X read_if (); X } X else X { X if (*p == dc.cmdchr) X comand (p); X else X { X if (*p == '\"') X p++; X if (*p == ' ') X robrk (); X text (p); X } X } X } X } X else X { X /* X * number X */ X X if (debugging) X fprintf (err_stream, X "***%s.comand: p=|%s|\n",myname, p); X X val = getnumeric (p); X if ((val > 0 && not_cond == 0) X || (val <= 0 && not_cond != 0)) X { X p = skipwd (p); X p = skipbl (p); X X if (*p == '\\' && *(p+1) == '{') X { X read_if (); X } X else X { X if (*p == dc.cmdchr) X comand (p); X else X { X if (*p == '\"') X p++; X if (*p == ' ') X robrk (); X text (p); X } X } X } X } X break; X case IG: X /* X * ignore input lines X * X * .ig name X */ X val = getval (p, &argtyp); X ignoring = TRUE; X defmac (p, sofile[dc.flevel]); X break; X case IN: X /* X * indenting X * X * .in [+/-N] X */ X val = getval (p, &argtyp); X set (&dc.inval, val, argtyp, 0, 0, dc.rmval - 1); X set_ireg (".i", dc.inval, 0); X dc.tival = dc.inval; X break; X case JU: X /* X * justify X * X * .ju X */ X dc.juval = YES; X break; X case LG: X /* X * ligature (IGNORED) X * X * .lg [N] X */ X break; X case LL: X /* X * line length X * X * .ll [+/-N] X * .rm [+/-N] X */ X val = getval (p, &argtyp); X set (&dc.rmval, val, argtyp, PAGEWIDTH, dc.tival + 1, HUGE); X set (&dc.llval, val, argtyp, PAGEWIDTH, dc.tival + 1, HUGE); X set_ireg (".l", dc.llval, 0); X break; X case LS: X /* X * line spacing X * X * .ls [+/-N=+1] X */ X val = getval (p, &argtyp); X set (&dc.lsval, val, argtyp, 1, 1, HUGE); X set_ireg (".v", dc.lsval, 0); X break; X case LT: X /* X * title length X * X * .lt N X */ X val = getval (p, &argtyp); X set (&dc.ltval, val, argtyp, PAGEWIDTH, 0, HUGE); X pg.ehlim[RIGHT] = dc.ltval; X pg.ohlim[RIGHT] = dc.ltval; X break; X case M1: X /* X * topmost margin X * X * .m1 N X */ X val = getval (p, &argtyp); X set (&pg.m1val, val, argtyp, 2, 0, HUGE); X break; X case M2: X /* X * second top margin X * X * .m2 N X */ X val = getval (p, &argtyp); X set (&pg.m2val, val, argtyp, 2, 0, HUGE); X break; X case M3: X /* X * 1st bottom margin X * X * .m3 N X */ X val = getval (p, &argtyp); X set (&pg.m3val, val, argtyp, 2, 0, HUGE); X pg.bottom = pg.plval - pg.m4val - pg.m3val; X break; X case M4: X /* X * bottom-most marg X * X * .m4 N X */ X val = getval (p, &argtyp); X set (&pg.m4val, val, argtyp, 2, 0, HUGE); X pg.bottom = pg.plval - pg.m4val - pg.m3val; X break; X case MACRO: X /* X * macro expansion X * X * (internal) X */ X maceval (p, macexp); X break; X case MC: X /* X * margin character (change bars) X * X * .mc [c [N]] X * X * right margin only, default 0.2i X */ X val = getval (p, &argtyp); X if (argtyp == '\r' || argtyp == '\n') X mc_ing = FALSE; /* turn off... */ X else X { X mc_ing = TRUE; /* turn on... */ X mc_space = 2; /* force these for now... */ X mc_char = argtyp; /* single char only!!! */ X X p = skipwd (p); X p = skipbl (p); X X val = getval (p, &argtyp); X set (&mc_space, val, argtyp, 2, 0, dc.llval); X } X break; X case NA: X /* X * no adjust X * X * .na X */ X dc.adjval = ADJ_OFF; X dc.juval = NO; X break; X case NE: X /* X * need n lines X * X * .ne N X */ X val = getval (p, &argtyp); X robrk (); X if ((pg.bottom - pg.lineno + 1) < (val * dc.lsval)) X { X space (HUGE); X } X break; X case NF: X /* X * no fill X * X * .nf X */ X robrk (); X dc.fill = NO; X break; X case NJ: X /* X * no justify X * X * .nj X */ X dc.juval = NO; X break; X case NR: X /* X * set number reg X * X * .nr R +/-N M X */ X val = getval (p, &argtyp); X p = skipwd (p); X p = skipbl (p); X if (!isalpha (*p)) X { X fprintf (err_stream, X "***%s: invalid or missing number register name\n", X myname); X } X else X { X /* X * indx is the register, R, and val is the final X * value (default = 0). getval does skipwd,skipbl X */ X indx = tolower (*p) - 'a'; X val = getval (p, &argtyp); X set (&dc.nr[indx], val, argtyp, 0, -INFINITE, INFINITE); X X /* X * now get autoincrement M, if any (default = 1). X * getval does skipwd,skipbl X */ X p = skipwd (p); X p = skipbl (p); X val = getval (p, &argtyp); X set (&dc.nrauto[indx], val, '1', 1, -INFINITE, INFINITE); X } X break; X case OF: X /* X * odd footer X * X * .of "a" "b" "c" X */ X val = getval (p, &argtyp); X gettl (p, pg.ofoot, &pg.oflim[0]); X break; X case OH: X /* X * odd header X * X * .oh "a" "b" "c" X */ X val = getval (p, &argtyp); X gettl (p, pg.ohead, &pg.ohlim[0]); X break; X case PC: X /* X * page number char X * X * .pc [c=NULL] X */ X val = getval (p, &argtyp); X if (argtyp == '\r' || argtyp == '\n') X dc.pgchr = EOS; X else X dc.pgchr = argtyp; X break; X case PL: X /* X * page length X * X * .pl N X */ X val = getval (p, &argtyp); X set (&pg.plval, X val, X argtyp, X PAGELEN, X pg.m1val + pg.m2val + pg.m3val + pg.m4val + 1, X HUGE); X set_ireg (".p", pg.plval, 0); X pg.bottom = pg.plval - pg.m3val - pg.m4val; X break; X case PM: X /* X * print macro names and sizes X * X * .pm [t] X */ X val = getval (p, &argtyp); X if (argtyp == '\r' || argtyp == '\n') X printmac (0); X else if (argtyp == 't') X printmac (1); X else if (argtyp == 'T') X printmac (2); X else X printmac (0); X break; X case PN: X /* X * page number X * X * .pn N X */ X val = getval (p, &argtyp); X tmp = pg.curpag; X set (&pg.curpag, val - 1, argtyp, tmp, -HUGE, HUGE); X pg.newpag = pg.curpag + 1; X set_ireg ("%", pg.newpag, 0); X break; X case PO: X /* X * page offset X * X * .po N X */ X val = getval (p, &argtyp); X set (&pg.offset, val, argtyp, 0, 0, HUGE); X set_ireg (".o", pg.offset, 0); X break; X case PS: X /* X * point size (IGNORED) X * X * .ps +/-N X */ X break; X case RR: X /* X * unset number reg X * X * .rr R X */ X val = getval (p, &argtyp); X p = skipwd (p); X p = skipbl (p); X if (!isalpha (*p)) X { X fprintf (err_stream, X "***%s: invalid or missing number register name\n", X myname); X } X else X { X indx = tolower (*p) - 'a'; X val = 0; X set (&dc.nr[indx], val, argtyp, 0, -HUGE, HUGE); X } X break; X case SO: X /* X * source file X * X * .so name X */ X val = getval (p, &argtyp); X p = skipwd (p); X p = skipbl (p); X if (getwrd (p, name) == 0) X break; X if (dc.flevel + 1 >= Nfiles) X { X fprintf (err_stream, X "***%s: .so commands nested too deeply\n", X myname); X err_exit (-1); X } X if ((sofile[dc.flevel + 1] = fopen (name, "r")) == NULL_FPTR) X { X fprintf (err_stream, X "***%s: unable to open %s\n", myname, name); X err_exit (-1); X } X dc.flevel += 1; X break; X case SP: X /* X * space X * X * .sp [N=1] X */ X val = getval (p, &argtyp); X set (&spval, val, argtyp, 1, 0, HUGE); X space (spval); X break; X case SS: X /* X * space char size (IGNORED) X * X * .ss N X */ X break; X case TI: X /* X * temporary indent X * X * .ti [+/-N] X */ X val = getval (p, &argtyp); X robrk (); X set (&dc.tival, val, argtyp, 0, 0, dc.rmval); X break; X case UL: X /* X * underline X * X * .ul [N] X */ X val = getval (p, &argtyp); X set (&dc.ulval, val, argtyp, 0, 1, HUGE); X dc.cuval = dc.boval = 0; X break; X } X} X X X X X X/*------------------------------*/ X/* comtyp */ X/*------------------------------*/ Xcomtyp (p, m) Xregister char *p; Xchar *m; X{ X X/* X * decodes nro command and returns its associated value. X * ptr "p" is incremented (and returned) X */ X X register char c1; X register char c2; X char *s; X char macnam[MNLEN]; X X /* X * quick check: if null, ignore X */ X if (*p == EOS) X return (COMMENT); X X /* X * skip past dot and any whitespace X */ X p++; X while (*p && (*p == ' ' || *p == '\t')) X p++; X if (*p == '\0') X return (COMMENT); X X /* X * First check to see if the command is a macro. If it is, X * truncate to two characters and return expansion in m X * (i.e. the text of the macro). Note that upper and lower X * case characters are handled differently. X */ X getwrd (p, macnam); X macnam[2] = EOS; X if ((s = getmac (macnam)) != NULL_CPTR) X { X strcpy (m, s); X return (MACRO); X } X c1 = *p++; X c2 = *p; X if (c1 == '\\' && c2 == '\"') return (COMMENT); X if (c1 == 'a' && c2 == 'd') return (AD); X if (c1 == 'a' && c2 == 'f') return (AF); X if (c1 == 'b' && c2 == 'd') return (BD); X if (c1 == 'b' && c2 == 'o') return (BO); X if (c1 == 'b' && c2 == 'p') return (BP); X if (c1 == 'b' && c2 == 'r') return (BR); X if (c1 == 'b' && c2 == 's') return (BS); X if (c1 == 'c' && c2 == '2') return (C2); X if (c1 == 'c' && c2 == 'c') return (CC); X if (c1 == 'c' && c2 == 'e') return (CE); X if (c1 == 'c' && c2 == 's') return (CS); X if (c1 == 'c' && c2 == 'u') return (CU); X if (c1 == 'd' && c2 == 'e') return (DE); X if (c1 == 'd' && c2 == 's') return (DS); X if (c1 == 'e' && c2 == 'c') return (EC); X if (c1 == 'e' && c2 == 'f') return (EF); X if (c1 == 'e' && c2 == 'h') return (EH); X if (c1 == 'e' && c2 == 'n') return (EN); X if (c1 == '.') return (EN); X if (c1 == 'e' && c2 == 'o') return (EO); X if (c1 == 'e' && c2 == 'x') return (EX); X if (c1 == 'f' && c2 == 'i') return (FI); X if (c1 == 'f' && c2 == 'l') return (FL); X if (c1 == 'f' && c2 == 'o') return (FO); X if (c1 == 'f' && c2 == 't') return (FT); X if (c1 == 'h' && c2 == 'e') return (HE); X if (c1 == 'i' && c2 == 'f') return (IF); X/* if (c1 == 'i' && c2 == 'e') return (IE);*/ X/* if (c1 == 'e' && c2 == 'l') return (EL);*/ X if (c1 == 'i' && c2 == 'g') return (IG); X if (c1 == 'i' && c2 == 'n') return (IN); X if (c1 == 'j' && c2 == 'u') return (JU); X if (c1 == 'l' && c2 == 'g') return (LG); X if (c1 == 'l' && c2 == 'l') return (LL); X if (c1 == 'l' && c2 == 's') return (LS); X if (c1 == 'l' && c2 == 't') return (LT); X if (c1 == 'm' && c2 == '1') return (M1); X if (c1 == 'm' && c2 == '2') return (M2); X if (c1 == 'm' && c2 == '3') return (M3); X if (c1 == 'm' && c2 == '4') return (M4); X if (c1 == 'm' && c2 == 'c') return (MC); X if (c1 == 'n' && c2 == 'a') return (NA); X if (c1 == 'n' && c2 == 'e') return (NE); X if (c1 == 'n' && c2 == 'f') return (NF); X if (c1 == 'n' && c2 == 'j') return (NJ); X if (c1 == 'n' && c2 == 'r') return (NR); X if (c1 == 'o' && c2 == 'f') return (OF); X if (c1 == 'o' && c2 == 'h') return (OH); X if (c1 == 'p' && c2 == 'c') return (PC); X if (c1 == 'p' && c2 == 'l') return (PL); X if (c1 == 'p' && c2 == 'm') return (PM); X if (c1 == 'p' && c2 == 'n') return (PN); X if (c1 == 'p' && c2 == 'o') return (PO); X if (c1 == 'p' && c2 == 's') return (PS); X if (c1 == 'r' && c2 == 'm') return (RM); X if (c1 == 'r' && c2 == 'r') return (RR); X if (c1 == 's' && c2 == 'o') return (SO); X if (c1 == 's' && c2 == 'p') return (SP); X if (c1 == 's' && c2 == 's') return (SS); X if (c1 == 't' && c2 == 'i') return (TI); X if (c1 == 't' && c2 == 'l') return (TL); X if (c1 == 'u' && c2 == 'l') return (UL); X X if (c1 == 't' && c2 == 'r') return (TR); X if (c1 == 'f' && c2 == 'c') return (FC); X X return (UNKNOWN); X} X X X X X X/*------------------------------*/ X/* gettl */ X/*------------------------------*/ Xgettl (p, q, limit) Xregister char *p; Xregister char *q; Xint *limit; X{ X X/* X * get header or footer title X */ X X /* X * skip forward a word... X */ X p = skipwd (p); X p = skipbl (p); X X /* X * copy and set limits X */ X strcpy (q, p); X limit[LEFT] = dc.inval; X limit[RIGHT] = dc.rmval; X} X X X X X X/*------------------------------*/ X/* getval */ X/*------------------------------*/ Xgetval (p, p_argtyp) Xregister char *p; Xregister char *p_argtyp; X{ X X/* X * retrieves optional argument following command. X * returns positive integer value with sign (if any) X * saved in character addressed by p_argt. X */ X X p = skipwd (p); X p = skipbl (p); X *p_argtyp = *p; X if ((*p == '+') || (*p == '-')) X ++p; X return (ctod (p)); X} X X X X X X/*------------------------------*/ X/* getnumeric */ X/*------------------------------*/ X X#define N_ADD 0 X#define N_SUB 1 X#define N_MUL 2 X#define N_DIV 3 X#define N_MOD 4 X#define N_LT 5 X#define N_GT 6 X#define N_LE 7 X#define N_GE 8 X#define N_EQ 9 X#define N_AND 10 X#define N_OR 11 X X Xgetnumeric (p) Xregister char *p; X{ X X/* X * retrieves numeric argument. will parse for number registers, X * constants, operations, and logical comparisons. no imbeded spaces! X * start at p (don't skip) X */ X X char name[10]; X int val; X int thisval; X int autoinc; X char buf[256]; X char *pbuf; X int next_op; X int nreg; X X val = 0; X next_op = N_ADD; X while (*p != EOS && !isspace (*p)) X { X if (!strncmp (p, "\\n", 2)) X { X if (debugging) X fprintf (err_stream, X "***%s.getnumeric: found number reg...\n",myname); X /* X * number register X */ X autoinc = 0; X p += 2; X if (*p == '+') X { X autoinc = 1; X p++; X } X else if (*p == '-') X { X autoinc = -1; X p++; X } X if (isalpha (*p)) X { X /* X * \nx form. find reg (a-z) X */ X nreg = tolower (*p) - 'a'; X p++; X X /* X * was this \n+x or \n-x? if so, do the X * auto incr X */ X if (autoinc > 0) X dc.nr[nreg] += dc.nrauto[nreg]; X else if (autoinc < 0) X dc.nr[nreg] -= dc.nrauto[nreg]; X X X val = do_oper (val, next_op, dc.nr[nreg]); X } X else if (*p == '%') X { X /* X * \n% form. find index into reg struct X */ X nreg = findreg ("%"); X p++; X if (nreg < 0) X { X fprintf (err_stream, X "***%s: no register match\n", X myname); X err_exit (-1); X } X X /* X * was this \n+% or \n-%? if so, do the X * auto incr X */ X if (autoinc > 0) X rg[nreg].rval += rg[nreg].rauto; X else if (autoinc < 0) X rg[nreg].rval -= rg[nreg].rauto; X X X val = do_oper (val, next_op, rg[nreg].rval); X } X else if (*p == '(') X { X /* X * \n(xx form. find index into reg struct X */ X p++; X name[0] = *p++; X name[1] = *p++; X if (name[1] == ' ' || name[1] == '\t' X || name[1] == '\n' || name[1] == '\r') X name[1] = '\0'; X name[2] = '\0'; X nreg = findreg (name); X if (nreg < 0) X { X fprintf (err_stream, X "***%s: no register match\n", X myname); X err_exit (-1); X } X X X /* X * was this \n+(xx or \n-(xx? if so, do the X * auto incr X */ X if (rg[nreg].rflag & RF_WRITE) X { X if (autoinc > 0) X rg[nreg].rval += rg[nreg].rauto; X else if (autoinc < 0) X rg[nreg].rval -= rg[nreg].rauto; X } X X val = do_oper (val, next_op, rg[nreg].rval); X } X } X else if (isdigit (*p)) X { X pbuf = buf; X while (1) X { X if (*p == EOS || isspace (*p)) X break; X if (*p == '\\') X break; X if (iscond (*p)) X break; X if (isoper (*p)) X break; X X *pbuf++ = *p++; X } X *pbuf = EOS; X X if (debugging) X fprintf (err_stream, X "***%s.getnumeric: buf:|%s| next_op:%d val:%d\n", X myname,buf,next_op,val); X X thisval = ctod (buf); X val = do_oper (val, next_op, thisval); X if (debugging) X fprintf (err_stream, X "***%s.getnumeric: thisval:%d val:%d\n", X myname,thisval,val); X } X X /* X * p should now be at the next thing, either a X * space, a null, or an operator X */ X if (*p == EOS || isspace (*p)) X break; X switch (*p) X { X case '+': X next_op = N_ADD; X p++; X break; X case '-': X next_op = N_SUB; X p++; X break; X case '*': X next_op = N_MUL; X p++; X break; X case '/': X next_op = N_DIV; X p++; X break; X case '%': X next_op = N_MOD; X p++; X break; X case '&': X next_op = N_AND; X p++; X break; X case ':': X next_op = N_OR; X p++; X break; X case '<': X p++; X if (*p == '=') X { X p++; X next_op = N_LE; X } X else X next_op = N_LT; X break; X case '>': X p++; X if (*p == '=') X { X p++; X next_op = N_GE; X } X else X next_op = N_GT; X break; X case '=': X p++; X if (*p == '=') X p++; X next_op = N_EQ; X break; X } X } X return (val); X} X X X X X X/*------------------------------*/ X/* do_oper */ X/*------------------------------*/ Xdo_oper (first, oper, second) Xint first; Xint oper; Xint second; X{ X int val; X X if (debugging) X fprintf (err_stream, X "***%s.do_oper: first:%d op:%d second:%d\n", X myname, first, oper, second); X X switch (oper) X { X case N_ADD: X val = first + second; X break; X case N_SUB: X val = first - second; X break; X case N_MUL: X val = first * second; X break; X case N_DIV: X val = first / second; X break; X case N_MOD: X val = first % second; X break; X case N_LT: X val = ((first < second) ? 1 : 0); X break; X case N_GT: X val = ((first > second) ? 1 : 0); X break; X case N_LE: X val = ((first <= second) ? 1 : 0); X break; X case N_GE: X val = ((first >= second) ? 1 : 0); X break; X case N_EQ: X val = ((first == second) ? 1 : 0); X break; X case N_AND: X val = ((first && second) ? 1 : 0); X break; X case N_OR: X val = ((first || second) ? 1 : 0); X break; X } X X return (val); X} X X X X X X/*------------------------------*/ X/* set */ X/*------------------------------*/ Xset (param, val, type, defval, minval, maxval) Xregister int *param; Xregister int val; Xregister char type; Xregister int defval; Xregister int minval; Xregister int maxval; X{ X X/* X * set parameter and check range. this is for basically all commands X * which take interger args X * X * no param (i.e. \r or \n) means reset default X * + means param += val (increment) X * - means param -= val (decrement) X * anything else makes an assignment within the defined numerical limits X * X * examples: X * X * .nr a 14 set register 'a' to 14 X * .nr a +1 increment register 'a' by 1 X * .nr a reset register 'a' to default value (0) X */ X X switch (type) X { X case '\r': X case '\n': X *param = defval; X break; X case '+': X *param += val; X break; X case '-': X *param -= val; X break; X default: X *param = val; X break; X } X *param = min (*param, maxval); X *param = max (*param, minval); X} X X X X X X/*------------------------------*/ X/* set_ireg */ X/*------------------------------*/ Xset_ireg (name, val, opt) Xregister char *name; Xregister int val; Xregister int opt; /* 0=internal, 1=user set */ X{ X X/* X * set internal register "name" to val. ret 0 if ok, else -1 if reg not X * found or 1 if read only X */ X X register int nreg; X X nreg = findreg (name); X if (nreg < 0) X return (-1); X X if ((rg[nreg].rflag & RF_WRITE) || (opt == 0)) X { X rg[nreg].rval = val; X X return (0); X } X X return (1); X} X X X X X X/*------------------------------*/ X/* read_if */ X/*------------------------------*/ Xread_if () X{ X X/* X * read input while in if statement. stop when a line starts with \} X */ X X char ibuf[MAXLINE]; X char *pp; X X while (getlin (ibuf, sofile[dc.flevel]) != EOF) X { X if (debugging) X fprintf (err_stream, X "***%s.read_if: ibuf=|%s|\n",myname,ibuf); X X pp = skipbl (ibuf); X if (*pp == '\\' && *(pp+1) == '}') X return; X X /* X * if line is a command or text X */ X if (ibuf[0] == dc.cmdchr) X { X comand (ibuf); X } X else X { X /* X * this is a text line. first see if X * first char is space. if it is, break X * line. X */ X if (ibuf[0] == ' ') X robrk (); X text (ibuf); X } X X pp = ibuf; X while (*pp != EOS) X { X if (*pp == '\\' && *(pp+1) == '}') X return; X } X } X} END_OF_command.c if test 30522 -ne `wc -c <command.c`; then echo shar: \"command.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f config.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"config.h\" else echo shar: Extracting \"config.h\" \(1819 characters\) sed "s/^X//" >config.h <<'END_OF_config.h' X#ifndef CONFIG_H X#define CONFIG_H X X/* X * for diffent os, define tos, unix, or minix. for gemdos, pick X * a compiler (alcyon, mwc, etc). see makefile for VERSFLAGS. X * X * for atari TOS, do: cc -Dtos -Dalcyon ... X * X * for minix, do: cc -D_MINIX -D_ST ... (ST minix) X * cc -D_MINIX ... (PC minix) X * X * for unix, do: cc -Dunix ... (generic) X * cc -Dunix -DBSD... (BSD) X * X * note: so far there is no specific ST minix version. -D_ST is ignored. X * X * nroff uses index/rindex. you may need -Dindex=strchr -Drindex=strrchr X * as well. this file is included in "nroff.h" which gets included in all X * sources so any definitions you need should be added here. X * X * all os-dependent code is #ifdef'ed with GEMDOS, MINIX_ST, MINIX_PC, X * MINIX, or UNIX. most of the differences deal with i/o only. X */ X#ifdef ALCYON X# ifndef tos X# define tos X# endif X# ifndef alcyon X# define alcyon X# endif X#endif X X#ifdef tos X# define GEMDOS X# undef minix X# undef unix X# undef MINIX X# undef MINIX_ST X# undef MINIX_PC X# undef UNIX X/*#define register*/ X#endif X X#ifdef alcyon X# ifndef ALCYON X# define ALCYON /* for gemdos version, alcyon C */ X# endif X# ifndef GEMDOS X# define GEMDOS X# endif X#endif X X#ifdef minix X# ifndef _MINIX X# define _MINIX X# endif X#endif X X#ifdef _MINIX X# define MINIX X# undef tos X# undef unix X# undef GEMDOS X# undef MINIX_ST X# undef MINIX_PC X# undef UNIX X# ifdef _ST X# ifndef atariST X# define atariST X# endif X# endif X# ifdef atariST X# define MINIX_ST X# else X# define MINIX_PC X# endif X#endif X X#ifdef unix X/* just in case <ctype.h> does not define it (slightly different anyway) */ X#define tolower(x) (isupper(x)?((x)-'A'+'a'):(x)) X# undef tos X# undef minix X# undef _MINIX X# undef GEMDOS X# undef _ST X# undef MINIX_ST X# undef MINIX_PC X# ifndef UNIX X# define UNIX X# endif X#endif X X#endif /*CONFIG_H*/ X END_OF_config.h if test 1819 -ne `wc -c <config.h`; then echo shar: \"config.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f escape.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"escape.c\" else echo shar: Extracting \"escape.c\" \(18010 characters\) sed "s/^X//" >escape.c <<'END_OF_escape.c' X/* X * escape.c - Escape and special character input processing portion of X * 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 <stdio.h> X#include "nroff.h" X X X/*------------------------------*/ X/* expesc */ X/*------------------------------*/ Xexpesc (p, q) Xchar *p; Xchar *q; X{ X X/* X * Expand escape sequences X */ X X register char *s; X register char *t; X register char *pstr; X register int i; X register int val; X register int autoinc; X char c; X char fs[5]; /* for font change */ X char nrstr[20]; X char fmt[20]; X char name[10]; X int nreg; X char *pfs; X int inc; X int tmp; X char delim; X X X s = p; X t = q; X X X /* X * if escape parsing is not on, just copy string X */ X if (dc.escon == NO) X { X while (*s != EOS) X { X *t++ = *s++; X } X *t = EOS; X strcpy (p, q); X X return; X } X X X /* X * do it... X */ X while (*s != EOS) X { X if (*s != dc.escchr) X { X /* X * not esc, continue... X */ X *t++ = *s++; X } X X X else if (*(s + 1) == dc.escchr) X { X /* X * \\ escape escape X */ X *t++ = *s++; X ++s; X } X X X else if (*(s + 1) == 'n') X { X /* X * \nx, \n(xx register X * X * first check for \n+... or \n-... (either form) X */ X s += 2; X autoinc = 0; X if (*s == '+') X { X autoinc = 1; X s += 1; X } X if (*s == '-') X { X autoinc = -1; X s += 1; X } X X X X /* X * was this \nx or \n(xx form? X */ X if (isalpha (*s)) X { X /* X * \nx form. find reg (a-z) X */ X nreg = tolower (*s) - 'a'; X X X /* X * was this \n+x or \n-x? if so, do the X * auto incr X */ X if (autoinc > 0) X dc.nr[nreg] += dc.nrauto[nreg]; X else if (autoinc < 0) X dc.nr[nreg] -= dc.nrauto[nreg]; X X /* X * display format X */ X if (dc.nrfmt[nreg] == '1') X { X /* X * normal decimal digits X */ X t += itoda (dc.nr[nreg], t, 6) - 1; X } X else if (dc.nrfmt[nreg] == 'i') X { X /* X * lower roman X */ X t += itoroman (dc.nr[nreg], t, 24) - 1; X } X else if (dc.nrfmt[nreg] == 'I') X { X /* X * upper roman X */ X t += itoROMAN (dc.nr[nreg], t, 24) - 1; X } X else if (dc.nrfmt[nreg] == 'a') X { X /* X * lower letters X */ X t += itoletter (dc.nr[nreg], t, 12) - 1; X } X else if (dc.nrfmt[nreg] == 'A') X { X /* X * upper letters X */ X t += itoLETTER (dc.nr[nreg], t, 12) - 1; X } X else if (dc.nrfmt[nreg] & 0x80) X { X /* X * zero-filled decimal X */ X sprintf (fmt, "%%0%dld", X (int)(dc.nrfmt[nreg] & 0x7F)); X fmt[5] = '\0'; X sprintf (nrstr, fmt, (long) dc.nr[nreg]); X tmp = dc.nrfmt[nreg] & 0x7F; X nrstr[tmp] = '\0'; X X strcpy (t, nrstr); X t += strlen (nrstr); X } X else X { X /* X * normal (default) X */ X t += itoda (dc.nr[nreg], t, 6) - 1; X } X ++s; X } X else if (*s == '%') X { X /* X * \n% form. find index into reg struct X */ X nreg = findreg ("%"); X if (nreg < 0) X { X fprintf (err_stream, X "***%s: no register match\n", X myname); X err_exit (-1); X } X X X /* X * was this \n+% or \n-%? if so, do the X * auto incr X */ X if (autoinc > 0) X rg[nreg].rval += rg[nreg].rauto; X else if (autoinc < 0) X rg[nreg].rval -= rg[nreg].rauto; X X X /* X * display format X */ X if (rg[nreg].rfmt == '1') X { X /* X * normal decimal digits X */ X t += itoda (rg[nreg].rval, t, 6) - 1; X } X else if (rg[nreg].rfmt == 'i') X { X /* X * lower roman X */ X t += itoroman (rg[nreg].rval, t, 24) - 1; X } X else if (rg[nreg].rfmt == 'I') X { X /* X * upper roman X */ X t += itoROMAN (rg[nreg].rval, t, 24) - 1; X } X else if (rg[nreg].rfmt == 'a') X { X /* X * lower letters X */ X t += itoletter (rg[nreg].rval, t, 12) - 1; X } X else if (rg[nreg].rfmt == 'A') X { X /* X * upper letters X */ X t += itoLETTER (rg[nreg].rval, t, 12) - 1; X } X else if (rg[nreg].rfmt & 0x80) X { X /* X * zero-filled decimal X */ X sprintf (fmt, "%%0%dld", X (int)(rg[nreg].rfmt & 0x7F)); X fmt[5] = '\0'; X sprintf (nrstr, fmt, (long) rg[nreg].rval); X tmp = rg[nreg].rfmt & 0x7F; X nrstr[tmp] = '\0'; X X strcpy (t, nrstr); X t += strlen (nrstr); X } X else X { X /* X * normal (default) X */ X t += itoda (rg[nreg].rval, t, 6) - 1; X } X s += 1; X } X else if (*s == '(') X { X /* X * \n(xx form. find index into reg struct X */ X s += 1; X name[0] = *s; X name[1] = *(s + 1); X if (name[1] == ' ' || name[1] == '\t' X || name[1] == '\n' || name[1] == '\r') X name[1] = '\0'; X name[2] = '\0'; X nreg = findreg (name); X if (nreg < 0) X { X fprintf (err_stream, X "***%s: no register match\n", X myname); X err_exit (-1); X } X X X /* X * was this \n+(xx or \n-(xx? if so, do the X * auto incr X */ X if (rg[nreg].rflag & RF_WRITE) X { X if (autoinc > 0) X rg[nreg].rval += rg[nreg].rauto; X else if (autoinc < 0) X rg[nreg].rval -= rg[nreg].rauto; X } X X X /* X * display format X */ X if (rg[nreg].rfmt == '1') X { X /* X * normal decimal digits X */ X t += itoda (rg[nreg].rval, t, 6) - 1; X } X else if (rg[nreg].rfmt == 'i') X { X /* X * lower roman X */ X t += itoroman (rg[nreg].rval, t, 24) - 1; X } X else if (rg[nreg].rfmt == 'I') X { X /* X * upper roman X */ X t += itoROMAN (rg[nreg].rval, t, 24) - 1; X } X else if (rg[nreg].rfmt == 'a') X { X /* X * lower letters X */ X t += itoletter (rg[nreg].rval, t, 12) - 1; X } X else if (rg[nreg].rfmt == 'A') X { X /* X * upper letters X */ X t += itoLETTER (rg[nreg].rval, t, 12) - 1; X } X else if (rg[nreg].rfmt & 0x80) X { X /* X * zero-filled decimal X */ X sprintf (fmt, "%%0%dld", X (int)(rg[nreg].rfmt & 0x7F)); X fmt[5] = '\0'; X sprintf (nrstr, fmt, (long) rg[nreg].rval); X tmp = rg[nreg].rfmt & 0x7F; X nrstr[tmp] = '\0'; X X strcpy (t, nrstr); X t += strlen (nrstr); X } X else X { X /* X * normal (default) X */ X t += itoda (rg[nreg].rval, t, 6) - 1; X } X s += 2; X } X } X X X else if (*(s + 1) == '\"') X { X /* X * \" comment X */ X *s = EOS; X *t = *s; X X return; X } X X X else if (*(s + 1) == '*') X { X /* X * \*x, \*(xx string X */ X s += 2; X if (*s == '(') X { X /* X * \*(xx form X */ X s += 1; X name[0] = *s; X name[1] = *(s + 1); X name[2] = '\0'; X pstr = getstr (name); X if (!pstr) X { X fprintf (err_stream, X "***%s: string not found\n", X myname); X err_exit (-1); X } X while (*pstr) X *t++ = *pstr++; X s += 2; X } X else X { X /* X * \*x form X */ X name[0] = *s; X name[1] = '\0'; X pstr = getstr (name); X if (!pstr) X { X fprintf (err_stream, X "***%s: string not found\n", X myname); X err_exit (-1); X } X while (*pstr) X *t++ = *pstr++; X s += 1; X } X } X X X else if (*(s + 1) == 'f') X { X /* X * \fx font X */ X s += 2; X pfs = fs; /* set up ret string */ X fs[0] = '\0'; X X /* X * it parses 1-2 char of s and returns esc seq for X * \fB and \fR (\fI is same as \fB) X */ X fontchange (*s, pfs); X X /* X * imbed the atari (vt52) escape seq X */ X while (*pfs) X *t++ = *pfs++; X ++s; /* skip B,I,R,S,P */ X } X X X else if (*(s + 1) == '(') X { X /* X * \(xx special char X */ X s += 2; X X /* X * it returns num char to skip and sets c to X * the ascii value of the char X */ X inc = specialchar (s, &c); X X /* X * skip proper num char in s and add c to target X */ X if (inc) X { X s += inc; X *t++ = c; X } X } X X X else if (*(s + 1) == 'e') X { X /* X * \e printable version of escape X */ X *t++ = dc.escchr; X s += 2; X } X X X else if (*(s + 1) == '`') X { X /* X * \` grave, like \(ga X */ X *t++ = 0x60; X s += 2; X } X X X else if (*(s + 1) == '\'') X { X /* X * \' accute, like \(aa X */ X s += 2; X *t++ = 0xBA; X } X X X else if (*(s + 1) == '-') X { X /* X * \- minus X */ X s += 2; X *t++ = 0x2D; X } X X X else if (*(s + 1) == '.') X { X /* X * \. period X */ X s += 2; X *t++ = 0x2E; X } X X X else if (*(s + 1) == ' ') X { X /* X * \(space) space X */ X s += 2; X *t++ = 0x20; X } X X X else if (*(s + 1) == '0') X { X /* X * \0 digital width space X */ X s += 2; X *t++ = 0x20; X } X X X else if (*(s + 1) == '|') X { X /* X * \| narrow width char (0 in nroff) X */ X s += 2; X } X X X else if (*(s + 1) == '^') X { X /* X * \^ narrow width char (0 in nroff) X */ X s += 2; X } X X X else if (*(s + 1) == '&') X { X /* X * \& non-printing zero width X */ X s += 2; X } X X X else if (*(s + 1) == '!') X { X /* X * \! transparent copy line X */ X s += 2; X } X X X else if (*(s + 1) == '$') X { X /* X * \$N interpolate arg 1<=N<=9 X */ X s += 2; X } X X X else if (*(s + 1) == '%') X { X /* X * \% hyphen X */ X s += 2; X *t++ = 0x2D; X *t++ = 0x2D; X } X X X else if (*(s + 1) == 'a') X { X /* X * \a X */ X s += 2; X } X X X else if (*(s + 1) == 'b') X { X /* X * \b'abc...' X */ X s += 2; X } X X X else if (*(s + 1) == 'c') X { X /* X * \c X */ X s += 2; X } X X X else if (*(s + 1) == 'd') X { X /* X * \d X */ X s += 2; X } X X X else if (*(s + 1) == 'h') X { X /* X * \h'N' horiz motion X */ X s += 2; X delim = *s++; X val = atoi (s); X for (i = 0; i < val; i++) X *t++ = ' '; X while (*s != delim) X { X if (*s == 0) X break; X s++; X } X if (*s) X s++; X X } X X X else if (*(s + 1) == 'k') X { X /* X * \kx X */ X s += 2; X } X X X else if (*(s + 1) == 'l') X { X /* X * \l'Nc' X */ X s += 2; X } X X X else if (*(s + 1) == 'L') X { X /* X * \L'Nc' X */ X s += 2; X } X X X else if (*(s + 1) == 'o') X { X /* X * \o'abc...' overstrike X */ X s += 2; X delim = *s++; X while (*s != EOS && *s != delim) X { X *t++ = *s++; X *t++ = 0x08; X } X s++; X } X X X else if (*(s + 1) == 'p') X { X /* X * \p X */ X s += 2; X } X X X else if (*(s + 1) == 'r') X { X /* X * \r X */ X s += 2; X } X X X else if (*(s + 1) == 's') X { X /* X * \sN,\s+-N X */ X s += 2; X } X X X else if (*(s + 1) == 't') X { X /* X * \t horizontal tab X */ X s += 2; X *t++ = 0x09; X } X X X else if (*(s + 1) == 'u') X { X /* X * \u X */ X s += 2; X } X X X else if (*(s + 1) == 'v') X { X /* X * \v'N' vert tab X */ X s += 2; X delim = *s++; X val = atoi (s); X for (i = 0; i < val; i++) X *t++ = 0x0A; X while (*s != delim) X { X if (*s == 0) X break; X s++; X } X if (*s) X s++; X } X X X else if (*(s + 1) == 'w') X { X /* X * \w'str' X */ X s += 2; X } X X X else if (*(s + 1) == 'x') X { X /* X * \x'N' X */ X s += 2; X } X X X else if (*(s + 1) == 'z') X { X /* X * \zc print c w/o spacing X */ X s += 2; X *t++ = *s++; X *t++ = 0x08; X } X X X else if (*(s + 1) == '{') X { X /* X * \{ X */ X s += 2; X } X X X else if (*(s + 1) == '}') X { X /* X * \} X */ X s += 2; X } X X X else if (*(s + 1) == '\n' || *(s + 1) == '\r') X { X /* X * \(newline) ignore newline X */ X s += 2; X } X X X else X { X /* X * \X any other character not above X */ X s += 1; X *t++ = *s++; X } X X } X X /* X * end the string and return it in original buf X */ X *t = EOS; X strcpy (p, q); X} X X X X X/*------------------------------*/ X/* specialchar */ X/*------------------------------*/ Xspecialchar (s, c) Xregister char *s; Xregister char *c; X{ X X/* X * handles \(xx escape sequences for special characters (atari-specific) X */ X X register char c1; X register char c2; X X c1 = *s; X c2 = *(s+1); X X /* X * symbols (std font) X */ X if (c1 == 'e' && c2 == 'm') {*c = 0x2D; return (2);} /* dash */ X if (c1 == 'h' && c2 == 'y') {*c = 0x2D; return (2);} /* hyphen */ X if (c1 == 'b' && c2 == 'u') {*c = 0xF9; return (2);} /* bullet */ X if (c1 == 's' && c2 == 'q') {*c = 0xF9; return (2);} /* square */ X if (c1 == 'r' && c2 == 'u') {*c = 0x5F; return (2);} /* rule */ X if (c1 == '1' && c2 == '2') {*c = 0xAB; return (2);} /* 1/2 */ X if (c1 == '1' && c2 == '4') {*c = 0xAC; return (2);} /* 1/4 */ X if (c1 == 'd' && c2 == 'e') {*c = 0xF8; return (2);} /* degree */ X if (c1 == 'd' && c2 == 'g') {*c = 0xBB; return (2);} /* dagger */ X if (c1 == 'f' && c2 == 'm') {*c = 0xBA; return (2);} /* dagger */ X if (c1 == 'c' && c2 == 't') {*c = 0x9B; return (2);} /* cent */ X if (c1 == 'c' && c2 == 'o') {*c = 0xBD; return (2);} /* copyrite */ X if (c1 == 'r' && c2 == 'g') {*c = 0xBE; return (2);} /* registered */ X if (c1 == 't' && c2 == 'm') {*c = 0xBF; return (2);} /* trademark */ X X if (c1 == 'p' && c2 == '2') {*c = 0xFD; return (2);} /* ^2 */ X if (c1 == 'p' && c2 == '3') {*c = 0xFE; return (2);} /* ^3 */ X if (c1 == 'p' && c2 == 'n') {*c = 0xFC; return (2);} /* ^n */ X if (c1 == 'a' && c2 == 'a') {*c = 0xBA; return (2);} /* acute */ X if (c1 == 'g' && c2 == 'a') {*c = 0x60; return (2);} /* grave */ X if (c1 == 'd' && c2 == 't') {*c = 0xFA; return (2);} /* dot */ X if (c1 == 'p' && c2 == 'p') {*c = 0xBC; return (2);} /* paragraph */ X if (c1 == '^' && c2 == 'g') {*c = 0x07; return (2);} /* ring bell */ X if (c1 == 'u' && c2 == 'a') {*c = 0x01; return (2);} /* up arrow */ X if (c1 == 'd' && c2 == 'a') {*c = 0x02; return (2);} /* dn arrow */ X if (c1 == '-' && c2 == '>') {*c = 0x03; return (2);} /* rt arrow */ X if (c1 == '<' && c2 == '-') {*c = 0x04; return (2);} /* lf arrow */ X if (c1 == 'd' && c2 == 'i') {*c = 0xF6; return (2);} /* divide */ X if (c1 == 's' && c2 == 'r') {*c = 0xFB; return (2);} /* sq root */ X if (c1 == '=' && c2 == '=') {*c = 0xF0; return (2);} /* == */ X if (c1 == '>' && c2 == '=') {*c = 0xF2; return (2);} /* >= */ X if (c1 == '<' && c2 == '=') {*c = 0xF3; return (2);} /* <= */ X if (c1 == '+' && c2 == '-') {*c = 0xF1; return (2);} /* +- */ X if (c1 == '~' && c2 == '=') {*c = 0xF7; return (2);} /* ~= */ X if (c1 == 'a' && c2 == 'p') {*c = 0x7E; return (2);} /* approx */ X if (c1 == 'n' && c2 == 'o') {*c = 0xAA; return (2);} /* not */ X if (c1 == 'm' && c2 == 'o') {*c = 0xEE; return (2);} /* member */ X if (c1 == 'c' && c2 == 'a') {*c = 0xEF; return (2);} /* intersect */ X if (c1 == 'c' && c2 == 'u') {*c = 0x55; return (2);} /* union */ X if (c1 == 'i' && c2 == '1') {*c = 0xF4; return (2);} /* integral1 */ X if (c1 == 'i' && c2 == '2') {*c = 0xF5; return (2);} /* integral2 */ X X if (c1 == 'b' && c2 == 'r') {*c = 0x7C; return (2);} /* box v rule */ X if (c1 == 'b' && c2 == 'v') {*c = 0x7C; return (2);} /* bold vert */ X if (c1 == 'p' && c2 == 'l') {*c = 0x2B; return (2);} /* math plus */ X if (c1 == 'm' && c2 == 'i') {*c = 0x2D; return (2);} /* math minus */ X if (c1 == 'e' && c2 == 'q') {*c = 0x3D; return (2);} /* math equal */ X if (c1 == '*' && c2 == '*') {*c = 0x2A; return (2);} /* math star */ X if (c1 == 's' && c2 == 'l') {*c = 0x2F; return (2);} /* slash */ X if (c1 == 'u' && c2 == 'l') {*c = 0x5F; return (2);} /* underrule */ X if (c1 == 's' && c2 == 'c') {*c = 0xDD; return (2);} /* section */ X X X /* X * greek X */ X if (c1 == '*' && c2 == 'a') {*c = 0xE0; return (2);} /* alpha */ X if (c1 == '*' && c2 == 'b') {*c = 0xE1; return (2);} /* beta */ X if (c1 == '*' && c2 == 'g') {*c = 0xE2; return (2);} /* gamma */ X if (c1 == '*' && c2 == 'd') {*c = 0x7F; return (2);} /* delta */ X if (c1 == '*' && c2 == 's') {*c = 0xE4; return (2);} /* sigma */ X if (c1 == '*' && c2 == 'p') {*c = 0xE3; return (2);} /* pi */ X if (c1 == '*' && c2 == 'm') {*c = 0xE6; return (2);} /* mu */ X X *c = ' '; X return (0); X} X X X X X/*------------------------------*/ X/* fontchange */ X/*------------------------------*/ Xfontchange (fnt, s) Xchar fnt; Xchar *s; X{ X X/* X * handles \fx font change escapes for R,B,I,S,P (atari-specific) X * resets current and last font in dc struct (last used for .ft X * with no args) X */ X X int tmp; X X *s = '\0'; X switch (fnt) X { X case 'R': /* Times Roman */ X if (dc.dofnt == YES) X strcpy (s, e_standout); X dc.lastfnt = dc.thisfnt; X dc.thisfnt = 1; X break; X case 'I': /* Times italic */ X if (dc.dofnt == YES) X strcpy (s, s_standout); X dc.lastfnt = dc.thisfnt; X dc.thisfnt = 2; X break; X case 'B': /* Times bold */ X if (dc.dofnt == YES) X strcpy (s, s_standout); X dc.lastfnt = dc.thisfnt; X dc.thisfnt = 3; X break; X case 'S': /* math/special */ X *s = '\0'; X dc.lastfnt = dc.thisfnt; X dc.thisfnt = 4; X break; X case 'P': /* previous (exchange) */ X if (dc.dofnt == YES) X { X if (dc.lastfnt == 1) X strcpy (s, e_standout); /* to R */ X else if (dc.lastfnt == 2) X strcpy (s, s_standout); /* to I */ X else if (dc.lastfnt == 3) X strcpy (s, s_standout); /* to B */ X else X *s = '\0'; /* nothing */ X } X X tmp = dc.thisfnt; /* swap this/last */ X dc.thisfnt = dc.lastfnt; X dc.lastfnt = tmp; X break; X default: X *s = '\0'; X break; X } X X set_ireg (".f", dc.thisfnt, 0); X} X X X X X X/*------------------------------*/ X/* findreg */ X/*------------------------------*/ Xfindreg (name) Xregister char *name; X{ X X/* X * find register named 'name' in pool. return index into array or -1 X * if not found. X */ X X register int i; X register char *prname; X X for (i = 0; i < MAXREGS; i++) X { X prname = rg[i].rname; X if (*prname == *name && *(prname + 1) == *(name + 1)) X break; X } X X return ((i < MAXREGS) ? i : -1); X} X X X X END_OF_escape.c if test 18010 -ne `wc -c <escape.c`; then echo shar: \"escape.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 2 \(of 5\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 4 5 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 5 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 Bill Rosenkranz |UUCP: {uunet,texsun}!convex!c1yankee!rosenkra Convex Computer Corp. |ARPA: rosenkra%c1yankee@convex.com
rosenkra@convex1.convex.com (William Rosencranz) (08/03/90)
--- part 3 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 3 (of 5)." # # Contents: # io.c low.c macros.c main.c # # Wrapped by rosenkra%c1yankee@convex.com on Thu Aug 2 13:40:46 1990 # PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f io.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"io.c\" else echo shar: Extracting \"io.c\" \(4007 characters\) sed "s/^X//" >io.c <<'END_OF_io.c' X/* X * io.c - low level I/O 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 <stdio.h> X#include "nroff.h" X X/*------------------------------*/ X/* getlin */ X/*------------------------------*/ Xgetlin (p, in_buf) Xchar *p; XFILE *in_buf; X{ X X/* X * retrieve one line of input text X */ X X register char *q; X register int i; X int c; X int nreg; X X q = p; X for (i = 0; i < MAXLINE - 1; ++i) X { X c = ngetc (in_buf); X if (c == EOF) X { X *q = EOS; X c = strlen (p); X return (c == 0 ? EOF : c); X } X *q++ = c; X if (c == '\n') X break; X } X *q = EOS; X X nreg = findreg (".c"); X if (nreg > 0) X set_ireg (".c", rg[nreg].rval + 1, 0); X X return (strlen (p)); X} X X X X X X X/*------------------------------*/ X/* ngetc */ X/*------------------------------*/ Xngetc (infp) XFILE *infp; X{ X X/* X * get character from input file or push back buffer X */ X X register int c; X X if (mac.ppb >= &mac.pbb[0]) X c = *mac.ppb--; X else X c = getc (infp); X X return (c); X} X X X X/*------------------------------*/ X/* pbstr */ X/*------------------------------*/ Xpbstr (p) Xchar *p; X{ X X/* X * Push back string into input stream X */ X X register int i; X X /* X * if string is null, we do nothing X */ X if (p == NULL_CPTR) X return; X if (p[0] == EOS) X return; X for (i = strlen (p) - 1; i >= 0; --i) X { X putbak (p[i]); X } X} X X X X X X/*------------------------------*/ X/* putbak */ X/*------------------------------*/ Xputbak (c) Xchar c; X{ X X/* X * Push character back into input stream. we use the push-back buffer X * stored with macros. X */ X X if (mac.ppb < &(mac.pbb[0])) X { X mac.ppb = &(mac.pbb[0]); X *mac.ppb = c; X } X else X { X if (mac.ppb >= &mac.pbb[MAXPBB - 1]) X { X fprintf (err_stream, X "***%s: push back buffer overflow\n", myname); X err_exit (-1); X } X *++(mac.ppb) = c; X } X} X X X X/*------------------------------*/ X/* prchar */ X/*------------------------------*/ Xprchar (c, fp) Xchar c; XFILE *fp; X{ X X/* X * print character with test for printer X */ X X/* this really slows things down. it should be fixed. for now, ignore X line printer... X X if (fp == stdout) X putc (c, fp); X else X putc_lpr (c, fp); X*/ X putc (c, fp); X} X X X X X X X/*------------------------------*/ X/* put */ X/*------------------------------*/ Xput (p) Xchar *p; X{ X X/* X * put out line with proper spacing and indenting X */ X X register int j; X char os[MAXLINE]; X X if (pg.lineno == 0 || pg.lineno > pg.bottom) X { X phead (); X } X if (dc.prflg == TRUE) X { X if (!dc.bsflg) X { X if (strkovr (p, os) == TRUE) X { X for (j = 0; j < pg.offset; ++j) X prchar (' ', out_stream); X for (j = 0; j < dc.tival; ++j) X prchar (' ', out_stream); X putlin (os, out_stream); X } X } X for (j = 0; j < pg.offset; ++j) X prchar (' ', out_stream); X for (j = 0; j < dc.tival; ++j) X prchar (' ', out_stream); X putlin (p, out_stream); X } X dc.tival = dc.inval; X skip (min (dc.lsval - 1, pg.bottom - pg.lineno)); X pg.lineno = pg.lineno + dc.lsval; X set_ireg ("ln", pg.lineno, 0); X if (pg.lineno > pg.bottom) X { X pfoot (); X if (stepping) X wait_for_char (); X } X} X X X X X/*------------------------------*/ X/* putlin */ X/*------------------------------*/ Xputlin (p, pbuf) Xregister char *p; XFILE *pbuf; X{ X X/* X * output a null terminated string to the file X * specified by pbuf. X */ X X while (*p != EOS) X prchar (*p++, pbuf); X} X X X X X/*------------------------------*/ X/* putc_lpr */ X/*------------------------------*/ X#ifdef GEMDOS X#include <osbind.h> X#endif X Xputc_lpr (c, fp) Xchar c; XFILE *fp; X{ X X/* X * write char to printer X */ X X#ifdef GEMDOS X Bconout (0, (int) c & 0x00FF); X#else X putc (c, fp); X#endif X} END_OF_io.c if test 4007 -ne `wc -c <io.c`; then echo shar: \"io.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f low.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"low.c\" else echo shar: Extracting \"low.c\" \(13787 characters\) sed "s/^X//" >low.c <<'END_OF_low.c' X/* X * low.c - misc low-level functions 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 <stdio.h> X#include "nroff.h" X X X X/*------------------------------*/ X/* atod */ X/*------------------------------*/ Xatod (c) Xchar c; X{ X X/* X * convert ascii character to decimal. X */ X X return (((c < '0') || (c > '9')) ? -1 : c - '0'); X} X X X X X X/*------------------------------*/ X/* robrk */ X/*------------------------------*/ Xrobrk () X{ X X/* X * end current filled line X */ X X if (co.outp > 0) X { X /* X * handle margin char (change bar) here for all filled lines X */ X co.outbuf[co.outp] = '\r'; X co.outbuf[co.outp+1] = '\n'; X co.outbuf[co.outp+2] = EOS; X X do_mc (co.outbuf); X X put (co.outbuf); X } X co.outp = 0; X co.outw = 0; X co.outwds = 0; X co.outesc = 0; X} X X X X X/*------------------------------*/ X/* ctod */ X/*------------------------------*/ Xctod (p) Xregister char *p; X{ X X/* X * convert string to decimal. processes only positive values. X * this takes a constant like "1", "1.0i", etc. X */ X X register long val; X register int d; X register char *pp = p; X register char *ptmp; X int rside = 0; X int lside = 0; X int has_rside = 0; X int has_lside = 0; X X if (*p == EOS) X return (0); X X ptmp = skipwd (pp); X pp = --ptmp; X X switch (*pp) X { X case 'i': X case 'c': X val = 0L; X while (*p != EOS && isdigit (*p)) X { X has_lside++; X lside = atod (*p); X p++; X if (lside == -1) X break; X val = 10L * val + (long) lside; X } X lside = (int) val; X if (*p == '.') X { X p++; X val = 0L; X while (*p != EOS && isdigit (*p)) X { X has_rside++; X rside = atod (*p); X p++; X if (rside == -1) X break; X val = 10L * val + (long) rside; X if (has_rside > 2) /* more than enough */ X break; X } X rside = (int) val; X } X X /* X * now put it together. 1.0i -> 240, 1.50i -> 360, etc. X */ X val = 0L; X if (has_lside) X { X val = (long) lside * BU_INCH; X } X switch (has_rside) X { X case 1: X val = val + ((long) rside * BU_INCH / 10L); X break; X case 2: X val = val + ((long) rside * BU_INCH / 100L); X break; X case 3: X val = val + ((long) rside * BU_INCH / 1000L); X break; X default: X break; X } X if (*pp == 'c') X val = (val * BU_CM) / BU_INCH; X X /* X * for now we convert to basic char size, 1 em... X */ X val = val / BU_EM; X X break; X X case 'P': X case 'm': X case 'n': X case 'p': X case 'u': X case 'v': X val = 0L; X while (*p != EOS) X { X d = atod (*p); X p++; X if (d == -1) X break; X val = 10L * val + (long) d; X } X switch (*pp) X { X case 'P': X val = val * BU_PICA; X break; X case 'p': X val = val * BU_POINT; X break; X case 'u': X val = val * BU_BU; X break; X case 'm': X val = val * BU_EM; X break; X case 'n': X val = val * BU_EN; X break; X case 'v': X val = val * BU_EM; X break; X } X X /* X * for now we convert to basic char size, 1 em... X */ X val = val / BU_EM; X X break; X X default: X /* X * this is the default behavior. it SHOULD make things X * compatible with the old way... X */ X val = 0L; X while (*p != EOS) X { X d = atod (*p); X p++; X if (d == -1) X break; X val = 10L * val + (long) d; X } X break; X } X X return ((int) val); X} X X X X X/*------------------------------*/ X/* inptobu */ X/*------------------------------*/ Xinptobu (ps) Xchar *ps; X{ X X/* X * convert input units to b.u. X */ X X return; X} X X X X X/*------------------------------*/ X/* butochar */ X/*------------------------------*/ Xbutochar (ps) Xchar *ps; X{ X X/* X * convert b.u. to char spaces X */ X X return; X} X X X X X/*------------------------------*/ X/* skipbl */ X/*------------------------------*/ Xchar *skipbl (p) Xregister char *p; X{ X X/* X * skip blanks and tabs in character buffer. return ptr to first X * non-space or non-tab char. this could mean EOS or \r or \n. X * also increments the arg ptr (side effect). X */ X X while ((*p != EOS) && (*p == ' ' || *p == '\t')) X ++p; X return (p); X} X X X X X/*------------------------------*/ X/* skipwd */ X/*------------------------------*/ Xchar *skipwd (p) Xregister char *p; X{ X X/* X * skip over word and punctuation. anything but space,\t,\r,\n, and EOS X * is skipped. return ptr to the first of these found. also increments X * the arg ptr (side effect). X */ X X while (*p != EOS && *p != ' ' && *p != '\t' && *p != '\r' && *p != '\n') X ++p; X return (p); X} X X X X X X/*------------------------------*/ X/* space */ X/*------------------------------*/ Xspace (n) Xint n; X{ X X/* X * space vertically n lines. this does header and footer also. X */ X X robrk (); X if (pg.lineno > pg.bottom) X return; X if (pg.lineno == 0) X phead (); X skip (min (n, pg.bottom + 1 - pg.lineno)); X pg.lineno += n; X set_ireg ("ln", pg.lineno, 0); X if (pg.lineno > pg.bottom) X pfoot (); X} X X X X X/*------------------------------*/ X/* getfield */ X/*------------------------------*/ Xchar *getfield (p, q, delim) Xregister char *p; Xregister char *q; Xchar delim; X{ X X/* X * get field from title X */ X X while (*p != delim && *p != '\r' && *p != '\n' && *p != EOS) X { X *q++ = *p++; X } X *q = EOS; X if (*p == delim) X ++p; X return (p); X} X X X X X X/*------------------------------*/ X/* getwrd */ X/*------------------------------*/ Xgetwrd (p0, p1) Xregister char *p0; Xregister char *p1; X{ X X/* X * get non-blank word from p0 into p1. X * return number of characters processed. X */ X X register int i; X register char *p; X char c; X X /* X * init counter... X */ X i = 0; X X X /* X * skip leading whitespace X */ X while (*p0 && (*p0 == ' ' || *p0 == '\t')) X { X ++i; X ++p0; X } X X X /* X * set ptr and start to look for end of word X */ X p = p0; X while (*p0 != ' ' && *p0 != EOS && *p0 != '\t') X { X if (*p0 == '\n' || *p0 == '\r') X break; X *p1 = *p0++; X ++p1; X ++i; X } X X c = *(p1 - 1); X if (c == '"') X c = *(p1 - 2); X if (c == '?' || c == '!') X { X *p1++ = ' '; X ++i; X } X if (c == '.' && (*p0 == '\n' || *p0 == '\r' || islower (*p))) X { X *p1++ = ' '; X ++i; X } X *p1 = EOS; X X return (i); X} X X X X X/*------------------------------*/ X/* countesc */ X/*------------------------------*/ X X#define ESC 27 X Xcountesc (p) Xregister char *p; X{ X X/* X * count atari escape sequence characters in given null-terminated X * string X */ X X register char *pp; X register int num; X X pp = p; X num = 0; X X while (*pp != EOS) X { X if (*pp == ESC) X { X /* X * count escape char (atari-specific, vt52) X * generally only p,q,b,and c will show up... X */ X switch (*(pp+1)) X { X case 'A': /* ESC-a */ X case 'B': X case 'C': X case 'D': X case 'E': X case 'H': X case 'I': X case 'J': X case 'K': X case 'L': X case 'M': X case 'd': X case 'e': X case 'f': X case 'j': X case 'k': X case 'l': X case 'o': X case 'p': X case 'q': X case 'v': X case 'w': X num += 2; X break; X case 'b': /* ESC-a-b */ X case 'c': X num += 3; X break; X case 'Y': /* ESC-a-b-c */ X case '[': /* Esc [ 7 m */ X num += 4; X break; X default: X num += 1; X break; X } X } X pp++; X } X X return (num); X} X X X X X/*------------------------------*/ X/* itoda */ X/*------------------------------*/ Xitoda (value, p, size) Xint value; Xregister char *p; Xregister int size; X{ X X/* X * convert integer to decimal ascii string X */ X X register int i; X register int j; X register int k; X register int aval; X char c[20]; X X aval = abs (value); X c[0] = EOS; X i = 1; X do X { X c[i++] = (aval % 10) + '0'; X aval /= 10; X X } while (aval > 0 && i <= size); X X if (value < 0 && i <= size) X c[i++] = '-'; X for (j = 0; j < i; ++j) X *p++ = c[i - j - 1]; X X return (i); X} X X X X X/*------------------------------*/ X/* itoROMAN */ X/*------------------------------*/ XitoROMAN (value, p, size) Xint value; Xregister char *p; Xregister int size; X{ X X/* X * convert integer to upper roman. must be positive X */ X X register int i; X register int j; X register int k; X register int aval; X char c[100]; X int rem; X X aval = abs (value); X c[0] = EOS; X i = 1; X X /* X * trivial case: X */ X if (aval == 0) X { X c[i++] = '0'; X goto done_100; X } X X /* X * temporarily mod 100... X */ X aval = aval % 100; X X if (aval > 0) X { X /* X * build backward X * X * | I| 1 X * | II| 2 X * | III| 3 X * | VI| 4 X * | V| 5 X * | IV| 6 X * | IIV| 7 X * | IIIV| 8 X * | XI| 9 X * | X| 0 X * | IX| 11 X * | IIX| 12 X */ X if ((aval % 5 == 0) && (aval % 10 != 0))/* 5 */ X c[i++] = 'V'; X else X { X rem = aval % 10; X if (rem == 9) /* 9 */ X { X c[i++] = 'X'; X c[i++] = 'I'; X } X else if (rem == 8) /* 8 */ X { X c[i++] = 'I'; X c[i++] = 'I'; X c[i++] = 'I'; X c[i++] = 'V'; X } X else if (rem == 7) /* 7 */ X { X c[i++] = 'I'; X c[i++] = 'I'; X c[i++] = 'V'; X } X else if (rem == 6) /* 6 */ X { X c[i++] = 'I'; X c[i++] = 'V'; X } X else if (rem == 4) /* 4 */ X { X c[i++] = 'V'; X c[i++] = 'I'; X } X else /* 3,2,1 */ X { X for (j = 0; j < rem; j++) X c[i++] = 'I'; X } X } X X aval /= 10; X if (aval == 0) X goto done_100; X X rem = aval % 10; X if (rem == 4) X { X c[i++] = 'L'; X c[i++] = 'X'; X } X else if (rem == 5) X { X c[i++] = 'L'; X } X else if (rem < 4) X { X for (j = 0; j < rem; j++) X c[i++] = 'X'; X } X else X { X for (j = 0; j < rem - 5; j++) X c[i++] = 'X'; X c[i++] = 'L'; X } X } X X Xdone_100: X /* X * divide by 100 (they are done) and temp mod by another 10 X */ X aval = abs (value); X aval /= 100; X X if (aval > 0) X { X rem = aval % 10; X if (rem == 4) X { X c[i++] = 'D'; X c[i++] = 'C'; X } X if (rem == 5) X { X c[i++] = 'D'; X } X else if (rem < 4) X { X for (j = 0; j < rem; j++) X c[i++] = 'C'; X } X else if (rem == 9) X { X c[i++] = 'M'; X c[i++] = 'C'; X } X else if (rem < 9) X { X for (j = 0; j < rem - 5; j++) X c[i++] = 'C'; X c[i++] = 'D'; X } X } X X X aval /= 10; X X if (aval > 0) X { X rem = aval % 10; X if (rem < 4) X { X for (j = 0; j < rem; j++) X c[i++] = 'M'; X } X } X X X if (value < 0) X c[i++] = '-'; X X for (j = 0; j < i; ++j) X *p++ = c[i - j - 1]; X X return (i); X} X X X X X/*------------------------------*/ X/* itoroman */ X/*------------------------------*/ Xitoroman (value, p, size) Xint value; Xchar *p; Xint size; X{ X X/* X * convert integer to lower roman X */ X X register int i; X register int len; X register int aval; X char c[100]; X X c[0] = EOS; X len = itoROMAN (value, c, size); X X for (i = 0; i < len; i++) X { X p[i] = c[i]; X if (isalpha (p[i])) X p[i] = tolower (c[i]); X } X X return (len); X} X X X X X/*------------------------------*/ X/* itoLETTER */ X/*------------------------------*/ XitoLETTER (value, p, size) Xint value; Xregister char *p; Xregister int size; X{ X X/* X * convert integer to upper letter value: 0,A,B,C,...,AA,AB,AC,... X */ X X register int i; X register int j; X register int k; X register int aval; X int rem; X char c[20]; X X aval = abs (value); X c[0] = EOS; X i = 1; X X /* X * 1 based: X * X * 0 0 X * 1 A X * 25 Z X * 26 AA X * 51 AZ X * 52 AAA X * ... X */ X if (aval == 0) X c[i++] = '0'; X else if (aval < 27) X { X c[i++] = aval - 1 + 'A'; X } X else X { X do X { X c[i++] = ((aval - 1) % 26) + 'A'; X aval = (aval - 1) / 26; X X } while (aval > 0 && i <= size); X } X X if (value < 0 && i <= size) X c[i++] = '-'; X X for (j = 0; j < i; ++j) X *p++ = c[i - j - 1]; X X return (i); X} X X X X/*------------------------------*/ X/* itoletter */ X/*------------------------------*/ Xitoletter (value, p, size) Xint value; Xregister char *p; Xregister int size; X{ X X/* X * convert integer to upper letter value: 0,a,b,c,...,aa,ab,ac,... X */ X X register int i; X register int j; X register int k; X register int aval; X char c[20]; X int rem; X X aval = abs (value); X c[0] = EOS; X i = 1; X X /* X * 1 based: X * X * 0 0 X * 1 A X * 25 Z X * 26 AA X * 51 AZ X * 52 AAA X * ... X */ X if (aval == 0) X c[i++] = '0'; X else if (aval < 27) X { X c[i++] = aval - 1 + 'a'; X } X else X { X do X { X c[i++] = ((aval - 1) % 26) + 'a'; X aval = (aval - 1) / 26; X X } while (aval > 0 && i <= size); X } X X if (value < 0 && i <= size) X c[i++] = '-'; X X for (j = 0; j < i; ++j) X *p++ = c[i - j - 1]; X X return (i); X} X X X X/*------------------------------*/ X/* min */ X/*------------------------------*/ X X#ifdef min X#undef min X#endif X Xmin (v1, v2) Xregister int v1; Xregister int v2; X{ X X/* X * find minimum of two integer ONLY X */ X X return ((v1 < v2) ? v1 : v2); X} X X X X X X/*------------------------------*/ X/* max */ X/*------------------------------*/ X X#ifdef max X#undef max X#endif X Xmax (v1, v2) Xregister int v1; Xregister int v2; X{ X X/* X * find maximum of two integers ONLY X */ X X return ((v1 > v2) ? v1 : v2); X} X X X X X X/*------------------------------*/ X/* err_exit */ X/*------------------------------*/ Xerr_exit (code) X{ X X/* X * exit cleanly on fatal error (close files, etc). also handles normal X * exit. X */ X X if (err_stream != stderr && err_stream != (FILE *) 0) X { X /* X * not going to stderr (-o file) X */ X fflush (err_stream); X fclose (err_stream); X } X if (debugging && dbg_stream != stderr && dbg_stream != (FILE *) 0) X { X fflush (dbg_stream); X fclose (dbg_stream); X } X if (out_stream != stdout && out_stream != (FILE *) 0) X { X /* X * not going to stdout (-l) X */ X fflush (out_stream); X fclose (out_stream); X } X X if (hold_screen) X { X wait_for_char (); X } X X exit (code); X} X X X X/*------------------------------*/ X/* wait_for_char */ X/*------------------------------*/ X#ifdef GEMDOS X#include <osbind.h> X#endif X Xwait_for_char () X{ X#ifdef GEMDOS X printf ("enter any key..."); fflush (stdout); X Cconin (); X#endif X} X X X END_OF_low.c if test 13787 -ne `wc -c <low.c`; then echo shar: \"low.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f macros.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"macros.c\" else echo shar: Extracting \"macros.c\" \(10226 characters\) sed "s/^X//" >macros.c <<'END_OF_macros.c' X/* X * macros.c - macro 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 <stdio.h> X#include "nroff.h" X X X X/*------------------------------*/ X/* defmac */ X/*------------------------------*/ Xdefmac (p, infp) Xregister char *p; XFILE *infp; X{ X X/* X * Define a macro. top level, read from stream. X * X * we should read macro 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 * putmac, after colmac... X */ X X register char *q; X register int i; X char name[MNLEN]; X char defn[MXMLEN]; X char newend[10]; X X X /* X * skip the .de 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 (!isprint (*name)) X { X fprintf (err_stream, X "***%s: missing or illegal macro 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 and see if we have a new end defined... X */ X q = skipwd (p); X q = skipbl (q); X for (i = 0; i < 10; i++) X newend[i] = EOS; X X for (i = 0; (i < 10) && ( isalpha (q[i]) || isdigit (q[i]) ); i++) X { X newend[i] = q[i]; X } X X X X /* X * read a line from input stream until we get the end of macro X * command (.en or ..). actually. we should have read the next X * field just above here to get the .de NA . or .de NA en string X * to be new end of macro. X */ X i = 0; X while (getlin (p, infp) != EOF) X { X if (p[0] == dc.cmdchr && p[1] == '\\' && p[2] == '\"') X { X /* X * comment, ignore it X */ X continue; X } X if (p[0] == dc.cmdchr && newend[0] != EOS X && p[1] == newend[0] && p[2] == newend[1]) X { X /* X * replacement end found X */ X break; X } X if (p[0] == dc.cmdchr && p[1] == 'e' && p[2] == 'n') X { X /* X * .en found X */ X break; X } X if (p[0] == dc.cmdchr && p[1] == dc.cmdchr) X { X /* X * .. found X */ X break; X } X X X /* X * collect macro from the line we just read. all this does X * is put it in the string defn. X */ X if ((i = colmac (p, defn, i)) == ERR) X { X fprintf (err_stream, X "***%s: macro definition too long\n", myname); X err_exit (-1); X } X } X X X /* X * store the macro X */ X if (!ignoring) X { X if (putmac (name, defn) == ERR) X { X fprintf (err_stream, X "***%s: macro definition table full\n", myname); X err_exit (-1); X } X } X} X X X X X X/*------------------------------*/ X/* colmac */ X/*------------------------------*/ Xcolmac (p, d, i) Xregister char *p; Xchar *d; Xregister int i; X{ X X/* X * Collect macro definition from input stream X */ X X char *pstart = p; X int istart = i; X X while (*p != EOS) X { X /* X * are we over the length limit for a single macro? 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 > istart) 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 * skip quoted things X */ X if (*p == '\\' && *(p+1) == '\\') X p++; 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/* putmac */ X/*------------------------------*/ Xputmac (name, p) Xchar *name; Xchar *p; X{ X X/* X * Put macro definition into table X * X * NOTE: any expansions of things like number registers SHOULD X * have been done already. 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 * macro looks like this in mb: X * X * mac.mb[MACBUF] size of total buf X * lastp < MXMDEF number of macros possible X * *mnames[MXMDEF] -> names, each max length X * ..._____________________________...____________________... X * / / /|X|X|0|macro 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 X return (OK); X} X X X X X X X/*------------------------------*/ X/* getmac */ X/*------------------------------*/ Xchar *getmac (name) Xregister char *name; X{ X X/* X * Get (lookup) macro 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 X/*------------------------------*/ X/* maceval */ X/*------------------------------*/ Xmaceval (p, m) Xregister char *p; Xchar *m; X{ X X/* X * Evaluate macro expansion X */ X X register int i; X register int j; X char *argp[15]; X char c; X int xc; X X X X /* X * replace command char with EOS X */ X *p++ = EOS; X X X /* X * initialize argp array to substitute command X * string for any undefined argument X * X * NO!!! this is fixed... X */ X/* for (i = 0; i < 10; ++i) X argp[i] = p; X*/ X /* X * skip the command name X */ X p = skipwd (p); X *p++ = EOS; X X X /* X * loop for all $n variables... X */ X for (i = 0; i < 10; ++i) X { X /* X * get to substituted param and if no more, reset remaining X * args to NULL and stop. using "i" here IS ok... X */ X p = skipbl (p); X if (*p == '\r' || *p == '\n' || *p == EOS) X { X if (debugging) X fprintf (err_stream, X "***%s.maceval: set_ireg(.$, %d, 0)\n", X myname,i); X X set_ireg (".$", i, 0); X for ( ; i < 10; i++) X { X argp[i] = NULL_CPTR; X } X break; X } X X X /* X * ...otherwise, see if this param is quoted. if it is, X * it is all one parameter, even with blanks (but not X * newlines...). look for another "c" (which is the quote). X * X * if no quote, just read the arg as a single word and null X * terminate it. X */ X if (*p == '\'' || *p == '"') X { X c = *p++; X argp[i] = p; X while (*p != c && *p != '\r' && *p != '\n' && *p != EOS) X ++p; X *p++ = EOS; X } X else X { X argp[i] = p; X p = skipwd (p); X *p++ = EOS; X } X } X X X /* X * m contains text of the macro. p contained the input line. X * here we start at the end of the macro def and see if there X * are any $n thingies. go backwards. X */ X for (i = strlen (m) - 1; i >= 0; --i) X { X /* X * found a $. X */ X if (i > 0 && m[i - 1] == '$') X { X if (!isdigit (m[i])) X { X /* X * it wasn't a numeric replacement arg so X * push this char back onto input stream X */ X putbak (m[i]); X } X else X { X /* X * it WAS a numeric replacement arg. so we X * want to push back the appropriate macro X * invocation arg. m[i]-'0' is the numerical X * value of the $1 thru $9. if the arg is X * not there, argp[n] will be (char *) 0 X * and pbstr will do nothing. X */ X xc = m[i] - '1'; X if (argp[xc]) X pbstr (argp[xc]); X --i; X } X } X else X { X /* X * no $ so push back the char... X */ X putbak (m[i]); X } X } X X /* X * at this point, the iobuf will hold the new macro command, full X * expanded for $n things. the return gets us right back to the X * main loop in main() and we parse the (new) command just as if X * it were read from a file. X */ X X} X X X X X X/*------------------------------*/ X/* printmac */ X/*------------------------------*/ Xprintmac (opt) Xint opt; /* 0=name&size,1=total size,2=full */ X{ X X/* X * print all macros and strings and tabulate sizes X */ X X register int i; /* was long, minix needs int */ X register long space; X register long totalspace; X register char *pname; X register char *pdef; X X X space = 0L; X totalspace = 0L; X X fflush (out_stream); X fflush (err_stream); 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 pname = (char *) (mac.mnames[i]); X pdef = pname + 3; X if (*(pname + 1) == '\0') X pdef = pname + 2; X X space = (long) strlen (pdef); X totalspace += space; X X switch (opt) X { X case 0: X fprintf (err_stream, "%s %ld\n", pname, space); X break; X case 2: X fprintf (err_stream, "%s %ld\n", pname, space); X fprintf (err_stream, "%s\n", pdef); X break; X case 1: X default: X break; X } X } X } X fprintf (err_stream, "Total space: %ld\n", totalspace); X X} X END_OF_macros.c if test 10226 -ne `wc -c <macros.c`; then echo shar: \"macros.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f main.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"main.c\" else echo shar: Extracting \"main.c\" \(19776 characters\) sed "s/^X//" >main.c <<'END_OF_main.c' X#include "config.h" X X/* X * main.c - main for nroff word processor X * X * similar to Unix(tm) nroff or RSX-11M RNO. adaptation of text processor X * given in "Software Tools", Kernighan and Plauger. 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#define NRO_MAIN /* to define globals in nro.h */ X X#include <stdio.h> X#ifdef GEMDOS X#include <sys\types.h> X#include <sys\time.h> X#else X#include <sys/types.h> X#include <sys/time.h> X#endif X#include "nroff.h" X X Xmain (argc, argv) Xint argc; Xchar *argv[]; X{ X register int i; X int swflg; X int ifp = 0; X char *ptmp; X#ifndef GEMDOS X char *pterm; X char capability[100]; X char *pcap; X char *ps; X#endif X X X X /* X * set up initial flags and file descriptors X */ X swflg = FALSE; X ignoring = FALSE; X hold_screen = FALSE; X debugging = FALSE; X stepping = FALSE; X mc_ing = FALSE; X out_stream = stdout; X err_stream = stderr; X dbg_stream = stderr; X X X /* X * this is for tmp files, if ever needed. it SHOULD start X * out without the trailing slash. if not in env, use default X */ X if (ptmp = getenv ("TMPDIR")) X strcpy (tmpdir, ptmp); X else X strcpy (tmpdir, "."); X X X /* X * handle terminal for \fB, \fI X */ X#ifdef GEMDOS X strcpy (s_standout, "\33p"); /* atari/TOS is easy... */ X strcpy (e_standout, "\33q"); X strcpy (s_bold, "\33p"); /* atari/TOS is easy... */ X strcpy (e_bold, "\33q"); X strcpy (s_italic, "\33p"); X strcpy (e_italic, "\33q"); X#else X s_standout[0] = '\0'; X e_standout[0] = '\0'; X s_bold[0] = '\0'; X e_bold[0] = '\0'; X s_italic[0] = '\0'; X e_italic[0] = '\0'; X if ((pterm = getenv ("TERM")) /* it must exist first... */ X && (tgetent (termcap, pterm) == 1)) /* ...so we fill buffer */ X { X /* X * we currently use standout mode for all weirdness X * lile BOLD, italic, etc. X */ X pcap = capability; X if (ps = tgetstr ("so", &pcap)) X { X /* X * sun has padding in here. this is NOT portable. X * better to use tputs() to strip it... X */ X while (*ps && *ps != 0x1b) ps++; X strcpy (s_standout, ps); X strcpy (s_bold, ps); X strcpy (s_italic, ps); X } X if (ps = tgetstr ("se", &pcap)) X { X while (*ps && *ps != 0x1b) ps++; X strcpy (e_standout, ps); X strcpy (e_bold, ps); X strcpy (e_italic, ps); X } X } X#endif X X X X /* X * initialize structures (defaults) X */ X init (); X X X /* X * parse cmdline flags X */ X for (i = 1; i < argc; ++i) X { X if (*argv[i] == '-' || *argv[i] == '+') X { X if (pswitch (argv[i], &swflg) == ERR) X err_exit (-1); X } X } X X X /* X * loop on files X */ X for (i = 1; i < argc; ++i) X { X if (*argv[i] != '-' && *argv[i] != '+') X { X /* X * open this file... X */ X if ((sofile[0] = fopen (argv[i], "r")) == NULL_FPTR) X { X fprintf (err_stream, X "***%s: unable to open file %s\n", X myname, argv[i]); X err_exit (-1); X } X else X { X /* X * do it for this file... X */ X ifp = 1; X profile (); X fclose (sofile[0]); X } X } X else if (*argv[i] == '-' && *(argv[i]+1) == 0) X { X /* X * - means read stdin (anywhere in file list) X */ X sofile[0] = stdin; X ifp = 1; X profile (); X } X X } X X X /* X * if no files, usage (should really use stdin...) X */ X if ((ifp == 0 && swflg == FALSE) || argc <= 1) X { X usage (); X X err_exit (-1); X } X X X /* X * normal exit. this will fflush/fclose streams... X */ X err_exit (0); X} X X X X X/*------------------------------*/ X/* usage */ X/*------------------------------*/ Xusage () X{ X /* X * note: -l may not work correctly X */ X fprintf (stderr, "Usage: %s [options] file [...]\n", myname); X fprintf (stderr, "Options: -a no font changes\n"); X fprintf (stderr, " -b backspace\n"); X fprintf (stderr, " -d debug mode (file: nroff.dbg)\n"); X#ifdef GEMDOS X fprintf (stderr, " -h hold screen before desktop\n"); X#endif X/*!!! fprintf (stderr, " -l output to printer\n");*/ X fprintf (stderr, " -m<name> macro file (e.g. -man)\n"); X fprintf (stderr, " -o<file> error log file (stderr is default)\n"); X fprintf (stderr, " -po<n> page offset\n"); X fprintf (stderr, " -pn<n> initial page number\n"); X fprintf (stderr, " -pl<n> page length\n"); X fprintf (stderr, " -s step through pages\n"); X fprintf (stderr, " -v print version only\n"); X fprintf (stderr, " +<n> first page to do\n"); X fprintf (stderr, " -<n> last page to do\n"); X fprintf (stderr, " - use stdin (in file list)\n"); X} X X X X X/*------------------------------*/ X/* init */ X/*------------------------------*/ Xinit () X{ X X/* X * initialize parameters for nro word processor X */ X X extern long time (); X X#ifdef MINIX X register int i; X#else X register long i; X#endif X time_t tval; X char *ctim; X X /* X * misc global flags, etc... X */ X mc_space = 2; X mc_char = '|'; X tval = time (0L); X ctim = ctime (&tval); X X /* X * basic document controls... X */ X dc.fill = YES; X dc.dofnt = YES; X dc.lsval = 1; X dc.inval = 0; X dc.rmval = PAGEWIDTH - 1; X dc.llval = PAGEWIDTH - 1; X dc.ltval = PAGEWIDTH - 1; X dc.tival = 0; X dc.ceval = 0; X dc.ulval = 0; X dc.cuval = 0; X dc.juval = YES; X dc.adjval = ADJ_BOTH; X dc.boval = 0; X dc.bsflg = FALSE; X dc.prflg = TRUE; X dc.sprdir = 0; X dc.flevel = 0; X dc.lastfnt = 1; X dc.thisfnt = 1; X dc.escon = YES; X dc.pgchr = '%'; X dc.cmdchr = '.'; X dc.escchr = '\\'; X dc.nobrchr = '\''; X for (i = 0; i < 26; ++i) X dc.nr[i] = 0; X for (i = 0; i < 26; ++i) X dc.nrauto[i] = 1; X for (i = 0; i < 26; ++i) X dc.nrfmt[i] = '1'; X X X /* X * initialize internal regs. first zero out... X */ X for (i = 0; i < MAXREGS; i++) X { X rg[i].rname[0] = EOS; X rg[i].rname[1] = EOS; X rg[i].rname[2] = EOS; X rg[i].rname[3] = EOS; X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X } X X X /* X * predefined regs. these are read/write: X */ X i = 0; X X strcpy (rg[i].rname, "%"); /* current page */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "ct"); /* character type */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "dl"); /* width of last complete di */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "dn"); /* height of last complete di */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "dw"); /* day of week (1-7) */ X rg[i].rval = 0; X if (!strncmp (&ctim[0], "Sun", 3)) X rg[i].rval = 1; X else if (!strncmp (&ctim[0], "Mon", 3)) X rg[i].rval = 2; X else if (!strncmp (&ctim[0], "Tue", 3)) X rg[i].rval = 3; X else if (!strncmp (&ctim[0], "Wed", 3)) X rg[i].rval = 4; X else if (!strncmp (&ctim[0], "Thu", 3)) X rg[i].rval = 5; X else if (!strncmp (&ctim[0], "Fri", 3)) X rg[i].rval = 6; X else if (!strncmp (&ctim[0], "Sat", 3)) X rg[i].rval = 7; X rg[i].rauto = 1; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "dy"); /* day of month (1-31) */ X rg[i].rauto = 1; X rg[i].rval = atoi (&ctim[8]); X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "hp"); /* current h pos on input */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "ln"); /* output line num */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "mo"); /* current month (1-12) */ X rg[i].rval = 0; X if (!strncmp (&ctim[4], "Jan", 3)) X rg[i].rval = 1; X else if (!strncmp (&ctim[4], "Feb", 3)) X rg[i].rval = 2; X else if (!strncmp (&ctim[4], "Mar", 3)) X rg[i].rval = 3; X else if (!strncmp (&ctim[4], "Apr", 3)) X rg[i].rval = 4; X else if (!strncmp (&ctim[4], "May", 3)) X rg[i].rval = 5; X else if (!strncmp (&ctim[4], "Jun", 3)) X rg[i].rval = 6; X else if (!strncmp (&ctim[4], "Jul", 3)) X rg[i].rval = 7; X else if (!strncmp (&ctim[4], "Aug", 3)) X rg[i].rval = 8; X else if (!strncmp (&ctim[4], "Sep", 3)) X rg[i].rval = 9; X else if (!strncmp (&ctim[4], "Oct", 3)) X rg[i].rval = 10; X else if (!strncmp (&ctim[4], "Nov", 3)) X rg[i].rval = 11; X else if (!strncmp (&ctim[4], "Dec", 3)) X rg[i].rval = 12; X rg[i].rauto = 1; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "nl"); /* v pos of last base-line */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "sb"); /* depth of str below base */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "st"); /* height of str above base */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "yr"); /* last 2 dig of current year*/ X rg[i].rauto = 1; X rg[i].rval = atoi (&ctim[22]); X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, "hh"); /* current hour (0-23) */ X rg[i].rauto = 1; X rg[i].rval = atoi (&ctim[11]); X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = 2 | 0x80; X i++; X X strcpy (rg[i].rname, "mm"); /* current minute (0-59) */ X rg[i].rauto = 1; X rg[i].rval = atoi (&ctim[14]); X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = 2 | 0x80; X i++; X X strcpy (rg[i].rname, "ss"); /* current second (0-59) */ X rg[i].rauto = 1; X rg[i].rval = atoi (&ctim[17]); X rg[i].rflag = RF_READ | RF_WRITE; X rg[i].rfmt = 2 | 0x80; X i++; X X X /* X * these are read only (by user): X */ X strcpy (rg[i].rname, ".$"); /* num args at current macro*/ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".A"); /* 1 for nroff */ X rg[i].rauto = 1; X rg[i].rval = 1; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".H"); /* hor resolution */ X rg[i].rauto = 1; X rg[i].rval = 1; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".T"); /* 1 for troff */ X rg[i].rauto = 0; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".V"); /* vert resolution */ X rg[i].rauto = 1; X rg[i].rval = 1; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".a"); X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".c"); X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".d"); X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".f"); /* current font (1-4) */ X rg[i].rauto = 1; X rg[i].rval = 1; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".h"); X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".i"); /* current indent */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".l"); /* current line length */ X rg[i].rauto = 1; X rg[i].rval = PAGEWIDTH - 1; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".n"); X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".o"); /* current offset */ X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".p"); /* current page len */ X rg[i].rauto = 1; X rg[i].rval = PAGELEN; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".s"); /* current point size */ X rg[i].rauto = 1; X rg[i].rval = 1; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".t"); X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".u"); X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".v"); /* current v line spacing */ X rg[i].rauto = 1; X rg[i].rval = 1; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".w"); /* width of prev char */ X rg[i].rauto = 1; X rg[i].rval = 1; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".x"); X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".y"); X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X i++; X X strcpy (rg[i].rname, ".z"); X rg[i].rauto = 1; X rg[i].rval = 0; X rg[i].rflag = RF_READ; X rg[i].rfmt = '1'; X X /* X * page controls... X */ X pg.curpag = 0; X pg.newpag = 1; X pg.lineno = 0; X pg.plval = PAGELEN; X pg.m1val = 2; X pg.m2val = 2; X pg.m3val = 2; X pg.m4val = 2; X pg.bottom = pg.plval - pg.m4val - pg.m3val; X pg.offset = 0; X pg.frstpg = 0; X pg.lastpg = 30000; X pg.ehead[0] = pg.ohead[0] = '\n'; X pg.efoot[0] = pg.ofoot[0] = '\n'; X for (i = 1; i < MAXLINE; ++i) X { X pg.ehead[i] = pg.ohead[i] = EOS; X pg.efoot[i] = pg.ofoot[i] = EOS; X } X pg.ehlim[LEFT] = pg.ohlim[LEFT] = dc.inval; X pg.eflim[LEFT] = pg.oflim[LEFT] = dc.inval; X pg.ehlim[RIGHT] = pg.ohlim[RIGHT] = dc.rmval; X pg.eflim[RIGHT] = pg.oflim[RIGHT] = dc.rmval; X X /* X * output buffer controls... X */ X co.outp = 0; X co.outw = 0; X co.outwds = 0; X co.lpr = FALSE; X co.outesc = 0; X for (i = 0; i < MAXLINE; ++i) X co.outbuf[i] = EOS; X X /* X * macros... X */ X for (i = 0; i < MXMDEF; ++i) X mac.mnames[i] = NULL_CPTR; X for (i = 0; i < MACBUF; ++i) X mac.mb[i] = EOS; X for (i = 0; i < MAXPBB; ++i) X mac.pbb[i] = EOS; X mac.lastp = 0; X mac.emb = &mac.mb[0]; X mac.ppb = NULL_CPTR; X X /* X * file descriptors (for sourced files) X */ X for (i = 0; i < Nfiles+1; ++i) X sofile[i] = NULL_FPTR; X} X X X X X/*------------------------------*/ X/* pswitch */ X/*------------------------------*/ Xpswitch (p, q) Xregister char *p; Xregister int *q; X{ X X/* X * process switch values from command line X */ X X int swgood; X char mfile[256]; X char *ptmac; X int indx; X int val; X X swgood = TRUE; X if (*p == '-') X { X /* X * since is STILL use the goofy atari/dri xmain code, i X * look for both upper and lower case. if you use dLibs X * (and if its startup code does not ucase the cmd line), X * you can probably look for just lower case. gulam and X * other shells typically don't change case of cmd line. X */ X switch (*++p) X { X case 0: /* stdin */ X break; X X case 'a': /* font changes */ X case 'A': X dc.dofnt = NO; X break; X X case 'b': /* backspace */ X case 'B': X dc.bsflg = TRUE; X break; X X case 'd': /* debug mode */ X case 'D': X dbg_stream = fopen (dbgfile, "w"); X debugging = TRUE; X if (dbg_stream == NULL_FPTR) X { X fprintf (err_stream, X "***%s: unable to open debug file %s\n", X myname, dbgfile); X X dbg_stream = stderr; X } X break; X X case 'h': /* hold screen */ X case 'H': X hold_screen = TRUE; X break; X X case 'l': /* to lpr (was P) */ X case 'L': X#ifdef GEMDOS X out_stream = (FILE *) 0; X#else X out_stream = fopen (printer, "w"); X#endif X co.lpr = TRUE; X break; X X case 'm': /* macro file */ X case 'M': X /* X * build macro file name. start with lib X * X * put c:\lib\tmac in environment so we can X * read it here. else use default. if you want X * file from cwd, "setenv TMACDIR ." from shell. X * X * we want file names like "tmac.an" (for -man) X */ X if (ptmac = getenv ("TMACDIR")) X { X /* X * this is the lib path (e.g. "c:\lib\tmac") X */ X strcpy (mfile, ptmac); X X /* X * this is the prefix (i.e. "\tmac.") X */ X strcat (mfile, TMACPRE); X } X else X /* X * use default lib/prefix (i.e. X * "c:\lib\tmac\tmac.") X */ X strcpy (mfile, TMACFULL); X X /* X * finally, add extension (e.g. "an") X */ X strcat (mfile, ++p); X X /* X * open file and read it X */ X if ((sofile[0] = fopen (mfile, "r")) == NULL_FPTR) X { X fprintf (stderr, X "***%s: unable to open macro file %s\n", X myname, mfile); X err_exit (-1); X } X profile (); X fclose (sofile[0]); X break; X X case 'o': /* output error log */ X case 'O': X if (!*(p+1)) X { X fprintf (stderr, X "***%s: no error file specified\n", X myname); X err_exit (-1); X } X if ((err_stream = fopen (p+1, "w")) == NULL_FPTR) X { X fprintf (stderr, X "***%s: unable to open error file %s\n", X myname, p+1); X err_exit (-1); X } X break; X X case 'p': /* .po, .pn */ X case 'P': X if (*(p+1) == 'o' || *(p+1) == 'O') /* -po___ */ X { X p += 2; X set (&pg.offset, ctod (p), '1', 0, 0, HUGE); X set_ireg (".o", pg.offset, 0); X } X else if (*(p+1) == 'n' || *(p+1) == 'N')/* -pn___ */ X { X p += 2; X set (&pg.curpag, ctod (p) - 1, '1', 0, -HUGE, HUGE); X pg.newpag = pg.curpag + 1; X set_ireg ("%", pg.newpag, 0); X } X else if (*(p+1) == 'l' || *(p+1) == 'L')/* -pl___ */ X { X p += 2; X set (&pg.plval, ctod (p) - 1, '1', 0, X pg.m1val + pg.m2val + pg.m3val + pg.m4val + 1, X HUGE); X set_ireg (".p", pg.plval, 0); X pg.bottom = pg.plval - pg.m3val - pg.m4val; X } X else /* -p___ */ X { X p++; X set (&pg.offset, ctod (p), '1', 0, 0, HUGE); X set_ireg (".o", pg.offset, 0); X } X break; X X case 'r': /* set number reg */ X case 'R': X if (!isalpha (*(p+1))) X { X fprintf (stderr, X "***%s: invalid number register name (%c)\n", X myname, (int) *(p+1)); X } X else X { X /* X * indx is the user num register and val X * is the final value. X */ X indx = tolower (*(p+1)) - 'a'; X val = atoi (p+2); X set (&dc.nr[indx], val, '1', 0, -INFINITE, INFINITE); X } X break; X X case 's': /* page step mode */ X case 'S': X stepping = TRUE; X break; X X case 'v': /* version */ X case 'V': X printf ("%s\n", version); X *q = TRUE; X break; X X case '0': /* last page */ X case '1': X case '2': X case '3': X case '4': X case '5': X case '6': X case '7': X case '8': X case '9': X pg.lastpg = ctod (p); X break; X X default: /* illegal */ X swgood = FALSE; X break; X } X } X else if (*p == '+') /* first page */ X { X pg.frstpg = ctod (++p); X } X else /* illegal */ X { X swgood = FALSE; X } X X X if (swgood == FALSE) X { X fprintf (stderr, "***%s: illegal switch %s\n", myname, p); X return (ERR); X } X X return (OK); X} X X X X X/*------------------------------*/ X/* profile */ X/*------------------------------*/ Xprofile () X{ X X/* X * process input files from command line X */ X X char ibuf[MAXLINE]; X X /* X * handle nesting of includes (.so). note that .so causes dc.flevel X * to be increased... X */ X for (dc.flevel = 0; dc.flevel >= 0; dc.flevel -= 1) X { X while (getlin (ibuf, sofile[dc.flevel]) != EOF) X { X /* X * if line is a command or text X */ X if (ibuf[0] == dc.cmdchr) X { X comand (ibuf); X } X else X { X /* X * this is a text line. first see if X * first char is space. if it is, break X * line. X */ X if (ibuf[0] == ' ') X robrk (); X text (ibuf); X } X } X X /* X * close included file X */ X if (dc.flevel > 0) X fclose (sofile[dc.flevel]); X } X if (pg.lineno > 0) X space (HUGE); X} X X X X X END_OF_main.c if test 19776 -ne `wc -c <main.c`; then echo shar: \"main.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 3 \(of 5\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 5 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 Bill Rosenkranz |UUCP: {uunet,texsun}!convex!c1yankee!rosenkra Convex Computer Corp. |ARPA: rosenkra%c1yankee@convex.com
rosenkra@convex1.convex.com (William Rosencranz) (08/03/90)
--- 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 <man.man`; then echo shar: \"man.man\" unpacked with wrong size! fi # end of overwriting check fi if test -f ms.man -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"ms.man\" else echo shar: Extracting \"ms.man\" \(3486 characters\) sed "s/^X//" >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 <ms.man`; then echo shar: \"ms.man\" unpacked with wrong size! fi # end of overwriting check fi if test -f nroff.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"nroff.h\" else echo shar: Extracting \"nroff.h\" \(15981 characters\) sed "s/^X//" >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 <ctype.h> 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 <nroff.h`; then echo shar: \"nroff.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f patchlvl.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"patchlvl.h\" else echo shar: Extracting \"patchlvl.h\" \(21 characters\) sed "s/^X//" >patchlvl.h <<'END_OF_patchlvl.h' X#define PATCHLEVEL 3 END_OF_patchlvl.h if test 21 -ne `wc -c <patchlvl.h`; then echo shar: \"patchlvl.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f strings.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"strings.c\" else echo shar: Extracting \"strings.c\" \(5761 characters\) sed "s/^X//" >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 <stdio.h> 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 <strings.c`; then echo shar: \"strings.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f text.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"text.c\" else echo shar: Extracting \"text.c\" \(13950 characters\) sed "s/^X//" >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 <stdio.h> 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 <text.c`; then echo shar: \"text.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f tmac.an -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"tmac.an\" else echo shar: Extracting \"tmac.an\" \(8405 characters\) sed "s/^X//" >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 <tmac.an`; then echo shar: \"tmac.an\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 4 \(of 5\). cp /dev/null ark4isdone MISSING="" for I in 1 2 3 4 5 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 5 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 Bill Rosenkranz |UUCP: {uunet,texsun}!convex!c1yankee!rosenkra Convex Computer Corp. |ARPA: rosenkra%c1yankee@convex.com
rosenkra@convex1.convex.com (William Rosencranz) (08/03/90)
--- part 5 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 5 (of 5)." # # Contents: # tmac.s version.h tests.uu # # Wrapped by rosenkra%c1yankee@convex.com on Thu Aug 2 13:42:52 1990 # PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f tmac.s -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"tmac.s\" else echo shar: Extracting \"tmac.s\" \(9432 characters\) sed "s/^X//" >tmac.s <<'END_OF_tmac.s' X.\" set this non-zero to turn on debugging X.nr Z 0 X.\" ************************************************************************** X.\" X.\" partial -ms package for nroff. macros for simple paper/report formats X.\" X.\" usage: nroff -ms file [...] X.\" X.\" included here are: X.\" X.\" TL, AU, AI, AB, AE, SH, NH, PP, LP, QP, XP, RS, RE, IP, I, B, R X.\" X.\" extensions include: X.\" X.\" TI (temp indent), EX (exit NOW) X.\" X.\" includes somewhat kludgy support for XS, XA, XE, PX (table of contents) 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 (Quote, Unquote, dash, footer parts, etc): X.\" X.ds Q "" X.ds U "" X.ds - -- X.ds CF "ImPoSsIbLe X.ds LF "\0 X.ds RF "\0 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.\" MO month: X.if \n(mo=1 .ds MO "January X.if \n(mo=2 .ds MO "February X.if \n(mo=3 .ds MO "March X.if \n(mo=4 .ds MO "April X.if \n(mo=5 .ds MO "May X.if \n(mo=6 .ds MO "June X.if \n(mo=7 .ds MO "July X.if \n(mo=8 .ds MO "August X.if \n(mo=9 .ds MO "September X.if \n(mo=10 .ds MO "October X.if \n(mo=11 .ds MO "November X.if \n(mo=12 .ds MO "December X.\" make some composites: X.ds Dy "\*(MO \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 DY "\n(dy \*(MO \*(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.\" MO March X.\" Dy March 4 X.\" dY March 4, 1990 X.\" DY 4 March 1990 <--- "normal" nroff form X.\" Yr 1990 X.\" TM 16:34:00 X.\" DA 16:34:00 March 4, 1990 X.\" Da 16:34:00 2/4/90 X.\" CT Sun March 4 16:34:00 1990 almost like ctime(2) X.\" X.\" ************************************************************************** X.\" X.\" startup stuff... X.\" X.pl 66 X.ll 6.0i X.lt 6.0i X.m1 3 X.m2 2 X.m3 3 X.m4 3 X.\" no header line on first page! (set back in AB, SH, NH, LP, PP, QP) X.tl |||| X.\" this is the default footer (date, centered) unless string CF is defined X.fo ||\*(DY|| X.\" these are for NH numbering (up to 5 levels, a la sun, X holds level) X.nr A 0 1 X.af A 1 X.nr B 0 1 X.af B 1 X.nr C 0 1 X.af C 1 X.nr D 0 1 X.af D 1 X.nr E 0 1 X.af E 1 X.nr X 1 1 X.\" X.\" ************************************************************************** X.\" X.\" MACROS... X.\" X.\" ---------------------------------------------------------------------- TL X.\" title for document (optional) X.\" X.de TL X.sp 4 X.ce 1000 X.\" reset footer. you MUST define CF, even to blank, to get the others! X.if !"\*(CF"ImPoSsIbLe" .fo |\*(LF|\*(CF|\*(RF| X.. X.\" ---------------------------------------------------------------------- AU X.\" author(s) (optional, requires .TL) X.\" X.de AU X.sp 2 X.. X.\" ---------------------------------------------------------------------- AI X.\" author's institution (optional, requires .TL) X.\" X.de AI X.sp 1 X.. X.\" ---------------------------------------------------------------------- AB X.\" abstract (optional, requires .TL, .AE) X.\" X.de AB X.br X.sp 2 X.\" check for arg to AB. can be "no" or something like "SUMMARY". if "no", X.\" no title above the abstract X.if !"$1"no" .if "$1"" ABSTRACT X.if !"$1"no" .if !"$1"" $1 X.if !"$1"no" .sp 1 X.\" set new line length... X.ce 0 X.ll 5.5i X.in 0.5i X.tl ||- % -|| X.. X.\" ---------------------------------------------------------------------- AE X.\" abstract end (optional, requires .TL) X.\" X.de AE X.br X.sp 1 X.\" reset... X.ce 0 X.in 0.0i X.ll 6.0i X.. X.\" ----------------------------------------------------------------------- SH X.\" section heading, no number (optional) X.\" X.de SH X.\" reset... X.ll 6.0i X.in 0.0i X.tl ||- % -|| X.\" see note in TL X.if !"\*(CF"ImPoSsIbLe" .fo |\*(LF|\*(CF|\*(RF| X.br X.ce 0 X.sp 2 X.ne 4 X.\" section title goes here, fill mode only so far... X.. X.\" ---------------------------------------------------------------------- NH X.\" numbered section heading. arg (required) is the section level. X.\" this would be MUCH simpler if the .if command supported "{...}". there is X.\" a bug in nroff. i does not set the .$ number register correctly (number of X.\" args for the current macro). that is the reason why level 1 must be set. X.\" X.de NH X.\" do everything from SH... X.SH X.\" if ".NH 0", reset numbering X.if $1=0 .nr A 1 1 X.if $1=0 .nr B 0 1 X.if $1=0 .nr C 0 1 X.if $1=0 .nr D 0 1 X.if $1=0 .nr E 0 1 X.if $1=0 .nr X 1 1 X.\" level 1 (two types here: ".NH" and ".NH 1"): X.\" once .$ num reg is fixed, these 5 should be: .if \n(.$=0 .nr A +1 etc. X.if "$1"" .nr A +1 X.if "$1"" .nr B 0 1 X.if "$1"" .nr C 0 1 X.if "$1"" .nr D 0 1 X.if "$1"" .nr E 0 1 X.if "$1"" .nr X 1 1 X.if "$1"1" .nr A +1 X.if "$1"1" .nr B 0 1 X.if "$1"1" .nr C 0 1 X.if "$1"1" .nr D 0 1 X.if "$1"1" .nr E 0 1 X.if "$1"1" .nr X 1 1 X.\" level 2 (increment B, reset lower levels): X.if "$1"2" .nr B +1 X.if "$1"2" .nr C 0 1 X.if "$1"2" .nr D 0 1 X.if "$1"2" .nr E 0 1 X.if "$1"2" .nr X 2 1 X.\" level 3 (increment C, reset lower levels): X.if "$1"3" .nr C +1 X.if "$1"3" .nr D 0 1 X.if "$1"3" .nr E 0 1 X.if "$1"3" .nr X 3 1 X.\" level 4 (increment D, reset lower levels): X.if "$1"4" .nr D +1 X.if "$1"4" .nr E 0 1 X.if "$1"4" .nr X 4 1 X.\" level 5 (increment E, no more lower levels!): X.if "$1"5" .nr E +1 X.if "$1"5" .nr X 5 1 X.\" print out the section number now, depending on current level... X.if \nX=1 \nA. X.if \nX=2 \nA.\nB. X.if \nX=3 \nA.\nB.\nC. X.if \nX=4 \nA.\nB.\nC.\nD. X.if \nX=5 \nA.\nB.\nC.\nD.\nE. X.\" section title goes here... X.. X.\" ----------------------------------------------------------------------- LP X.\" start a new left block paragraph (either .LP or .PP required) X.\" X.de LP X.br X.\" reset... X.tl ||- % -|| X.ce 0 X.sp 1 X.ll 6.0i X.in 0.0i X.. X.\" ----------------------------------------------------------------------- PP X.\" start a new indented paragraph (either .LP or .PP required) X.\" X.de PP X.\" do everything for LP, then make a temp indent... X.LP X.ti +0.5i X.. X.\" ----------------------------------------------------------------------- XP X.\" start a new extended paragraph (bibliography) X.\" X.de XP X.br X.\" reset... X.tl ||- % -|| X.ce 0 X.sp 1 X.ll 6.0i X.in 0.5i X.ti -0.5i X.. X.\" ----------------------------------------------------------------------- QP X.\" start a new quoted paragraph (indented and shorter) X.\" X.de QP X.br X.tl ||- % -|| X.ce 0 X.sp 1 X.\" set new line length, indent. PP, LP, SH, and NH reset X.ll 6.0i X.in 0.0i X.ll -0.5i X.in +0.5i X.. X.\" ----------------------------------------------------------------------- IP X.\" indented paragraph with tag (relative) X.\" X.de IP X.br X.tl ||- % -|| X.ce 0 X.sp 1 X.if \n(.i>4 .in -0.5i X.in +0.5i X.}D "***DEBUG IP: indent before tag is: \n(.i" X.}D .br X.if !"$1"" .ti -0.5i X.if !"$1"" \&$1 X.if !"$1"" .br X.}D "***DEBUG IP: indent after tag is: \n(.i" X.. X.\" ----------------------------------------------------------------------- RS X.\" start relative indent (requires .RE) X.\" X.de RS X.ce 0 X.br X.\" if there is arg, use that as indent, otherwise use +5 X.if \n(.$>0 .in +$1 X.if \n(.$=0 .in +0.5i X.}D "***DEBUG RS: indent after RS is: \n(.i" X.}D .br X.. X.\" ----------------------------------------------------------------------- RE X.\" end relative indent X.\" X.de RE X.ce 0 X.br X.\" if there is arg, use that as unindent, otherwise use -5 X.if \n(.$>0 .in -$1 X.if \n(.$=0 .in -0.5i X.if \n(.i<5 .in 0.0i X.}D "***DEBUG RE: indent after RE is: \n(.i" X.}D .br X.. X.\" ----------------------------------------------------------------------- XS X.\" table of contents start X.\" X.de XS X.bp X.ce 1 XTable of Contents X.ce 0 X.ll 8.0i X.sp 1 X.\" \&123456789012345678901234567890123456789012345678901234567890 X\&NOTE: add/del "dots" until line ends here ---------------->| (del this line) X.br X.\" save the page number... X.ds Xx "$1 X.\" first entry goes here... X.. X.\" ----------------------------------------------------------------------- XE X.\" table of contents end X.\" X.de XE X.\" dump last page number... X\&\0........................... \*(Xx X.br X.. X.\" ----------------------------------------------------------------------- XA X.\" subsequent table of contents entry X.\" X.de XA X.\" dump last page number... X\&\0........................... \*(Xx X.br X.\" save next page number... X.ds Xx "$1 X.\" next entry goes here... X.. X.\" ----------------------------------------------------------------------- PX X.\" print table of contents X.\" X.de PX X.\" this is a NOP without diversions... X.ll 6.0i X.. X.\" ----------------------------------------------------------------------- TI X.\" temporary indent X.\" X.de TI X.ce 0 X.ti +0.5i X.. X.\" ----------------------------------------------------------------------- EX X.\" exit NOW! (no extra space at end of document) X.\" X.de EX X.sp X.ex X.. X.\" ----------------------------------------------------------------------- I X.\" italic text X.\" X.de I X\&\fI X.if !"$1"" $1\fR$2 X.. X.\" ----------------------------------------------------------------------- B X.\" bold text X.\" X.de B X\&\fB X.if !"$1"" $1\fR$2 X.. X.\" ----------------------------------------------------------------------- R X.\" Roman (normal) text X.\" X.de R X\&\fR 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.. END_OF_tmac.s if test 9432 -ne `wc -c <tmac.s`; then echo shar: \"tmac.s\" unpacked with wrong size! fi # end of overwriting check fi if test -f version.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"version.h\" else echo shar: Extracting \"version.h\" \(534 characters\) sed "s/^X//" >version.h <<'END_OF_version.h' X#ifndef VERSION_H X#define VERSION_H X X#include "patchlvl.h" X X/* X * to get around no valid argv[0] with some compilers... X */ Xchar *myname = "nroff"; Xint patchlevel = PATCHLEVEL; X X#ifdef GEMDOS Xchar *version = "nroff (TOS) v1.10 07/30/90 wjr"; X#endif X#ifdef MINIX_ST Xchar *version = "nroff (Minix-ST) v1.10 07/30/90 wjr"; X#endif X#ifdef MINIX_PC Xchar *version = "nroff (Minix-PC) v1.10 07/30/90 wjr"; X#endif X#ifdef UNIX Xchar *version = "nroff (Unix) v1.10 07/30/90 wjr"; X#endif X X#endif /*VERSION_H*/ END_OF_version.h if test 534 -ne `wc -c <version.h`; then echo shar: \"version.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f tests.uu -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"tests.uu\" else echo shar: Extracting \"tests.uu\" \(32307 characters\) sed "s/^X//" >tests.uu <<'END_OF_tests.uu' Xbegin 644 tests.shar.Z XM'YV0(T*`>"$FC9L7<]`H&`&""IHT<T!`!!$&1,(R;-A0E#/FH9TR+D"`D%*F XMS9N/%-WDH?/0S1D08LJ8>2.G#`B6$]D8+,/B)IHR;D#4<0,GS)@U"R72@9G' XM8A@[!E^F66J0SAN*(,RD86,SC!LR-_/`B0I"1,*L6\N("-GPZLDR<N[(F6JS XM#!Z(=*(F36+&Y\0P'#W:G#CF31LX7.GP!)'G31T0=[9JG%/&)DN;,S.^B>P2 XM1)LR<^:$.=-UZ6400,GH6)@@@8@B7T&\Z7LQX\:.:3ZZ$+$PZ9`W;A0'G[.: XMH4@I18(0:5+$A>(Y="+:C>'"C1S4>*@[7FI71O7KW5ULQS[C.WGQ=>@D%9D& XMCHLV$=NC7]K&:U'2[[UZMC\:Y/@V8[P7$8#S@>`&&@(:B.!VZX$`1QOF/?A% XM?6X4*"%\!=8$!TUT)*@AAP5:%2!\-[T1((,C)'6%'&'``4<98(G1E!QO4.;& XM&BP",0:+>;A06!NR!37%4"`H48=&,N0`0@PUZ""##3K04,.2.>0`0V]0!$$% XM$CT09)`.+]0QAQQ>N@&FF&36,888(.R`W89R+)7EE@JDT==S2[70%W+*,><< XM:-&!T$)%(I"P1PQ]B`!""#V4U<(8BKIY65`*B%1&1U<E!)@.(%PAF8%O+/66 XM'"W(11=V>)&E%5<@<"$"G\LUA^<<KBJ`$66V8FH1&IN"4`0>=+`X1EZ=N0JK XMG[.ZVBH*,^0@`P@=`6:48G+0FH("E(%EU@M>8/'""XKZ<*RL@$;$`P\G%.$$ XM$5\\8<07X_X)W1PG*(#%991M9),=@*7A6$2S@H""5V!=EL9UV\&1WAPI9$63 XM@32:T9<=U,4`@X-AT-$15Q\AZ8*]91B%!EJL%A9<&`9%1,;!E^8%7$3`@8#& XM9B5B=VEZEOUT$Z`4F::S5>Z1#)J]D;$$0H)BVM0"B?7M6&-(JX(&V50CYQ=4 XMTH)2N)_3<T"=5D1%5VV=O8#9I'!-$,_6%PIN7-4TC1@?U1_#(9V6\,+Z^F23 XM"@5&W;6]]N)K6;F0P663'$2*EM<<9DQ+TU9-Q5S19V>$04-/5#PQQ9(N>,>8 XM8]?5-,>1@=:7A[W\RM&C"Q]C86\+!=E&HXTX>J6'`NJRZRZ\R<4J;W1UWLES XML\^VX(9-8-PQAJ#+\Q#OK&!(^I,;E8J$FJZ:RL&IL;TC6ZZR0Q5U%(Q3&RT7 XM<"_-D88>982@@%9)I29;7Z.:2NQ+'5V*%/QV[@R=H'V9CGD&519#(4I1C'(4 XMI-JD-TI9"GN\TEZG/M4V47V$5/:KRUV@HZJTM$H$`K1.K6Y5AES-;%>]^E6P XMID465X50#LKB`@IH$(,9/"M:PJ*6M;!%OFUUZUOA>B$(SI6N=;7K72^L%Q9< XMH"R[A.$PK**.]2R%AYLIIGQHX)1UU(8=ZHQMB;4"HZ+N@)F#_8\R2ZD#'&`2 XM!O4M[SYFD]9G="@PKIA!5!)#8T]T<CP0<,4E+&&!O9BHJ+S0@55_/$,@4P*6 XM._P$;8;D2D0(YK!0P24B9WA#2,@(`C+(9"=8>=L;!JDLJ\B,8*PJ"HO.P"(X XMH*%K2@&!&L2T%#'4)`QK`)C.V-#&I?#1)BAPP1S62(8W2`TG#!.D&"TB/JD5 XM\PY!>=8OY]`32BKF,"R:"QN:8A!/#D=O!K*++T$9S+RDH'6$!*=STG#*299E XM!8J:PU60Z9F0N6&29"C8/'4VACK(H2;!D<A7@-*A!I)RC#89`T'A`LY(=B4V XM-?&D5OIX&CC*+&2>O$X8[LC0TVBE6NI9YB_GMS-@U6P-E5EC1?MST3!D='YW XMTME'_P?'D!C$#F]`Z4'!J<K1M')DHA28"Y(`A89E##47;$I/6=DB!!UTD(@! XM@0UL,,6J6O6J556611-I-!1,\UI+W!`(IH35LII5JRQ5&QKK*!/Z`.8,!@&K XM"VQC`Q?4@)UFS:OUE#52KBIDB6Q82EWOJM?"EG(JB`2*(O_ZGAB`8`:%C>P' XM_;B3B)B!1D"R*-!J]A.7PF60;7@69"6K5[Y6-BN8;>E+3:D88($6LJ,E[5D5 XM-4W4&J:DIKG*3"PI!]#2X+&RS:MICV?9U.Z66C6SJ!A"917J+7$F(.`#'UH` XM@A((2KK!%0E:25-)Y*)@EC1EJ1OJT(:8R$&NG@0!4;.+565)%)23,PJ-!CE, XM$#R+O5=5UK.&:92A+3$O(%@!#.R*5_Q.MIL$#:=)1SHE_BIT#H-DBX'SJRCY XMB7*0"I7JA+.J*(4&AZ'',RE5IVDO)TC!748821G@M!0CT*0^=+@?X+`@HQD+ XMX5-2J!%0:N>&VV%A=CO.D<D^@@<?&>:I8ASD(:/+!Q.C6,4L!H&+Y0#C^V%W XMLA;M[$M1X&%JP4BNZ]TPAP6*4Y3*QI];FR\6G!"QOOP%MPZBT8/EJ='8S(3* XM&4.N&-I(OIB=QI/J.X-SX4`CJ'@2+`8IRQ1F0X<[E*TM;V##'!0E(Q`L`2YN XM2,,9>!442D*!EW4@C1Q:EX2E\"HB,0&*9]ZP,JV0SY1C8(..MPD"T95$#*PZ XM314RC0<4T*$-#=NBQ*!E&`J1H74.&9Q)*?DC8UO6,;%)M$?3@@*&Y8W0)@)- XMMFI&FN.Q2#'VNG.57RW.UCG!DCXY*G"`24G@T'K=#9L-./T&+?W$Q%&\P8(C XMT]"16F,T/D1)CVV!!)V5==IG1]U059"ML[LM)0QL<'0>,&E,@&6*#L44^+[[ XM/09['PY&+!L6^2I]FMJP@>%*<PL<7!:4Q$2D,8^):,BY\\^'.;QF)7_1&.R4 XM!O)%S5[??F2Z@U)PN(S:7D0H@QA"#=?.&$3<&?-7IR,>AHF#()/'W&<9N6(O XM$0C;#"X@@QC.H"A*3J3;<($XK9,&%G<WY<YQ?@-3@>3)CKWA001%)U%+W&9_ XM%T;0ZSNF3",M:\Z\!"A0H9$;/A/0U*4A#+B6VF5O6_*?9$3O4+!7$*9.+3=D XMS"8KJ\FP:-(44TZT8#+]VDV:Y@(5"&PMBH*[$Z%8AG/:*]F=E$D82">1B(Q! XM!US@@D[$$/Q?&T4H`[U.YC9'R3"-Z07#?X'QES>4C-JK"09)`QYD<YU=:]_7 XMP,:\YCF/Z<]W<N:D3RXO,^R5TI<$3H!Y^]=0GOO&\7XBI^GG/Q,<^I:17OQ8 XM\!MMX&QA,18=EQ%-\6@KPT$N40<0\1,QDH`.`A?^@FA!41AL0%[.M6XD=1H& XMH3!+D1F%-W(2V&A7@4/3PE"09TME`!51!QSA]C#Y5VR49`9#P7+TMX(UX8(L XMMQ^E-STP44)8((*;08(I(1LK)W409R#D18'+\S`H*'(:)0=GT(3!07_C]1ES XML3QO985NU13WIA^0)T\9>$7\DH$V,3K]UD86408QIA?WHC-SL6EN1872=A45 XMH4IYT4^\=!T8J($](8,ZTX6,]X4@8"_W1FB7`B-&F(<9&!&!%A0/,SD&(286 XMH6E!84K=Q&_FQQ(9$S@ZTU-SQ%`)X1AL$",V81*MUG-@41.\E!<H84IYN(/^ XM(B;V@D;W0W]$:'C$-H`$,TEH(WIREVGL`Q:^-C.X@@7U(0<HI2WB!!3J`QQE XM%XQE$`=U0#@N=6@XIS-[YD9M&%+89FA&Z'V]]FO!UF8IL!I+M'=8(`1ET'24 XMU4<N!5Z_EG?VPA<DHQ&J.!@144%!4DUD0(^%V'OU9SA@<8-;$4L3L6='$22D XMUA<500=B,1A?P8E6<1T3H8@V0@<]<1KS2$L#*9$O0I#1XA+DPX:[2!R'N$1] XM=`/"I2C'0SXN65MA,QX5P8*X-$ANT!>E!9.S\2EP=QIT`'E<YSI8D`05V7$7 XM:554,)'V8CT:858?^3]V5(?PZ'9/*1+7(94!24NUIFEH8)6)AI588#W+8U9= XM]EDTQGT&4E9364NA`E1OE3("(U&[%UA@-88)AE5#49*D00:#I!4]R48-:7J? XMLH^#Q(Y#L'N4H4N807B;01:U)6^ME5L4X2(A@Y%!L5RGV#@*17]WQW)+2(@) XM-DR7PG."9Q-9:%XD55NF=&\B23Z)QIEDX)D@82]"$&FUV5^,A'P9Q4=D\6AM XMD!YUH'9-81>Q)B:Y@1DA0P?^!!HYB)G2X@89)F\WJ9NVV8O&-C6VT7%8TWZ^ XM"1?`V1FP%C*4`8"+F320J"8*!7+D*4XUTR(O`A@]TU!W1U(5<3QW@#'X<7L- XMEX3`,9I4Z(7,=)JNYIC\J9KDQ9I!J3/ZF:#TEWUYL81G>(T$R8'6]!/V8I>\ XM5Z'\&"2I2!,YHQ\518O_DJ!,6%YP@4YAE$ZGD1JL\S&Y<T1?\$+!XS]+04,V XM)"A]E#S+\RA#]$+18U!3="DGE#W;`T+9\1W@0Q1&T8Q8!!F*ESZ!YS[PPQ#R XM(V_U,Q?W`RT_<13ODP8WBB<`U$4%0D"%<BB)LBB-(@*/$BD-=(@/=*01Q"F> XM8AO^."JEPJ4:E"J=$34?)$#;,4*25D)&FBEUZBO`DD,MI*3:D1XQQ"PR4`-4 XM%84ZQ`77LFT^Y"W@`@(^(*@"1T0SNCN@2@=*-&.H:I1B!@).9@0I1A)1-F55 XM!H>KFE=96:M756-EB:M8=:NU>F.VD6.TPR(]YJL;!F0W(F3`061&U@:I:E9L XMQD4$&9'PB6US-HEV]F)YQE#=V&>9J#.`AHG&&HYIH(V))@*+=D>.AC94\`:1 XM-FE,86F8!I9B&!N?MGNB)F'JM13M9*RI%A2KMHKD4S/0(FN406O^1AGEE6LZ XM0X[@=XY<U&P$TSI5A7N5V9L2^Q7/5GWL`;"G(335UC!Y$W=S-K!68:QH]VV/ XMB6<Q9K+E-D7G=D7I)BI]-#"QX78@&F\Q)81516\=MYDVX:9C]!#]=DMD`'`@ XM.'`6@7&)=E2>N!0*=X4B@7O&>G,0)W$4EW5+FW'\NG$C4V\`>V_^UG\B!Q;Q XMJC?&:G(2AGN"<A5(V(-^Y(81\3F/,;8SAQHUAS#ID;2LI:&[:CVFN7.N!A:` XM&G0=Q6E;:W1LD71+=P9-)Q4[J:UP>[55!V%_*Q)8-[>F!$Y"(Q)>UV9A-W:* XMTIL$F;+&*13;AK-W-JXT,G>Y9W=X)[4K.6/0VG?""'CL@Z"[2!:HX0:)!QP# XM"0*.1Y12,W#&6GD8<7(B\:QEM7DB`7&=9W[G)WH7V10$>WKSIGK3UWJOMQL. XMTUN7BQU/A!BUQQ:XQZ&!19+`-WQ<,'WAJ7R:TYO.1R;1Y[[&6GT,A7V\QI8. XM:XYLP;Q8Y;S06WY71+;5JWZ\"9[7!'^J(Q)^HZ_)9JSH2Q4(JG\`M10&_'_+ XM:Y3&6E4"2(`%R(D(^+QHLX#WXX`7$8%8\2)SP6H"16P9V`;.554<2)DZ\X$" XMMXN->!-W<((1E((:)08LR(-2][W@9*P92[@("1SF.XA"3(LO&!2F$Z=!Z,"0 XM249F6VDI4;4`ZGD:D85.R):6JH(#6HA-K*!:R&\;484#.<7^:A-'2!%B0(8X XM(Q(>*A)J^+5L^(U="DYS&);[88>9B(?C"AA[>"3T^8<R'(C7X9%EG&!37,5Q XMMHC:>+85X2"/F+:8*!(/@Q6>48ES&XDULXE*.:(^$T<L,HK748I'@HK&JHJH XMV8H8$76QB(>3#!4GBHM1<<8.HQF\J)V_:*R/YG?#&'AF>XPZ)A++"*5**AS1 XMZ`;3^''6B(WY]&JC%+ZGT8UJO%;DJHV5UK_`EC82DXZSJZIEY8[P.%)O:<8B XM@8^KHH^L]J'^^(_/VY7048C&.A$299`B@9`:,14$R9!KX)#M#)$%2)$KHY0/ XMDY&V%AS*5%4>:<_U&%"Q29*<]I<4\6R^K)+EG*H>';Z\*BA+(B@?W<'LU:JO XMNF(<(F62*V,<;,[68ZQ(F=`9T\E3U)0O8M)^E%=O&;=W%,A7Z0;;I--;Z982 XM_95T"-1C*=2G`](B<99EE9;@6U5L\C``>U4]O5Q&LXQ-%Q$H,,%@555Z&5!\ XM29T7#2,`?%7IV9CS=L62>5J4"9^;*Y^9V;$B09NV2;$WK3-OJX1129H!%;BH XMB:"KR5#RYII7`9L3"9CA.YO8V5]LD9N=F<"Q\;[C^1(C.YS.>;K8D9SJ\Q'& XM:@;-^9RP-+5\3=?3F6'X"1./G6%)S)T:X9WYTG[WFWR773,*Q6?_^])FM=92 XMHX;M:7`O<;&R*)T:=<HELD;6*1(/"J'&RK:AZ=<DS,9[*=@'*A(?:U$IRJ"" XMJ)IE<`>%C!^F39%3\7@:<<<3@:&Q\6>ZUZ$09Z'IW4<F@3;'B[@EVH*U&!$6 XM5=BCML$E_=+_'>``/N`"7N!.C:O453RH.JI(M*0,TC]D:D.4RJ/(HSS,$Z0. XMGAY#.BG5,Z>(VBLNE.%TT*3B`Z5A(Z7H<XGL8Z5BBJ4W2S\79#]DD3]@RC_" XM\S]Z@AW>81V"0B@&M*8)Y*8+)#VJ5CV'BD(2=*=?'"JR<4%[>BIVX:<O`:@A XMON,PQ!LD9$(?+D$JQ*C%HJ16'JDS8#&.-<;5@JD\I"USP"V<&D1X8.5#A"X, XM7J-O_AU*E$ZS1[[VI:\VTT]7%#9:U'?A\47IM%/T-!%KI4:7V`9;09^F-!V= XMO6)+P4FEN)\SLY^FA#7\O5,U`5?0<4E&3!G#4L3\#4NBSG)@\RDQP2E)X`(] XMT>HP$`.O[@(P(`,L$*/*E$ZM_NJP+NOJ!>NV'J.HH3%U,XADP"\GPUWXQRM+ XM`7-@2Q'Y]`(U81*@O4RG+G6ISA+C@5(K1A8KU)`VC,;F!4O!PDT=PCI(Y@)1 XM-56UNETVX5=U5%ER)59DM:KN#E-KY55MI=1N(%=T1>L%9F##]>Z*Q1*#E+YU XM!0,!CU^'=4@$#TB,U0:.%5MB-O#%=5N:=9^FI&5J^1ZBA:L6K[0<W\CS)$ZO XM!5SM3ENG-7E`0MRZY:[4XELH;^\J3UQ*>UP==17*Q5PP^%\:P0=5H#Z=X00+ XMRE`DX>ET-&4@,`4M@^W2Q0>!>15/#P4L50)\D%WWCO/7\5U>N=]%?UZ#E&@# XM1E@;5DKPB6`!-24H@)R2?A.(]5!@41]J\#!:)E<\'@0@<#&.-6'N]4E]U.D@ XM@/=P)_=6_?6#M%&!KUXT'TN181OWID8=ER^8I1]@S"*2II/7(01Y/])\KRCO XM]??O"`*:/_@&4?@J"KXN@/B:'^L5KR@`W?@:<6_/LC(OP=]LY5)D`0-RU:+* XM`AV&'$IA,/>KW/1,+%`[8IZI&/RF;UX]86OT4?K7P=\L&GMFM!0VVW9,;514 XM2)`E1_Q!X7F?(3"5V1/6B&Z:J*(QPDLWPC#IGEY-$`28G_@K$`/QO_I+0E]K XM)`,Z:1,TH&3LU`)C3TPM$T)3%=K0J/,S;\]><`$W$`1"`@F@?TNDOD!`=)=D XMK-U0BA.?K&T,OP-8(8S?+<D7C$X#;K<5M5-FBO5K-]EOC7$_G7'M8@;X`R:5 XM:??EF[!C$YI`$JA_`68"UA?]QY+XWTXA@('-^[D]AZ<`&2`3<0.:[P'BO_NW XM1*9?NNM]%]`TE!L*2$@&R?LK"TU`^5T'IL<!\XT0X"4C`]>$@3`(!F%"&12# XM9'`,FD$UB`;78!IT*NWH#,I!-C@'WZ`;O(-M$`VVCB](!_N@'<R#=1`/UD%T XM8@.Q(/1;>M[/"P9"0.@'!6$C9(1PD`_^P45("1_A(,1-E7`26L)-^`;W8"9T XMA)HP%+I!0I@$#*$(Y((L1Q%R0E#("B'A*,2$J]`5RL),2`I-X<-`A5)'%8K" XM61@++V$<[(7`<!>"04\8#%OA)]2#L%`8%D->&`F/H3,,AH00[XF`+"C\$&$7 XM3(;&<!G20FS(#+.A,FR&VC`<=D(K6`JGX2'$A=*(&S[#;P@*B2$[[(;,L!:: XMPU.8"-6A./2&K_`7OL-UV`[MX3X4A]$0"VI!:Y@*_2$^A(>^4!(>1'X("664 XM$2%5=6YL0+CA0>8H'`CP41>.!PPZ.;#AID>'NQYT"L2!.2:E*,+'DR(?)^Y\ XM=`;UL>+"5/QX<4T.+LBXSD#C]H>8FH@X+H#4N?&`IGX<`FE3;XJ!3`HY!1*W XMG)VB($Q.3V405,&`IIP'J7+S@5#ABB.'I!35M^M24'%0*0H9(@-@0`[X+69N XMAVBJ-?=#.M6GVHFA2LX]Q`;G';;#J8)I(B'HD06B=_I4#-(#=4H/'=X3`5=5 XM6AT(H(:W4`C2KG-6!N^@86R#AY$A#D.=)A(4(D)4@XD1,B+&R;@8#UQC5(SW XM4`_Z-[AH57K=7SR'@I$S5A6%&!F_%F64C)@1#IH5Q\@/2^-=*XRG43421M1( XM&TTC;+R-`)$QBK[4N!#]X&X;C%@%V'U&>L@!R]EJY(VN,3DB0\NX&S-C:OR- XMHG&*P#K(HK\"8W$$CE>%-,;&UU@;N>,_E(U8A3460^6(&VWC&-1KX;$\>L?U XMZ!H?(WC,CLAQ.Y+'\Z@;Q>-W[(T(8C/*-+\(&+=@:*R/ZG$^FL?OB![AXST4 XMD.QQ.1Y'YP@0]2-S3`*>L3KZQ^L8':V'=@R0\M$]YL,%>1\UI&;L:`]2.$I( XM@EC$L*-5L8_X$$&6Q@)Y(C&DB^R.[I%%CD;>Z"&'H8/\;R&-5U$][@(!/UI5 XMD8M#[^O91;R`%ZTCJO.1TA%"AH3^2")CAHF<D0<R0[[(]]@B&22!O)$$+DL: XMN"VI);LDE_R2S#%'!I<=:1-X(."8<^'AP=VXI=`5OZ)%Q(A`2B.B13K0$8'" XM1Z2*B2HK0JJ2Z*3&1R.A&BAN)58IE^CBV@Z,DXE<:L9]*9LXIGA&CK,+Y8'' XM]40U]1,5")P:BD8.@O0*)0<J+`A<>')7),HUQ<X5XB+EE;,5A4K+(3E.T>58 XMR)>#E"1Q6=@`&%`#P.(/DT)BL8>0Q3;GJ6`ECQ-5:Y'.F<H[UT3PP/AB%9ZC XM2%41/V<3`)TXTXE6;J<8NH<0'R"1&Q(*:T1],+H^5#,@'=M;.85C5]",2U<S XM-)WA6R:=CDA6BU`G!$M=2&B!]P2V!2%6Y^K4"ZWS=<#NUK&.7*<L=MVONY>\ XMCM8%.]8Q[`($.'$IR&XH*3M=<E2<W<^"=F1`VI6$M[!3X&6VFQD"A]N-!?(D XM+`9:N!N!U:)N-+"I$*/2W;JC*HMOJQ2\D>%5Y!U4N0KUKO6A*+5R+?7=3^-J XM<>7@:82$M_#8R\"+6Q#OX`D6@"<S'0K07"R@9>*!O)HG>5)+QE,I5V'D@9:/ XME_+B4=.\+2,/YYB\)=(&8,O2M)H7K^7)M9?'6V0>Q2M[3#-L=I><AZ*T6G-1 XM,C\/2+X$NLB:CIZZC`AYT?O-@:<7]9@,'R"3U>7J!9>L!_,8"M<++]R%O\D5 XML4=@BN;9&RAI3V!\2]/P]GH3X;L.=2_^X3V]AS;K#R@!?(+O85Q.D'GX^@+> XM*X4R\_6I.IL`^?A,K3$,E*\)63[+91[LW]X3>)[/[WV<ES#Z1.<AW'1+1/7E XMO=N).QG?ZK0OYZ?V"4E]A_LZ@^Z+?T-@\TU`Q!<]!6`5M("_+[Y40WAI4ZC3 XM!TQ^U9"_-3_0<"U#X/(C@<O$!`H,%+A-M)]40%#PTD`\$1@H3LA?'3!_5R$- XMH+\UN/YDX"!Q?_!OB?0/F^`"H,O4JWI03X#2CZ-A0`&GU9,NFC,'XD"]MP1Y XM8'7P@?_E_P7`'S@7@F!Q="A%L`&"`"48`=?(!'2"V!,#FL\-B(,\(/++@.?S XMZ*3/ZK<^;U8*?"LK,`VUR_DI_L2)_UPB[N\&*E#4P$"EGG1QH`G4!?2/JU!` XMI1X2A:`L*?-)T!)J7_8?".A_`["#+H7X"4*QP`)L@`LP">I`$QIAGN`,A(*_ XMKS*5S`KH`J[@-!R(>E$7XL<YNAQ19(V$A@;QCGY#>3@BXV@>I9';4!_2T>?X XM1ZUD/Q2D>A0_\E'0>`T1*2#%HX[4D,9#<F@+)V1!C*0=<AVZPT&:&S$I)]VC XMA323<L)-FDACI!64ADS2CWK24AI([>@C#86D])5ZPT5*'"^I*Y6D"5&6FM(E XM4@CGH9',A:'TDQ[26RI*86DP9:6^\90*Q&JH2HFI,&V(QU275L8V6@[[:#U< XMI=(TF6)37*I-G2DR'8?;M)@>4FI:29LD-(NFW!0<BM-=2DY]J24%IN'TF>;2 XM=#I+T>DZK8S>-)NJ4WD*2=LH*H6CUS2?IM-82D^A*2^MIHS4ENK3>AI/OVD^ XM%*CWE#XV5'U*2W]I.IRH`]6>\E,XV$ZM:2.%J!N5H$948XI11ZI(W:C#=*%. XM4E[Z3YEI0%6IK12FCE)*ZD[-J1QUJ"L5I'[3DXI3Y^E(9:@=-:'"4YWZ2GFJ XM3.6HO=2C*M2"&E.9ZDPMJ2%5H^Y4J5I4E>D;=:D?]:BF5*=*4H-J+1VJ6M6@ XM$E4K:52Y:EG]J<O1JUK4<PI5IVI;K:H'M9PVT[#J4U%J3J6KW12O@M.Q6DQ; XM!^X(EKZRM^!$P4(K?XOQJ'`_JGD$UCI)/8J4II0@I3)6FD0_&:54(I5JB5>J XM=QG*F!@7$B5-7)0N<;"6*5C)$WT<I613EE(H`J%,&1*3'%+TE!B$3S'%+D7E XME%1YT(JH<BH^5E:YJ%SE2XBL6G%9U`!G<4-NY:7*5+J2S0&17HD';FM:+"*Z XMH\$Y5U.5UD"`W&150M)N?KIUF3<YH.7"D=)Q20)4"@D@NZ.*U*,R<HKPU00Y XM);UC>K60>G44.DBS$B&%JI.LD)?1O$I)&*E)R^M]/*_E\;WFUP')7O4K(66. XMZQ6]SM>R(B+M*Z7`K\WQO^Y7`KLA9R-:I84+-CC2.NKH8(VCA2VP%'8[[E(. XM.4<!;&T4L!$6Q*K83XIBUZN)'9`M-KY^R.JJ)/_B>.U!3U*]ME<$.6(_K(9\ XML>[5O]I5#`LBZ6M]_:KW5<@"618K9'OJ*,VP5T5)UKKAN%8];'J,DCLV-L98 XM`\ME"6R/O;(7]LF"2/"*50!GCQQP/U+HS<WL^H[N)DM[IR\#25H/",D?;VR) XMA+`N=L*"V"T;9F$IE.V,4M:Q*-4[JV3U;'OLKP@V/F;9`%MH%RU_A:0DULGZ XMV2++8*7LLQBT23;18MDNNV>;K%Z%CKJ1SFY8*@MG'VRCY;2'%M+ZV-9H:+7L XMJ0VQ[?7+&D@)ZVAAK*?EJO*5TLY9*R!>L2J.Q;.U5L7*VBK99]OAG^V+O);U XM85I3JVEI+:IUM<UVQ>K980LEG2VL[;)\=LB*V>J*;`4FJ36G5G;62MM8BV@C XM[:<]MM(QV7)8),MLS>UX;+6,-MHN6?1Z:]GAO*V,W%9,XA?`:2;1[!2YKG33 XMZ+79[8HWU^IWY6T?]MYV4G=;;&<LPK4>O-;&^EI"&VU_++P]L?56VW9"=`MQ XM[^6WU8OAEMB.6TY+;77LIKVV*#?;*EP"F7$E;:[-MQUWRB[;D%MM2^S%M;45 XM]]SJVJNB;C_N?Y2W-W<]EESX>G)'+LXEL2M7D;;<3[ARLZW+;8A_U@K4V8F; XM:9%NT&6R.1?7.MP<"W&/;)7EN@/6Y@;;"@MFC:ZP+;>K]MV.7069=ANNC=RY XM5D7J>MN9"W93;-(=NF'WZ0Y"+`ES10+@G`%D-BZJ6>Q:%[5KTC.X<I;G3D>? XM2UZSKKV]NFRW[-Y=M%MV+>[:K8Q6]_(NW+:K<5^NE_R\8#+T@M[1&WBM"N#$ XMHF<2L#;7^=`H_\=PE0'%HT=9N#A)6C4<D6NLU@-/BL3:.^+X9(E#B8#2LJJX XM]D$H-2M)V5+E[;/JC]"Z)LN4?"`1D_*`H%8A=RE7JX=;E1,$3R5%)[<4125M XM?8HBX/G2"BR7*G4OE^NMH^[+B=](%0-B0`ZH5,;UDJ"YL:A<S:+XC7/0E4:) XM7V)92!PEB5@OHB0DV`4KTBRI!J=@;GUG:<0']P`?!@D58`*W!U"0!2G`?&(# XM.W(!4P`)W)XB,`6HP"!A`ID'"SB$B?!FR)2\62]+Y:=<S/&@,(E#8@K!([A: XM8HQ5\E,XQSVB8'X$?1PN_<"!U%EL8&6GJ%.>$I00D49#D%`*`"@&$Z04W%3V XMW`TF2++&)#4RQ-6#X<L/QIA!V!_Q"B)\$XQPS""9+]@_D6#])BV8BBMY+*0& XM!T=A43-T0)35[$U`&"QHX:?0%;KP2_C"'>(#PV!J.:UP%$E!P658!4>I%JR. XMA@H46!)@10EGI$#<A*G#$\X).G@*\^`^XH/!0AP>PG5881YA,'R49,;=&0P8 XMK.)@'ON2B/GP(J;!3=@[/.*(L(9WL"2BQ%;8$F-AL+"%,[$7#@J<N!3.C)$$ XMT(H)='K!CZ44C^$9[%.:<'E8Q3E8"K?A*BR/KK`IHL5T&"MH8CQ,:CPQ+P[% XMOWB)@&`Q+(.IU?^0-Q3X!2"'*`6(4;$KH2:H2R8<"2.V'6J+3C`SR*00KY=6 XM9R\637H8&4*@Z@2^6Z)B?)\_\0K`8XE08&#<`.T%U9,U@2^P7#,7,)#7T2%V XMQ%B`"50$*F!TVD@R,L1..")/Y(H<&H000RX"P%@(M(XF`&V&4J*Q`CT'O`GD XM*0",(?(1(%9@80BTA#``C%4Q%GC)E$0F&P2:[)#1L+W`R;%!)WN>08(<@/$0 XM&,E``2%3/69$E%ER3X;($OF*-"B;0`58A$&HR:W#"'"%BC`%@D5E6`J+2;01 XM99`LD,DR1E:2)89#X&-]'`3X,4GPQ\0J(#-DIXR1"S(6.,A7(0@HY+&LA[FQ XMN&QE5:R8])&V<0>J"9[B-W!/H'@3Q4`&W,><$[^M=RFTW_?[)F=O\Q"_C/5. XM[M8/LGY][TG\D^9C2@U?%O<2-ROR[5(UD?GZX1PG'TIK`3FM02XHWEZB:'Z/ XMHO:%K:"R3XW*VMJ:]V1N-52;N56FW]\:?MU#<)4A,<`&)&<O)2UPY?Q-KF4Q XM7/3FI0`LH^L7F,YOD4OB%XH\*BEP;V)',X8*<&`J4,X4L3LQP7VA'!?C<XQ% XM6/!H4$DFTCR+!"9\ACG'G%7#D7@9P^)FS-BJRB6>PUQX&N/B@A)RY3-]'AG) XMLM1`X?SLB0`6!WK#C"1MS6(A7(NE\2U&PINQ8IGBN76@14)YN,\+6ADW:#=< XMB27T,Z;0T;@(W^$!#1WELS?&(^KE$!_HBVF'X;-1B@$-X[EM:&)LAD>&%-E7 XM(9H-CV@W#*$)AHD&S!5:16]B`JV+/W$L\<6E;<;(@!P=ON0SCZ[!>PY$0V(1 XM387W,]P[TD$X2=OA)<T6FO0U[B2B>#/.`"JMH8=QA_[00'I+"VG$1:1'2H0. XM7Y=83`MH#*WX=C$H1M/0:3,J88+DR<@421D)4T`<%P&1<.+4<X]&QTG#!FF$ XMU84%VO%I><<Y`R)PBAGC%U=25;''1B,?-X6V'#+Z\5#ZQ]_$1(I03UU6\')" XM-B5U]T?KQJHBD1L"1\X7=3=9SNHI4JLI\C^QR#;!1(KD#6962/(-0AE!`25_ XM-YH[161UF)PB0#DFS^0Q"V$C"^PM$D>B*;A?*U%Z0UJ"(VD/]ZKHZF=M/:(U XM"!#*%:'NPNE=7:YA\KF>UB;R*!/KLM($DO)56,H#+5;O-LD2E5<6.*G*R)I9 XM6X]Q+5FT<JGNRC7A6H;E8&V4:BRKMA[G)DZLY5'ME@'%[HG+$4%5[^M6#7'R XMLD(NSWSX$M\;P:R:-H-A_F*(N3>A/<8L$*BUZ'W9I#=+;IAK;21HS;:^$ASL XM,1OG]!"9EX1RIBJ']2):YB$RG3.S8VVM26HZD[C/7%E%,TLDOIDU2QW*SII\ XM\0=HM7&KN2]0B)JB-:(OD`.*0RY.L5:CF'V7'&[NOAOD^[(*5[&U^X/5D(K` XM&6E;12]'G-LV?J`0D4HYV\KF?%S37%G8E<O5!]AMD*`UJC.-&MQ6@__ZX<'] XMO6",`%Z6=<Q9(F`NLC3T`^*F$.EN2S2$\3S21`!W7@I#@BXH"L_-:JK."8@( XM1.#SZ(#1S054``H@`D%@!F9@5A4$F$/@<)1^&.Y\'12`H_=#4"AQ_6&0S.XI XMD`6<P!.``E,@"3CEKY,U2!2@<`%CU%[0!/QG+^H#/`84PAL)@``BP(&'@!0@ XM*E0@"3P!)V`OLH!C^,M!F#0\'-\-1UH`ICXS="!IL3R_`#">M[U0>O-M<,R+ XMCM3`*`D01&Y:`XYX-1%`(:Q&V8D-GTMM&'"P4FF*250HQ#O)1%H7YEVYI9A7 XML!K&:H(G8*WQ=3"X42J@`M!\/P9&E]0@CCR!#,Q.:_Z/%V4L:8_0&.`OY(`[ XMHX@H!T0``V\*#MPE0'`S(,&?I9GZ(E5%@W.1C3AC0'CVEC))@`EP8)W$P['` XM"^D)&W&*X(D7D.=8A=\(3&)JSEUNK]"S]79E3JQ#9(N[`:.=>S<SV^8/=]LK XM+&W*FA*=]J",VC#Q-"O*Y8NUR52.0]RN.4U)W]@<MC'E]:V*G#)/<5_9ZGT[ XMR-HFX&C</_CF+%>;Y[9O_2!X?$\N"QP``^`OWY:_R%7-U=]P$<FILUJTSIT\ XM.XM@SLV[1=9VYAFA6V9M9U*.H_^;$ZC=B_IA0S3<3:9T=YLIY;X[;JP!EC)C XMB+?Q1M[*>UY;%0JN-?`$]!;8#X/K6F_]O11F#/>>`MX;?(MO)R#,JXH(1]]F XM2WT_+_;=']QW&C`S-V=^TQ-C+A+PMXC2:;."?R>@V/"_P4D`GQNOIX!3B-%% XM2<I"!Y_G82U7X?`W\,!E^11AUT)\V%1PW^W!"TM`[PL#_9YS\0.GTZ[Y)TMJ XM%$'2N"U'<E0(%IEBX<=RZT@-%."HOH,,UVDCT3K8\'B5P\_`IF;HY/J@__"I XMIE=4.A%'Z?<[B7/@:JXLO8@<@.(T7(H#"BK>PO7<%8_9,%OTMBLR8+I1M^K6 XM*S&`!NB`&G`#G,3%J-GVQ=91"2O!7LSL@@N6G;QG4W*@+7O!.`_HY&3\C^=) XM1.ZD\$-PG:PF+OBZ<<S:XHROEHIQGM5JT_&;V'SO^(B("%Z[4E)?U5KDQ/JF XM?*V<-3?/5D-N$]CV78?;JK(J"F>L2,`/^U;DW3>`DC/G'(+)_?:F"MP$@D08 XM[MV1V>F%H>,9[V%Y=)RB$#NF0H_H<Y';`%L/8CX@[OIGGQ='`T`<8:D&(WK" XM.ZOMR.>V%XQR@V%LP@24[3+$EN2]SB$`/[>WTQE94)"]ZTM^'3Z8D>::8R![ XMVXLG8`6*@!20ND7@"O1E$;RC7W0'TAE<(+0#LVCS_4#7$\Y&[L3,O;#3\,?$ XM4E!P)*I&<L2&K?P1X@/]	Q229"A-NT1&P):%D>5\^";F/N3C[!)C;'Q%C! XM+]F$/2-#J8`_><7\;K(#L8"UX!-0/@E.02&\R_;7=N*.RE;^QL>#;#RR*Y26 XMK\C3\N$6C*#0&DPDHA`48.-(D0Y<LI8'?X1/PSZB/SCS`L5?C.1[_,D%HS64 XMR^I4A`NRAY80@W\]?&"DFQU6;"(^#V/;+\W$XO@QL`2CV3N5YW?H!$`,$O^^ XM9F@&0!/9-D&!WQX:ST5D^SZ*4OI!PXMV&A0;3ES;6&->Z&]HXQ!\S1]F-HKP XM8;%FO/EWIB_8$!LB(Y?'7C!OV$<1T@/L+/(C[,X#!<>P:9A)?Y'R?/XT5.+] XM`(_]EGH?*8KNQ%GYI);C,UJ4XO,WGGJSI";NHD%%/NKSK0,)&(X^K.#9B&;" XM"GO^4Y2-BL`VS!\W4G](`0N,%,)PUL#"GT]>Z>B_+POA/F!D@`"\/4@@F#.! XM).`$%G4P'P)((`@X@2-0!(B`^X#N)>8)_,4G,(ZAO;2G]E,@!(C[>[2SWK"< XM=L53GM//)3?0D?Q6IU?O?P$S#11]`DY^22$&[BB`V!-W9!_,@SG>J^Y2(`NP XM`(`O\`G^P+?N!1_A'_R`O_`3/L,W^`0?!#"!\7T$)#ZS;PY44,NO&6W?!+C] XMHO;VTWZF(P'K7@3$_;4WXOT=]>%[?6_LI?N:R>Y+KP@,@?`]OK>[JD<;?R$H XM$!2680![4#:"$6GXP%?H5L_@GXU&L0W3I"<8A.0DW,")@Y$:,>'."*'N5QRU XMS"[;[DI8S=<;TKX53#NQ.1ETJ>3PT,8U20B;MM((0T'[M(K0;B^26.NXYI<X XM:56$\"[<7UO4%U'@1.M[+<V*H')\V]_Q/;^(F1Z:D&'R#^"/&32):(T,^7'W XM:P(HJ@O!@>?O>LLB&8#^?]_RJ"\#Q_17KL2WNX*.G_^9R25IE;!JT`;1!PQ_ XM0XN[=M$:`R+[Q0C:<+)Y=/:P7A2QKV$7$&L\K8?F%/>T27.A/+YPO6I[J;G> XML^WZF3*M>QQL5]^^7OL!.6!7BH0\;1-V2'XB%GGY#<[HE[$3B..,`B;5#5`2 XM8?$Y:_+H[*FV_W-5_?-!B>A;7I5`US^N2J#LVOU'EO8O_\4,_3<KQIT\(?=U XMO]PI>W-G\V:+7@'_&274G76'W5T!(-LP5JCQ#(?:QR+>C7<6R+-4ICT<^<0D XM\?<Q=^N=''+E=7KPG8,&L-1S]%WQTC_`%-+;91`7['<H5OTG6210R4:^4%L< XM>`B>)]/JN7H0#)EGP2EWT<4%Z/]1>/%*-H+AQ79KGB_2Y@%*]4G<TDMP,GU$ XM#H@%O'@21LP"QYQXS%N*%QRL>()&BW<PC7@PGA(X.>$<--X1QKG<>'L-'-/I XM27A2"'LPMR104N`A8;T$>7/+)4/DB3!W#7V"Y(UT*AN35\J`!?=%`O7T27F; XM'B#S,;5W6)Z!D4"=&_O)ES>AW1L*W-1"Y@T;9EX\@^8%!0]@$D,T`$IOWHL7 XMI1DE#MW#!#$I,_P?&4A'Z'FZA:SW`7EZ@-[)(>CU'83>[F$5P!@B#)"73_0N XMC-[(L`?6#)$>7_-+D`VQP3('3EQZH$2F!RCU@>X=*0@HA1N'23S3HG5WIAZ? XM-^NE>JO>FW'ZO7KY22AH&\QZ`D,%D3,L>+B>O3#Y,6<FB:\'-@![ZH@*N&&P XM@,G>YK#L-7OJQ>8`\E%[UIXX*!(,@AR?QW>N17LA7[@W[ATEY=XVV(I)8M_* XMX;`!KGOMGA#R[@%^\=Z+,.]M(^_.3J".;`G]WN;P[RE\$!]$*!$^?!.APV<1 XM-GP2'\5G\35[PHX2:+QM>]T>/0CN@0`C'W)@\L5_[B!6<?^EA,'%(`CS30$R XM'\U'S;&$*B%*2!-.$0G4S?>AZ`<[']H0/_U\QT8[LT5-:$/?6>/JG8$QR%:B XM=H@$25_'PO3Q+A_++!B$2'U.GQ"D!%I]+@&?<Q-6%2OA5EA8L(!\F'@WVD$> XM79]$\O699/&2V!?^P`2A1ANHN?`U&E!]$)4D4&G?]A$)`H`2!MPWH<E]1T/= XM!P!.A7C?QY)$R79[7VK0]_%_ZEW@%S-<+X3?$\C7H(&`GQ?X`NY]QA=@B#:` XM$SUA0MA'3`1*H&ZG%7J%UL,`N/D%`4I<.?/Y"4&AGZF1HI%^^1LWR%T4?:!6 XMES2S30DUF[96)>!LJ1<H5_VI!Z*5]Z<DP'Y#VU>W&])^C=SM=];U2;K?R"!\ XM]7[%E]3&6<U$<EV-0]=E;0I"@I#735^RF=CFU[E6MUE@A[9).:22UX$@P`>( XM72.WV#4J!P+N]]C)`#B`Q>`)5G;T%_GG`Z2'FMTG1Z/0AY[=,G'1Z0P*&*NB XMO05@J-V?H]KY</TA?NB`06`B&,\@;S@!VEL6Y#1L=T[@S!(N%1-"6$R">E!E XM3$!/$`14`1IB$J`A"@$:XJ(F2DAY6(,"UA/0(_;"C-8Z7`&@!W!P`G`''\'W XM4QE88D(05G@&H&/:3J@Q,IQXE@<<(.>Y(^H#H-'N'143`44WZ70%D(0$UAD\ XM$L07ND0^62;Q$T3F`C"(><_U$00H`=Q>S#?S37-87\AV".I0Q1%$II=A+<87 XMU=>#&$T=WI76A,D;\D3X0V?D85B`3JCX8`U5B1ED(@PT!UI/`(*A$P.>@O9F XMC$[PDM+WK1`&NDV)9\HH/KY/G`!\&0UK`94(`R@*3*+`L/<Y/PA*5;(TU`B^ XM1`N"$00.5X$($`-0&@)'*508(&DIFD0G2W@EB2)C%J4TBMK;IZB86222B::H XM$7B*^0;WI'F8BM:@A$@EU@36",LP270:6"`4%R-*!&X&#D:/C#3Y7JCQZE`$ XMSLH2>%F@#&2`[2%2R(K(X@33$RP=2T$34`5T8`6*X&+NF'QR!94(`;T_6*(4 XMH"7*A%TBHO,E*H;11.NP>>1WUP&@Z/V@$U0B#\0$4(O/@EZ4+D(BZV+\Y!U` XM9$J8HP&)Z!RQS*HX)6IO,H#KDY1$'9T!QX`1($^VXA)1+XX?\*+$AR^:4_OB XM@7=O^(N=@[MH*EHWK(C!6"\JC#1-E^(P(@GL(KV(,)9OU]*[:`):C!T#\J0O XMSGE^&9C'+NXYQQ@6D`6`!NT>_N&N0`9L",BX*(X,K*)]03+"B@WCQ1@Q'HQ, XMD!`0!`P!2T!#P/%=B5DB3+@EUGPT(W>G+IYH&Z,0E#,J:`)CMU@PGCA%HZM( XMRC",+X%`4S.8!/^#O,@!F1NVWE%Q5(0,_0:5*$J<;#(#6,)0G(PW8ZF3-S@_ XMG"((P#[`#1E*0N'C)1A\(PGF/94$"\6Q,4A,C!'9Q3@SN@`#GA)F,\9/Y0%$ XMYB>Z$Z,#FQ`H8@7RQ*.@=I`/?.-^,2_Z)UW!L0.0I15]P;&H,7D['=-W1_!T XM##+8B><P+72M1+GB"LIARYK%%)_`&36)P.&7''=@8@]2ZH`,205\5Q.\?>?; XML6B`##0SR/XQ+,0M,:/_1EZL$=+&S\#;28PK(Q;@,@H=]V+,F"]Z/QGCY>@U XM=HS(F`EGRW2.[&(U81&\`:)C1D`Z*HVG(_?X6-@+X>/#"%E,CI6CE\@U%H]% XM3'GP+\*-^PDGD4F0:-2B)[%B,!2)1OS$WUQ]1\FD$S02C(.+R*B]S0!EQ\MQ XMOO4P@)E=H'/`B4PCX.4]5A#@([6X/Y*/6:/EV"^>C]Z!338%\%!\(QO"2YP1 XMWL^U*'`L?=_3+EB2J8Q7%/Y(+?X6_.,>MC4"9EUC<21`=HP0V<Y(LX0H:,/) XM*#T,8WSC;W&,B#N&35_@-_YZ&8&TR#1B4=\C0Y$_:@1`)`I).0J1_.+_>#,> XMD2TD#\D#Y6.%R57P1<J,8F3_.$0&845D#U(>Y(P1(B?Q,,T!:T![P"Y2'&2! XM&F%#4@786#_"Y.B"-D*^<+)@`7RD'SF_E8XU0Q2)PGD0F019\$RP>SY!+*CX XM5"':AD*BW]0(ZD/DP4.*D)L'6/!&GI`<4/FX0AJ1+D#FV#H\`?(-WL<W7I*1 XMI`G)0XZ+5*.Y:#6BBRFD_TA$`I`Q`PU0C3T15X<;TJ7D!1%%T$<9E`12WKW1 XMPS`C'<3Q,$P""6<`+X%H0$ROALZP%M@)'<9?:$I\'3W!WK?,Z1)_@6VP(80& XM:8`H^5=99P9B;]@>OGY=74:$'Q*'9IQXJ!XB'[\7:*8<KG506UOG',IQRI=T XM6/Q9D0N"P'$=\G'+GP/1_"4J@=SV]2E]A[L9^)4>XE:,'/9W%:&'!67OM2S, XM`%X19!'^97)_VR;GJ4R4YU^P1%)25T`=N596?&XD!97H(*H9AB)VD\*%2VA: XMA3@C_FL98N##(08^'F+@`R(&/B*B?%$CE`CV0HD('YR(7HF:>([I*RRB2""8 XMO8B6PK`83@PL\)*]8"/BB!A3HR<A7A1L@(\8V8`&Y0K/*"$6B2D<)U$VW&ZC XM$I/8LJ4J/QJY6#7&A--<`EA&_I(WXX\V)E8N92(+)`2AB</@$JA4C@QLHF&0 XMAH`((H&<6`K1B?L.KG$GSF>,F"NA3.R)F]'FN,WM!]50^Y@!$HKGB4@0(9YX XMI5"JB-;H&X!2T?@H7A1H`PHP*3Z)E6);<2E2)=0BP4(K(B("A^)#;)"*1)BI XM>"QZEOID6<`TFHT+HTO#-]***:-(H)>=<+GBB;<K5B,.B.@0Q[QXRH2FB(L5 XMBP3)L>A8)(MGP+)(3&X45EFT&!LF2VZE+@E7CF]RI<8(3+:+PB4)R5"XC2T4 XMB#1`B@1OY/C8>*F09B3'^*,%C!.D@1(RDHU,8\*XDIR-)B/]^#8Z2&ED>5DQ XMMI?@5GCF2P9ADDS\M.<D2PG9"2<TYI9%8\)H+_"7L:+X&%RJEZTD6Z!$!C[F XMY75`8()<!N8<B8K<C-X!G+8SHF/T&W;S,P*-H0P%R8I,@HQB?GDT*B45YL-H XM.OZ7(!*<YC1"C5+C7Y1+GHMQ98@Y5R*88HN"":<!:6'C@VE!+@GY!H79&:B- XMI@3;Z%9L3_.B9ADW/AS<@<C@'ZXD=V-$IQ$\!)O&WD@M.I!?#S`"QS@_*J9( XM,#A>,X4CM'`X!A2)(\!Q_!0B0!_?I5*:%31;MC;5X8;^EICQK;4`J8HKR5Y* XMCC\7?`F8)9A6H:`)HA%JEPS[:%GR9*'C`<(5@`60)/<TWD`["1-+<:@=BR#` XMZ^@2!`ZQX\=T,M:.*=SM&!3DCF3`[AA.[">^8^"X`)H4P>-2,#SJ?^,ER"0= XM)(],(O/X&#B/_`;TR$_0!-0+]?@P6H^'00:H;!!H@6;'*&"^C!]FH7E@CIB8 XMH[(9ITT2IJ(GXVA^CA3!+0(_2IKSHX5I:>:82"1;<$H6F$:)H4E'UII'Y(]& XM"(9+!V0/ED"F%`SD@T5FGCZ[C'34M>PQ2B9^225BD)X>S$$TG&@>9,L0&Z*1 XM;$$7Z6&:D.1FS;A*VI$=8[+T0H8_,>3<,D/R*X$B;$D5+(ZNTPQR@PR<#2?T XM)F[^D`FGUCAD0ILL9+@I$FR8'$AKZ$2FF!.!-@AR3I$@$TEQ17Z#623'F48F XM2P8GS/@PAI'OY;-9Q42;-R?'J6,^*35#L]ESBI@_Y_D(I^61"85^T$AF2WK3 XMU<'/=09%)1PP2#YI%8<0ADA"(Y9!IM!'KA&/Y,5H2O"-]L)OL6^P"I5D9W!) XMMGN:9"G$288&GJ2#`$JFDUR!T.EQEI>F),()8I:;/F?2R4HJFK`D$SD[/HRT XMY-@I*]H+ZUK,-K,]"[7AGMFMX1?4!60!:+XTPJ1(T%T"F>"ED"E>WHR5I^)# XM3*IOQR3+$!0":<LDB4!4TAC-$DW01W8&:($T*1T]+]2D-2D18),7HF[)34*` XMIR<X.4GV&^-DBKD4GI.A9-UI9P9U*27Q:7SVF?A%GFFSW897'3N94?9L'&4. XM('G&DW'224E/RFVNPDF9^PV-@=)EU4^69L`?HB3\I69UG*/4%SP(`P3R][6E XM5K/9V(9]-91G6_0''M96Z*<(07[I5G+;>?CEU)]7SK(@`R1U[^&9`U)>=F81 XM_XE_S3G\I^*V'Q)0#T*:<16@`/\;P`%=Q`Q!Q>=3WKP,YT2Y1!GT!!1B/&9& XM)0#$G'[`?R8`TYL8`8)N</H-A$#H\#XE4;[`@:``DT@6*3OV,H4'69`F!A7` XM&VE0B+&@ZDZS2$CTH#<!5`$D>&`(J`HJ6#5?_Z=A17TV#_SG]4FVN0K\Y_:9 XM6RZ';YP_&<<%?ZC9U38=VG'G9QLP(5QP>9Q/A!WV<=;70OG7=8?0'Y0C_?TI XMX->%`(9:?_@GV:9_$F=N:(7`_3$)SD(`FBN-?[R2#U"'%@B;W;OPA[I%]TA9 XMTGXI0"8`%V`&"`$/D"(J!?1R3<"2``%Q`8GH(MJ(F@&/J%$B!6@^,X`-@(@Z XMHI<H(RH#@*(S@"+*B-(`H&@-8(J2`#:`(VICF(LS@`A)B:ZB,0`H.HI:HJ4H XM)DH"H**6J"JJBWJBFF@IU(E^HKIH+6H&)`$DP"TJ!9``N2@RRHLNH[XH,MJ* XM8J*<&BPJBU:BR*@QNHS>HLAH+KJ,\J+(J"^ZC`*C]H*Y:#$0H\MH#)",VAA+ XMPC5*B]JBG%H[2HQFH_"H43(%;`ZUTA(T`?41(J02%10,&#B``$2)/D`CU+/` XMC(Y0OP4),"6PHB.42T("X``C5`X@ZM5CVIL-@$4)$V14#W0_"E#_J`L0D/H_ XM@@)`*I":``1I,CI"01:[Z`BUD%(5)(!#"I&2`!)IRC=C@&!+0@V@CX8]'>E' XM:I1``0^934I%34",DTZ:(N8_/BE&R@3YH\.=3KI.!!@BZ8PA!1QB-4`_RN49 XMI9,H2>I8F*0':4JJD(Y0+*E+&I%B?C@I4^J1'GMQXB&6)("E/VE8VI1RI&*I XM4'J4'&(V@`4UE4I`:NE8BHB6I`8I2IJ0KJ0-Z0CUDL:D+L!4FF@(&':I)KJH XM)75H*5(*`!6FY>CF@)C*I&PI8>J6%@%E"7L8]O0%"Q`6T`,X%ACI9=HJN`&: XM*6=J%QB8CT4_*O%4B5S3LX"SO0>0Q6K:!OP6JVE02I9J;C;`,#I$):,]P,40 XM=D0$3$]9<`0`!6F'1H"40!TLAV>*FW*F1PLB5!8X=QI+;Q($N`@Z`8T99]VF XM,D`/\"SLILHINC)Q7!/GFMI!._4/N"ED@9WVIB(`$Y!.9A--P6*2$7RG?0%N XM^EN,IT$+$@`8D`'K2F(V!1",2X@1\#48I]7IE`"?E@7Z*:L@JV0,[&E!V@-0 XM%?^I"'`$S$\%*F[JDB2HV,<<H%!D!%Y!&?`O\*<]`$2:H`8!9$`(A!=$,><: XM`%B@A@"%@@T@`HQOYV`1H"BH.SL3,*I$]04EZHGJ!*2H*^II&IO"J*RHC$JC XMQG:JJ6<:HZ*H%U^-VIKZJ#DJD-KLU:BPJ6=*HA:I,VJ0>C0L&7P`08H")*,I XM0)0Z`T2ITR65FD3U#TNJB6JDJJA'0_]0*&"0*RJ4*J5JJ:T;"L#T8*D"@Y:J XMI/ZH3>J16D1%%[MHE%H#_$T(U)O*I.ZH+VH!00.(`"NJ`96FSGQV*I[*75@] XM1*J7&J>"J>:!(5J7NJ5]`!&`F@(=<0`3E&^P`94J!)1OG`!,D!(!!C!!8$`] XMQ@19+C.??8%%#0E!`51WK3$).D`,(`,X"2[)S89TX#W_I[W`JKJJL"JVAB1( XM=;*J"!:)X@"V:I.`J\H`-P#2D04L"3R0JLJK,I\ZXW6`1?6JJ9O/%JRVJJ\J XML0H"W``O`.SU`G!K6``1T!0`H\HJTH$`BI"HZNT1*BPA3Q^G4$/,`,5J$?J% XMVJ$\&^OW>GUQ&=$@:GL1*64<]BD"V*L:)5K'?5*A;!WX^=:)GUDH\2=:Y3@7 XM0M<0AL)FRA]?IU`V<O"G=RA_1I2'7,(:%=V?<9L<FOTU*A8K]R<#T`!5@AXJ XM_H64\F''6E):9R8K2AFIUJ2>Z0*D!?@`%\-`>F:9B\#H+$J-&B6:SZ1"C`H! XM>NJGJ"A<HMMH/*JS>E'8:,\*J(Y0VN@Z:I10IB``L%I"#1*C:;E9"B5GO1UJ XMNI02IG?%C`$%E"6`Z;^C\,P8WN-8X8X.&#%*V6JVGJUH:TB0IF(!>$!BFIRR XMK07$F84%+&HT``\TBY*M:6O>FK:V"JX;VXJ6V@M8@&-*`TBE<$#5"@%1`<0+ XM2?$;?!C#0=6ZFMH&.`#`<Y,2K<:;>,8I9",O@"<Q*Q83T0&?E!=H!".%84A: XM*@TM0.EJNIZNJ*L/</5\-0\C/?%+R!53Z=NZ?10*,^MA^B0XKHEI_[``!1,D XM`,P:I@8%+0`)U:?NKBX`"9";_JXA*8'1LKH!P40:P`/XIXS3U[I$K*PB@`I@ XMO7)O0D`54/$A!YS"RD81<!37P3BFJ7VFS>L,M+(&IN!+8[HDT$JX*V0ZO#*O XMQ:OOBI2N`,*K[@J_&J^ZZ6"Z04VODFKU>KT6`=GK]CH%=*^0T\,!OB)JO<?V XM`+^F`>:KI(J^<FIF*9.0F$*ITT5U<5TD41G&:DJ7#E'$:QK@`[RGB<9BFK5& XMIONK"T"]6J\J`/:JO<9H!.QB9AE:!D;8^-K!-K!](>K#I=*N1^M2*L):3S?L XM`W2TRJQ&ZXHZE9ZP_VL`R\(J9@G&1H%<:&(R[`*;;]@+40!<ZK0^L#X/DT%= XM6!<M`!3E(]@$&FQ&.E?L3)(K6SI@2*]?;/(ZPLZO^RO@"I5.L5,I!7O%7K#M XM*U6J,TD582Q26L("&#NLUOJ07:0#WM6:QD9DAQ@-P,:B/FZL!9O%8K!<[.1: XMQO),=:GT6F)H;S?`#="/:GZW:0QPO)H'>(]C`92VIY:L;LKCV$[&:2=[-/`X XMT1,%5<E>LCR.I&K*]JD/$"I['2QJJRQX*LHVJB/-)ANW'JVC['6`]\P_1*K/ XM*A+43M)3+XO+F@>E[%$JIOJPHXMYH,H:LSBJ+YO+^@K![!"%PR:S/(XARLS> XMLJXB)CM%]:DX;#;[R4:SW*P/Z\TV=^#L,?LICK/;6SG;S`*7Y@$L>\UVLRMJ XM-5O+"K/Z)3#+RTJS/FP]2\JJL[>L/GL=++.V+`[KST*SL>PZ.]!6IN^L#\MO XM$K/;K#DK`BRTJ2P_B\-"M*^L1*O0QK/705D"602T/NR?^LQ*JO=L./LI>K3M XMK$4[TF*T($!9\EMPM)]B#8#2+FHAK4/KTCZS9<F48,MFIIOI9VJ7O:^:Z;/P XM11U!(MGRJIE"%C]M&'4$'65";0_P6Q2U2-!1>P01`>B$_:J93@E,K4BV`!UE XM"Q!4NP`U![U<JUCKS+&,K!A;QQ:R6*P6>\,.JD:`")`$M`%0P!LP!<P!28`8 XM<"\&JE)/FLH$&`%\`%J;U[IN4@!>FYAFL!64%85Z>8^+V@QPD<ZE7BQ@*]:2 XML5XK61H$:#ZNJHN*V%910]22^BFV#2NJ0ZLH/+8=F!3P-'I@E2T.B]F&J7V! XM97NTUJ^EK6C[!JRH&^P6:[7:!C6`\BK6GK%D+1QKE`0!I9"+NL%J'E6`5!'8 XMEIM,@%31C]87%VF&83'``#?JHB`"H+5J+5OKUL*U<JU:,*?NM2C`74O=#@%X XM;9K:UPZ`I>K0BJKJJDW!JBJLOJJ#J^/9K=*J$-"M2MY"%LJG;<BM4@&_ZK2* XMJPZNQBJR:B^TM^8M&7"LUA#V0N,)>_4$O6H6X*S:JLQJM$JU8@'J;90`66"K XMVBJWZJU>J_VMG@E[71_:'A95&XJK&VFYB@7TM4S02G+7=KCV`G:[OMXCSNU; XM&]?>BZ\#95NZV@N]K:8*Q5JJYNI0,ADT$YP"["7!NJL8@IKDAWVL(2MPZ-6E XMK$ZH[;>O>J$YKB3GKTZA_*3OY]9-;=#A\"=0'JQ]P8<0)UB'ZJ=>EQWZ<68H XM=VBV2:QJZ/P)?DFY'0)YB+$F=HG*'/I!@+GWI`PAR'*4(NL`"KB916AN?9A_ XM[0YQ;GZ(YU01',%^!T[TASDH2!`@%F`LP0%&()((=:X9-;;H3CP%2Z'UA`3% XM90H':QB%[4=/X.QHB]QBJW<9[!12C<"`W:8`PJ*J8;V1!0#-38+K81&"+G8J XMXBZWJVER*N(.`0O%=>!BE$U`5$3PX=Z+=\3_%!%PN%(`E6?H5$X?4U'`PC"Z XMMEX:@I_&-CM>1.""+"T=U(T(`D0!/4$+4$W$!E7`@8@Z\JU10-(Q490W'T'K XMUMNRE/)&$]`4](<OY;WVI+`4K=ODB030#*;$;[H4X&1-@7QZ,.P4JN#,@#"4 XM>[YNQ[,A(B)-#6Z"8^@8R8KM`'3PN[6#CK"LV`7-"KQ[C]$$IQOW43D0(U', XM((';AK@#[_8A@(`@#,5O(`?`'\5IX)H'"`M8PPLI28``3X#$@)C!NW/,553L XM#&,KVTGBC"F*U\$O`>R:>`[*LF8C&C%3@<.K^4P!54`3\/X$?'[9LM,5E+PY XM1#56H9&09,$M,<*8$J)!4Q`I;H$G'GNG(,84^HR)X(6`#'CNSL'6>!1N36<P XM(G(*&5A/P)/V!'=93Q#%]@04&-G+U6(!3\#><D/Z'H9!3Q%YU`PB@-$+DZ"@ XM/4%K^#!($G+>9NGH1HIO!F7`PG0B/`/<P2"V`-!!'L`JC#Q@@^*7-_@C2U\& XM<FA8E88#.A$$F&64+,@U`?&D/6_]9E+`'5%BT#<1)!4&0LHV_F22.B)64!#` XM)<GNM1<$:)"/`:&W3%9C%B+YL.B5OM!!'3!L1(I1)BYQ#;9-M\1`<\+ID4YG XM98"V8`%9TT@1,_!;#,<P=K%POD*0YHB#@;Z91N%7/Y&^C=Y-`M`L%ZEOY@MG XM,+]AHN=K[,(%34'T>VRRG:6O]8OZ1@77GGRV_#X,G2\R!OV*OM-OCEC]P@37 XM[^/@$J2_.]KZRT(5,<XO0?+^2K_``OD[_YZ^K$WV*W)R/_`)]]N#]+^?+_@; XM^@+`,)[\.S*8OP4P^JO]ZK]UI?<KO#C`XB]N(0!/P/3O^7O_7L`),/O;_&K` XM_^_X2_V"P`0P]FL!'\#X1PF\_\8,#/#WV\!TP*.O!&SZUK\&L/HK`V?`[B\' XM#/\&P"OP#BP"GP'XK_+[`[>_$:3_*P1#P!^P$5P!C\`PL.8;@IC`W6\0?`,/ XMP1%P5LD"\\`OL`N`^5;!C$'Y%!@NP2?P/0(TR@''`U@`<VC`ZN,&O`5#P44P XM!>P"4\'R61Y@!B>)FR\6O`"CP$^P"JP#V\'V+Q*,=+B(S<[YAA/<"#^`]JL' XMTP=G<!\\`P<%-;`<'/YRP5$P(=P#[VB/<.EW;+)+67`3W`#/P8*P%RP%W\&& XM,!G<";>&&#`3G`?OP9^P`LS_)K\RV"H<"5_!D[`-)@K;P)<P'3P(A\!3<"K\ XM"D/"?#`N#`3OPI;P`UP*:Y*:<!@\!C\!:T!/P/="(H+E(OP24,"M855@.#1% XMEZN_\8HL)TAL<'#R-62=*1E<$;@BM`Q"8X\TP39CRHO]U'N)I<`AZ8$2EUB6 XMT@\B-6$)T<#W%I(O3%RXA*A1HIZ+UF%ZP^EP.`Q"#A/VPKF[GT`>-DF'V0@_ XMK6AO-#Q61@3'(D,L<,R^FP8!&2[)#Z>!=Y8F(@=P(\Q[5(1CXUA18$8\._<& XM<<&851.Z2]9[>/1TK$*EXX*M9*+>H0,SQ))-I*R(3I##"'$<,HREG+*D3MR4 XMU<0[&E"<$W<,.[%9UA/;Q`@DW'DR)L5$\4],B7623S%?5I8-$F/PNDGIK(M0 XMYE7@#YN"6("1T#;JOA;!<Z(WX'R_XDBPJ,D>H*]W5FT`FWE`3_#FU42@KLH` XM;]#"!`D'81NPPFAP*-R5?0I)14\0&`?#>#&B\[G",\4P*/P':[]Z,6(<"_O! XMLW`]=AA;PH(Q^'LM%L*%,20R&?/%DO`Q_!?;!H/Q8(P*HQ.5KQ!D067%-(-9 XMB38X+3&O28%>2AV9\?8+&<<,+N1D'!I;QH0Q"=P9<XRZL3',&P>NMC%N+!IC XMQKVQ8ES$U,:`L7",&X_&Q;$L3!O'QJVP:0P=]\4]"'(,&BO'JL-EG.Q.Q[NQ XM="P9)\?9,66<&R\14:SV6Q&4/ZKB@182IVSDDE!R]@`<B]E)`I=L->O>'/`0 XM!STV011[*E(EW]Q#$3F\C!U:EXDM4GIIB%GL['PG(`!/RI8,>$HL`VF9H)D> XM2`';F_05*]/)]PQ+Q%TQJ(!G:`2C`;(6&W/&OK%WC`5<`4`(H4=/:(K@P5>0 XM!,M@(+)Q_!QKORVR<]PNPLBWL(L\(X_()?*G<")?$)K5BDR0Q,BS\8TLGP') XMN;!-1B*K&B8R'X8B]\A8<0@F)W(2Y0YF""RD!N1#A[;WY03],3AQ4X`Z\@9/ XM&O1!:4*8]SIM@!16T]4))GNO2V'G2!E,,W!F9:$!1VKK&-Q1$.`:_D*/IL80 XM%'.!6)G'9#2%V%V&=#R,4("_4%Z\`1KB&L#@*1/HBET@\=D)85ZYY^#%"5R! XM"*!,.`'Z$XT`%D`!H@,U$>(2+:,!H:Q>9`2E#T2@3-2&`.YMV#K4`+4.9"'` XMT1]CP;I!@70&S^1`DSV6$1B!X[A$C,%BL5MA9HP.D,150"$JR`\#3=H!MIX/ XM"&ZG`SM,)UH'ZK=DAFA:/Q&2\&$2!U*YPB4VH(>=(-I<,,P@VG!8;AL*LBFA XMS67(7L?9MQ:LDS1*H2M:K;GP)&*5$=6Y06Y5Y"K4N5)HT\;[5:$"*Y,;USFY XMC!*4ZV^P&,??:Y;\L9_:899KFVVY:6BHM(8Z18<<FDM17G_YY\;ZY2C,DIP, XM40.PA\45<[>'DJQ]*,3LR<VY[X+&+,H9.$R)-FGM2BC+B:+`[?8%WF[6$!&$ XMNPGRN,M=K+AW9E6A$-<,ZBX(P.Z2A"A#^EJM!1>Z2DAC$YY(^^ZPXN_&S%,$ XMLA+P#AD$[X]0=UD5BRN1$:(>!CC#_W?QT@0-+]$L$DP!&Z]1T/%"'%)#R*L5 XM*!1]EVR!\^J\00#/RQE9:1_+&&+RSED('M';&1B]M,8BZ9_I8TLO'J!0R'A[ XM[YG)`,H;*6:S//6&+P-8GLO6<"Z["^NY]2X]2(#7"P6`O8OSLKLX&RMEKUK, XM%J2]\=O:VXNXO;E&IRCW#KKHV"N#]]V]V@9;H/>RQLT@Y[A`JBS8#?86O@B^ XM2`#A*Y$<OA@%J+/W/1J,+W7B^)(/N2:69/D6:#L:G&'$W(SVF5#H!)/"'C`H XMP@P#PZAPR[;ZTBWR4AOBY[+-4V4E@Q'_%;7OL#&ZIIFZX$KQ&O:^[V.XM$<* XMOZ>!U*3K@1+'+TN1+/G`W7'W:V^:@78,^"OH8<(RI2;IR;3`A7#+ACZ'R*DD XM@CL!#L^]\#)<_B+/];-IHP2;%$EA!BP\C\+]LP=<!]\U`$TP["-SAM&Q^CQM XM)L,X</QK"O-D]'/J*T#7CM3Q+"P\$VJ@KS)\NQ'!OS``K4$W!/EO!TT#3X`3 XM)B^L#"O0OW`&C?YNT.RS[TRI=;X'M`M=09/0%[0)/4.CT"TG%A`#FQ2_,PX] XM0:?`,'0/??HB(@$T$,U!I\]_<`Y-0:=LQ7,<<CP3P`[T7L,9#M'X<Q0];:(. XM@7`2?44WT,FS%CVW0-#PR?=RBYS`4C02G0,KT6#P_9NAF=$$B2V<&,O(P7,I XMM*ZTP73+_MQ"1W0G7#+\0HO1_[,,+4<[T76T&U*]U<AX](\F6;K1%O08W<S1 XM&$TT$8`(,\^+\!KP`]#0$X$=_1CGPK;J_HQ`O]!OM"2=12/2G.$CO$C?T4%R XM'OW\AM&E="$-T##1)_2@EDK#PK)Q+CQ?<L**](!#Z_(KL@6K^V&XNH5344-: XMY+ITR./)7OR9J0J1;$"CTB\'+HT!LXNA]`<]2N_07;`I749#TV5P2.%,&]&/ XM-"P=2<O2D_0V;2)!PSW!]4RHM8EN2$N`V5PR6'1K*%!X&=SP\P)TS#*PB#HL XM#L_1UH.5=LF@P_ETQ[*8[<_M<`'KK=0W!,]/,R#/PWU$/6Q#I7N`C/((Q]2\ XMX<N9_/V<?;@%=-2F=6,#,4`-#J]L&O44,3-;Q`^'0\Q/BP3H]%8Y$53$R\5% XMW#;HB*)S:@SYU9X>,=4@S$C.5J9(O!20Q(N:2;PN/3N2C$J,VWEZPV_/XA*+ XM+RZ<3'S2Z49,L5$\>"HO`MM5T53CQ$]U2!U<3-6"I[`)52_-4EQ1/!4[Q3KQ XM26U58-5Q"UB-%(O56C$<8S-FR%\Q6Y`K$\AE,23!)/[1^L$XQA8[P&XQG1$> XMS\6+4EV,IAT/&2@W?8MLQHQT*_VC?<91R6`L'H_'5EICK,P4UKIT$S.,.=;Y XMVPC=17O02T]P'!XOUJ,Q'=U[#-;%("L=65_-FG5<+!YWUB`2R/4LF$AI==Y` XM.BL84V:0+%D_T<;P&ET<,9B(=?N\62O6J#4WK?_:UM7Q;(T`0]'',5N06R_6 XM@3$M76\BTH3:Q5)$6X4.9VE=&6?'RG56R$E;P3:R2,!@,M=H-!%]0TO'_30? XM-EQ?UL\Q:0T>F];)-26]'5_7N33PO%T?UXIU>HU:QV>]\R6#'E?)C65^Q*J$ XM"NPQNJL]NA:-#7S<.-8G6HU<(LC8QX)7?GR('8OO&WA2M0#(^;4#>G4BD@;R XM^88@)\@A&`VSE="DWRMR$4L0+&@FYX(FSW<[@;'B5ZR56=(OG5T(T\C%J^MA XMRQ;(=#XLLZTJD2>X=DYCR$3G-XE14P25@T$`P8C7G*$\[5Q_U[>UA'$DOW<Z XMLI+,(Z<&]O..1B0#U\4U>_U-@]?<]=Q26=\+*C3`DBP=V?+2CLQ0,-E2]CF' XM91/7Y34W/647V=;#D3T)V@9>=HK<F(G5<B)-&25+R<*!-F(E*[Y8<J4GA&S) XMZU*7#`7LSV!R[>S"CLG\\?&03@_(@)KE@B;;!FHR<HDXNLE2-)P\J3T,<[). XM('?\%&H,R!`<Y,GHV)[<1BS5W>K#F"`+RLM%.AT$&,J`04^0*&\?YJEH,X,^ XMR@Z/I,RJ5,HN#*:L;3PT4X1.UG%D$J\.J-PVB,K@;3I]L^DKJ+(,,%JLRAH: XMSS)%M,HQ2;(+&:B>QB9:4"M;U2+!6TUA]\HU);#L81YBP_*UF\)$P<Y.VW>B XM.95N"^?"+/O-P0L]`32:UOLQO[*YQ`0;BK5L.,@NAF4Z=BD?8M[RM00N?\5K XMP?!9?/[;QZ</^=,$%RPV0^%B,Q3!18P=4N2&Y;)*,^7JN&3*Q(P#Q%[J<IRD XM,;?+8YW&'"^W<?-RP/K[#:Q46\'ZY-9U=X*)0.7ZR^OG7M=^;H<#LQ!6,.MF XM:EMA)P*(".KA;T;FIA`.,W%&<XNYRX+%T(FVN9;=FQLN[-SF@GVX.Q#="NC3 XMB\1N'[Y&XBIOF`S"0730,/2'(Z+`$+B"O4$`V%L$>+U8@`STYY*ZJQT*6B*X XM=FR4L@#0*(YU=C;Y6@\E;^_3#1Q$W48?5E!,.,L)1AC2AOR]X,8,)7S2$Y^! XM5Z#?:%%TRW4P=Q,HXX$)%!!:<'KV64A0T$[*@J87BH@79:9`01DHBBH,IQ$4 XM,L7^R(E7$-QA$,E.$4$<+0]!MK3T)11O]^*=-S0.!P.MD4TD9G.`7!C;M+UE XM`[WW9TB],DPOG4Y,!0<+V&'HV@UJKVKH3JP2&`T@"".(-_];GR%PK-WWR9MQ XM"UH[EXX-BOMJ@.J><@?F;1)`B+.C%6P?LW=T,#XA!OW%M.3A@1)IHAAT([QA XM)US3^WAS%X3>O<'NN&/H`PJ53E2N10#7^P0P!R2AM">I5GM)0/@V[74*25QP XM*P0L:LA!%%`%)`'(@;5W#UY/+D#@*A$89#6!;3)(A*UI@``4!!P%A-FD21K@ XM,TM$V`H!(27!`JNA)F2\"3C>@T7)9"T"<A$#<`HD`52PK'U,YBFUD#$\)P\X XMK3J"\PHL#)O$6[$P^A-!L804`>((=>*1A:WT;0!"@\,%2\$,@(*#!J0#[12V XMHLJ:A[RW,FP?20`*'@;L)ZG;4!*#BZU-N$'XA/\Z7*\:P6*0!<.IY")U7.$W XM`#!Z8]#)EW93T=0DX&:9LF`-<@JGP=;J@!(D+%XRF>@N3'&&-BR'N0W;RG5@ XM)*Y18K#K,.<0W3V;S\W55=S-`]&-<8M$1/?&K=9UW-_GQVTOCY]:Z$`Y=O?+ XM>ES*?>66H1#K\S?(=;D4J\Q-<R_,<2CV9>:Z"J-XQ(P"V``X`$3Z40;=(J4/ XMD(IOS(.XR4V(RH;L!>+:=O<%BRO</6/`WY=KM*.YE@6<*[SBS[QAHFNDB+HN XMXZGKZCJ,NZX[`95F:V<G>FLU?K;.GIH'!;X96.",8T!AC7_C!%,$OI)PX);R XM!U[$@./?^$BS*9?@#,4)KF*HX/L)"TX7?!MF,3INC5]1*PD)7H/;%S<X!5*( XM[.`]>(9ACU?CIFH^/H1C0$9X/Y:$'PT#>=YZ14$667AJH/9%X2/!%+Z]90P5 XM04/ND*/**\ESJH5/Y!3YD.`B<`A@>.3"LISC&CG:*K:N)&>XI=VC-04IN4I> XMAKML`'=-'G!_7HLG>&O>,MQ'MRT>KS9?K#A$ZN-F1+/X(@Y9S=P^>;^*'/ZK X;26YS>(42K'.<0&D>PD0FQVT@&'P,4<Y2<"4` X` Xend END_OF_tests.uu if test 32307 -ne `wc -c <tests.uu`; then echo shar: \"tests.uu\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 5 \(of 5\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 5 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 Bill Rosenkranz |UUCP: {uunet,texsun}!convex!c1yankee!rosenkra Convex Computer Corp. |ARPA: rosenkra%c1yankee@convex.com