[alt.sources] Psroff 2.0 Part 04 of 16

clewis@ecicrl.UUCP (Chris Lewis) (11/17/90)

Submitted-by: Chris Lewis <clewis@ecicrl.uucp>
Archive-name: psroff2.0/Part04

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents:  man/pk2sfp.1.S ps.c utils/hpinterp.c
# Wrapped by clewis@ecicrl on Fri Nov 16 23:35:33 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 4 (of 16)."'
if test -f 'man/pk2sfp.1.S' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'man/pk2sfp.1.S'\"
else
  echo shar: Extracting \"'man/pk2sfp.1.S'\" \(15257 characters\)
  sed "s/^X//" >'man/pk2sfp.1.S' <<'END_OF_FILE'
X.\"Copyright 1988 by Chris Lewis 90/07/18
X.TH PK2SFP 1 local
X.SH NAME
Xpk2sfp,pk2ditwid,pktype,pk2ps \- PK/SFP format font file handling utilities
X.SH SYNOPSIS
X.B pk2sfp
X.BI "[-D" opts "]"
X.BI "[" options "]"
Xfonts ...
X.br
X.B pk2sfp
X.B -m
X.BI "[-D" opts "]"
X.BI "[" options "]"
Xmap font map font ...
X.br
X.B pk2ditwid
X.BI "[-D" opts "]"
X.B "[-S]"
X.B "[-s]"
Xfiles...
X.br
X.B pktype
X.BI "[-v]"
X.BI "[-f" char "]"
X.BI "[-l" char "]"
X.BI "[-D" opts "]"
Xfiles...
X.br
X.B pk2ps
X.B "[-f]"
X.B "[-v]"
X.BI "[-D" opts "]"
Xfiles...
X.SH DESCRIPTION
XThese programs allow you to manipulate PK and SFP format font files,
Xwhich
X.B psroff
Xcan use with Hewlett Packard Laserjet (or compatible) printers.
XThese programs are usually found in %%LIBDIR%%.
X.SH "Converting SFP and PK files: pk2sfp"
X.P
X.B pk2sfp
Xreads each of its argument files, and converts them into HPLJ format
Xfonts (HP SFP format), and outputs them to standard output sorted
Xin ascending order of character code.
XThe output does not normally contain "SET FONT ID" sequences.
XThis is how HP distributes their fonts on floppies.
X.P
X.B pk2sfp
Xconcatenates all the conversions of the input files together on standard
Xoutput.
X.P
X.B pk2sfp
Xwith the
X.B "-m"
Xoption allows you to merge font files, at the same time changing the
Xencoding.
XMost of the options for simple font conversions apply to
X.B pk2sfp
Xwith the
X.B "-m"
Xoption, but merging is covered more completely in "Merging SFP and PK
Xfonts" below.
X.P
X.B pk2sfp
Xcan read both PK and SFP format files (the latter effectively being a
X``no-op'' conversion - which can be useful for checking format validity
Xand changing header characteristics, see below).
X.P
X.B pk2sfp
Xattempts to infer certain header characteristics by the basename
Xof the input font file name if the input font is PK format.
XThe
X.B psroff
Xnaming convention is:
X.BR path / troffname . pointsize . "[pk|sfp]"
X.sp
X.in +.5i
X.nf
XAll ROMAN8 encodings unless MATH8.
XAll 0 strokeweight, unless Bold.
XAll upright, unless Italic
XAll Roman typeface, unless otherwise specified
X
XR	: Normal Roman
XI	: Italic
XB	: Bold
XS	: MATH8 Symbol
XX	: Bold italic
X\&.X	: <typeface> Bold italic
X\&.I	: <typeface> Italic
X\&.B	: <typeface> Bold
X\&.R	: <typeface> Normal
XH or H.	: Helvetica typeface
XC or C.	: Courier typeface
X          typefaces should be extended.
X.fi
X.in -.5i
X.P
X.B pk2sfp
Xwill pass through SFP characteristics unchanged, unless you change them
Xexplicitly (see below).
X.P
X.SH "Additional options for pk2sfp"
X.P
XThe
X.BI "-s" na
Xoption will set the symbol set.
XEg:
X.B "-s8U"
Xsets the symbol set to "ROMAN8".
X.P
X.BI "-t" "0|1"
Xsets the orientation to ``upright'' (0) or ``italic'' (1).
X.P
X.BI "-w" n
Xsets the stroke weight, 0 is normal, -7 is very light and 7 is very
Xbold.
X-3 and 3 are traditional values.
X.P
X.BI "-f" n
Xsets the typeface to ``n''.
XFor example, Times Roman is ``5''.
X.P
X.BI "-i" n
Xcauses
X.B pk2sfp
Xto emit fontid sequences in front of each downloaded
Xfont, incrementing the id by one for each font, starting with number
X.IR n .
XFor compatibility with
X.B psroff
Xit is suggested that ``n'' be at least 1000.
X.P
XSpecifying
X.B "-v"
Xrequests pk2sfp to tell you what it's doing on stderr.
X.P
XThe
X.B "-S"
Xtells
X.B pk2sfp
Xthat it's dealing with a font intended for
X.BR psroff "'s"
XS font.
XThis has no effect unless
X.B "-p"
Xis specified.
X.P
XThe
X.B "-p"
X("partial downloading") feature indicates to
X.B pk2sfp
Xthat the fonts are intended for use with
X.B psroff
Xand that characters that aren't used by
X.B psroff
X(eg: half of a ROMAN8 font isn't used) will be dropped from the
Xoutput font.
XThe font being read are assumed to be ROMAN8 fonts and the list of
Xvalid characters will correspond to the characters that
X.B psroff
Xneeds from ROMAN8 sets.
XSpecify
X.B "-S"
Xtoo if you want to do this to MATH8 fonts which are intended for
Xthe characters that
X.B psroff
Xneeds from the MATH8 set.
X.P
XThe
X.B "-P"
Xoption tells pk2sfp to mark the fonts it downloads as permanent,
Xwhich means they are not cleared by a software reset, only explicit
Xdeletions or printer power-offs.
XThis option does not do anything unless
X.BI "-i" n
Xspecified as well.
X.P
XPlease note: the tables used to control
X.B "-p"
Xare compiled into
X.BR pk2sfp .
XIf you change the character translations in lj.c or lj.fonts, you
Xwill have to rebuild
X.BR pk2sfp .
XThe partial option should not be used for auxiliary fonts (fonts
Xwhich supply characters not in ROMAN8 or MATH8).
XUse the
X.B "-m"
X(merge) options for creating specialized reduced size font sets for
Xsuch fonts.
X.P
XThe following example shows how you could preload your laserjet
Xwith fonts (in sizes 8, 9, 10, 11 and 12).
XThis demonstrates the use of
Xthe
X.BR -p "," -P ","
Xand
X.B -S
Xoptions to use up as little Laserjet memory as possible.
X(These fonts should be marked ``b'' (builtin) in
X.IR lj.fonts ")."
X.sp
X.in +.25i
X.nf
X F=%%LJF%%
X pk2sfp -pP -i1000 $F/R.[89].pk $F/R.1[0-2].pk | lp
X pk2sfp -SpP -i1006 $F/S.[89].pk $F/S.1[0-2].pk | lp
X.fi
X.in .-25i
X.sp
X.P
XAll of the preceding options take place on all of the fonts specified in
Xthe command line.
XMost of the options perform no sanity checks on their arguments.
XThe reader is cautioned to read the HP manuals before attempting anything
Xfancy with options that affect header descriptors.
X.SH "Merging PK and SFP fonts: pk2sfp -m"
X.P
XThere are a wealth of fonts and font formats in the world.
XPerforming simple conversions between one format and the other would
Xlead to you having a considerably bigger repertoire of fonts.
XRight?
X.P
XWell, not always.
XNot only to the formats change from one font format to another, but
X.B encodings
Xdo too.
XIf you simply converted Knuth's fonts in PK format to SFP and used them
Xon your Laserjet you're bound to be disappointed, because a character in
XKnuth's font isn't necessarily in the same place in standard SFP fonts.
XEg: If you used the hex code 0x7B to print a left brace-bracket (that's
Xwhat it is in ASCII and ROMAN8 fonts right?), you'd find that in Knuth's
XCMR font you'll get a "ff" ligature instead.
XWorse, other ASCII/ROMAN8 characters don't exist in CMR at all.
X.P
XSo, font conversion often needs more than simple format translation
Xto work out the way you want.
X.P
XThe
X.B "-m"
Xoption to
X.B pk2sfp
Xis intended to do just that: take characters from a combination of
Xfonts, change encodings as necessary, and create one output font.
X.BR Psroff "'s"
XHP Laserjet S font is created in this way from four separate PK fonts.
X.P
XThe
X.B "-m"
Xoption to
X.B pk2sfp
Xindicates that preceding each font file specified a map file will be
Xgiven.
XEach font file will be appended together (with only one SFP header)
Xwith the translations specified by the map files and copied to
Xstandard output.
XAny character not mentioned in a map file is not copied.
XThe map file applies to the font files following until overridden
Xby the next map file.
XThe map file specifies the translations with lines of the following format:
X.sp
X.in +.5i
X.nf
Xfrom  to  description
X.fi
X.in -.5i
X.sp
X.P
X.I From
Xspecifies the character in the font file to be selected.
XAny character that doesn't match a ``from'' line will not be
Xcopied to the output.
X.I To
Xspecifies what character number the ``from'' character should be
Xchanged to.
XIf ``to'' is omitted, it is assumed to be the same as ``from''.
XThe description is free form text and is ignored.
XFrom, to and description are separated by white space.
XEmpty lines or lines beginning with "#" are comments.
X.P
X``From'' and ``to'' can be specified in any of the following formats:
Xa single non-numeric character other than ``#'',
Xa decimal number starting with a non-zero digit,
Xan octal number consisting of a zero digit followed by numeric digits,
Xor hexadecimal consisting of a zero digit, followed by 'x' or 'X', followed
Xby digits and upper or lower case 'a' through 'f'.
XIf the ``to'' string is a single double quote ("), it is duplicated
Xfrom the ``from'' string.
XThe error checking isn't very exhaustive, so it is recommended that you
Xuse the
X.B -v
Xoption to check things.
XThe
X.B -v
Xoption will also give you a very verbose description of what characters
Xits translating and what characters it couldn't find.
X.P
XThere are some examples of this in the source tree for
X.B psroff ,
Xthat generate a ROMAN8 and MATH8 SFP in 10 points.
XLook in utils/Makefile for ``testmerge'', utils/maps contains some
Xuseful translation maps, and utils/fonts contains a few PK files for
Xyour experimentation.
X.B Psroff
Xis shipped with PK format font files that were created by use of this
Xutility.
X.SH "Creating width tables: pk2ditwid"
X.P
X.B pk2ditwid
Xis used to generate a ditroff format width table file (used by
X.B psroff
Xwidth table installation via
X.B gfnttab
Xand
X.BR dit2catwid )
Xfrom PK or SFP font files.
XThe output files are generated in the current directory with the
Xsame name as the basename of the input files, with a ".WID"
Xsuffix.
X.P
XThe
X.B -S
Xoption indicates to
X.B pk2ditwid
Xthat the font file is a
XPK or SFP used for the symbol font, otherwise
X.B pk2ditwid
Xassumes that it is a normal font.
X.P
XThe
X.B -s
Xoption tells
X.B pk2ditwid
Xto shut up and do the best it can.
XOrdinarily
X.B pk2ditwid
Xis extremely chatty about which characters it could find etc.,
Xwhich is rarely of major interest to the user.
XWhich is why
X.BR psroff "'s"
Xinstallation script puts
X.BR pk2ditwid "'s"
Xoutput in log files and makes no attempt to show them to the user.
X.P
X.BR pk2ditwid "'s"
Xexact operation is somewhat bizarre, the following is a simplified
Xdescription:
X.P
XNormally,
X.B psroff
Xworks with pure ROMAN8 and MATH8
Xencoded fonts for normal and symbol font sets respectively.
X(ROMAN8 and MATH8 are two of HP's standard "char-to-glyph" mapping tables).
XHowever,
XThe MATH8 and ROMAN8 encodings do not exactly reflect CAT
X.BI troff 's
Xdivisions of characters.
XIn
X.BR troff2ps 's
Xbackend drivers, there are tables that correspond to CAT normal and symbol,
Xwhich are indexed by CAT code to select which HP font and character sequence
Xshould be emitted by the backend to print a specific CAT character.
X.P
XMost CAT codes are single HP characters, but a few are done by concatenation
X(for example \e(34 may be) or overstrike
X(\e(co may be).
X.P
X.B pk2ditwid
Xuses the backend tables and reads each of the font files given as arguments.
XIt then generates a ditroff-like width table that contains width information
Xfor each sequence of HP characters needed to generate a CAT character.
XThe width tables are fairly simple, and contain three fields of principle
Xinterest:
X.P
XColumn one is the CAT
X.B troff
Xcharacter name.
XSingle characters are themselves, dual characters are prefixed by "\e("
Xin
X.BR troff .
X.P
XThe second column indicates the width of that character in 1/300th's of an
Xinch when the character is printed at 10 points.
X(Which are the default
X.BR gfnttab / dit2catwid
Xsettings)
X.P
XThe third column is the kerning information, and is a number formed
Xby or'ing a 1 and/or 2 together.
XA ``1'' denotes an descender (eg: ``g''),
Xand a ``2'' denotes a character with an ascender (eg: ``k'').
X.P
XPlease note this is only ditroff-\f3like\fP \(em the output is not
Xintended to go through real
X.B makedev
Xwhich will probably complain about multiple-character emit sequences and
Xmissing directives.
X.P
XThe wierdness comes from the fact that it's possible to override the
XCAT character to HP sequence translation by adding directives to the
X.I lj.fonts
Xfile but the sequences are built-in (so I'm lazy...) to
X.BR pk2ditwid .
XIf you choose to add in translation overrides to
X.IR lj.fonts ,
Xyou will have to recompile
X.B pk2ditwid
Xand rerun the width table build and install procedures
Xto recompute and install the new width tables.
XThe Makefile uses the
X.B troff2ps
Xbinary to generate a compileable table of translation sequences, using
Xboth the built-in backend map plus the
X.I lj.fonts
Xoverride you've specified,
Xplus the mkenctab shell script to generate the pk2ditwid tables.
XThis is so durn complicated, that I simply automated it all:
Xin the
X.B psroff
Xsource directory area, change
X.B lib/lj.fonts
Xto reflect the translations you need,
Xand rebuild and reinstall
X.BR psroff .
X.P
XIf you're just adding new fonts to
X.BR psroff 's
Xrepertoire, this isn't all necessary, just install the fonts into
X%%LJF%% (using the proper naming convention),
Xupdate
X.IR lj.fonts ,
Xand go into the widths source directory and type ``make ljwidths widths''
Xthen su to root and ``make installwidths''.
X.P
X.B pk2ditwid
Xneed only be run on one font in each family, and by default, the build
Xprocedure runs
X.B pk2ditwid
Xonce each font (in the size closest to 10) that it finds in the
X%%LJF%% directory.
X.SH "Examining PK and SFP font files: pktype"
X.P
X.B pktype
Xreads PK and SFP format files and generates files suffixed with ".D"
Xwhich contain a description of the font and each character.
XIf the
X.B "-v"
Xoption is specified, an approximation of the character image is displayed
Xtoo.
XThe
X.BI "-f" char
Xand
X.BI "-l" char
Xoptions allow you to specify a range of characters to print, where
Xthe
X.B -f
Xspecifies the first character, and
X.B -l
Xspecifies the last character.
X.SH "Displaying PK and SFP font files: pk2ps"
X.P
X.B pk2ps
Xtakes each of the specified files and generates bitmap Postscript
Xfonts and appends to each commands to draw a table.
XThe table contains each character in the font, and below it are
Xdecimal, hexidecimal and octal numbers representing the character code.
XThe output of
X.B pk2ps
Xis on standard output.
X.P
XThe
X.B -f
Xoption causes
X.B pk2ps
Xto omit the table printing commands and some of the extra Postscript, leaving
Xonly the Postscript font definition.
XThe resultant output can then be used as a Postscript font (via inclusion
Xin ps.lib etc.).
XThe font is named for the basename of the filename.
X``<path>/cmr10.358pk'' will be called ``cmr10''.
XThe font is supposedly properly scaled, so Postscript ``scalefont'' will
Xwork normally and generate the size font you expect.
XWarning: this uses bitmapped fonts: displaying these characters at
Xconsiderably
Xlarger sizes or at odd multiples of the ``true'' size (the size of the
Xexample is actually 10 * 358 / 300) may lead to some objectionable
Xjaggies.
X.P
XIn all four utilities, the
X.BI "-D" opts
Xoption allows you to turn on debugging.
XSee
X.BR troff2ps (1)
Xfor further information.
XNote: if DEBUG compiled out, this will not be available.
X.SH FILES
X.if t .ta 2.5i
X.if n .ta 3.5i
X%%LJF%%	troff2ps LJ font directory.
X.br
X%%LIBDIR%%/lib/lj.fonts	LJ font definitions and translation overrides.
X	not read by pk2sfp/pktype/pk2ditwid
X.SH "BUGS"
X.B pk2sfp
Xshould really have multiple output files when requested by an option.
X.B pk2ditwid
Xand
X.B pk2sfp
Xshould be able to read the
X.I lj.fonts
Xfile instead of being recompiled.
X.B pk2ditwid
Xonly understands backspace or character concatenation sequences
X(eg: "a\010b" or "ab"),
Xany translation that contains any other escape sequence will not be
Xparsed properly and may generate bizarre widths, though it will
Xbe moderately sane if all of the characters in the escape sequence
Xare nonprintable (or not in the font file).
XSuch escape sequences may also affect operation of
X.B pk2sfp "'s"
Xpartial downloading feature (by including characters that you don't
Xreally need - which is harmless).
X.SH "SEE ALSO"
Xtroff2ps(1L), \fIlj.fonts\fP,
XHewlett Packard's HP Laserjet Reference Manuals.
X.SH AUTHOR
XWritten by Chris Lewis
END_OF_FILE
  if test 15257 -ne `wc -c <'man/pk2sfp.1.S'`; then
    echo shar: \"'man/pk2sfp.1.S'\" unpacked with wrong size!
  fi
  # end of 'man/pk2sfp.1.S'
fi
if test -f 'ps.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ps.c'\"
else
  echo shar: Extracting \"'ps.c'\" \(18467 characters\)
  sed "s/^X//" >'ps.c' <<'END_OF_FILE'
X/*	Copyright 1985, 1986, 1987, 1988 Chris Lewis
X		All Rights Reserved
X
X    Permission to copy and further distribute is freely given provided
X    this copyright notice remains intact and that this software is not
X    sold for profit.
X
X	Project:	Generic Troff drivers
X	Module:		ps.c
X	Author: 	Chris Lewis
X	Specs:		PostScript driver
X */
X
X#include "defs.h"
X
X#ifdef	PS
X#include "ps.h"
X
X#ifndef	lint
Xstatic char SCCSid[] =
X    "@(#)ps.c: 2.2 Copyright 90/10/12 13:09:32 Chris Lewis";
X#endif
X
X/*	ps.c will generate some additional "print" commands to cause
X	the printer to "print" back who did the job, and how long it
X	took.  define NOCHATTER if you don't want this.
X */
Xstatic long charCount;
X
X#ifdef	FORM
Xstatic char Overlay[100] = {""};
X#endif
X
X#define	USED	01
X
Xstruct troff2befont psStdFont[108] = {
X
X/*	Note on X-shift, Y-shift and point scale factor:
X	The first two are shifts in the baseline position of the
X	character, and the third is a multiplier of the point size.
X	If they are zero, nothing happens.  If they are non-zero,
X	they are first multiplied by .01, then (in the case of the
X	shifts), multiplied by the current points to get a shift
X	value in TROFF2PS[XY] coordinates.  In the case of point scale
X	factor, it is multiplied by <currentpointsize> * .01 and becomes
X	the pointsize of the sequence to be emitted.
X */
X/*          +-------------------------------- Troff character number
X	    |
X            |    +--------------------------- N: standard fonts
X            |    |                            S: symbol font
X            |    |                            D: draw macro
X            |    |                            n: new font
X            |    |
X            |    |  +------------------------ X-shift
X            |    |  |                         Note: positive is right.
X            |    |  |
X            |    |  |  +--------------------- Y-shift
X            |    |  |  |                      Note: positive is up.
X            |    |  |  |
X            |    |  |  |  +------------------ Point scale factor
X            |    |  |  |  |
X            |    |  |  |  |   +-------------- Sequence
X            |    |  |  |  |   |
X            v    v  v  v  v   v */
X	/*  0*/	{N, 0, 0, 0, "h"},
X	/*  1*/	{N, 0, 0, 0, "t"},
X	/*  2*/	{N, 0, 0, 0, "n"},
X	/*  3*/	{N, 0, 0, 0, "m"},
X	/*  4*/	{N, 0, 0, 0, "l"},
X	/*  5*/	{N, 0, 0, 0, "i"},
X	/*  6*/	{N, 0, 0, 0, "z"},
X	/*  7*/	{N, 0, 0, 0, "s"},
X	/*  8*/	{N, 0, 0, 0, "d"},
X	/*  9*/	{N, 0, 0, 0, "b"},
X	/* 10*/	{N, 0, 0, 0, "x"},
X	/* 11*/	{N, 0, 0, 0, "f"},
X	/* 12*/	{N, 0, 0, 0, "j"},
X	/* 13*/	{N, 0, 0, 0, "u"},
X	/* 14*/	{N, 0, 0, 0, "k"},
X	/* 15*/	{N, 0, 0, 0, NOC},
X	/* 16*/	{N, 0, 0, 0, "p"},
X	/* 17*/	{D, 0, 0, 0, "do34em"},
X	/* 18*/	{N, 0, 0, 0, ";"},
X	/* 19*/	{N, 0, 0, 0, NOC},
X	/* 20*/	{N, 0, 0, 0, "a"},
X	/* 21*/	{N, 0, 0, 0, "_"},
X	/* 22*/	{N, 0, 0, 0, "c"},
X	/* 23*/	{N, 0, 0, 0, "`"},
X	/* 24*/	{N, 0, 0, 0, "e"},
X	/* 25*/	{N, 0, 0, 0, "'"},
X	/* 26*/	{N, 0, 0, 0, "o"},
X	/* 27*/	{D, 0, 0, 0, "do14"},
X	/* 28*/	{N, 0, 0, 0, "r"},
X	/* 29*/	{D, 0, 0, 0, "do12"},
X	/* 30*/	{N, 0, 0, 0, "v"},
X	/* 31*/	{N, 0, 0, 0, "-"},
X	/* 32*/	{N, 0, 0, 0, "w"},
X	/* 33*/	{N, 0, 0, 0, "q"},
X	/* 34*/	{N, 0, 0, 0, "/"},
X	/* 35*/	{N, 0, 0, 0, "."},
X	/* 36*/	{N, 0, 0, 0, "g"},
X	/* 37*/	{D, 0, 0, 0, "do34"},
X	/* 38*/	{N, 0, 0, 0, ","},
X	/* 39*/	{N, 0, 0, 0, "&"},
X	/* 40*/	{N, 0, 0, 0, "y"},
X	/* 41*/	{N, 0, 0, 0, NOC},
X	/* 42*/	{N, 0, 0, 0, "%"},
X	/* 43*/	{N, 0, 0, 0, NOC},
X	/* 44*/	{N, 0, 0, 0, "Q"},
X	/* 45*/	{N, 0, 0, 0, "T"},
X	/* 46*/	{N, 0, 0, 0, "O"},
X	/* 47*/	{N, 0, 0, 0, "H"},
X	/* 48*/	{N, 0, 0, 0, "N"},
X	/* 49*/	{N, 0, 0, 0, "M"},
X	/* 50*/	{N, 0, 0, 0, "L"},
X	/* 51*/	{N, 0, 0, 0, "R"},
X	/* 52*/	{N, 0, 0, 0, "G"},
X	/* 53*/	{N, 0, 0, 0, "I"},
X	/* 54*/	{N, 0, 0, 0, "P"},
X	/* 55*/	{N, 0, 0, 0, "C"},
X	/* 56*/	{N, 0, 0, 0, "V"},
X	/* 57*/	{N, 0, 0, 0, "E"},
X	/* 58*/	{N, 0, 0, 0, "Z"},
X	/* 59*/	{N, 0, 0, 0, "D"},
X	/* 60*/	{N, 0, 0, 0, "B"},
X	/* 61*/	{N, 0, 0, 0, "S"},
X	/* 62*/	{N, 0, 0, 0, "Y"},
X	/* 63*/	{N, 0, 0, 0, "F"},
X	/* 64*/	{N, 0, 0, 0, "X"},
X	/* 65*/	{N, 0, 0, 0, "A"},
X	/* 66*/	{N, 0, 0, 0, "W"},
X	/* 67*/	{N, 0, 0, 0, "J"},
X	/* 68*/	{N, 0, 0, 0, "U"},
X	/* 69*/	{N, 0, 0, 0, "K"},
X	/* 70*/	{N, 0, 0, 0, "0"},
X	/* 71*/	{N, 0, 0, 0, "1"},
X	/* 72*/	{N, 0, 0, 0, "2"},
X	/* 73*/	{N, 0, 0, 0, "3"},
X	/* 74*/	{N, 0, 0, 0, "4"},
X	/* 75*/	{N, 0, 0, 0, "5"},
X	/* 76*/	{N, 0, 0, 0, "6"},
X	/* 77*/	{N, 0, 0, 0, "7"},
X	/* 78*/	{N, 0, 0, 0, "8"},
X	/* 79*/	{N, 0, 0, 0, "9"},
X	/* 80*/	{N, 0, 0, 0, "*"},
X	/* 81*/	{N, 0, 0, 0, "\\261"},
X	/* 82*/	{N, 0, 0, 0, "\\256"},
X	/* 83*/	{N, 0, 0, 0, "\\257"},
X	/* 84*/	{D, 0, 0, 0, "doff"},
X	/* 85*/	{N, 0, 0, 0, "\\242"},
X	/* 86*/	{D, 0, 0, 0, "doFl"},
X	/* 87*/	{D, 0, 0, 0, "doFi"},
X	/* 88*/	{N, 0, 0, 0, "\\("},
X	/* 89*/	{N, 0, 0, 0, "\\)"},
X	/* 90*/	{N, 0, 0, 0, "["},
X	/* 91*/	{N, 0, 0, 0, "]"},
X	/* 92*/	{S, 0, 0, 0, "\\260"},
X	/* 93*/	{N, 0, 0, 0, "\\262"},
X	/* 94*/	{N, 0, 0, 0, "="},
X	/* 95*/	{S, 0, 0, 0, "\\322"},
X	/* 96*/	{N, 0, 0, 0, ":"},
X	/* 97*/	{N, 0, 0, 0, "+"},
X	/* 98*/	{N, 0, 0, 0, NOC},
X	/* 99*/	{N, 0, 0, 0, "!"},
X	/*100*/	{N, 0, 0, 0, "\\267"},
X	/*101*/	{N, 0, 0, 0, "?"},
X	/*102*/	{S, 0, 0, 0, "\\242"},
X	/*103*/	{N, -60, 0, 0, "|"},
X	/*104*/	{N, 0, 0, 0, NOC},
X	/*105*/	{S, 0, 0, 0, "\\323"},
X	/*106*/	{D, 0, 0, 0, "dosq"},
X	/*107*/	{N, 0, 0, 0, "$"},
X    };
X
Xstruct troff2befont psSymFont[] = {
X/*          +-------------------------------- Troff character number
X	    |
X            |    +--------------------------- N: standard fonts
X            |    |                            S: symbol font
X            |    |                            D: draw macro
X            |    |                            n: new font
X            |    |
X            |    |  +------------------------ X-shift (scaled by point)
X            |    |  |                         Note: positive is right.
X            |    |  |
X            |    |  |  +--------------------- Y-shift (scaled by point)
X            |    |  |  |                      Note: positive is up.
X            |    |  |  |
X            |    |  |  |  +------------------ Point scale factor
X            |    |  |  |  |
X            |    |  |  |  |   +-------------- Sequence
X            |    |  |  |  |   |
X            v    v  v  v  v   v */
X	/*  0*/	{S, 0, 0, 0, "\\171"},
X	/*  1*/	{S, 0, 0, 0, "\\161"},
X	/*  2*/	{S, 0, 0, 0, "\\156"},
X	/*  3*/	{S, 0, 0, 0, "\\155"},
X	/*  4*/	{S, 0, 0, 0, "\\154"},
X	/*  5*/	{S, 0, 0, 0, "\\151"},
X	/*  6*/	{S, 0, 0, 0, "\\172"},
X	/*  7*/	{S, 0, 0, 0, "\\163"},
X	/*  8*/	{S, 0, 0, 0, "\\144"},
X	/*  9*/	{S, 0, 0, 0, "\\142"},
X	/* 10*/	{S, 0, 0, 0, "\\170"},
X	/* 11*/	{S, 0, 0, 0, "\\150"},
X	/* 12*/	{S, 0, 0, 0, "\\146"},
X	/* 13*/	{S, 0, 0, 0, "\\165"},
X	/* 14*/	{S, 0, 0, 0, "\\153"},
X	/* 15*/	{S, 0, 0, 0, NOC},
X	/* 16*/	{S, 0, 0, 0, "\\160"},
X	/* 17*/	{N, 0, 0, 0, "@"},
X	/* 18*/	{S, 0, 0, 0, "\\257"},
X	/* 19*/	{S, 0, 0, 0, NOC},
X	/* 20*/	{S, 0, 0, 0, "\\141"},
X	/* 21*/	{S, 0, 0, 0, "\\174"},
X	/* 22*/	{S, 0, 0, 0, "\\143"},
X	/* 23*/	{N, 0, 0, 0, "\\042"},
X	/* 24*/	{S, 0, 0, 0, "\\145"},
X	/* 25*/	{S, 0, 0, 0, "\\075"},
X	/* 26*/	{S, 0, 0, 0, "\\157"},
X	/* 27*/	{S, 0, 0, 0, "\\254"},
X	/* 28*/	{S, 0, 0, 0, "\\162"},
X	/* 29*/	{S, 0, 0, 0, "\\255"},
X	/* 30*/	{S, 0, 0, 0, "\\164"},
X	/* 31*/	{4, 0, 0, 0, "O"},
X	/* 32*/	{N, 0, 0, 0, "\\134"},
X	/* 33*/	{S, 0, 0, 0, "\\131"},
X	/* 34*/	{D, 0, 0, 0, "BellSymbol"},
X	/* 35*/	{S, 0, 0, 0, "\\245"},
X	/* 36*/	{S, 0, 0, 0, "\\147"},
X	/* 37*/	{S, 0, 0, 0, "\\312"},
X	/* 38*/	{S, 0, 0, 0, "\\265"},
X	/* 39*/	{S, 0, 0, 0, "\\336"},
X	/* 40*/	{S, 0, 0, 0, "\\167"},
X	/* 41*/	{S, 0, 0, 0, NOC},
X	/* 42*/	{S, 0, 0, 0, "\\321"},
X	/* 43*/	{S, 0, 0, 0, NOC},
X	/* 44*/	{S, 0, 0, 0, "\\106"},
X	/* 45*/	{S, 0, 0, 0, "\\121"},
X	/* 46*/	{S, 0, 0, 0, "\\127"},
X	/* 47*/	{S, 0, 0, 0, "\\310"},
X	/* 48*/	{4, 0, 0, 0, "M"},
X	/* 49*/	{S, 0, 0, 0, "\\126"},
X	/* 50*/	{S, 0, 0, 0, "\\114"},
X	/* 51*/	{S, 0, 0, 0, "\\055"},
X	/* 52*/	{S, 0, 0, 0, "\\107"},
X	/* 53*/	{S, 0, 0, 0, "\\362"},
X	/* 54*/	{S, 0, 0, 0, "\\120"},
X	/* 55*/	{S, 0, 0, 0, "\\314"},
X	/* 56*/	{S, 0, 0, 0, "\\311"},
X	/* 57*/	{N, 0, 0, 0, "\\176"},
X	/* 58*/	{S, 0, 0, 0, "\\266"},
X	/* 59*/	{S, 0, 0, 0, "\\104"},
X	/* 60*/	{S, 0, 0, 0, "\\326"},
X	/* 61*/	{S, 0, 0, 0, "\\123"},
X	/* 62*/	{S, 0, 0, 0, "\\273"},
X	/* 63*/	{S, 0, 0, 0, "\\076"},
X	/* 64*/	{S, 0, 0, 0, "\\130"},
X	/* 65*/	{S, 0, 0, 0, "\\074"},
X	/* 66*/	{S, 0, 0, 0, "\\244"},
X	/* 67*/	{S, 0, 0, 0, "\\307"},
X	/* 68*/	{S, 0, 0, 0, "\\125"},
X	/* 69*/	{S, 0, 0, 0, "\\330"},
X	/* 70*/	{4, 0, 0, 0, "J"},
X	/* 71*/	{4, 0, 0, 0, "B"},
X	/* 72*/	{4, 0, 0, 0, "A"},
X	/* 73*/	{4, 0, 0, 0, "C"},
X	/* 74*/	{4, 0, 0, 0, "D"},
X	/* 75*/	{4, 0, 0, 0, "E"},
X	/* 76*/	{4, 0, 0, 0, "F"},
X	/* 77*/	{4, 0, 0, 0, "G"},
X	/* 78*/	{4, 0, 0, 0, "K"},
X	/* 79*/	{4, 0, 0, 0, "I"},
X	/* 80*/	{4, 0, 0, 0, "H"},
X	/* 81*/	{S, 0, 0, 0, "\\264"},
X	/* 82*/	{S, 0, 0, 0, "\\270"},
X	/* 83*/	{S, 0, 0, 0, "\\261"},
X	/* 84*/	{S, 0, 0, 0, "\\243"},
X	/* 85*/	{S, 0, 0, 0, "\\263"},
X	/* 86*/	{S, 0, 0, 0, "\\272"},
X	/* 87*/	{S, 0, 0, 0, "\\271"},
X	/* 88*/	{S, 0, 0, 0, "\\173"},
X	/* 89*/	{S, 0, 0, 0, "\\175"},
X	/* 90*/	{N, 0, 0, 0, "\\302"},
X	/* 91*/	{N, 0, 0, 0, "\\301"},
X	/* 92*/	{N, 0, 0, 0, "\\303"},
X	/* 93*/	{N, 0, 0, 0, "\\043"},
X	/* 94*/	{S, 0, 0, 0, "\\334"},
X	/* 95*/	{S, 0, 0, 0, "\\316"},
X	/* 96*/	{N, 0, 0, 0, "\\304"},
X	/* 97*/	{S, 0, 0, 0, "\\306"},
X	/* 98*/	{S, 0, 0, 0, NOC},
X	/* 99*/	{N, 0, 0, 0, "\\263"},
X	/*100*/	{4, 0, 0, 0, "L"},
X	/*101*/	{S, 0, 0, 0, "\\052"},
X	/*102*/	{S, 0, 0, 0, "\\315"},
X	/*103*/	{4, 0, 0, 0, "N"},
X	/*104*/	{S, 0, 0, 0, NOC},
X	/*105*/	{S, 0, 0, 0, "\\053"},
X	/*106*/	{S, 0, 0, 0, "\\256"},
X	/*107*/	{N, 0, 0, 0, "\\247"},
X};
X
XpsPage() {
X    if (!currentPage)
X	return;
X    printf("hits misses\n");
X    printf("PageSave restore\n");
X    printf("/misses exch def /hits exch def\n");
X    printf("ShowPage\n");
X    pagePending = 1;
X}
X
Xstatic
XdoPageStart() {
X    currentPage++;
X    printf("%%%%Page: ? %d\n", currentPage);
X#ifdef	FORM
X    printf("/Form { %s } def\n",
X	Overlay[0] == '+' ? (Overlay[0] = '\0', Overlay+1) : Overlay);
X#endif
X    printf("/PageSave save def\n");
X    pagePending = 0;
X    printf("StartPage\n");
X}
X
XpsSetFont(font, points)
Xint font, points; {
X    if (lastPoints != points || font != lastFont) {
X	struct fonttable *fp = &fonttable[font];
X	if (fp->fontSeq && *fp->fontSeq && !(fp->flags&USED)) {
X	    char buffer[512];
X	    int n;
X	    FILE *f = fopen(fp->fontSeq, "r");
X	    if (!f) {
X		fprintf(stderr, "%s: cannot open fontfile %s\n",
X		    progname, fp->fontSeq);
X	    } else {
X		DBP((D_BEND,"Downloading %s\n", fp->fontSeq));
X		while((n = fread(buffer, 1, sizeof(buffer), f)) > 0) {
X		    fwrite(buffer, 1, n, stdout);
X		}
X		fclose(f);
X	    }
X	}
X
X	fp->flags |= USED;
X#ifdef	FONTMACRO
X	printf("/%s %d SetFont\n", fp->fontName, points);
X#else
X	printf("/%s dup /curFont exch def findfont\n",
X	    fp->fontName);
X	printf("%d dup /curPoints exch def scalefont setfont\n", points);
X#endif
X	lastPoints = points;
X	lastFont = font;
X    }
X}
X
Xint indraw = 0;
X
XpsChar(x, y, font, points, troffChar, sequence)
Xint x, y;
Xint font, points, troffChar;
Xregister char *sequence; {
X    register int nx = TROFF2PSX(x), ny = TROFF2PSY(y);
X    register struct troff2befont *rp;
X
X    if (pagePending) {
X	resetState();
X	doPageStart();
X    }
X
X    if (font < 0) {
X#ifdef	TRY
X	if (!indraw) {
X#endif
X	    printf("newpath\n");
X	    emitnum(nx);
X	    putchar(' ');
X	    emitnum(ny);
X	    printf(" moveto\n");
X	    indraw = 1;
X#ifdef	TRY
X	}
X#endif
X	return;
X#ifdef	TRY
X    } else if (indraw) {
X	printf("stroke\n");
X	indraw = 0;
X#endif
X    }
X
X    charCount++;
X
X    DBP((D_BEND,"BEFORE (troffChar,x,y,font,points) = (%d,%d,%d,%d,%d)\n",
X	troffChar, x, y, font, points));
X    if (font == 3) {
X	rp = &be->besymfont[troffChar];
X    } else {
X	rp = &be->bestdfont[troffChar];
X    }
X
X    switch(rp->t2b_font) {
X	/* Only fonts with "N" are subject to font translation */
X	case N:
X	    if (font == 3)
X		font = 0;	/* Special chars are Courier */
X	    else {
X		DBP((D_BEND,"psSetChar %d->%s (%s)\n", font,
X		    xlatetable[font]->troffName,
X		    xlatetable[font]->fontName));
X		font = xlatetable[font] - fonttable;
X	    }
X	    break;
X	case S:
X	    font = 3;
X	    break;
X	case D:
X	    break;
X	default:
X	    /* Typically used when the R and S fonts don't have the
X	       character desired, so select the font via the index
X	       in the fonts.?? file */
X	    font = rp->t2b_font;
X	    break;
X    }
X
X    if (!sequence)
X	sequence = rp->t2b_charseq;
X
X    if (!sequence) {
X	fprintf(stderr, "No coding for %d\n", troffChar);
X	return;
X    }
X
X    /*	We're committed now - the "if" statements avoid floating
X	arithmetic on slow machines */
X
X    if (rp->t2b_scale) points *= (.01 * rp->t2b_scale);
X    if (rp->t2b_xc) nx += points * (.01 * rp->t2b_xc);
X    if (rp->t2b_yc) ny += points * (.01 * rp->t2b_yc);
X
X    psSetFont(font, points);
X
X    DBP((D_BEND,"AFTER (sequence,x,y,font,points) = (%s,%d,%d,%d,%d)\n",
X	sequence, nx, ny, font, points));
X
X    if (rp->t2b_font == D) {
X	emitnum(nx);
X	printf(" ");
X	emitnum(ny);
X	printf(" ");
X	printf("%s\n", sequence);
X    } else {
X	emitnum(nx);
X	if (lastYPos != ny) {
X	    printf(" ");
X	    emitnum(ny);
X	    printf("(%s)Y\n", sequence);
X	    lastYPos = ny;
X	} else
X	    printf("(%s)X\n",sequence);
X    }
X}
X
X/*	Specialized emit routine:
X	outputs number divided by PSSCALEFACTOR, rounded to the first
X	decimal place without using floats/double
X */
Xemitnum(val)
Xregister int val; {
X    register int neg;
X    if (val < 0) {
X	neg = 1;
X	val = -val;
X    } else {
X	neg = 0;
X    }
X    if (neg)
X	printf("-");
X    printf("%d", val / PSSCALEFACTOR);
X    val = ((val % PSSCALEFACTOR) * 10 /*+ (PSSCALEFACTOR / 2)*/) /
X	PSSCALEFACTOR;
X    if (val)
X	printf(".%d", val);
X}
X
Xextern char nodename[];
X
XpsProlog() {
X    extern char *ctime();
X    extern char *strchr();
X    char buffer[30];
X    FILE *library;
X    long curtime;
X
X    currentPage = 0;
X    pagePending = 1;
X
X    library = libopen(printer, "lib");
X
X    time(&curtime);
X    strcpy(buffer, ctime(&curtime));
X    *strchr(buffer, '\n') = '\0';
X    getnodename();
X
X    printf("%%!PS-Adobe-1.0\n");
X    printf("%%%%Title: (stdin)\n");
X    printf("%%%%Creator: %s %s\n", progname, shortversion);
X    printf("%%%%PsroffVersion: %s\n", version);
X    printf("%%%%CreationDate: %s\n", buffer);
X    printf("%%%%For: %s\n", username);
X    printf("%%%%Pages: (atend)\n");
X    printf("%%%%DocumentFonts: (atend)\n");
X    printf("%%%%EndComments\n");
X    printf("/GlobalSave save def\n");
X    printf("/hits 0 def /misses 0 def\n");
X    /* special backends (eg: psfig) need this */
X    printf("/resolution %d def\n", TROFFRESOLUTION);
X#ifndef	NOCHATTER
X    /* compatibility with behandler.ps */
X    printf("statusdict /jobname (%s@%s %s %s %s) def\n",
X	username, nodename, buffer, progname, shortversion);
X    printf("(%s@%s %s %s %s\\n) print\n", username, nodename, buffer,
X	progname, shortversion);
X    printf("flush\n");
X#endif
X    printf("usertime /btime exch def\n");
X    psXlate(library);
X    doprologs();
X    printf("%%%%EndProlog\n");
X    fclose(library);
X}
X
XpsEpilog() {
X    int i;
X    if (!currentPage)
X	return;
X    printf("%%%%Trailer\n");
X    if (metrics)
X	printf("%d metrics\n", charCount);
X#ifndef	NOCHATTER
X    printf("(Execution time (seconds): ) print\n");
X    printf("usertime btime sub 0.001 mul (          ) cvs print\n");
X    printf("(; Pages: %d) print\n", currentPage);
X    printf("(\\n) print\n");
X    printf("flush\n");
X#endif
X    printf("GlobalSave restore\n");
X    printf("%%%%DocumentFonts:");
X    for (i = 0; i < MAXFONTS; i++)
X	if (fonttable[i].flags&USED)
X	    printf(" %s", fonttable[i].fontName);
X    printf("\n");
X    printf("%%%%Pages: %d\n", currentPage);
X#ifndef	NOCONTROLD
X    putchar('\004');
X#endif
X}
X
XpsXlate(library)
XFILE *library; {
X    char buf[512];
X    while (fgets(buf, sizeof(buf), library))
X	if (0 == strncmp(buf, "%%%", 3))
X	    interp(&buf[3], psXlate, "ps");
X	else
X	    fputs(buf, stdout);
X}
X
XpsOverlay(overlay)
Xchar *overlay; {
X#ifdef	FORM
X    strcpy(Overlay, overlay);
X    printf("%%%%%%Form set: %s\n", Overlay);
X#endif
X}
X
X#ifdef	INSPECIAL
XpsDraw(origX, origY, s)
Xint origX, origY;
Xregister char *s; {
X    register int opcode, ctindex = 0, temp, neg;
X    /*static int curDX = -1, curDY = -1;*/
X    short int numbers[100];
X
X    DBP((D_CAT, "psDraw: (%d,%d): %s\n", origX, origY, s));
X    /* Special invocation to get the newpath/moveto done */
X    psChar(origX, origY, -1, -1, (char*) NULL, (char*) NULL);
X    while(*s && isspace(*s)) s++;
X    opcode = *s;
X    neg = 1;
X    for (;*s;s++) {
X	if (isspace(*s))
X	    continue;
X	else if (*s == '\\')
X	    s += 3;
X	else if (*s == '-')
X	    neg = -1;
X	else if (!isdigit(*s))
X	    continue;
X	else {
X	    temp = *s - '0';
X	    while(isdigit(*(s+1)))
X		temp = temp * 10 + (*++s - '0');
X	    numbers[ctindex++] = neg * temp;
X	    neg = 1;
X	}
X    }
X    switch(opcode) {
X	case 'l':
X	    DBP((D_CAT, "drawline: %d, %d\n", numbers[0], numbers[1]));
X	    emitnum((int) numbers[0]);
X	    putchar(' ');
X	    emitnum((int) -numbers[1]);
X	    printf(" rlineto\n");
X	    break;
X	case 'a':
X	    for (temp = 0; temp < 4; temp++) {
X		emitnum((int) ((temp % 2) ? -numbers[temp]: numbers[temp]));
X		putchar(' ');
X	    }
X	    printf("Arc\n");
X	    break;
X	case 'c':
X	    numbers[1] = numbers[0];
X	case 'e':
X	    DBP((D_CAT, "drawellipse: %d, %d\n", numbers[0], numbers[1]));
X	    emitnum((int) numbers[0]);
X	    putchar(' ');
X	    emitnum((int) numbers[1]);
X	    printf(" Ellipse\n");
X	    break;
X	case '~':
X	    if (ctindex < 4) {
X		fprintf(stderr, "%s: too few points to spline: %s\n",
X		    progname, s);
X		break;
X	    }
X	    fprintf(stderr, "%s: Don't support splines yet\n", progname);
X	    /* Some of the following is inspired from tpscript.
X	       First convert to RELATIVE to the starting point.
X	       Further, There's a bug in PIC that returns negatively one
X	       unit LESS than it went forward - fudge it here */
X	    for (temp = 2; temp < ctindex; temp++) {
X		if (numbers[temp] < 0)
X		    numbers[temp]--;
X		numbers[temp] += numbers[temp-2];
X	    }
X	    if (ctindex == 4) {
X		emitnum((int) numbers[0] / 2);
X		putchar(' ');
X		emitnum((int) -numbers[1] / 2);
X		putchar(' ');
X		emitnum((int) (numbers[0] + numbers[2]) / 2);
X		putchar(' ');
X		emitnum((int) -(numbers[1] + numbers[3])/ 2);
X		putchar(' ');
X		emitnum((int) numbers[2]);
X		putchar(' ');
X		emitnum((int) -numbers[3]);
X		printf(" rcurveto\n");
X	    }
X	    break;
X	default:
X	    fprintf(stderr, "%s: invalid draw code %c\n", progname, opcode);
X	    indraw = 0;
X	    break;
X    }
X    printf("stroke\n");
X}
X#endif
X#endif /* PS */
END_OF_FILE
  if test 18467 -ne `wc -c <'ps.c'`; then
    echo shar: \"'ps.c'\" unpacked with wrong size!
  fi
  # end of 'ps.c'
fi
if test -f 'utils/hpinterp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'utils/hpinterp.c'\"
else
  echo shar: Extracting \"'utils/hpinterp.c'\" \(18062 characters\)
  sed "s/^X//" >'utils/hpinterp.c' <<'END_OF_FILE'
X/*	Copyright 1985, 1986, 1987, 1988 16:50:03 Chris Lewis
X		All Rights Reserved
X
X    Permission to copy and further distribute is freely given provided
X    this copyright notice remains intact and that this software is not
X    sold for profit.
X
X	Project:	Generic Troff drivers
X	Module:		hpinterp.c
X	Author: 	Chris Lewis
X	Specs:		interprets HPLJ sequences.
X */
X
X#ifndef	lint
Xstatic char SCCSID[] =
X    "@(#)hpinterp.c 2.1 Copyright 90/07/18 16:50:03 Chris Lewis";
X#endif
X
X/*	To install:
X
X	hpinterp needs to know byte order in shorts.  At run time it
X	will attempt to figure it out.  If you get an abort, or if the
X	results are idiotic:
X
X	    If you are little-endian (eg: 386/pdp-11/vax), define SMALLEND.
X	    If you are big-endian (eg: pyramid/68000), undef BIGEND.
X
X	cc -o hpinterp hpinterp.c
X
X	Decide on a directory where you're going to run hpinterp and
X	create a directory called "FONTS" (or change the defines for
X	BINFILE and DESCFILE to have a better path).
X
X	usage:
X
X	    hpinterp < hpljescapefile > /tmp/output
X
X	/tmp/output will contain an englishy *very* verbose listing
X	of all of the escape sequences except for the contents of
X	font header/download/transfer/raster sequences.
X
X	Each font downloaded is caught into a file FONTS/f<fontnumber>
X	and a bit of english is saved in FONTS/f<fontnumber>.desc.
X	Including some character maps (range restricted by firstchar and
X	lastchar).  You can turn off the verbose output listing by setting
X	verbose to 0.  setting "debug" to 1 (if verbose is 1 too), prints
X	ESC<string> sequences as well as the english.
X
X	(One of these days I'll get it to do all of this stuff by command
X	line options....)
X */
X#include <stdio.h>
X#include <ctype.h>
X#undef	BIGEND
X#undef SMALLEND
X#define	dbprintf(x)	if (verbose) printf x
X#define	ESCAPE	0x1b
X
X#define	uchar	unsigned char
Xint firstchar = 0;
Xint lastchar = 0xff;
X
Xtypedef int(*FUNC)();
X
Xint lastschar;
Xint lastfontid;
X
Xdouble curX = 0, curY = 0;
Xint emitting = 0;
X
XFILE *out = (FILE *) NULL;
XFILE *txtout = (FILE *) NULL;
Xint count = 0;
Xint verbose = 0;
Xint debug = 0;
Xint genps = 0;
Xint chars = 0;
Xint characteristic = 1;
X
Xshort canon();
X
Xreadhex(len)
Xint len; {
X    while(len--) GETCHAR();
X}
X
XGETCHAR() {
X    int c;
X    c = getchar();
X#ifdef	DEBUG
X    if (isprint(c))
X	printf("GETCHAR: %c\n", c);
X    else
X	printf("GETCHAR: %02x\n", c);
X#endif
X    return(c);
X}
X
X#define	TRANSFER	1
X#define	TRANSPARENT	2
X#define	FONTHEADER	3
X#define	DOWNLOAD	4
Xstruct fontdesc {
X    short f1;
X    uchar f2;
X    uchar fd_type;
X    short f3;
X    short fd_base;
X    short fd_cellwidth;
X    short fd_cellheight;
X    uchar fd_orientation;
X    uchar fd_fixedprop;
X    short fd_symset;
X    short fd_pitch;
X    short fd_height;
X    short f4;
X    uchar f5;
X    uchar fd_style;
X    uchar fd_weight;
X    uchar fd_typeface;
X};
X
Xstruct download {
X    uchar f1;
X    uchar f2;
X    uchar f3;
X    uchar f4;
X    uchar dl_orientation;
X    short dl_leftoffset;
X    short dl_topoffset;
X    short dl_charwidth;
X    short dl_charheight;
X    short dl_deltax;
X    uchar  dl_data[1];
X};
X
Xchar	*fchcont[] = {
X    "Delete all fonts",
X    "Delete all temporary fonts",
X    "Delete last font ID specified",
X    "Delete last font ID and char code",
X    "Make Temp font",
X    "Make Perm font",
X    "Copy/Assign",
X    NULL};
Xchar *spcont[] = {
X    "Fixed",
X    "Proportional",
X    NULL};
Xchar *stcont[] = {
X    "Upright",
X    "Italic",
X    NULL};
Xchar *tfcont[] = {
X    "Line Printer",
X    "Pica",
X    "Elite",
X    "Courier",
X    "Helvetica",
X    "Times Roman",
X    "Gothic",
X    "Script",
X    "Prestige Elite",
X    "Caslon",
X    "Orator",
X    NULL};
Xchar *sgcont[] = {
X    "Left-most position",
X    "Current Cursor",
X    NULL};
Xchar *pscont[] = {
X    "Disable",
X    "Enable",
X    NULL};
X
X
Xint	movex(),movey(), papinctrl();
Xint	spset(), psset(), styset(), strset(), tfset();
X
Xstruct intlist {
X    char *code;
X    char *name;
X    char **parmnames;
X    FUNC exec;
X} intlist[] = {
X    {"&lO",	"Orientation"},
X    {"(sP",	"Spacing", spcont, spset},
X    {"(sH",	"Pitch"},
X    {"(sV",	"Point Size", NULL, psset},
X    {"(sS",	"Style", stcont, styset},
X    {"(sB",	"Stroke", NULL, strset},
X    {"(sT",	"Typeface", tfcont, tfset},
X    {"&lP",	"Page Length"},
X    {"&lE",	"Top Margin"},
X    {"&lF",	"Text Length"},
X    {"&aL",	"Left Margin"},
X    {"&aM",	"Right Margin"},
X    {"&lC",	"Motion Index"},
X    {"&lD",	"Lines/Inch"},
X    {"*tR",	"Resolution"},
X    {"*rA",	"Start Graphics", sgcont},
X    {"*bW",	"Transfer"},
X    {"*rB",	"End Graphics"},
X    {"&aR",	"Move to Row"},
X    {"&aC",	"Move to Column"},
X    {"&aH",	"Move to Column (Decipoints)", NULL, movex},
X    {"&aV",	"Move to Row (Decipoints)", NULL, movey},
X    {"&dD",	"Underline on"},
X    {"&d@",	"Underline off"},
X    {"&pX",	"Transparent Print"},
X    {"&lL",	"Perf Skip", pscont},
X    {"&kH",	"HMI"},
X    {"&kS",	"Font Pitch"},
X    {"&kG",	"Line Termination"},
X    {"&sC",	"Line Wrap"},
X    {"&lX",	"Number of Copies"},
X    {"&lH",	"Paper Input Control", NULL, papinctrl},
X    {"*pX",	"Horizontal cursor (dots)"},
X    {"*pY",	"Vertical cursor (dots)"},
X    {"*cD",	"Font ID"},
X    {"*cE",	"Character Code"},
X    {"*cF",	"Font/Char control", fchcont},
X    {")sW",	"Create Font Header"},
X    {"(sW",	"Download Character"},
X    {"&fY",	"Macro ID"},
X    {"&fX",	"Macro control"},
X    {"&fS",	"Push/Pop"},
X    {"*cA",	"Horizontal Rule/Pattern Size"},
X    {"*cH",	"Horizontal Rule/Pattern Size"},
X    {"*cB",	"Vertical Rule/Pattern Size"},
X    {"*cV",	"Vertical Rule/Pattern Size"},
X    {"*cP",	"Print Rule/Pattern"},
X    {"*cG",	"Grey scale/pattern id"},
X    {"&lT",	"Job offset control"},
X    {NULL,NULL}
X};
X
Xunion {
X    struct fontdesc b_fd;
X    struct download b_dl;
X    char b_buffer[2048];
X} buffer;
X
Xinterp(prefix, anchor, number, suffix)
Xchar prefix, anchor, suffix;
Xdouble number; {
X    int multi;
X    register int i;
X    char lookup[4];
X
X    if (debug)
X	dbprintf(("ESC%c%c%g%c\n", prefix, anchor, number, suffix));
X
X    if (islower(suffix))
X	suffix = toupper(suffix);
X
X    sprintf(lookup, "%c%c%c", prefix, anchor, suffix);
X    for (i = 0; intlist[i].code; i++) {
X	if (0 == strcmp(intlist[i].code, lookup)) {
X	    dbprintf(("%s:", intlist[i].name));
X	    if (intlist[i].parmnames) {
X		int j;
X		for (j = 0; j < number; j++) {
X		    if (!intlist[i].parmnames[j])
X			break;
X		}
X		if (intlist[i].parmnames[j])
X		    dbprintf((" %s\n", intlist[i].parmnames[j]));
X		else
X		    dbprintf((" %g\n", number));
X	    } else
X		dbprintf ((" %g\n", number));
X	    if (intlist[i].exec)
X		(*intlist[i].exec)(number);
X	    break;
X	}
X    }
X
X    multi = 0;
X    /* For parsing variable length ones */
X    switch(prefix) {
X	case '*':
X	    if (anchor == 'b' && suffix == 'W')
X		multi = TRANSFER;
X	    break;
X	case '&':
X	    if (anchor == 'p' && suffix == 'X')
X		multi = TRANSPARENT;
X	    break;
X	case ')':
X	    if (anchor == 's' && suffix == 'W')
X		multi = FONTHEADER;
X	    break;
X	case '(':
X	    if (anchor == 's' && suffix == 'W')
X		multi = DOWNLOAD;
X	    break;
X    }
X    if (prefix == '*' && anchor == 'c' && suffix == 'E') {
X	lastschar = number;
X    }
X    if (prefix == '*' && anchor == 'c' && suffix == 'D') {
X	lastfontid = number;
X    }
X    if (multi)
X	readdesc(multi, (int) number);
X}
X
X#ifdef	SMALLEND
X#define	smallend	1
X#endif
X#ifdef	BIGEND
X#define	smallend	0
X#endif
X
X#if	!defined(SMALLEND) && !defined(BIGEND)
Xunion	t {
X    char a[2];
X    short b;
X};
Xint	smallend;
X#endif
X
Xshort
Xcanon(v)
Xshort v; {
X    if (smallend) {
X	return(((v & 0xff) << 8) | ((v&0xff00) >> 8));
X    } else
X	return(v);
X}
X
X#define	BINFILE		"FONTS/f%d"
X#define	DESCFILE	"FONTS/f%d.desc"
X
Xreaddesc(type, bytecount)
Xint type; int bytecount; {
X    int points;
X    char *typeface;
X    char *style;
X    char filename[1000];
X    switch(type) {
X	default:
X	    readhex(bytecount);
X	    break;
X	case DOWNLOAD:
X	    fread((char *) &buffer, 1, bytecount, stdin);
X	    sprintf(filename, BINFILE, lastfontid);
X	    if (out) fclose(out);
X	    if ((out = fopen(filename, "a")) == NULL) {
X		fprintf(stderr, "Can't open %s\n", filename);
X		out = NULL;
X	    }
X	    sprintf(filename, DESCFILE, lastfontid);
X	    if (txtout) fclose(txtout);
X	    if ((txtout = fopen(filename, "a")) == NULL) {
X		fprintf(stderr, "Can't open %s\n", filename);
X		txtout = NULL;
X	    }
X	    if (lastschar >= firstchar && lastschar <= lastchar) {
X		if (txtout) {
X		    fprintf(txtout, "Character: %c\n", lastschar);
X		    fprintf(txtout, "  orientation: %d\n",
X			buffer.b_dl.dl_orientation);
X		    fprintf(txtout, "  leftoffset: %d\n",
X			canon(buffer.b_dl.dl_leftoffset));
X		    fprintf(txtout, "  topoffset: %d\n",
X			canon(buffer.b_dl.dl_topoffset));
X		    fprintf(txtout, "  charwidth: %d\n",
X			canon(buffer.b_dl.dl_charwidth));
X		    fprintf(txtout, "  charheight: %d\n",
X			canon(buffer.b_dl.dl_charheight));
X		    fprintf(txtout, "  deltax: %d\n",
X			canon(buffer.b_dl.dl_deltax));
X		    if (chars)
X			plotchars(txtout, &buffer.b_dl);
X		}
X	    }
X	    if (out) {
X		fprintf(out, "\033*c%dE", lastschar);
X		fprintf(out, "\033(s%dW", bytecount);
X		fwrite((char *) &buffer, 1, bytecount, out);
X	    }
X	    break;
X
X	case FONTHEADER:
X	    if (txtout) fclose(txtout);
X	    if (out) fclose(out);
X
X	    fread((char *) &buffer, 1, bytecount, stdin);
X	    points = (double) canon(buffer.b_fd.fd_height) * 72 / 4 / 300 + .5;
X	    switch(buffer.b_fd.fd_typeface) {
X		case 0: typeface = "Line Printer"; break;
X		case 1: typeface = "Pica"; break;
X		case 2: typeface = "Elite"; break;
X		case 3: typeface = "Courier"; break;
X		case 4: typeface = "Helvetica"; break;
X		case 5: typeface = "Times-Roman"; break;
X		case 6: typeface = "Gothic"; break;
X		case 7: typeface = "Script"; break;
X		case 8: typeface = "Prestige"; break;
X		case 9: typeface = "Caslon"; break;
X		case 10: typeface = "Orator"; break;
X		default: typeface = "               ";
X		    sprintf(typeface, "T%d", buffer.b_fd.fd_typeface);
X		    break;
X	    }
X	    switch(buffer.b_fd.fd_style) {
X		case 0:
X		    style = "Upright";
X		    break;
X		case 1:
X		    style = "Italic";
X		    break;
X	    }
X	    sprintf(filename, BINFILE, lastfontid);
X	    if ((out = fopen(filename, "w")) == NULL) {
X		fprintf(stderr, "Can't open %s\n", filename);
X		out = NULL;
X	    }
X	    sprintf(filename, DESCFILE, lastfontid);
X	    if ((txtout = fopen(filename, "w")) == NULL) {
X		fprintf(stderr, "Can't open %s\n", filename);
X		txtout = NULL;
X	    }
X	    /*fprintf(out, "\033*c%dD", lastfontid);*/
X	    fprintf(out, "\033)s%dW", bytecount);
X	    fwrite((char *) &buffer, 1, bytecount, out);
X	    if (txtout) {
X		fprintf(txtout, "Height: %d\n", canon(buffer.b_fd.fd_height));
X		fprintf(txtout, "  Points (rounded): %d\n", points);
X		fprintf(txtout, "  Points (floating): %.2f\n",
X		    (double) canon(buffer.b_fd.fd_height) * 72 / 4 / 300);
X		fprintf(txtout, "Pitch: %d\n", canon(buffer.b_fd.fd_pitch));
X		fprintf(txtout, "  Pitch (chars/inch): %d\n",
X		    4 * 300 / canon(buffer.b_fd.fd_pitch));
X		if (buffer.b_fd.fd_fixedprop)
X		    fprintf(txtout, "Proportional width font\n");
X		else
X		    fprintf(txtout, "Fixed width font\n");
X		fprintf(txtout, "Stroke weight: %d\n", buffer.b_fd.fd_weight);
X		fprintf(txtout, "Style: %d; (%s)\n", buffer.b_fd.fd_style,
X		    style);
X		fprintf(txtout, "Typeface: %d; (%s)\n", buffer.b_fd.fd_typeface,
X		    typeface);
X		fprintf(txtout, "Symset: %04x; (%d%c)\n",
X		    canon(buffer.b_fd.fd_symset),
X		    canon(buffer.b_fd.fd_symset) >> 5,
X		    (canon(buffer.b_fd.fd_symset) & 0x1f) + 'A' - 1);
X
X		fprintf(txtout, "Type: %x\n", buffer.b_fd.fd_type);
X		fprintf(txtout, "Base: %d\n", canon(buffer.b_fd.fd_base));
X		fprintf(txtout, "Cellwidth: %d\n", canon(buffer.b_fd.fd_cellwidth));
X		fprintf(txtout, "Cellheight: %d\n", canon(buffer.b_fd.fd_cellheight));
X		fprintf(txtout, "Orientation: %d\n", buffer.b_fd.fd_orientation);
X		fprintf(txtout, "Height: %d\n", canon(buffer.b_fd.fd_height));
X	    }
X    }
X}
X
Xplotchars(f, dl)
Xstruct download *dl;
XFILE *f; {
X    short x, y, bx, by, bytes, byteindex, bitindex, bit;
X    bytes = (canon(dl->dl_charwidth) + 7) / 8;
X    for (y = 0; y < canon(dl->dl_charheight); y++) {
X	fprintf(f, "        ");
X	for (x = 0; x < (canon(dl->dl_charwidth) + canon(dl->dl_leftoffset));
X		x++) {
X	    bx = x - canon(dl->dl_leftoffset);
X	    by = y;
X	    if (bx >= 0) {
X		byteindex = bytes * by + bx / 8;
X		bitindex = (7 - (bx % 8));
X		if (dl->dl_data[byteindex] & (1 << bitindex))
X		    bit = 'X';
X		else
X		    bit = ' ';
X	    } else
X		bit = ' ';
X	    if (x == 0 && y == canon(dl->dl_topoffset))
X		bit = '+';
X	    if (bit == ' ' && y == canon(dl->dl_topoffset))
X		bit = '=';
X	    fputc(bit, f);
X	}
X	fputc('\n',f);
X    }
X}
X
X
X/*	We've got ESC<prefix><anchor>
X *	read number/suffix pairs
X */
Xmultisequence(prefix, anchor)
Xchar prefix, anchor; {
X    int c, neg, seendot;
X    double v;
X    while(1) {
X	v = 0;
X	seendot = 0;
X	neg = 1;
X	while(isdigit(c = GETCHAR()) || (c == '.') || (c == '-') || (c == '+')) {
X	    if (c == '+') {
X		continue;
X	    }
X	    if (c == '.') {
X		seendot = 10;
X		continue;
X	    }
X	    if (c == '-') {
X		neg *= -1;
X		continue;
X	    }
X	    if (seendot) {
X		v += (double) (c - '0') / seendot;
X		seendot *= 10;
X	    } else
X		v = v * 10 + c - '0';
X	}
X	v *= neg;
X	interp(prefix, anchor, v, c);
X	if (!islower(c))
X	    break;
X    }
X}
X
Xprinthex(buf, n)
Xchar *buf; int n; {
X    int i;
X    dbprintf(("SEQ:"));
X    for (i = 0; i < n; i++) {
X	if (isprint(buf[i]))
X	    putchar(buf[i]);
X	else
X	    dbprintf(("\\%02x", buf[i]));
X    }
X    dbprintf(("\n"));
X}
X
Xshort pts[] = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 4, 4};
Xreadescape() {
X    int c, v, v1, v2, v3;
X    c = GETCHAR();
X    switch(c) {
X	case '9':
X	    dbprintf(("Clear Margins\n"));
X	    return;
X	case '=':
X	    dbprintf(("Half linefeed\n"));
X	    return;
X	case 'E':
X	    dbprintf(("Reset\n"));
X	    return;
X	case 'z':
X	    dbprintf(("Self test\n"));
X	    return;
X	case 'Y':
X	    dbprintf(("Display functions on\n"));
X	    return;
X	case 'Z':
X	    dbprintf(("Display functions off\n"));
X	    return;
X	case ')':
X	    c = GETCHAR();
X	    if (isdigit(c)) {
X		v = 0;
X		while(isdigit(c)) {
X		    v = v * 10 + c - '0';
X		    c = GETCHAR();
X		}
X		switch(c) {
X		    case 'X':
X			dbprintf(("Secondary font %d\n", v));
X			break;
X		    case '@':
X			dbprintf(("Secondary font value %d\n", v));
X			break;
X		    default:
X			dbprintf(("HUH ESC)%d%c\n", v, c));
X		}
X		return;
X	    }
X	    multisequence(')', c);
X	    return;
X	case '(':
X	    c = GETCHAR();
X	    if (isdigit(c)) {
X		v = 0;
X		while(isdigit(c)) {
X		    v = v * 10 + c - '0';
X		    c = GETCHAR();
X		}
X		switch(c) {
X		    case 'X':
X			dbprintf(("Primary font %d\n", v));
X			if (genps) {
X			    endemit();
X			    characteristic = 0;
X			    printf("/f%d findfont %d scalefont setfont\n",
X				v, pts[v&0xf]);
X			}
X			break;
X		    case '@':
X			dbprintf(("Primary font value %d\n", v));
X			break;
X		    default:
X			dbprintf(("Symbol set: %d%c\n", v, c));
X		}
X		return;
X	    }
X	    multisequence('(', c);
X	    return;
X	case '&':
X	    c = GETCHAR();
X	    multisequence('&', c);
X	    return;
X	case '*':
X	    c = GETCHAR();
X	    multisequence('*', c);
X	    return;
X	default:
X	    dbprintf(("Huh? %02x\n", c));
X	    return;
X    }
X}
X
Xmain(argc, argv)
Xint argc; char **argv; {
X    int c;
X    extern char *optarg;
X
X#if	!defined(BIGEND) && !defined(SMALLEND)
X    union t ta;
X    ta.a[0] = 0x01;
X    ta.a[1] = 0x02;
X    smallend = ((ta.b&0xff) == 0x01);
X#endif
X    while((c = getopt(argc, argv, "dpv")) != EOF)
X	switch(c) {
X	    case 'p':
X		genps++;
X		break;
X	    case 'v':
X		verbose++;
X		break;
X	    case 'd':
X		debug++;
X		break;
X	    case '?':
X		fprintf(stderr, "usage: hpinterp [-d][-p][-v]< file");
X		exit(1);
X	}
X
X
X    if (genps) {
X	printf("/M { moveto } def\n");
X	printf("/S { show } def\n");
X    }
X    while((c = GETCHAR()) != EOF) {
X	if (c == ESCAPE) {
X	    readescape();
X	} else {
X	    if (isprint(c))
X		dbprintf(("Char: %c\n", c));
X	    else
X		dbprintf(("Char: 0x%02x\n", c));
X	    emitchar(c);
X	}
X    }
X    if (out) fclose(out);
X    if (txtout) fclose(txtout);
X    endemit();
X}
X
Xmovex(num)
Xdouble num; {
X    curX = num;
X    endemit();
X}
X
Xmovey(num)
Xdouble num; {
X    curY = num;
X    endemit();
X}
X
Xemitchar(c)
Xint c; {
X    if (!genps)
X	return;
X
X    if (characteristic)
X	selchar();
X
X    if (!emitting)
X	printf("%g %g M(", curX/10, (72 * 11) - (curY/10));
X
X    emitting = 1;
X
X    switch(c) {
X	case '(': case ')': case '\\':
X	    printf("\\%c", c);
X	    break;
X	default:
X	    if (c > ' ' && c < 0x7e)
X		printf("%c", c);
X	    else
X		printf("\\%03o", c&0xff);
X	    break;
X    }
X}
X
Xendemit() {
X    if (emitting)
X	printf(")S\n");
X    emitting = 0;
X}
X
Xpapinctrl(num)
Xdouble num; {
X    int n = num;
X    if (num == 0) {
X	endemit();
X	if (genps)
X	    printf("showpage\n");
X    }
X}
X
Xint ps_pointsize = 10;
Xint ps_style = 1;
Xint ps_stroke = 0;
Xint ps_symset = 0;
Xint ps_tface = 5;
Xint ps_spacing = 0;
X
Xspset(num)
Xdouble num; {
X    ps_spacing = num;
X    characteristic = 1;
X    endemit();
X}
Xpsset(num)
Xdouble num; {
X    characteristic = 1;
X    ps_pointsize = num;
X    endemit();
X}
Xstyset(num)
Xdouble num; {
X    characteristic = 1;
X    ps_style = num;
X    endemit();
X}
Xstrset(num)
Xdouble num; {
X    characteristic = 1;
X    ps_stroke = num;
X    endemit();
X}
Xtfset(num)
Xdouble num; {
X    characteristic = 1;
X    ps_tface = num;
X    endemit();
X}
X
X#define	TMS	"Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic"
X#define COUR	"Courier", "Courier-Oblique", "Courier-Bold",\
X    "Courier-BoldOblique"
X#define HELV	"Helvetica", "Helvetica-Oblique", "Helvetica-Bold",\
X    "Helvetica-BoldOblique"
X
X#define	LAST	7
X
Xchar *fonts[LAST][4] = {{COUR}, {COUR}, {COUR}, {COUR}, {HELV}, {TMS},
X    {COUR}};
X
Xselchar() {
X    int idx = 0;
X    char **font;
X#ifdef	NEVER
X    printf("ps_pointsize: %d\n", ps_pointsize);
X    printf("ps_style: %d\n", ps_style);
X    printf("ps_stroke: %d\n", ps_stroke);
X    printf("ps_symset: %d\n", ps_symset);
X    printf("ps_tface: %d\n", ps_tface);
X    printf("ps_spacing: %d\n", ps_spacing);
X#endif
X    if (ps_tface >= LAST)
X	ps_tface = 3;
X    idx = 0;
X    if (ps_stroke > 0)
X	idx = 2;
X    if (ps_style != 0)
X	idx++;
X    printf("/%s findfont %d scalefont setfont\n", fonts[ps_tface][idx],
X	ps_pointsize);
X    characteristic = 0;
X}
END_OF_FILE
  if test 18062 -ne `wc -c <'utils/hpinterp.c'`; then
    echo shar: \"'utils/hpinterp.c'\" unpacked with wrong size!
  fi
  # end of 'utils/hpinterp.c'
fi
echo shar: End of archive 4 \(of 16\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 16 archives.
    echo "Read the README to get started with psroff installation"
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0
-- 
Chris Lewis, Phone: TBA
UUCP: uunet!utai!lsuc!ecicrl!clewis
Moderator of the Ferret Mailing List (ferret-request@eci386)
Psroff mailing list (psroff-request@eci386)