Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v47i104: viz - viz - make invisible characters visible; od on steroids, Part01/03

8 views
Skip to first unread message

wde...@nfra.nl

unread,
Mar 27, 1995, 1:28:00 PM3/27/95
to
Submitted-by: wde...@nfra.nl
Posting-number: Volume 47, Issue 104
Archive-name: viz/part01
Environment: UNIX

Viz copies its input to its output, converting invisible characters
to a visible form. If the -t option is used, the output is
formatted in a form that can be completely inverted by inviz,
which allows a binary file to be converted to a text form and then back.
It is much more flexible than either cat -v or od (either old or
POSIX od), and it is also 2\-4 times faster.

By default, the input is treated as a sequence of characters.
However, a file format may be specified, in which case
viz can handle files containing a mixture of data of arbitrary types.

The format can include repeat counts
and comments that are embedded in the output stream.

Uninteresting data can be skipped over and not printed on stdout.

Additional flexibility is provided through user-settable variables,
which can be used as repeat counts. Simple math can be done on the
variables, and chars, shorts, or integers from the input stream
can be stored in them.

---- Cut Here and feed the following to sh ----
#! /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".
# Contents: viz-1.1.0 viz-1.1.0/viz.1 viz-1.1.0/viz.c
# Wrapped by kent@ftp on Sat Mar 25 15:26:13 1995
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 1 (of 3)."'
if test ! -d 'viz-1.1.0' ; then
echo shar: Creating directory \"'viz-1.1.0'\"
mkdir 'viz-1.1.0'
fi
if test -f 'viz-1.1.0/viz.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/viz.1'\"
else
echo shar: Extracting \"'viz-1.1.0/viz.1'\" \(16818 characters\)
sed "s/^X//" >'viz-1.1.0/viz.1' <<'END_OF_FILE'
X.TH VIZ 1 local
X.de R
X.ft 1
X.it 1 }N
X.if !"\\$1"" \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6
X..
X.SH NAME
Xviz \- Makes invisible characters visible; binary file lister
X.SH SYNOPSIS
X.B viz
X[
X.B \-f
X.I fmt
X|
X.B \-F
X.I fmtfile
X] [
X.B \-h
X] [
X.B \-l
X.I n
X]
X.br
X [
X.B \-p
X|
X.B \-o
X|
X.B \-P
X.I len
X|
X.B \-O
X.I len
X] [
X.I file ...
X]
X.SH DESCRIPTION
X.I Viz
Xcopies its input to its output, converting invisible characters
Xto a visible form. If no
X.IR file s
Xare given,
X.I stdin
Xis read.
XIf the \fB\-t\fP option is used, the output is
Xformatted in a form that can be
Xcompletely inverted (see \fIinviz\fP),
Xwhich allows a binary file to be converted
Xto a text form, edited, and then converted back.
XIt is much more flexible than either
X.I cat\ \-v
Xor
X.IR od
X(either old or POSIX \fIod\fP),
Xand it is also 2\-4 times faster.
X.PP
XBy default, the input is treated as a sequence of characters.
XHowever, a file format
Xmay be specified, in which case
X.I viz
Xcan handle files containing a mixture of data of arbitrary types.
X.PP
XThe format can contain include repeat counts
Xand comments to be embedded in the output stream.
X.PP
XUninteresting data can be skipped over and not printed on stdout.
X.PP
XAdditional flexibility is provided through user-settable variables, which
Xcan be used as repeat counts. Simple math can be done on the variables, and
Xchars, shorts, or integers from the input stream can be stored
Xin them.
X.SH OPTIONS
X.ta .5i 1i 1.5i
X.HP
X\-f \fIfmt\fP: specifies the type of input data, and how to
Xformat the output.
X.HP
X\-F \fIfmtfile\fP: gives the name of a file containing a
X.I fmt
Xstring.
X.HP
X\-h: print a help message on stderr, then exit.
X.HP
X\-l \fIn\fP: limit output to no more than
X.I n
Xcharacters per line (def 80).
X.HP
X\-p: print offsets (each line begins \fIoffset\fB:\fR ).
X.HP
X\-P\ \fIlen\fP: print offsets using the format
X\fIlen\fB*\fIn\fB+\fIoffset\fB:\fR.
XThis is useful if the input file is organized into fixed-length
Xlogical records of data.
X.HP
X\-o, \-O len: like \-p and \-P, but the offset is printed in octal.
X.HP
X\-t: prints the type of input data (e.g. int or float)
Xin the output stream; this allows
Xnon-text data to be retranslated properly, so that the output can be
Xcompletely inverted by
X.IR inviz (1)
Xto reproduce the original input.
X.br
X.HP
X\-L: display a readable version (on \fIstderr\fP)
Xof the internal representation of the
Xformat string; not useful for ordinary use.
X.HP
X\-D: turn on debug mode; not useful for ordinary use.
X.SH OUTPUT
XBy default, the input is treated as a stream of ASCII characters.
XPart or all of the input can optionally be interpreted as shorts, ints,
Xlongs (all signed or unsigned), or floats or doubles.
XSince all characters are made visible, newlines and empty lines in the
Xoutput are not significant.
X.PP
XWhen
X.I viz
Xis translating ASCII characters,
X.IP \(bu
Xprinting characters are passed through untouched;
X.IP \(bu
Xthe usual C escape sequences are used for backspace (\fB\\b\fP),
Xformfeed (\fB\\f\fP), newline (\fB\\n\fP), return (\fB\\r\fP), tab (\fB\\t\fP),
Xbackslash (\fB\\\\\fP),
Xand null (\fB\\0\fP);
X.IP \(bu
Xif compiled with an ANSI\ C compiler,
X.I viz
Xalso uses these additional escape sequences:
Xaudible bell \(-> \fB\\a\fP and vertical tab \(-> \fB\\v\fP;
X.IP \(bu
Xthe caret (\fB^\fP) is printed as \fB\\^\fP, so that a plain caret can
Xbe used as a prefix for control characters (see next bullet);
X.IP \(bu
Xother characters in the range \\0..\\037 are displayed as control characters
X(e.g. 01 is displayed as \fB^A\fP);
X.IP \(bu
Xcharacters above \\0177 are displayed as octal C escape sequences
X(\fB\\\fInnn\fR).
X.PP
X.I Viz
Xcan print integer data (char, short, int, or long)
Xin decimal, octal, hex, or binary (default decimal),
Xor use a user-specified
X.IR printf ()
Xformat.
XIf a multi-byte number is printed in binary, the binary representations
Xof the bytes are separated by commas to improve readability.
X.PP
XFloats and doubles can be printed using a
X.IR printf ()
X.RB ``f''
Xor
X.RB ``g''
Xformat (default \fBg\fP), or use a user-specified
X.IR printf ()
Xformat.
X.PP
XIf the
X.B \-t
X(type of data)
Xoption is used, output lines containing numbers are begun with
X\fB\\#C\fP, \fB\\#S\fP, \fB\\#I\fP, \fB\\#L\fP, \fB\\#F\fP, or
X\fB\\#D\fP,
Xindicating that the line contains char, short, int, long, float, or double-size
Xnumeric data, respectively. This allows
X.IR inviz( 1 )
Xto exactly invert the output.
X.SH FORMAT SPECIFICATION
XThe output format is controlled with the
X.B \-f
X.I fmt
Xor
X.B \-F
X.I fmtfile
Xoptions. A format
Xspecifies the types of data contained in the file and how to print them.
XA
X.I fmtfile
Xis the name of a file containing a format;
Xthis is very useful for holding complex or frequently-repeated formats.
X.SS Simple Formats
XA simple format is
X.ti +.5i
X[
X.I repeat_count
X]
X.I datasize
X[
X.I output_format
X]
X.br
Xor
X.br
X.ti +.5i
X[
X.I repeat_count
X]
X.I output_format
X.br
XFor instance,
X.B '20 short u'
Xsays to read 20 objects whose size is that of a short, and interpret them
Xas unsigned decimal values.
XWhitespace is optional around any of the elements of a format.
XThe members of a simple format are:
X.HP
X.I repeat_count
Xtells how many items of size
X.I datasize
Xto process from the input stream.
XIf the format doesn't begin with a repeat count, an infinite loop
Xis assumed and the format is applied to the entire input stream.
XA repeat count is one of
X.RS
X.IP \(bu
Xa decimal number (e.g. 120);
X.IP \(bu
Xa double-dollar sign (\fB$$\fP),
Xmeaning repeat until EOF is encountered on the input; or
X.IP \(bu
Xa
X.I viz
Xregister \fB$\fIc\fR, where \fIc\fP can be any character.
XRegisters are discussed below.
X.RE
X.HP
X.I datasize
Xindicates the size of each input datum in bytes. Valid datasizes are
X.RS
X.RS
X.BR char ,
X.B C
X.br
X.BR short ,
X.B S
X.br
X.BR int ,
X.B I
X.br
X.BR long ,
X.B L
X.br
X.BR float ,
X.B F
X.br
X.BR double ,
X.BR D
X.br
X.BR Z
X.fi
X.RE
XThe single-character uppercase names [\fBCSILFD\fP] are shorthand for
X.BR char ,
X.BR short ,
X\fIetc\fP.
XIf the long form is used, it has to be followed by a non-alphabetic character;
Xuse whitespace if necessary.
XThere is no explicit "unsigned" size, as each unsigned type is always the
Xsame size as the corresponding signed form.
XThe special datasize
X.B Z
Xmeans a zero-terminated string (\fIi.e.\fP, a null-terminated string);
Xsee output format
X.BR a ,
Xbelow.
XThe
X.B Z
Xtype is the only datasize that doesn't correspond to a fundamental C\ type.
X.RE
X.HP
X.I output_format
Xspecifies how to interpret and print the data. Valid output formats
Xare:
X.RS
X.IP \fB~\fP
XDiscard (don't print) the input.
XThe default
X.I datasize
Xis
X.BR char .
X.IP \fBa\fP
XInterpret the input as a character and print using the rules given above
Xfor text.
XSimilar to
X.IR od(1) 's
X.B \-a
Xoption.
XThe only allowed datasizes are
X.B char
X(or \fBC\fP)
Xand
X.BR Z .
XThe
X.B Z
Xdatasize is special. It corresponds to all characters in the input
Xstream from the current position up through a null.
XThis is useful for printing null-terminated strings that are embedded
Xin fixed-length fields that otherwise contain garbage.
XThe number of characters matched by a
X.B Z
Xdatasize can be collected into a
X.I viz
Xregister, so that you can then skip the remaining junk.
XSee also output format
X.BR c .
X.IP \fBb\fP
XInterpret the input as non-negative and integral-valued,
Xand print as a binary number.
XThe default
X.I datasize
Xis
X.BR char .
X.IR Datasize 's
X.B float
Xand
X.B double
Xcannot be used with the
X.BR b
Xoutput format.
X.IP \fBc\fP
XInterpret the input as a character and print using their ASCII representation,
Xexcept for non-printing characters and blanks,
Xwhich are printed as 3-digit octal numbers \fB\\\fInnn\fR.
XThe only allowed datasize is
X.B char
X(or \fBC\fP).
XSimilar to
X.IR od(1) 's
X.B \-c
Xoption.
XThe only allowed datasize is
X.B char
X(or \fBC\fP).
XSee also output format
X.BR a .
X.IP \fBd\fP
XInterpret the input as a signed integral-valued number and print it
Xin decimal.
XThe default
X.I datasize
Xis
X.BR int .
X.IR Datasize 's
X.B float
Xand
X.B double
Xcannot be used with the
X.B d
Xoutput format.
X.IP \fBf\fP
XInterpret the input as a float or double, and print it using
X.I printf(3s)
X.B "%f"
Xformat.
XThe allowed
X.IR datasize 's
Xare
X.B float
X(the default) and
X.BR double .
X.IP \fBg\fP
XInterpret the input as a float or double, and print it using
X.I printf(3s)
X.B "%g"
Xformat.
XThe allowed
X.IR datasize 's
Xare
X.B float
X(the default) and
X.BR double .
X.IP \fBh\fP
XInterpret the input as an unsigned number and print it
Xin hexadecimal.
XThe default
X.I datasize
Xis
X.BR int .
X.IR Datasize 's
X.B float
Xand
X.B double
Xcannot be used with the
X.B h
Xoutput format.
X.IP \fBo\fP
XInterpret the input as an unsigned number and print it
Xin octal.
XThe default
X.I datasize
Xis
X.BR int .
X.IR Datasize 's
X.B float
Xand
X.B double
Xcannot be used with the
X.B o
Xoutput format.
X.IP \fBu\fP
XInterpret the input as an unsigned number and print it
Xin decimal.
XThe default
X.I datasize
Xis
X.BR int .
X.IR Datasize 's
X.B float
Xand
X.B double
Xcannot be used with the
X.B u
Xoutput format.
X.IP \fBx\fP
XA synonym for \fBh\fP (hex) format.
X.IP \fB"\fIprintfstring\fB"\fR
XIf you enter a quoted string, then the
X.I printfstring
Xis used as a printf format. It is up to you to give a format that
Xis appropriate to the datatype; no checking is done. For instance, you
Xmight use
X.ti +.5i
X.B
X\-f 'I " %+d "'
X.br
Xto have integers always printed with signs.
X.RE
X.PP
X.SS Default Datasizes and Output Formats
X.PP
XIf you specify the datasize, but not the output format, the
Xdefaults are:
X.sp
X.ta 2.5i 3i 3.5i 4.0i 4.5i 5i
XDatasize Default Output Format
X.ta 3i 3.5i 4.0i 4.5i 5i
X.sp .5
X.nf
X\fBC\fP, \fBchar\fP, \fBZ\fP \fBa\fP
X\fBS\fP, \fBshort\fP, \fBI\fP, \fBint\fP, \fBL\fP, \fBlong\fP \fBd\fP
X\fBF\fP, \fBfloat\fP, \fBD\fP, \fBdouble\fP \fBg\fP
X.fi
X.PP
XIf you specify an output format, but not the datasize, the defaults are:
X.sp
X.ta 2i 2.5i 3i 3.5i 4i 4.5i 5i
XOutput Format Default Datasize
X.ta 2.5i 3i 3.5i 4i 4.5i 5i
X.sp .5
X.nf
X\fBa\fP, \fBb\fP, \fBc\fP, \fB~\fP \fBchar\fP
X\fBd\fP, \fBu\fP, \fBo\fP, \fBh\fP, \fBx\fP \fBint\fP
X\fBf\fP, \fBg\fP \fBfloat\fP
X.fi
X.SS Concatenation
XFormats can be concatenated, and are then processed one after the
Xother:
X.ti +.5i
X.B
X\-f '24Ca 5Fg'
X.br
Xprocesses 24 characters and then 5 floats.
X.SS Grouping
XFormats can be grouped and nested with parentheses:
X.ti +.5i
X.B
X\-f 'int 3(24a 5g)'
X.br
Xmeans 1 int, then 3 groups of 24\ chars\ + 5\ floats.
XSince the format doesn't begin with a number, then entire format is
Xrepeated until EOF is reached; it's equivalent to
X.ti +.5i
X.B
X\-f '$$(int 3(24a 5g))'
X.br
X.SS Comments
XA format can contain \fB[\fIcomment\fB]\fR, in which case
Xthe
X.I comment
Xis embedded in the output stream.
XFor instance,
X.ti +.5i
X.B
X\-f 'I [Power: ] F'
X.br
Xprints one integer, then the string "\fBPower:\ \fP", and then a float.
XWithin a comment, the usual C escape sequences are recognized, as are the
X.I viz
Xregisters `\fB$\fIc\fR' (the contents of \fB$\fIc\fR are substituted
Xwherever the string is encountered). The special meaning of \fB$\fP
Xmay be escaped by preceding it with a backslash.
X.SS Input Comments
XAll text from an exclamation point (\fB!\fP) through a newline is considered
Xa comment about the format, and is ignored (it's not put into the
Xoutput stream, either). This allows you to comment long format files.
XFor instance, a format file could contain
X.in +.5i
X.nf
X.B
XI~ >n\ \ \ \ !Read the number of bytes into register n
X.B
X$n/F\ \ \ \ \ ! convert to a number of floats
X.fi
X.in -.5i
X(See the section on \fBRegisters\fP.)
X.SS Newlines
XA newline can be placed in the output stream either by using a comment
Xcontaining a newline
Xsuch as ``\fB[\\n]\fP'', or any of the special format members
X``\fBn\fP'', ``\fB;\fP'', and ``\fB\\n\fP''.
X(These three are completely equivalent; use whichever suits best.)
XThe advantage of using the the special formats
Xinstead of a comment is that it gives better-looking output:
X.I viz
Xknows about the newline inserted by the
Xformat, and takes this into account when formatting
Xoutput.
X.SS Seeking
XIf the input stream allows seeking, you can invoke
X.I fseek()
Xby entering
X.br
X.ti +.5i
X.I offset
X.B seek
X.I whence
X\ \ or \ \
X.I offset
X.B !
X.I whence
X.br
XHere, whence is one of `\fB0\fP', `\fB1\fP', or `\fB2\fP', and indicates
Xseeking from the beginning of the file, current location in the file,
Xor end of the file. For example,
X.ti +.5i
X\fB25 ! 1 \ \ \fRor\fP \ \ 25 seek 1\fR
X.br
Xseeks 25 characters forward from the current location in the file;
X.ti +.5i
X\fB0 ! 0 \ \ \fRor\fP \ \ 0 seek 0\fR
X.br
Xrewinds the file; and
X.ti +.5i
X\fB\-25 ! 2 \ \ \fRor\fP \ \ \-25 seek 2\fR
X.br
Xgoes to 25 characters before the end of the file.
X.SS Variables: Viz Registers
XYou can put the value of any integer data type read from the input stream
Xinto a
X.IR register ,
Xby following the format with
X``\fB>\fIregistername\fR.''
XFor instance,
X.ti +.5i
X.B
X\-f 'I~ >n'
X.br
Xcollects an integer (but doesn't print its value, since the output format
Xis "\fB~\fP"), and stores the value in the register named
X.BR n .
XIf you used a repeat count in the format, the value stored in the register
Xis the last read value.
XFor the special case of the
X.B Z
Xdatasize, the value stored in a register is the number of characters
Xthat were matched by the
X.B Z
Xdatasize, including the trailing null.
XThis allows you to know how
Xmany characters were processed by the
X.B Z
Xformat.
X.sp .5
XThere are 255 registers you can use, named with any single character
Xother than null. The register can be used as a
Xcount by prefixing it with "\fB$\fP". For instance, if a data stream
Xcontains an integer count that indicates the number of following floats,
Xyou could print just the float values by using
X.ti +.5i
X.B
X\-f 'I~ >n $nF'
X.br
XThis reads but doesn't print the number of bytes (\fBI~\fP),
Xstores the count in register \fB$n\fP (\fB>n\fP),
Xand then reads and prints that number of floats (\fB$nF\fP).
X.sp .5
XIf you do not store the value of an integer in a register, it is
Xautomatically stored in register \fB$#\fP.
XThus the above example could also have been written as
X.ti +.5i
X.B
X\-f 'I~ $#F'
X.sp .5
X.br
XYou can do arithmetic on registers. This is typically used for
Xconverting a byte count into a count of, say, integers. The syntax is
X.ti +.5i
X.I
X\fB$\fPregistername op value \fR[\fP op value \fR...]\fP
X.R
X.br
XThe operators
X.I op
Xand their effects are
X.RS
X.ta .5i 2.5i
X Operator Effect
X.nf
X.ta .75i 2i
X.sp .5
X \fB=\fP assign \fIvalue\fP to \fIregistername\fP
X \fB+\fP add \fIvalue\fP to \fIregistername\fP
X \fB\-\fP subtract \fIvalue\fP from \fIregistername\fP
X \fB*\fP multiply \fIregistername\fP by \fIvalue\fP
X \fB/\fP divide \fIregistername\fP by \fIvalue\fP
X \fB%\fP \fIregistername\fP modulo \fIvalue\fP
X.sp .5
X.fi
X.RE
XIn addition, the special unary operator \fBP\fP prints the
Xregister value as a decimal number in the output stream, but has no other
Xeffect. For example
X.ti +.5i
X\-f '$I = 3P+4P $xP'
X.br
Xsets $I to 3, prints $I, adds 4 to $I, and then prints the new value
Xof $I, and finally prints the value of $x.
X.sp .5
XThe
X.I value
Xis either an unsigned number, or \fB$\fIregistername\fR, or
Xone of [\fBCSILFD\fP], which stand for, respectively, sizeof(char),
Xsizeof(short), sizeof(int), sizeof(long), sizeof(float), and sizeof(double).
XNote that these letters are the same as used for specifying datasizes.
XFor instance, if a data stream
Xcontains an integer count that indicates the number of following bytes,
Xbut the data are a group of floats,
Xyou could convert the byte count to a number of floats, and then
Xprint the float values by using the format
X.ti +.5i
X\-f 'I~ >n $n/F $nF'
X.br
XThis reads but doesn't print the number of bytes (\fBI~\fP),
Xstores the count in register \fB$n\fP (\fB>n\fP),
Xdivides the number of bytes by the size of a float(\fB$n/F\fP),
Xand then reads and prints that number of floats (\fB$nF\fP).
X.PP
XOperators are evaluated left-to-right, and there is no precedence.
XFor instance, ``\fB$n+3*5\fP'' adds 3 to \fB$n\fP and then multiplies
X\fB$n\fP by 5; it \fIdoesn't\fP add 15 to \fB$n\fP.
X.PP
XThere are several special registers. You have already read about
X$#; the complete list of special registers is:
X.RS
X.IP \(bu
X.B $#
Xholds the last integer value scanned if you didn't
Xuse ">\fIc\fP" to name another register.
X.IP \(bu
X.B $(
Xis a counter: it counts the number of iterations at the current
Xparenthesis depth (a separate copy is kept for each depth).
X.IP \(bu
X.B $@
Xcontains the total number of bytes processed so far.
X.RE
XThe
X.B $(
Xcounter can be useful in labelling successive values read,
Xor successive records in a file. For example:
X.ti +.5i
X\-f '3( [$(: ] I F \\n)'
X.br
Xprints
X.nf
X.in +.5i
X1:\ \ \ \fIintvalue\fP\ \ \ \fIfloatvalue\fP
X2:\ \ \ \fIintvalue\fP\ \ \ \fIfloatvalue\fP
X3:\ \ \ \fIintvalue\fP\ \ \ \fIfloatvalue\fP
X.in -.5i
X.fi
X.SH NOTES
XThis program used to be called
X.IR vis ,
Xbut then HP came up with its own program of the same name.
XToo bad.
END_OF_FILE
if test 16818 -ne `wc -c <'viz-1.1.0/viz.1'`; then
echo shar: \"'viz-1.1.0/viz.1'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/viz.1'
fi
if test -f 'viz-1.1.0/viz.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/viz.c'\"
else
echo shar: Extracting \"'viz-1.1.0/viz.c'\" \(38649 characters\)
sed "s/^X//" >'viz-1.1.0/viz.c' <<'END_OF_FILE'
X/*
X * Usage:
X * $0 [ options... ] [ files ]
X
X * Filters the named files; if there are no files, stdin is used.
X
X * Options:
X * -r: reverse short-, int-, and long-sized objects.
X * N.B. General byte-swapping throughout the file should
X * be handled by something like dd.
X * -f fmt: format output according to fmt (default "a").
X * -F file: file contains format.
X * -h: print help message, then exit.
X * -l x: limit output to no more than x characters per line (default 80).
X * -p: print offsets (lines begin <offset>:<tab> ).
X * -o: like -p, but print using octal.
X * -P len: print offsets (lines begin <len>x<n>+<offset>:<tab> ).
X * -O: like -P, but print offset part using octal.
X * -t: use \# T (T=F,I,...) to indicate data type; also
X * start newlines for each data type or copyout, and
X * terminate copyouts with tabs. WARNING: inviz can't properly
X * invert output unless -t is set.
X
X * -L: print a human-readable version of the internal representation
X * of the format.
X * -D: turn on debug mode.
X
X * Formats:
X * see grammar.y for structure.
X
X * Output formatting:
X * Ascii:
X * bell -> \a (__STDC__ only)
X * backspace -> \b
X * formfeed -> \f
X * newline -> \n
X * return -> \r
X * tab -> \t
X * vertical tab -> \v (__STDC__ only)
X * backslash -> \\
X * ^ -> \^
X * all other printing characters (octal 040 - 177): unchanged
X * all other non-printing characters in the range 0 - 039: ^@ ^A, etc
X * all others -> \nnn
X * In addition, after transforming newline to \n, a true newline is printed.
X
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include "string.h"
X#include "memory.h"
X#include <errno.h>
X
X#include "viz.h"
X#include "version.h"
X
Xextern errno;
Xextern int sys_nerr;
Xextern char *sys_errlist[];
X
X
Xextern char *malloc();
Xextern optind, opterr;
Xextern char *optarg;
X
Xchar *prog;
Xchar *fmttext = "a"; /* Default format */
Xint show_list = 0; /* show the format list */
Xint debug = 0; /* ==list + show the creation of the list */
Xint show_type = 0; /* use \# T to show data type */
Xint process_to_eof = 1; /* !0 means user gave a counted item list */
Xint print_offset_octal = 0; /* print offsets using octal output */
Xint reverse_int = 0; /* reverse ea integral type before evaluating */
Xint do_condense = 1; /* bool: condense list if !0 */
X
Xint print_offset = 0;
X
X/* Describes what's happening on the current line. */
Xstruct {
X int maxlen; /* Maximum line length */
X int avail; /* Amount remaining on current line
X * before running into maxlen.
X */
X int avail_nl; /* amount remaining after doing newline
X * plus any offset labelling, etc.
X */
X char mode; /* Current output mode: ( a/c/C/S/.../\0 ) */
X} line = { 80, 80, 80, '\0' };
X
Xint item_len;
X
X/* For printing values in binary */
Xchar binary[256][9];
X
X/* Registers for storing counts */
Xlong count_reg[256];
X
X/* Amount of data (in chars) that have been processed so far. */
Xlong *data_offset = &count_reg[(int) '@'];
X
Xstatic struct {
X char *main; /* main i/o buffer */
X char *secondary; /* when needed, data is copied here for alignment */
X char *end; /* marks 1 past last valid posn in main buf */
X char *next; /* points to next char in main that is unprocessed */
X} readbuf = { NULL, NULL, NULL, NULL };
X
Xint out_of_size = 0; /* Set to 1 when read_data has returned all it can in
X * requested size
X */
Xint out_of_data = 0; /* Set to 1 when read_data has returned all it can
X * (note that EOF occurs before read_data finishes
X * returning all the final data from its buffer)
X */
X
X
Xtypedef union {
X char *c;
X unsigned char *uc;
X short *s;
X unsigned short *us;
X int *i;
X unsigned int *ui;
X long *l;
X unsigned long *ul;
X float *f;
X double *d;
X } ALLTYPE;
X
X#ifdef MIN
X#undef MIN
X#endif
X
X#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
X
X/* Need should be used before outputting an item; it makes sure there's
X * enough space on the current line, and if not, it calls do_newline
X * to get the space. It's a macro because it's called on a per-item basis.
X */
X#define need(n) { \
X register mode; \
X if (line.avail < (n) ) { \
X mode = line.mode; \
X do_newline(); \
X set_mode(mode); \
X } \
X}
X
X/* OUTPUTSTR uses need() to check that there's room for a string; then
X * prints it, and adjusts the available-space counter. It's a macro
X * because it's called on a per-item basis.
X */
X#define OUTPUTSTR(s) \
X{ \
X register n=0; \
X register char *q, *p; \
X q = p = (s); \
X while (*p) { \
X n++; \
X if (*p++ == '\t') n += 7; \
X } \
X need(n); \
X fputs((q), stdout); \
X line.avail -= n; \
X}
X
X/* adj_count(x) is used to keep a counter in the valid range when
X * it's counting to EOF. (Note that a file could be larger than
X * LONG_MAX, so counting bytes through EOF would not be good.)
X * Therefore adj_count(x) checks if x < 0 (which is the sign that
X * we are counting to EOF) and replaces it with UPTO_EOF, a number
X * that is less than 0 but not << 0. If x > 0, we don't assign
X * anything to x. adj_count() should not appear in any inner loop,
X * of course.
X */
X#define adj_count(x) (x < 0 ? x = UPTO_EOF : UPTO_EOF)
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X int n;
X void fillformat();
X void viz();
X void viz_text();
X void line_init();
X void binary_init();
X
X int i, nfiles;
X
X prog = argv[0];
X
X rootlist = NIL;
X
X binary_init();
X
X if ( (i = get_options(argc, argv)) == 0)
X return 1;
X
X if (yyparse() != 0)
X return 1;
X
X if (process_to_eof) {
X /* Apply an <inf> multiplier to the user's list. Potential
X * problem: when the list includes sublists, the rootlist
X * returned by the grammar points to the first sublist.
X * Thus, we repackage the entire list as a sublist of a new root;
X * this makes sure that the count applied to the rootlist is
X * applied to the entire list.
X */
X MEMBER *temp = newlist(rootlist);
X temp->count = UPTO_EOF;
X rootlist = temp;
X }
X
X if (debug || show_list) {
X (void) fprintf(stderr, "Before condensing:\n");
X printlist(0, rootlist);
X (void) fprintf(stderr, "--------\n");
X }
X
X if (do_condense) {
X n = condenselist(rootlist);
X
X if (debug || show_list) {
X (void) fprintf(stderr, "After condensing:\n");
X (void) fprintf(stderr, "%d change%s\n", n, (n!=1) ? "s" : "");
X printlist(0, rootlist);
X (void) fprintf(stderr, "--------\n");
X }
X } else {
X if (debug || show_list) {
X (void) fprintf(stderr, "List condensing is turned off\n");
X }
X }
X
X fillformat(rootlist);
X
X
X nfiles = argc - i;
X
X if (i == argc) {
X if (read_data_init() == -1)
X return 1;
X clearerr(stdin);
X out_of_size = 0;
X out_of_data = 0;
X
X line_init();
X
X if (print_offset)
X (void) put_offset();
X
X viz(rootlist, 1);
X } else {
X do {
X if (freopen(argv[i], "r", stdin) == (FILE *) NULL) {
X (void) fprintf(stderr, "%s: failed to open %s: ",prog, argv[i]);
X perror("");
X } else {
X
X if (read_data_init() == -1)
X return 1;
X clearerr(stdin);
X out_of_size = 0;
X out_of_data = 0;
X
X *data_offset = 0;
X
X if (nfiles > 1)
X (void) printf("\n==> %s <==\t\n", argv[i]);
X
X line_init();
X
X if (print_offset)
X (void) put_offset();
X
X viz(rootlist, 1);
X }
X
X } while (++i < argc);
X }
X
X if ( !out_of_data && process_to_eof && !ferror(stdin) ) {
X /* There can be up to (sizeof(double) - 1) characters that remain
X * unprocessed, if the final input elements are 'D', but only 1
X * char remains on stdin. Process the remainder in ascii.
X */
X viz_text((long) sizeof(double), 1, 'C', NULL, 0);
X }
X
X if (line.avail < (line.maxlen-1) ) { /* Note that line_init sets
X * line.avail=line.maxlen-1
X * for an empty line */
X (void) putchar('\n');
X }
X return 0;
X}
X
Xvoid
Xbinary_init()
X{
X /* Initializes the array binary[256][9] with
X * the binary ascii representation of 0..255.
X */
X
X int i, j, n;
X static char *s16[16] = {
X "0000", "0001", "0010", "0011",
X "0100", "0101", "0110", "0111",
X
X "1000", "1001", "1010", "1011",
X "1100", "1101", "1110", "1111",
X };
X
X
X for (i=0; i<16; i++)
X for (n=i*16, j=0; j<16; j++) {
X (void) strcpy(binary[n+j], s16[i]);
X (void) strcpy(binary[n+j]+4, s16[j]);
X }
X}
X
Xint get_options(argc, argv)
Xint argc;
Xchar **argv;
X{
X /* Sets options; returns argv index of first file argument.
X * If there are no file arguments, returns argc.
X */
X int c;
X char *loadfile();
X int fmt_done = 0;
X int i;
X
X while ( (c = getopt(argc, argv, "c:f:F:hl:oO:pP:tDL")) != -1) {
X switch (c) {
X case 'r':
X reverse_int = 1;
X break;
X case 'f':
X if (fmt_done) {
X (void) fprintf(stderr,
X "%s: Only one instance of -f and/or -F may be used.\n",
X prog);
X exit(1);
X }
X fmttext = optarg;
X fmt_done = 1;
X break;
X case 'F':
X if (fmt_done) {
X (void) fprintf(stderr,
X "%s: Only one instance of -f and/or -F may be used.\n",
X prog);
X exit(1);
X }
X fmttext = loadfile(optarg);
X fmt_done = 1;
X if (fmttext == NULL) {
X (void) fprintf(stderr,
X "%s: Failed to load format from `%s' -- ",
X prog, optarg);
X if (errno > 0 && errno <= sys_nerr)
X (void) fprintf(stderr, "%s\n", sys_errlist[errno]);
X else
X (void) fprintf(stderr, "errno = %d\n", errno);
X exit(1);
X }
X break;
X case 'h':
X (void) fprintf(stderr, "\
XUsage:\n%s [-f fmt | -F file] \n\
X\t[-r] [-h] [-l x] [-p|o] [-P|O len] [-t] [-L] [-D] [file ...]\n",
X prog);
X (void) fprintf(stderr, "\
XOptions:\n");
X (void) fprintf(stderr, "\
X-f fmt: format output according to fmt (default \"a\").\n\
X-F file: format is contained in file.\n\
X\n\
X-h: print this help message on stderr, then exit.\n\
X-l x: limit output to no more than x characters per line (default 80).\n\
X-p: print offsets (each line is begun <offset>:<tab> ).\n\
X-P len: print offsets using format <len>*<n>+<offset>:<tab> ).\n\
X-o, -O len: like -p and -P, but using octal for offset.\n\
X-r: reverse bytes in each integer-type value before interpreting\n\
X (this applies to short, int, and long-sized data).\n\
X-t: use \\# <T> to show data type (so inviz can invert result).\n\
X-L: print internal version of the format (not generally useful).\n\
X-D: turn on debug mode (not generally useful).\n\n");
X
X (void) fprintf(stderr, "\
XFormats:\n\
XIf fmt doesn't begin with a count, it's repeated until EOF is reached.\n\
XBasic format: [count] input_size output_fmt [ >reg_char ].\n\
X + count: decimal or $reg_char or $$.\n\
X + input_size: one of C/Z/S/I/L/F/D.\n\
X + output_fmt: one of a/b/c/d/u/o/h/x/f/g/~/\"printf-fmt\".\n\
X + Default pairings: [abc~] <-> C; [duohx] <-> I; [fg] <-> F\n\
X [CZ] <-> a; [SIL] <-> d; [FD] <-> g\n\
X + Illegal pairings: [CSIL] & [fg]; [SILFD] & [ac]; [FD] & [abcduohx]\n");
X (void) fprintf(stderr, "\
XSpecial formats:\n\
X + n or \\n output a newline; e.g. 17n means 17 newlines\n\
X + [xxx] output comment xxx; e.g. 2[hello] means print `hello' twice\n\
XCompound formats:\n\
X + The above simple formats can be concatenated:\n\
X 24a5f means 24 ascii chars, then 5 floats\n\
X + Parentheses group and nest:\n\
X I3(24a5f) means 1 int, then 3 groups of 24 chars & 5 floats\n");
X exit(0);
X break;
X case 'l':
X line.maxlen = atoi(optarg);
X break;
X case 'o':
X print_offset_octal = 1;
X /* FALLTHROUGH */
X case 'p':
X if (print_offset) {
X fprintf(stderr,
X "Options -p|o and -P|O are mutually exclusive\n");
X exit(1);
X }
X print_offset = 1;
X break;
X case 'O':
X print_offset_octal = 1;
X /* FALLTHROUGH */
X case 'P':
X if (print_offset) {
X fprintf(stderr, "Options -p and -P are mutually exclusive\n");
X exit(1);
X }
X print_offset = atoi(optarg);
X if (print_offset < 2) {
X fprintf(stderr,
X "%s: record length for offsets must be > 1; you used `%s'\n",
X prog, optarg);
X exit(1);
X }
X break;
X case 't':
X show_type = 1;
X break;
X case 'L':
X show_list = 1;
X break;
X case 'D':
X debug = 1;
X break;
X case '?':
X return 0;
X /* NOTREACHED */
X break;
X default:
X (void) fprintf(stderr,
X "%s: unexpected option `%c' returned to get_options\n",
X prog, c);
X return 0;
X /* NOTREACHED */
X break;
X }
X }
X return optind;
X}
X
Xvoid fillformat(list)
XMEMBER *list;
X{
X MEMBER *p;
X
X#define IC (p->u.iospec.ichar)
X#define OC (p->u.iospec.ochar)
X
X for (p = list; p != NIL; p = p->next) {
X if (p->type == T_LISTHEAD) {
X fillformat(p->u.sublist);
X } else if (p->type == T_IOSPEC) {
X if (p->u.iospec.fmt != NULL)
X ; /* Format already assigned by user */
X
X else if (OC == 'a' || OC == 'c' || OC == '~')
X ; /* Format isn't used for 'a', 'c', '~' output */
X
X else if (IC == 'C' && OC == 'b')
X p->u.iospec.fmt = Cb_fmt;
X else if (IC == 'C' && OC == 'o')
X p->u.iospec.fmt = Co_fmt;
X else if (IC == 'C' && OC == 'd')
X p->u.iospec.fmt = Cd_fmt;
X else if (IC == 'C' && OC == 'u')
X p->u.iospec.fmt = Cu_fmt;
X else if (IC == 'C' && OC == 'x')
X p->u.iospec.fmt = Cx_fmt;
X
X else if (IC == 'Z' && OC == 'b')
X p->u.iospec.fmt = Zb_fmt;
X else if (IC == 'Z' && OC == 'o')
X p->u.iospec.fmt = Zo_fmt;
X else if (IC == 'Z' && OC == 'd')
X p->u.iospec.fmt = Zd_fmt;
X else if (IC == 'Z' && OC == 'u')
X p->u.iospec.fmt = Zu_fmt;
X else if (IC == 'Z' && OC == 'x')
X p->u.iospec.fmt = Zx_fmt;
X
X else if (IC == 'S' && OC == 'b')
X p->u.iospec.fmt = Sb_fmt;
X else if (IC == 'S' && OC == 'o')
X p->u.iospec.fmt = So_fmt;
X else if (IC == 'S' && OC == 'd')
X p->u.iospec.fmt = Sd_fmt;
X else if (IC == 'S' && OC == 'u')
X p->u.iospec.fmt = Su_fmt;
X else if (IC == 'S' && OC == 'x')
X p->u.iospec.fmt = Sx_fmt;
X
X else if (IC == 'I' && OC == 'b')
X p->u.iospec.fmt = Ib_fmt;
X else if (IC == 'I' && OC == 'o')
X p->u.iospec.fmt = Io_fmt;
X else if (IC == 'I' && OC == 'd')
X p->u.iospec.fmt = Id_fmt;
X else if (IC == 'I' && OC == 'u')
X p->u.iospec.fmt = Iu_fmt;
X else if (IC == 'I' && OC == 'x')
X p->u.iospec.fmt = Ix_fmt;
X
X else if (IC == 'L' && OC == 'b')
X p->u.iospec.fmt = Lb_fmt;
X else if (IC == 'L' && OC == 'o')
X p->u.iospec.fmt = Lo_fmt;
X else if (IC == 'L' && OC == 'd')
X p->u.iospec.fmt = Ld_fmt;
X else if (IC == 'L' && OC == 'u')
X p->u.iospec.fmt = Lu_fmt;
X else if (IC == 'L' && OC == 'x')
X p->u.iospec.fmt = Lx_fmt;
X
X else if (IC == 'F' && OC == 'f')
X p->u.iospec.fmt = Ff_fmt;
X else if (IC == 'F' && OC == 'g')
X p->u.iospec.fmt = Fg_fmt;
X
X else if (IC == 'D' && OC == 'f')
X p->u.iospec.fmt = Df_fmt;
X else if (IC == 'D' && OC == 'g')
X p->u.iospec.fmt = Dg_fmt;
X
X else {
X (void) fprintf(stderr,
X "%s: ichar = `%c', ochar = `%c' in fillformat()!\n",
X prog, IC, OC);
X break;
X }
X }
X }
X#undef IC
X#undef OC
X}
X
Xvoid line_init()
X{
X /* Allow 1 position at end of line for the newline that is bound to
X * eventually be printed.
X */
X line.avail_nl = line.avail = line.maxlen - 1;
X line.mode = '\0';
X}
X
Xdo_newline()
X{
X /* Starts a new line of output; the output mode is set to '\0' */
X
X putchar('\n');
X line_init();
X if (print_offset)
X (void) put_offset();
X line.avail_nl = line.avail; /* amount available after doing newline */
X}
X
Xvoid set_mode(newmode)
Xint newmode;
X{
X /* Set_mode changes modes. If the mode is currently the desired mode,
X * no action is taken. Otherwise, if the mode is currently '\0',
X * it means that nothing has yet been written to the current line
X * (excepting a possible offset), and a newline need not be done
X * before output setting mode. Otherwise, if the mode is switching into
X * or out of 'a' and show_type is set, do_newline is called to set up
X * a new line; the mode is then set.
X
X * Special case: if the old mode is '~', and we are printing offsets,
X * force a newline to begin so that skipped data don't cause a
X * nonsensical offset on the line following the skipped data
X
X * Set_mode is a function on the assumption that mode changes are
X * relatively rare, compared to outputting many values at a single mode.
X */
X
X#if 0
X fprintf(stderr,
X "set_mode: line.mode = %c newmode = %c print_offset = %d\n",
X line.mode, newmode, print_offset);
X#endif
X
X if (newmode == line.mode)
X return;
X
X if (show_type) {
X if (line.avail != line.avail_nl) {
X /* have printed something; may need a newline */
X if (line.mode == 'a' || newmode == 'a'
X || (print_offset && line.mode == '~'))
X do_newline();
X }
X
X if (newmode != '\0' && newmode != 'a') {
X printf("\\# %c ", newmode);
X line.avail -= 6;
X }
X } else if (print_offset && line.mode == '~') {
X do_newline();
X }
X line.mode = newmode;
X}
X
Xread_data_init()
X{
X if ( readbuf.main == NULL) {
X if ( (readbuf.main = malloc((unsigned) BUFFERSIZE)) == NULL ||
X (readbuf.secondary = malloc((unsigned) BUFFERSIZE)) == NULL ) {
X (void) fprintf(stderr,
X "%s: malloc failed in read_data_init: ", prog);
X perror("");
X return -1;
X }
X }
X readbuf.end = readbuf.main + BUFFERSIZE;
X readbuf.next = readbuf.end;
X return 0;
X}
X
Xvoid
Xseek_data(dsize, offset, whence)
Xint dsize; /* Size of one datum */
Xlong offset; /* How much to seek, in units of dsize */
Xint whence; /* 0, 1, 2 mean seek w.r.t. start, cur, eof */
X{
X /* If seeking relative to current location, convert to an absolute
X * seek from origin (because we've probably read past user's notion
X * of current location.
X */
X long my_offset = dsize*offset;
X int my_whence = whence;
X if (whence == 1) {
X my_offset += *data_offset;
X my_whence = 0;
X }
X if (fseek(stdin, my_offset, my_whence) != 0) {
X fprintf(stderr, "%s: fseek(stdin, %ld, %d) failed:\n",
X prog, offset*dsize, whence);
X perror("");
X if (my_whence != whence) {
X fprintf(stderr, "N.B. Actual call was fseek(stdin, %ld, %d), \
Xto correct for %s's readahead.\n", my_offset, my_whence, prog);
X }
X exit(1);
X }
X /* Invalidate the current contents of the input stream */
X readbuf.next = readbuf.end;
X}
X
Xread_data(dsize, type, n, p)
Xint dsize; /* Size of one datum; must be < length of an io buffer */
Xint type; /* one of 'C' 'S', 'I', 'L', 'F', 'D', 'Z' */
Xlong n; /* number of dsize elt's requested; ignored for type==Z;
X * if < 0, LONG_MAX is substituted.
X */
Xchar **p; /* On return, *p pts to beginning of first datum */
X
X /* Return: 0 on EOF or fread error; else number available, 0 .. n
X * (A 0 return, if not EOF or error, means that there are fewer than dsize
X * chars available).
X */
X{
X register int m, nc;
X
X char *s;
X int nread;
X
X if (n < 0)
X n = LONG_MAX;
X
X /* Check if we need to get more data:
X * we get more whenever there is less than dsize data
X * remaining in our buffer (or when the type is 'Z' and there isn't
X * a null somewhere in the input buffer); otherwise, we return whatever
X * we have already available (dsize is size of one datum) */
X
X nc = readbuf.end - readbuf.next; /* number of remaining chars */
X
X /* fprintf(stderr, "readdata request is %d nc = %d... ", n, nc); */
X
X if (nc < dsize ||
X (type == 'Z' && (s = memchr(readbuf.next, '\0', nc)) == NULL) ) {
X /* need more */
X
X if (nc > 0)
X (void) memcpy(readbuf.main, readbuf.next, nc);
X
X readbuf.next = readbuf.main;
X
X /* Read more data and recompute nc */
X nread = fread(readbuf.main + nc, 1, BUFFERSIZE - nc, stdin);
X readbuf.end = readbuf.main + nc + nread;
X nc = readbuf.end - readbuf.next;
X
X if (nc < dsize)
X out_of_size = 1;
X if (nc == 0)
X out_of_data = 1;
X }
X /* fprintf(stderr, "%d\n", nc); */
X
X /* Compute m = number of dsize elements available in buffer; m is the
X * return value from read_data. We assume that all m elements
X * be consumed by caller.
X
X * Note that we've tested, above, that the number of available
X * characters is at least dsize; m will be > 0.
X */
X if (type == 'Z') {
X if ((s = memchr(readbuf.next, '\0', nc)) == NULL)
X m = nc; /* Didn't reach a null; oh well. */
X else
X m = s + 1 - readbuf.next;
X } else {
X m = MIN( nc / dsize, n);
X }
X
X
X /* Now let nc be the number of characters in m elements: */
X nc = m * dsize;
X if (aligned(type, readbuf.next)) {
X *p = readbuf.next;
X } else {
X (void) memcpy(readbuf.secondary, readbuf.next, nc);
X *p = readbuf.secondary;
X }
X readbuf.next += nc;
X
X if (reverse_int) {
X switch (type) {
X case 'S':
X {
X register i;
X register short *sp;
X for (sp = (short *) *p, i=m+1; --i; ++sp) {
X REVERSE_SHORT(*sp, short);
X }
X }
X break;
X
X case 'I':
X {
X register int i;
X register int *ip;
X for (ip = (int *) *p, i=m+1; --i; ++ip) {
X REVERSE_INT(*ip, int);
X }
X }
X break;
X
X case 'L':
X {
X register int i;
X register long *lp;
X for (lp = (long *) *p, i=m+1; --i; ++lp) {
X REVERSE_LONG(*lp, long);
X }
X }
X break;
X default:
X /* No action is default */
X break;
X }
X }
X /* fprintf(stderr, "readdata returning %d\n", m); */
X return m;
X}
X
Xvoid
Xunread_data(n)
Xlong n; /* number of chars to unread */
X
X /* Can cause terrible problems if n > number_points gotten on last
X * read_data. Silently tries to protect itself against
X * invalid arguments. (There didn't seem to be much point
X * in telling caller about invalid arguments, as caller should
X * know exactly how much data it got on last call to read_data().)
X */
X{
X
X
X
X if (readbuf.next - readbuf.main < n)
X return; /* Can't push back n chars */
X
X readbuf.next -= n;
X
X return;
X}
X
Xput_offset()
X{
X char offset_buf[60];
X int i;
X
X if (print_offset == 1) {
X if (print_offset_octal)
X (void) sprintf(offset_buf, "%#6o:\t", *data_offset);
X else
X (void) sprintf(offset_buf, "%6d:\t", *data_offset);
X
X } else {
X register int l = *data_offset / print_offset;
X register int m = *data_offset % print_offset;
X if (print_offset_octal)
X (void) sprintf(offset_buf, "%d*%d+%#3o:\t", print_offset, l, m);
X else
X (void) sprintf(offset_buf, "%d*%d+%3d:\t", print_offset, l, m);
X }
X /* Compute amount on line. Allow 8 for tab -- but strlen() returns
X * 1 for tab, so add 7 more. The line.avail value is increased by
X * 1 to allow for fact that it's decremented by line_init.
X */
X i = (line.maxlen - (line.avail + 1)) + strlen(offset_buf) + 7;
X /* Take result modulo 8 by masking off lowest 3 bits. */
X i &= ~7;
X line.avail = line.maxlen - i;
X (void) fputs(offset_buf, stdout);
X
X return 0;
X}
X
Xvoid
Xviz(list, iteration)
XMEMBER *list;
Xint iteration; /* which iteration of the list this is */
X{
X
X register i;
X MEMBER *p;
X
X long count;
X int size;
X char ichar;
X
X int n;
X long lastv;
X
X void viz_text(), viz_numeric();
X
X ALLTYPE u;
X
X count_reg[(int) '('] = iteration;
X
X for (p = list; p != NIL && !out_of_size ; p = p->next) {
X
X count = (p->count >= 0) ? p->count :
X (p->count == UPTO_EOF) ? LONG_MAX : count_reg[ - p->count];
X if (count <= 0)
X continue;
X
X switch (p->type) {
X case T_IOSPEC:
X switch (p->u.iospec.ochar) {
X case 'a':
X viz_text(count, p->u.iospec.size,
X p->u.iospec.ichar, p->u.iospec.fmt,
X (int) p->u.iospec.reg_no);
X break;
X case '~':
X /* Output nothing, but read at least the last value so that
X * we can store it in a register if need be. ...ok, we should
X * really do a seek here, but I don't think it matters that
X * much and it would be a pain to incorporate seeking when
X * not all input sources might support it.
X */
X set_mode('~');
X size = p->u.iospec.size;
X ichar = p->u.iospec.ichar;
X lastv = 0;
X /* save the last value. This is a kludgy way
X * of doing it, but what the hey.
X */
X switch (ichar) {
X case 'C':
X for (; count && (n = read_data(size, ichar, count, &u.c));
X count -= n) {
X *data_offset += n * size;
X lastv = (long) *(u.c + n - 1);
X }
X break;
X case 'Z':
X for (; count &&
X (n = read_data(size, ichar, count, &u.c)); count--) {
X *data_offset += n * size;
X lastv = n;
X }
X break;
X case 'S':
X for (; count &&
X (n = read_data(size, ichar, count, (char **) &u.s));
X count -= n) {
X *data_offset += n * size;
X lastv = (long) *(u.s + n - 1);
X }
X break;
X case 'I':
X for (; count &&
X (n = read_data(size, ichar, count, (char **) &u.i));
X count -= n) {
X *data_offset += n * size;
X lastv = (long) *(u.i + n - 1);
X }
X break;
X case 'L':
X for (; count &&
X (n = read_data(size, ichar, count, (char **) &u.l));
X count -= n) {
X *data_offset += n * size;
X lastv = *(u.l + n - 1);
X }
X break;
X default:
X /* Don't need to save values of float or double data;
X * just read it
X */
X for (; count && (n = read_data(size, ichar, count, &u.c));
X count -= n) {
X *data_offset += n * size;
X }
X break;
X }
X if (p->u.iospec.reg_no)
X count_reg[p->u.iospec.reg_no] = lastv;
X else
X count_reg['#'] = lastv;
X break;
X default:
X viz_numeric(count, p->u.iospec.size,
X p->u.iospec.ichar, p->u.iospec.ochar,
X p->u.iospec.fmt, (int) p->u.iospec.reg_no);
X break;
X }
X break;
X case T_LISTHEAD:
X for (i=0; i < count && !out_of_size; i++)
X viz(p->u.sublist, i+1);
X /* Re-load $( with iteration count for this level; was overwritten
X * by recursive call to viz().
X */
X count_reg[(int) '('] = iteration;
X break;
X case T_COPYOUT:
X {
X
X if (show_type)
X do_newline();
X for (i=0; i < count; i++) {
X char s[1000];
X viz_decode(p->u.copyout, 'a', s);
X OUTPUTSTR(s);
X if (show_type)
X OUTPUTSTR("\t");
X }
X }
X break;
X case T_SEEK:
X {
X int whence;
X if (p->u.seek.direction < 0 && p->u.seek.direction >= -255)
X whence = count_reg[-p->u.seek.direction];
X else
X whence = p->u.seek.direction;
X seek_data(1, p->u.seek.count, whence);
X }
X break;
X case T_NEWLINE:
X /* Put out n-1 newlines; then use do_newline to get the
X * final newline out.
X */
X for (i=1; i < count; i++)
X putchar('\n');
X do_newline();
X break;
X case T_MATH:
X /* Do math on register */
X n = p->u.math.operand;
X if (n == UPTO_EOF)
X n = iteration;
X else if (n < 0)
X n = count_reg[-n];
X
X for (i=0; i < count; i++) {
X switch (p->u.math.operator) {
X case '+':
X count_reg[p->u.math.reg_no] += n;
X break;
X case '-':
X count_reg[p->u.math.reg_no] -= n;
X break;
X case '*':
X count_reg[p->u.math.reg_no] *= n;
X break;
X case '/':
X count_reg[p->u.math.reg_no] /= n;
X break;
X case '%':
X count_reg[p->u.math.reg_no] %= n;
X break;
X case '=':
X count_reg[p->u.math.reg_no] = n;
X break;
X case 'P':
X /* Special case: null operator, w/ side effect of
X * printing register.
X */
X {
X char buf[100];
X (void) sprintf(buf, "%ld ", count_reg[p->u.math.reg_no]);
X OUTPUTSTR(buf);
X }
X break;
X default:
X (void) fprintf(stderr,
X "%s: unknown math operator `%c' in viz().\n",
X prog, p->u.math.operator);
X exit(1);
X }
X }
X /***
X (void) fprintf(stderr, "data_offset = %d Register %c = %d\n",
X *data_offset, p->u.math.reg_no, count_reg[p->u.math.reg_no]);
X ***/
X break;
X default:
X (void) fprintf(stderr, "%s: unknown member type %d in viz().\n",
X prog, p->type);
X exit(1);
X break;
X }
X }
X}
X
Xvoid
Xviz_text(count, size, ichar, fmt, reg_no)
Xlong count; /* negative counts process data forever */
Xint size;
Xint ichar;
Xchar *fmt;
Xint reg_no;
X{
X int n;
X register int i;
X register unsigned char c;
X register ALLTYPE u;
X register l;
X register last_was_backslash_0=0;
X ALLTYPE t;
X
X char item_buf[1000]; /* output buffer for each non-ascii item */
X
X set_mode('a');
X
X if (fmt != NULL) {
X /* User-assigned format */
X for (; count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &t.uc));
X ichar == 'Z' ? count-- : (count -= n)) {
X if (ichar == 'Z') {
X /* Treat it as a string */
X (void) sprintf(item_buf, fmt, t.c);
X l = strlen(item_buf);
X need(l);
X line.avail -= l;
X (void) puts(item_buf);
X *data_offset += n;
X } else {
X /* Treat it as a bunch of characters */
X u.uc = t.uc;
X for (i = n; i != 0; --i, (*data_offset)++ ) {
X (void) sprintf(item_buf, fmt, *u.uc++);
X l = strlen(item_buf);
X need(l);
X line.avail -= l;
X (void) puts(item_buf);
X }
X }
X }
X
X } else {
X /* Use built-in rules for outputting data */
X
X for (; count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &t.uc));
X ichar == 'Z' ? count-- : (count -= n)) {
X u.uc = t.uc;
X for (i = n; i != 0; --i, (*data_offset)++ ) {
X c = *u.uc++;
X if (isascii(c) && isprint(c)) {
X if (c == '\\' || c == '^') {
X need(2);
X (void) putchar('\\');
X (void) putchar(c);
X line.avail -= 2;
X last_was_backslash_0 = 0;
X } else {
X if (last_was_backslash_0 && isdigit(c)) {
X /* Start newline to distinguish "\03" from "\0" "3" */
X do_newline();
X }
X need(1);
X (void) putchar(c);
X line.avail--;
X last_was_backslash_0 = 0;
X }
X } else {
X /* Non-printing. N.B. Can't take the common putchar('\\')
X * lines out to the top, because if we print a '\\', and then
X * find we really need four characters, it's too late to
X * take back the already-printed backslash.
X */
X need(2);
X last_was_backslash_0 = 0;
X switch (c) {
X case '\0':
X (void) putchar('\\');
X (void) putchar('0');
X last_was_backslash_0 = 1;
X line.avail -= 2;
X break;
X#ifdef __STDC__
X case '\a':
X (void) putchar('\\');
X (void) putchar('a');
X line.avail -= 2;
X break;
X#endif
X case '\b':
X (void) putchar('\\');
X (void) putchar('b');
X line.avail -= 2;
X break;
X case '\f':
X (void) putchar('\\');
X (void) putchar('f');
X line.avail -= 2;
X break;
X case '\n':
X (void) putchar('\\');
X (void) putchar('n');
X line.avail -= 2;
X (*data_offset)++;
X do_newline();
X set_mode('a');
X (*data_offset)--;
X break;
X case '\r':
X (void) putchar('\\');
X (void) putchar('r');
X line.avail -= 2;
X break;
X case '\t':
X (void) putchar('\\');
X (void) putchar('t');
X line.avail -= 2;
X break;
X#ifdef __STDC__
X case '\v':
X (void) putchar('\\');
X (void) putchar('v');
X line.avail -= 2;
X break;
X#endif
X default:
X#ifndef EBCDIC
X if (c <= ' ') {
X (void) putchar('^');
X (void) putchar(c + 'A' - 1);
X line.avail -= 2;
X break;
X } else
X#endif
X {
X need(4);
X (void) sprintf(item_buf, "\\%3.3o", (int) c);
X (void) fputs(item_buf, stdout);
X line.avail -= 4;
X }
X break;
X }
X }
X }
X }
X } /* endif (fmt == NULL) */
X
X /* Store the count away. */
X count_reg[reg_no ? reg_no : '#'] = (ichar != 'Z') ? (long) c : n;
X}
X
Xvoid
Xviz_numeric(count, size, ichar, ochar, fmt, reg_no)
Xlong count; /* negative counts process data forever */
Xint size;
Xint ichar;
Xint ochar;
Xchar *fmt;
Xint reg_no;
X{
X register int i;
X int n;
X ALLTYPE u;
X long lastv;
X
X char item_buf[100]; /* output buffer for each item */
X
X if (ochar == 'c')
X set_mode('c');
X else
X set_mode(ichar);
X
X switch (ichar) {
X case 'C':
X case 'Z':
X /* chars */
X if (ochar == 'c') {
X for (; count && adj_count(count) &&
X (n=read_data(size, ichar, count, (char **) &u.uc));
X ichar == 'Z' ? count-- : (count -= n)) {
X
X for (i = n; i != 0; i--, (*data_offset)++) {
X if (isprint(*u.uc) && !isspace(*u.uc)) {
X (void) sprintf(item_buf, " %c ", (int) *u.uc++);
X } else if (*u.uc == '\0') {
X (void) sprintf(item_buf, " \\0 ", (int) *u.uc++);
X } else {
X (void) sprintf(item_buf, "\\%3.3o ", (int) *u.uc++);
X }
X OUTPUTSTR(item_buf);
X }
X }
X if (ichar != 'Z')
X lastv = (long) *(u.uc - 1);
X else
X lastv = n;
X
X } else if (ochar == 'b') {
X /* print in binary */
X for (; count && adj_count(count) &&
X (n = read_data(size, ichar, count, &u.uc));
X ichar == 'Z' ? count-- : (count -= n)) {
X for (i = n; i != 0; i--, (*data_offset)++) {
X /* register unsigned uc = *u.uc++;
X fprintf(stderr, "uc = %d\n", uc);
X */
X (void) sprintf(item_buf, fmt, binary[*u.uc++]);
X OUTPUTSTR(item_buf);
X }
X }
X if (ichar != 'Z')
X lastv = (long) *(u.uc - 1);
X else
X lastv = n;
X
X } else if (ochar == 'd') {
X /* plain char */
X for (; count && adj_count(count) &&
X (n = read_data(size, ichar, count, &u.c));
X ichar == 'Z' ? count-- : (count -= n)) {
X for (i = n; i != 0; i--, (*data_offset)++) {
X (void) sprintf(item_buf, fmt, (int) *u.c++);
X OUTPUTSTR(item_buf);
X }
X }
X if (ichar != 'Z')
X lastv = (long) *(u.c - 1);
X else
X lastv = n;
X
X } else {
X /* unsigned char */
X for (;count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &u.uc));
X ichar == 'Z' ? count-- : (count -= n)) {
X for (i = n; i != 0; i--, (*data_offset)++) {
X (void) sprintf(item_buf, fmt, (unsigned int) *u.uc++);
X OUTPUTSTR(item_buf);
X }
X }
X if (ichar != 'Z')
X lastv = (long) *(u.uc - 1);
X else
X lastv = n;
X }
X break;
X case 'S':
X /* shorts */
X if (ochar == 'd') {
X /* signed short */
X for (; count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &u.s));
X count -= n) {
X for (i = n; i != 0; i--, *data_offset += sizeof(short)) {
X (void) sprintf(item_buf, fmt, (int) *u.s++);
X OUTPUTSTR(item_buf);
X }
X }
X lastv = (long) *(u.s - 1);
X
X } else if (ochar == 'b') {
X /* output in binary representation */
X for (; count && adj_count(count) &&
X (n = read_data(size, ichar, count, &u.c));
X count -= n) {
X for (i = n; i != 0; i--, *data_offset += sizeof(short)) {
X register unsigned short us = *u.us++;
X (void) sprintf(item_buf, fmt
X#if (L_SHORT > 7)
X , binary[(us >> 56) & 0377]
X#endif
X#if (L_SHORT > 6)
X , binary[(us >> 48) & 0377]
X#endif
X#if (L_SHORT > 5)
X , binary[(us >> 40) & 0377]
X#endif
X#if (L_SHORT > 4)
X , binary[(us >> 32) & 0377]
X#endif
X#if (L_SHORT > 3)
X , binary[(us >> 24) & 0377]
X#endif
X#if (L_SHORT > 2)
X , binary[(us >> 16) & 0377]
X#endif
X , binary[(us >> 8) & 0377]
X , binary[us & 0377]
X );
X OUTPUTSTR(item_buf);
X }
X }
X lastv = (long) *(u.us - 1);
X
X } else {
X /* unsigned short */
X for (;count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &u.us));
X count -= n) {
X for (i=n; i != 0; i--, *data_offset += sizeof(unsigned short)) {
X (void) sprintf(item_buf, fmt, (unsigned int) *u.us++);
X OUTPUTSTR(item_buf);
X }
X }
X lastv = (long) *(u.us - 1);
X }
X break;
X case 'I':
X /* ints */
X if (ochar == 'd') {
X /* signed int */
X for (;count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &u.i));
X count -= n) {
X for (i = n; i != 0; i--, *data_offset += sizeof(int)) {
X (void) sprintf(item_buf, fmt, *u.i++);
X OUTPUTSTR(item_buf);
X }
X }
X lastv = (long) *(u.i - 1);
X
X } else if (ochar == 'b') {
X /* output in binary representation */
X for (; count && adj_count(count) &&
X (n = read_data(size, ichar, count, &u.c));
X count -= n) {
X for (i = n; i != 0; i--, *data_offset += sizeof(int)) {
X register unsigned int ui = *u.ui++;
X (void) sprintf(item_buf, fmt
X#if (L_INT > 7)
X , binary[(ui >> 56) & 0377]
X#endif
X#if (L_INT > 6)
X , binary[(ui >> 48) & 0377]
X#endif
X#if (L_INT > 5)
X , binary[(ui >> 40) & 0377]
X#endif
X#if (L_INT > 4)
X , binary[(ui >> 32) & 0377]
X#endif
X#if (L_INT > 3)
X , binary[(ui >> 24) & 0377]
X#endif
X#if (L_INT > 2)
X , binary[(ui >> 16) & 0377]
X#endif
X , binary[(ui >> 8) & 0377]
X , binary[ui & 0377]
X );
X OUTPUTSTR(item_buf);
X }
X }
X lastv = (long) *(u.i - 1);
X
X } else {
X /* unsigned int */
X for (;count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &u.ui));
X count -= n) {
X for (i = n; i != 0; i--, *data_offset += sizeof(unsigned int)) {
X (void) sprintf(item_buf, fmt, *u.ui++);
X OUTPUTSTR(item_buf);
X }
X }
X lastv = (long) *(u.ui - 1);
X }
X break;
X case 'L':
X /* longs */
X if (ochar == 'd') {
X /* signed long */
X for (;count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &u.l));
X count -= n) {
X for (i = n; i != 0; i--, *data_offset += sizeof(long)) {
X (void) sprintf(item_buf, fmt, *u.l++);
X OUTPUTSTR(item_buf);
X }
X }
X lastv = *(u.l - 1);
X
X } else if (ochar == 'b') {
X /* output in binary representation */
X for (; count && adj_count(count) &&
X (n = read_data(size, ichar, count, &u.c));
X count -= n) {
X for (i = n; i != 0; i--, *data_offset += sizeof(long)) {
X register unsigned int ul = *u.ul++;
X (void) sprintf(item_buf, fmt
X#if (L_LONG > 7)
X , binary[(ul >> 56) & 0377]
X#endif
X#if (L_LONG > 6)
X , binary[(ul >> 48) & 0377]
X#endif
X#if (L_LONG > 5)
X , binary[(ul >> 40) & 0377]
X#endif
X#if (L_LONG > 4)
X , binary[(ul >> 32) & 0377]
X#endif
X#if (L_LONG > 3)
X , binary[(ul >> 24) & 0377]
X#endif
X#if (L_LONG > 2)
X , binary[(ul >> 16) & 0377]
X#endif
X , binary[(ul >> 8) & 0377]
X , binary[ul & 0377]
X );
X OUTPUTSTR(item_buf);
X }
X }
X lastv = (long) *(u.ul - 1);
X
X } else {
X /* unsigned long */
X for (;count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &u.ul));
X count -= n) {
X for (i = n; i != 0; i--, *data_offset += sizeof(unsigned long)) {
X (void) sprintf(item_buf, fmt, *u.ul++);
X OUTPUTSTR(item_buf);
X }
X }
X lastv = (long) *(u.ul - 1);
X }
X break;
X /* NOTREACHED */
X break;
X case 'F':
X /* floats */
X for (; count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &u.f));
X count -= n) {
X for (i = n; i != 0; i--, *data_offset += sizeof(float)) {
X (void) sprintf(item_buf, fmt, *u.f++);
X OUTPUTSTR(item_buf);
X }
X }
X lastv = 0;
X break;
X case 'D':
X /* doubles */
X for (; count && adj_count(count) &&
X (n = read_data(size, ichar, count, (char **) &u.d));
X count -= n) {
X for (i = n; i != 0; i--, *data_offset += sizeof(double)) {
X (void) sprintf(item_buf, fmt, *u.d++);
X OUTPUTSTR(item_buf);
X }
X }
X lastv = 0;
X break;
X default:
X (void) fprintf(stderr,
X "%s: ichar = `%c', ochar = `%c' in viz_numeric()!\n",
X prog, ichar, ochar);
X exit(1);
X break;
X }
X count_reg[reg_no ? reg_no : '#'] = lastv;
X}
END_OF_FILE
if test 38649 -ne `wc -c <'viz-1.1.0/viz.c'`; then
echo shar: \"'viz-1.1.0/viz.c'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/viz.c'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0

wde...@nfra.nl

unread,
Mar 27, 1995, 1:28:09 PM3/27/95
to
Submitted-by: wde...@nfra.nl
Posting-number: Volume 47, Issue 105
Archive-name: viz/part02
Environment: UNIX

#! /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".

# Contents: viz-1.1.0/Artistic viz-1.1.0/Copying viz-1.1.0/lists.c
# viz-1.1.0/translate.h viz-1.1.0/viz.h viz-1.1.0/vizgrammar.y


# Wrapped by kent@ftp on Sat Mar 25 15:26:13 1995
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 2 (of 3)."'
if test -f 'viz-1.1.0/Artistic' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/Artistic'\"
else
echo shar: Extracting \"'viz-1.1.0/Artistic'\" \(5182 characters\)
sed "s/^X//" >'viz-1.1.0/Artistic' <<'END_OF_FILE'
X
X
X
X
X The "Artistic License"
X
X Preamble
X
XThe intent of this document is to state the conditions under which a
XPackage may be copied, such that the Copyright Holder maintains some
Xsemblance of artistic control over the development of the package,
Xwhile giving the users of the package the right to use and distribute
Xthe Package in a more-or-less customary fashion, plus the right to make
Xreasonable modifications.
X
XDefinitions:
X
X "Package" refers to the collection of files distributed by the
X Copyright Holder, and derivatives of that collection of files
X created through textual modification.
X
X "Standard Version" refers to such a Package if it has not been
X modified, or has been modified in accordance with the wishes
X of the Copyright Holder.
X
X "Copyright Holder" is whoever is named in the copyright or
X copyrights for the package.
X
X "You" is you, if you're thinking about copying or distributing
X this Package.
X
X "Reasonable copying fee" is whatever you can justify on the
X basis of media cost, duplication charges, time of people involved,
X and so on. (You will not be required to justify it to the
X Copyright Holder, but only to the computing community at large
X as a market that must bear the fee.)
X
X "Freely Available" means that no fee is charged for the item
X itself, though there may be fees involved in handling the item.
X It also means that recipients of the item may redistribute it
X under the same conditions they received it.
X
X1. You may make and give away verbatim copies of the source form of the
XStandard Version of this Package without restriction, provided that you
Xduplicate all of the original copyright notices and associated disclaimers.
X
X2. You may apply bug fixes, portability fixes and other modifications
Xderived from the Public Domain or from the Copyright Holder. A Package
Xmodified in such a way shall still be considered the Standard Version.
X
X3. You may otherwise modify your copy of this Package in any way, provided
Xthat you insert a prominent notice in each changed file stating how and
Xwhen you changed that file, and provided that you do at least ONE of the
Xfollowing:
X
X a) place your modifications in the Public Domain or otherwise make them
X Freely Available, such as by posting said modifications to Usenet or
X an equivalent medium, or placing the modifications on a major archive
X site such as uunet.uu.net, or by allowing the Copyright Holder to include
X your modifications in the Standard Version of the Package.
X
X b) use the modified Package only within your corporation or organization.
X
X c) rename any non-standard executables so the names do not conflict
X with standard executables, which must also be provided, and provide
X a separate manual page for each non-standard executable that clearly
X documents how it differs from the Standard Version.
X
X d) make other distribution arrangements with the Copyright Holder.
X
X4. You may distribute the programs of this Package in object code or
Xexecutable form, provided that you do at least ONE of the following:
X
X a) distribute a Standard Version of the executables and library files,
X together with instructions (in the manual page or equivalent) on where
X to get the Standard Version.
X
X b) accompany the distribution with the machine-readable source of
X the Package with your modifications.
X
X c) accompany any non-standard executables with their corresponding
X Standard Version executables, giving the non-standard executables
X non-standard names, and clearly documenting the differences in manual
X pages (or equivalent), together with instructions on where to get
X the Standard Version.
X
X d) make other distribution arrangements with the Copyright Holder.
X
X5. You may charge a reasonable copying fee for any distribution of this
XPackage. You may charge any fee you choose for support of this Package.
XYou may not charge a fee for this Package itself. However,
Xyou may distribute this Package in aggregate with other (possibly
Xcommercial) programs as part of a larger (possibly commercial) software
Xdistribution provided that you do not advertise this Package as a
Xproduct of your own.
X
X6. The scripts and library files supplied as input to or produced as
Xoutput from the programs of this Package do not automatically fall
Xunder the copyright of this Package, but belong to whomever generated
Xthem, and may be sold commercially, and may be aggregated with this
XPackage.
X
X7. C subroutines supplied by you and linked into this Package in order
Xto emulate subroutines and variables of the language defined by this
XPackage shall not be considered part of this Package, but are the
Xequivalent of input as in Paragraph 6, provided these subroutines do
Xnot change the language in any way that would cause it to fail the
Xregression tests for the language.
X
X8. The name of the Copyright Holder may not be used to endorse or promote
Xproducts derived from this software without specific prior written permission.
X
X9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
XIMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
XWARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X
X The End
END_OF_FILE
if test 5182 -ne `wc -c <'viz-1.1.0/Artistic'`; then
echo shar: \"'viz-1.1.0/Artistic'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/Artistic'
fi
if test -f 'viz-1.1.0/Copying' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/Copying'\"
else
echo shar: Extracting \"'viz-1.1.0/Copying'\" \(12487 characters\)
sed "s/^X//" >'viz-1.1.0/Copying' <<'END_OF_FILE'
X GNU GENERAL PUBLIC LICENSE
X Version 1, February 1989
X
X Copyright (C) 1989 Free Software Foundation, Inc.
X 675 Mass Ave, Cambridge, MA 02139, USA
X Everyone is permitted to copy and distribute verbatim copies
X of this license document, but changing it is not allowed.
X
X Preamble
X
X The license agreements of most software companies try to keep users
Xat the mercy of those companies. By contrast, our General Public
XLicense is intended to guarantee your freedom to share and change free
Xsoftware--to make sure the software is free for all its users. The
XGeneral Public License applies to the Free Software Foundation's
Xsoftware and to any other program whose authors commit to using it.
XYou can use it for your programs, too.
X
X When we speak of free software, we are referring to freedom, not
Xprice. Specifically, the General Public License is designed to make
Xsure that you have the freedom to give away or sell copies of free
Xsoftware, that you receive source code or can get it if you want it,
Xthat you can change the software or use pieces of it in new free
Xprograms; and that you know you can do these things.
X
X To protect your rights, we need to make restrictions that forbid
Xanyone to deny you these rights or to ask you to surrender the rights.
XThese restrictions translate to certain responsibilities for you if you
Xdistribute copies of the software, or if you modify it.
X
X For example, if you distribute copies of a such a program, whether
Xgratis or for a fee, you must give the recipients all the rights that
Xyou have. You must make sure that they, too, receive or can get the
Xsource code. And you must tell them their rights.
X
X We protect your rights with two steps: (1) copyright the software, and
X(2) offer you this license which gives you legal permission to copy,
Xdistribute and/or modify the software.
X
X Also, for each author's protection and ours, we want to make certain
Xthat everyone understands that there is no warranty for this free
Xsoftware. If the software is modified by someone else and passed on, we
Xwant its recipients to know that what they have is not the original, so
Xthat any problems introduced by others will not reflect on the original
Xauthors' reputations.
X
X The precise terms and conditions for copying, distribution and
Xmodification follow.
X
X GNU GENERAL PUBLIC LICENSE
X TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
X
X 0. This License Agreement applies to any program or other work which
Xcontains a notice placed by the copyright holder saying it may be
Xdistributed under the terms of this General Public License. The
X"Program", below, refers to any such program or work, and a "work based
Xon the Program" means either the Program or any work containing the
XProgram or a portion of it, either verbatim or with modifications. Each
Xlicensee is addressed as "you".
X
X 1. You may copy and distribute verbatim copies of the Program's source
Xcode as you receive it, in any medium, provided that you conspicuously and
Xappropriately publish on each copy an appropriate copyright notice and
Xdisclaimer of warranty; keep intact all the notices that refer to this
XGeneral Public License and to the absence of any warranty; and give any
Xother recipients of the Program a copy of this General Public License
Xalong with the Program. You may charge a fee for the physical act of
Xtransferring a copy.
X
X 2. You may modify your copy or copies of the Program or any portion of
Xit, and copy and distribute such modifications under the terms of Paragraph
X1 above, provided that you also do the following:
X
X a) cause the modified files to carry prominent notices stating that
X you changed the files and the date of any change; and
X
X b) cause the whole of any work that you distribute or publish, that
X in whole or in part contains the Program or any part thereof, either
X with or without modifications, to be licensed at no charge to all
X third parties under the terms of this General Public License (except
X that you may choose to grant warranty protection to some or all
X third parties, at your option).
X
X c) If the modified program normally reads commands interactively when
X run, you must cause it, when started running for such interactive use
X in the simplest and most usual way, to print or display an
X announcement including an appropriate copyright notice and a notice
X that there is no warranty (or else, saying that you provide a
X warranty) and that users may redistribute the program under these
X conditions, and telling the user how to view a copy of this General
X Public License.
X
X d) You may charge a fee for the physical act of transferring a
X copy, and you may at your option offer warranty protection in
X exchange for a fee.
X
XMere aggregation of another independent work with the Program (or its
Xderivative) on a volume of a storage or distribution medium does not bring
Xthe other work under the scope of these terms.
X
X 3. You may copy and distribute the Program (or a portion or derivative of
Xit, under Paragraph 2) in object code or executable form under the terms of
XParagraphs 1 and 2 above provided that you also do one of the following:
X
X a) accompany it with the complete corresponding machine-readable
X source code, which must be distributed under the terms of
X Paragraphs 1 and 2 above; or,
X
X b) accompany it with a written offer, valid for at least three
X years, to give any third party free (except for a nominal charge
X for the cost of distribution) a complete machine-readable copy of the
X corresponding source code, to be distributed under the terms of
X Paragraphs 1 and 2 above; or,
X
X c) accompany it with the information you received as to where the
X corresponding source code may be obtained. (This alternative is
X allowed only for noncommercial distribution and only if you
X received the program in object code or executable form alone.)
X
XSource code for a work means the preferred form of the work for making
Xmodifications to it. For an executable file, complete source code means
Xall the source code for all modules it contains; but, as a special
Xexception, it need not include source code for modules which are standard
Xlibraries that accompany the operating system on which the executable
Xfile runs, or for standard header files or definitions files that
Xaccompany that operating system.
X
X 4. You may not copy, modify, sublicense, distribute or transfer the
XProgram except as expressly provided under this General Public License.
XAny attempt otherwise to copy, modify, sublicense, distribute or transfer
Xthe Program is void, and will automatically terminate your rights to use
Xthe Program under this License. However, parties who have received
Xcopies, or rights to use copies, from you under this General Public
XLicense will not have their licenses terminated so long as such parties
Xremain in full compliance.
X
X 5. By copying, distributing or modifying the Program (or any work based
Xon the Program) you indicate your acceptance of this license to do so,
Xand all its terms and conditions.
X
X 6. Each time you redistribute the Program (or any work based on the
XProgram), the recipient automatically receives a license from the original
Xlicensor to copy, distribute or modify the Program subject to these
Xterms and conditions. You may not impose any further restrictions on the
Xrecipients' exercise of the rights granted herein.
X
X 7. The Free Software Foundation may publish revised and/or new versions
Xof the General Public License from time to time. Such new versions will
Xbe similar in spirit to the present version, but may differ in detail to
Xaddress new problems or concerns.
X
XEach version is given a distinguishing version number. If the Program
Xspecifies a version number of the license which applies to it and "any
Xlater version", you have the option of following the terms and conditions
Xeither of that version or of any later version published by the Free
XSoftware Foundation. If the Program does not specify a version number of
Xthe license, you may choose any version ever published by the Free Software
XFoundation.
X
X 8. If you wish to incorporate parts of the Program into other free
Xprograms whose distribution conditions are different, write to the author
Xto ask for permission. For software which is copyrighted by the Free
XSoftware Foundation, write to the Free Software Foundation; we sometimes
Xmake exceptions for this. Our decision will be guided by the two goals
Xof preserving the free status of all derivatives of our free software and
Xof promoting the sharing and reuse of software generally.
X
X NO WARRANTY
X
X 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
XOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
XPROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
XOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
XMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
XTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
XPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
XREPAIR OR CORRECTION.
X
X 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
XWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
XREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
XINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
XOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
XTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
XYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
XPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
XPOSSIBILITY OF SUCH DAMAGES.
X
X END OF TERMS AND CONDITIONS
X
X Appendix: How to Apply These Terms to Your New Programs
X
X If you develop a new program, and you want it to be of the greatest
Xpossible use to humanity, the best way to achieve this is to make it
Xfree software which everyone can redistribute and change under these
Xterms.
X
X To do so, attach the following notices to the program. It is safest to
Xattach them to the start of each source file to most effectively convey
Xthe exclusion of warranty; and each file should have at least the
X"copyright" line and a pointer to where the full notice is found.
X
X <one line to give the program's name and a brief idea of what it does.>
X Copyright (C) 19yy <name of author>
X
X This program is free software; you can redistribute it and/or modify
X it under the terms of the GNU General Public License as published by
X the Free Software Foundation; either version 1, or (at your option)
X any later version.
X
X This program is distributed in the hope that it will be useful,
X but WITHOUT ANY WARRANTY; without even the implied warranty of
X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X GNU General Public License for more details.
X
X You should have received a copy of the GNU General Public License
X along with this program; if not, write to the Free Software
X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X
XAlso add information on how to contact you by electronic and paper mail.
X
XIf the program is interactive, make it output a short notice like this
Xwhen it starts in an interactive mode:
X
X Gnomovision version 69, Copyright (C) 19xx name of author
X Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
X This is free software, and you are welcome to redistribute it
X under certain conditions; type `show c' for details.
X
XThe hypothetical commands `show w' and `show c' should show the
Xappropriate parts of the General Public License. Of course, the
Xcommands you use may be called something other than `show w' and `show
Xc'; they could even be mouse-clicks or menu items--whatever suits your
Xprogram.
X
XYou should also get your employer (if you work as a programmer) or your
Xschool, if any, to sign a "copyright disclaimer" for the program, if
Xnecessary. Here a sample; alter the names:
X
X Yoyodyne, Inc., hereby disclaims all copyright interest in the
X program `Gnomovision' (a program to direct compilers to make passes
X at assemblers) written by James Hacker.
X
X <signature of Ty Coon>, 1 April 1989
X Ty Coon, President of Vice
X
XThat's all there is to it!
END_OF_FILE
if test 12487 -ne `wc -c <'viz-1.1.0/Copying'`; then
echo shar: \"'viz-1.1.0/Copying'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/Copying'
fi
if test -f 'viz-1.1.0/lists.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/lists.c'\"
else
echo shar: Extracting \"'viz-1.1.0/lists.c'\" \(12372 characters\)
sed "s/^X//" >'viz-1.1.0/lists.c' <<'END_OF_FILE'


X
X#include <stdio.h>
X#include <ctype.h>
X#include "string.h"

X#include <errno.h>
X
X#include "viz.h"
X
Xextern errno;
X
Xextern char *malloc();
X
Xvoid
Xprintlist(level, list)
Xint level;


XMEMBER *list;
X{
X MEMBER *p;
X

X if (level > 0)
X (void) fprintf(stderr, "%*.*s ", level*4, level*4, " ");


X
X for (p = list; p != NIL; p = p->next) {
X

X if (p->count == UPTO_EOF)
X (void) fprintf(stderr, "<inf>");
X else if (p->count < 0)
X (void) fprintf(stderr, "$%c", - p->count);
X else
X (void) fprintf(stderr, "%d", p->count);
X


X if (p->type == T_LISTHEAD) {
X

X (void) fprintf(stderr, "(sublist) ");
X
X } else if (p->type == T_COPYOUT) {
X
X (void) fprintf(stderr, "[%s] ", p->u.copyout);
X
X } else if (p->type == T_SEEK) {
X
X (void) fprintf(stderr, "%l!%d ", p->u.seek.count,
X p->u.seek.direction);
X
X } else if (p->type == T_MATH) {
X
X (void) fprintf(stderr, "$%c%c%d ",
X p->u.math.reg_no, p->u.math.operator, p->u.math.operand);
X
X } else if (p->type == T_NEWLINE) {
X
X (void) fputs("\\n ", stderr);
X
X } else {
X
X (void) fprintf(stderr, "(%c,%c,%d",
X p->u.iospec.ichar, p->u.iospec.ochar, p->u.iospec.size);
X if (p->u.iospec.reg_no > 0)
X (void) fprintf(stderr, ">%c", p->u.iospec.reg_no);
X (void) fprintf(stderr, ") ");
X }
X }
X (void) fprintf(stderr, "\n");


X
X for (p = list; p != NIL; p = p->next) {
X if (p->type == T_LISTHEAD)

X printlist(level+1, p->u.sublist);
X }
X}
X
X/* Create a new list with mem its first member.
X * Do this by
X * - allocating a T_LISTHEAD member that points to mem as its sublist;
X * - give the listhead a repeat count of 1;
X * - give the listhead a NIL next field.
X * Return ptr to the listhead.
X */
XMEMBER *
Xnewlist(mem)
XMEMBER *mem;


X{
X MEMBER *p;
X

X p = (MEMBER *) malloc(sizeof(MEMBER));
X if (p != NIL) {
X p->next = NIL;
X p->type = T_LISTHEAD;
X p->count = 1;
X p->u.sublist = mem;
X }
X return p;
X}
X
X/* Add a member to a list; returns 1st arg */
XMEMBER *addmember(list, member)
XMEMBER *list; /* listhead member */
XMEMBER *member;


X{
X MEMBER *p;
X

X p = list->u.sublist;
X while (p->next)
X p = p->next;
X
X p->next = member;
X member->next = NIL;
X
X return list;
X}
X
X/* Makes the core of an iospec -- everything except for a reg_no is
X * filled in (fmt is NULL, but is implied by the ichar/ochar setting).
X */
XIOSPEC
Xmakecore(ichar, ochar)
Xint ichar;
Xint ochar;
X{
X IOSPEC io;
X int defaultichar();
X int defaultochar();
X
X if (ichar == 0 && ochar == 0) {
X ichar = 'C';
X ochar = 'a';
X } else if (ichar == 0) {
X ichar = defaultichar(ochar);
X } else if (ochar == 0) {
X ochar = defaultochar(ichar);
X }
X
X io.size = getsize(ichar);
X io.ichar = ichar;
X io.ochar = ochar;
X io.fmt = NULL;
X io.reg_no = 0;
X
X return io;
X}
X
X/* Makes the core of an iospec when a printf-style outform is given */
XIOSPEC
Xmakecorepct(ichar, fmt)
Xint ichar;
Xchar *fmt;
X{
X IOSPEC io;
X
X if (ichar == 0) {
X io.ichar = 'C';
X io.ochar = 'a';
X } else {
X io.ichar = ichar;
X io.ochar = defaultochar(ichar);
X }
X
X io.size = getsize(ichar);
X io.fmt = fmt;
X io.reg_no = 0;
X
X return io;
X}
X
X/* Condenses a list.
X * Returns the total number of changes made to the list.
X
X * condenselist() does the following:
X * - combines similar adjacent members into single members;
X * - combines similar adjacent sublists into single sublists;
X * - merges sublists that have unit repeat count or are of
X * unit length into the body of the list;
X */
Xint
Xcondenselist(list)
XMEMBER *list; /* pointer to a listhead member */
X{
X /* Work over each member of list. Each pass is recursive on
X * sublists, so that all sublists are completely processed before
X * a current list is processed.
X
X * Combining duplicates is done first, so that sublists can be
X * merged into the current list, if at all possible. However,
X * once a list has been merged, there may be a new duplicate
X * at the merge point. Therefore, if there are any merged sublists,
X * we have to repeat the member-combining passes.
X
X * Pass 1: comb_dup_nl()
X * Combine adjacent duplicate non-lists into single members.
X
X * Pass 2: comb_dup_list()
X * Combine adjacent duplicate lists into single lists.
X
X * Pass 3: merge_sublist()
X * Merge sublists that have unit repeat counts or are one
X * element long into current list.
X
X */
X int nmerge;
X int nchange = 0;
X
X do {
X nchange += comb_dup_nl(list);
X nchange += comb_dup_list(list);
X nmerge = merge_sublist(list);
X nchange += nmerge;
X } while (nmerge > 0);
X return nchange;
X}
X
X
Xint
Xcomb_dup_nl(list)
XMEMBER *list; /* Pointer to a member of list; can be listhead or otherwise */
X{
X register MEMBER *p, *q;
X
X /* Combine adjacent duplicate non-list members into single members. */
X
X int nchange = 0;
X
X /* Process sublists first */


X for (p = list; p != NIL; p = p->next) {
X if (p->type == T_LISTHEAD)

X nchange += comb_dup_nl(p->u.sublist);
X }
X
X /* Now process duplicate non-list members */
X p = list;
X while ( (q = p->next) != NIL) {
X if (p->type == q->type) {
X if (
X (p->type == T_IOSPEC &&
X (p->count == UPTO_EOF || p->count >= 0) &&
X (q->count == UPTO_EOF || q->count >= 0) &&
X p->u.iospec.reg_no == q->u.iospec.reg_no &&
X p->u.iospec.size == q->u.iospec.size &&
X p->u.iospec.ichar == q->u.iospec.ichar &&
X p->u.iospec.ochar == q->u.iospec.ochar &&
X p->u.iospec.fmt == q->u.iospec.fmt) ||
X (p->type == T_MATH &&
X p->u.math.reg_no == q->u.math.reg_no &&
X p->u.math.operator == q->u.math.operator &&
X p->u.math.operand == q->u.math.operand) ||
X (p->type == T_COPYOUT &&
X (strcmp(p->u.copyout, q->u.copyout) == 0)) ||
X (p->type == T_NEWLINE)
X ) {
X /* Two successive non-list members do the same thing;
X * join them.
X */
X nchange++;
X if (p->count == UPTO_EOF || q->count == UPTO_EOF)
X p->count = UPTO_EOF;
X else
X p->count += q->count;
X p->next = q->next;
X /* Don't advance member pointer p; that way, we'll
X * compare the combined member to next one.
X */
X } else {
X /* Can't reduce these members; advance to next member */
X p = q;
X }
X } else {
X /* Can't reduce these members; advance to next member */
X p = q;
X }
X }
X return nchange;
X}
X
Xint
Xcomb_dup_list(list)
XMEMBER *list; /* Pointer to a member of list; can be listhead or otherwise */
X{
X register MEMBER *p, *q;
X int nchange;
X
X /* Combine adjacent duplicate lists into single lists. */
X
X for (nchange = 0, p=list; p != NIL; ) {
X
X if (p->type != T_LISTHEAD) {
X /* Not a list */
X p = p->next;
X continue;
X }
X nchange += comb_dup_list(p->u.sublist);
X
X q = p->next;
X if (q == NIL)
X return nchange;
X
X if (q->type != T_LISTHEAD) {
X /* Not a sublist */
X p = q->next;
X continue;
X }
X
X if (((p->count > 0 && q->count > 0) ||
X (p->count == UPTO_EOF && q->count == UPTO_EOF)) &&
X duplicates(p->u.sublist, q->u.sublist)) {
X /* Two successive lists do the same thing; join them. */
X nchange++;
X if (p->count == UPTO_EOF || q->count == UPTO_EOF)
X p->count = UPTO_EOF;
X else
X p->count += q->count;
X p->next = q->next;
X
X /* Don't advance member pointer p; that way, we'll
X * compare the combined member to next one.
X */
X } else {
X /* Can't reduce these members; advance to next member */
X p = q;
X }
X }
X return nchange;
X}
X
Xint
Xmerge_sublist(list)
XMEMBER *list; /* Pointer to a member of list; can be listhead or otherwise */
X{
X /* Merge sublists of list that have unit repeat counts or are one
X * element long into list.
X
X * Return resulting list length.
X */
X
X register MEMBER *p, *end;
X int nchange;
X long test;
X
X for (nchange=0, p=list; p != NIL; p = p->next) {
X
X /* p points to successive members of list */
X
X if (p->type != T_LISTHEAD) {
X /* Not a listhead; nothing to merge here */
X continue;
X }
X
X /* First, merge p's sublists into it. */
X nchange += merge_sublist(p->u.sublist);
X
X
X /* In following line, note that a single-member sublist
X * has the value p->u.sublist->next == NIL.
X */
X
X if ( (p->count < 0 && p->count != UPTO_EOF) ||
X (p->count > 1 && p->u.sublist->next != NIL)) {
X /* Can't merge sublist into current list:
X * either a count comes from a register, or
X * sublist has multiple members and our repeat count > 1.
X */
X continue;
X }
X
X /* Get here if the sublist is repeated once or if it's
X * got just 1 member. Merge the sublist into current list.
X */
X nchange++;
X if (p->count == UPTO_EOF || p->count > 1) {
X /* Sublist must have only one member. Fold the repeat
X * counts together, so that the listhead member contains
X * a count of 1, and it can then be discarded.
X */
X
X /* If either count is UPTO_EOF, use that as total count.
X * Otherwise, don't merge unless the product of the two
X * values can still fit into a long.
X */
X if (p->count == UPTO_EOF || p->u.sublist->count == UPTO_EOF) {
X p->u.sublist->count = UPTO_EOF;
X } else {
X test = p->u.sublist->count * p->count;
X if (test / p->count != p->u.sublist->count)
X continue;
X else
X p->u.sublist->count = test;
X }
X }
X /* The listhead now has a repeat count of one. Replace it with
X * the sublist. Find end of list, and connect it to successor
X * of current listhead.
X */
X end = p->u.sublist;
X while (end->next)
X end = end->next;
X end->next = p->next;
X
X /* Copy the first member of the sublist onto the
X * listhead member.
X
X * [[ It would be better to just discard the listhead member
X * and insert the sublist member, but since the lists are
X * singly-linked, we don't easily know who is pointing to
X * the listhead, so we can't adjust their pointers.
X * An alternative would be to make the listhead member
X * into a no-op that points to the former first member
X * of the sublist, and optionally remove the no-op on
X * a second pass. But since the list member structures
X * are small and discarded listheads will probably be
X * only occasional, copying is cheaper than a ton of compares
X * on a second pass. ]]
X */
X *p = *(p->u.sublist);
X }
X return nchange;
X}
X
Xduplicates(list1, list2)
XMEMBER *list1, *list2; /* listhead or other list member */
X{
X /* Returns non-zero if two lists are the same, including their
X * count fields. However, if either count field is < 0, the two
X * lists will automatically compare unequal, so that we don't have to
X * try to determine if the count registers will necessarily contain
X * the same value at execution time.
X
X * Note that if you want to compare the xxx and yyy in the
X * lists 3(xxx) and 14(yyy), you should pass pointers to the first
X * members of xxx and yyy, so that you don't compare the repeat
X * counts "3" and "14", which will of course compare unequal.
X
X */
X
X for (; list1 != NIL && list2 != NIL;
X list1 = list1->next, list2 = list2->next) {
X
X if (list1->type != list2->type)
X return 0;
X
X if (list1->count < 0 || list2->count < 0 ||
X list1->count != list2->count)
X return 0;
X
X switch (list1->type) {
X
X case T_COPYOUT:
X
X if (strcmp(list1->u.copyout, list2->u.copyout) != 0)
X return 0;
X break;
X
X case T_MATH:
X
X if (list1->u.math.reg_no != list2->u.math.reg_no ||
X list1->u.math.operator != list2->u.math.operator ||
X list1->u.math.operand != list2->u.math.operand)
X return 0;
X break;
X
X case T_IOSPEC:
X
X if (list1->u.iospec.size != list2->u.iospec.size ||
X list1->u.iospec.ichar != list2->u.iospec.ichar ||
X list1->u.iospec.ochar != list2->u.iospec.ochar ||
X list1->u.iospec.fmt != list2->u.iospec.fmt ||
X list1->u.iospec.reg_no != list2->u.iospec.reg_no)
X return 0;
X break;
X
X case T_LISTHEAD:
X
X if (duplicates(list1->u.sublist, list2->u.sublist) == 0)
X return 0;
X
X break;
X


X default:
X (void) fprintf(stderr,

X "%s: unknown type %d in duplicates()\n", prog, list1->type);
X }
X }
X if (list1 != NIL || list2 != NIL)
X return 0; /* list lengths differ */
X else
X return 1;
X
X /* NOTREACHED */
X}
X
X/* Returns the number of members of a sublist; returns 0 if list is
X * not a listhead.
X */
Xlistlen(list)
XMEMBER *list; /* Points to a listhead */
X{
X int n;
X if (list->type != T_LISTHEAD)
X return 0;
X
X for (n=0, list = list->u.sublist; list != NIL; n++, list = list->next)
X ;
X return n;
X}
END_OF_FILE
if test 12372 -ne `wc -c <'viz-1.1.0/lists.c'`; then
echo shar: \"'viz-1.1.0/lists.c'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/lists.c'
fi
if test -f 'viz-1.1.0/translate.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/translate.h'\"
else
echo shar: Extracting \"'viz-1.1.0/translate.h'\" \(1684 characters\)
sed "s/^X//" >'viz-1.1.0/translate.h' <<'END_OF_FILE'
X
X/* The following macros are 15-20% faster than using the usual [but
X * much more compact] (c + 1 - '0') sort of translation.
X */
X#define translate_octal(cc, s) \
X{ \
X register i; \
X for (cc = 0, i=4; isdigit(*s) && *s != '8' && *s != '9' && --i != 0;) { \
X cc <<= 3; \
X switch (*s++) { \
X case '0': \
X break; \
X case '1': \
X cc |= 1; \
X break; \
X case '2': \
X cc |= 2; \
X break; \
X case '3': \
X cc |= 3; \
X break; \
X case '4': \
X cc |= 4; \
X break; \
X case '5': \
X cc |= 5; \
X break; \
X case '6': \
X cc |= 6; \
X break; \
X default: \
X cc |= 7; \


X break; \
X } \
X } \
X}
X

X#define translate_hex(cc, s) \
X{ \
X for (cc = 0; isxdigit(*s); ) { \
X cc <<= 4; \
X switch (*s++) { \
X case '0': \
X break; \
X case '1': \
X cc |= 1; \
X break; \
X case '2': \
X cc |= 2; \
X break; \
X case '3': \
X cc |= 3; \
X break; \
X case '4': \
X cc |= 4; \
X break; \
X case '5': \
X cc |= 5; \
X break; \
X case '6': \
X cc |= 6; \
X break; \
X case '7': \
X cc |= 7; \
X break; \
X case '8': \
X cc |= 8; \
X break; \
X case '9': \
X cc |= 9; \
X break; \
X case 'a': \
X case 'A': \
X cc |= 10; \
X break; \
X case 'b': \
X case 'B': \
X cc |= 11; \
X break; \
X case 'c': \
X case 'C': \
X cc |= 12; \
X break; \
X case 'd': \
X case 'D': \
X cc |= 13; \
X break; \
X case 'e': \
X case 'E': \
X cc |= 14; \
X break; \
X default: \
X cc |= 15; \


X break; \
X } \
X } \
X}

END_OF_FILE
if test 1684 -ne `wc -c <'viz-1.1.0/translate.h'`; then
echo shar: \"'viz-1.1.0/translate.h'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/translate.h'
fi
if test -f 'viz-1.1.0/viz.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/viz.h'\"
else
echo shar: Extracting \"'viz-1.1.0/viz.h'\" \(7927 characters\)
sed "s/^X//" >'viz-1.1.0/viz.h' <<'END_OF_FILE'
X/* Dep.h handles the system dependencies */
X#include "dep.h"
X
Xextern long count_reg[256];
Xextern int process_to_eof;
Xextern int debug;
Xextern char *prog;
Xextern char *fmttext;
X
X#define UPTO_EOF -1000 /* Code for '$' used as a number; must not be -255..0,
X * because those are the codes for the $x registers.
X */
X
X#define T_LISTHEAD 00000001
X#define T_COPYOUT 00000010
X#define T_IOSPEC 00000100
X#define T_NEWLINE 00001000
X#define T_MATH 00010000
X#define T_SEEK 00100000
X
Xtypedef struct {
X short size;
X char ichar;
X char ochar;
X unsigned char reg_no; /* If reg_no != 0, indicates that the value
X * read in at runtime is to be stored in
X * count_reg[reg_no].
X */
X char *fmt; /* Format spec, such as "%d", to control
X * printing of these data.
X */
X
X} IOSPEC;
X
Xtypedef struct member *LISTHEAD;
X
Xtypedef struct {
X short reg_no;
X short operator;
X long operand;
X} REG_MATH;
X
Xtypedef struct {
X long count;
X int direction;
X} STRM_SEEK;
X
Xtypedef union {
X LISTHEAD sublist;
X char *copyout;
X IOSPEC iospec;
X REG_MATH math;
X STRM_SEEK seek;
X} ITEM;
X
Xtypedef struct member {
X struct member *next;
X
X int type; /* One of T_LISTHEAD, T_COPYOUT, T_IOSPEC,
X * T_NEWLINE, T_MATH, T_PRINT
X */
X
X long count; /* Number of repeats of u.<type>.
X * If count < 0, take actual count from
X * count_reg[-count].
X */
X
X ITEM u; /* union of listhead ptr, copyout ptr, iospec, math */
X} MEMBER;
X
Xtypedef MEMBER *MEMP;
X
X#define NIL ((MEMP) 0)
X
XMEMP rootlist;
X
X
Xtypedef union {
X char *sval;
X int ival;
X long lval;
X unsigned long nval;
X ITEM item;
X MEMP memp;
X} YYSTYPE;
X
Xextern void printlist(); /* Prints a list in human-readable form */
Xextern int condenselist(); /* Condenses a list to most efficient form */
Xextern int listlen(); /* Length of a list */
Xextern int duplicates(); /* Non-zero if two lists or mem's are similar */
Xextern MEMP newlist(); /* Creates a new listhead */
Xextern MEMP addmember(); /* Adds a member to the tail of a list */
Xextern IOSPEC makecore(); /* Creates the basic structure of a member */
Xextern IOSPEC makecorepct(); /* like makecore(), but takes user's own fmt */
Xextern int defaultichar(); /* Returns default ichar for given ochar */
Xextern int defaultochar(); /* Returns default ochar for given ichar */
Xextern int getsize(); /* Returns size of input data, given ichar */
Xextern int inval4reg(); /* Checks if datum can be stored in a #x reg */
Xextern int comb_dup_nl(); /* Combines duplicate non-list members */
Xextern int comb_dup_list(); /* Combines duplicates sublists */
Xextern int merge_sublist(); /* Merges a sublist into parent list */
Xextern void viz_decode(); /* Interprets viz copyouts */
X
X
X
X/* REVERSE_nn reverses an nn-char atomic object, x. It
X * requires an additional argument Type_nn that specifies the
X * type of the atomic object.
X */
X#define REVERSE_2(x, Type_2) { \
X union { char c[2]; Type_2 i; } u0, u1; \
X u0.i = (x); \
X u1.c[1] = u0.c[0]; \
X u1.c[0] = u0.c[1]; \
X (x) = u1.i; \
X }
X
X#define REVERSE_3(x, Type_3) { \
X union { char c[3]; Type_3 i; } u0, u1; \
X u0.i = (x); \
X u1.c[2] = u0.c[0]; \
X u1.c[1] = u0.c[1]; \
X u1.c[0] = u0.c[2]; \
X (x) = u1.i; \
X }
X
X#define REVERSE_4(x, Type_4) { \
X union { char c[4]; Type_4 i; } u0, u1; \
X u0.i = (x); \
X u1.c[3] = u0.c[0]; \
X u1.c[2] = u0.c[1]; \
X u1.c[1] = u0.c[2]; \
X u1.c[0] = u0.c[3]; \
X (x) = u1.i; \
X }
X
X#define REVERSE_5(x, Type_5) { \
X union { char c[5]; Type_5 i; } u0, u1; \
X u0.i = (x); \
X u1.c[4] = u0.c[0]; \
X u1.c[3] = u0.c[1]; \
X u1.c[2] = u0.c[2]; \
X u1.c[1] = u0.c[3]; \
X u1.c[0] = u0.c[4]; \
X (x) = u1.i; \
X }
X
X#define REVERSE_6(x, Type_6) { \
X union { char c[6]; Type_6 i; } u0, u1; \
X u0.i = (x); \
X u1.c[5] = u0.c[0]; \
X u1.c[4] = u0.c[1]; \
X u1.c[3] = u0.c[2]; \
X u1.c[2] = u0.c[3]; \
X u1.c[1] = u0.c[4]; \
X u1.c[0] = u0.c[5]; \
X (x) = u1.i; \
X }
X
X#define REVERSE_7(x, Type_7) { \
X union { char c[7]; Type_7 i; } u0, u1; \
X u0.i = (x); \
X u1.c[6] = u0.c[0]; \
X u1.c[5] = u0.c[1]; \
X u1.c[4] = u0.c[2]; \
X u1.c[3] = u0.c[3]; \
X u1.c[2] = u0.c[4]; \
X u1.c[1] = u0.c[5]; \
X u1.c[0] = u0.c[6]; \
X (x) = u1.i; \
X }
X
X#define REVERSE_8(x, Type_8) { \
X union { char c[8]; Type_8 i; } u0, u1; \
X u0.i = (x); \
X u1.c[7] = u0.c[0]; \
X u1.c[6] = u0.c[1]; \
X u1.c[5] = u0.c[2]; \
X u1.c[4] = u0.c[3]; \
X u1.c[3] = u0.c[4]; \
X u1.c[2] = u0.c[5]; \
X u1.c[1] = u0.c[6]; \
X u1.c[0] = u0.c[7]; \
X (x) = u1.i; \
X }
X
X#if ( L_SHORT == 2 )
X#define REVERSE_SHORT REVERSE_2
X#endif
X#if ( L_SHORT == 3 )
X#define REVERSE_SHORT REVERSE_3
X#endif
X#if ( L_SHORT == 4 )
X#define REVERSE_SHORT REVERSE_4
X#endif
X#if ( L_SHORT == 5 )
X#define REVERSE_SHORT REVERSE_5
X#endif
X#if ( L_SHORT == 6 )
X#define REVERSE_SHORT REVERSE_6
X#endif
X#if ( L_SHORT == 7 )
X#define REVERSE_SHORT REVERSE_7
X#endif
X#if ( L_SHORT == 8 )
X#define REVERSE_SHORT REVERSE_8
X#endif
X
X
X#if ( L_INT == 2 )
X#define REVERSE_INT REVERSE_2
X#endif
X#if ( L_INT == 3 )
X#define REVERSE_INT REVERSE_3
X#endif
X#if ( L_INT == 4 )
X#define REVERSE_INT REVERSE_4
X#endif
X#if ( L_INT == 5 )
X#define REVERSE_INT REVERSE_5
X#endif
X#if ( L_INT == 6 )
X#define REVERSE_INT REVERSE_6
X#endif
X#if ( L_INT == 7 )
X#define REVERSE_INT REVERSE_7
X#endif
X#if ( L_INT == 8 )
X#define REVERSE_INT REVERSE_8
X#endif
X
X#if ( L_LONG == 2 )
X#define REVERSE_LONG REVERSE_2
X#endif
X#if ( L_LONG == 3 )
X#define REVERSE_LONG REVERSE_3
X#endif
X#if ( L_LONG == 4 )
X#define REVERSE_LONG REVERSE_4
X#endif
X#if ( L_LONG == 5 )
X#define REVERSE_LONG REVERSE_5
X#endif
X#if ( L_LONG == 6 )
X#define REVERSE_LONG REVERSE_6
X#endif
X#if ( L_LONG == 7 )
X#define REVERSE_LONG REVERSE_7
X#endif
X#if ( L_LONG == 8 )
X#define REVERSE_LONG REVERSE_8
X#endif
X
X
X/* Macro <S><o>_fmt give format for printing data of size S in format o */
X
X#define Bb_fmt "0b%s "
X#define Bo_fmt "%#5o "
X#define Bd_fmt "%5d "
X#define Bu_fmt "%4u "
X#define Bx_fmt "%#5x "
X
X#define Cb_fmt "0b%s "
X#define Co_fmt "%#5o "
X#define Cd_fmt "%5d "
X#define Cu_fmt "%4u "
X#define Cx_fmt "%#5x "
X
X#define Zb_fmt "0b%s "
X#define Zo_fmt "%#5o "
X#define Zd_fmt "%5d "
X#define Zu_fmt "%4u "
X#define Zx_fmt "%#5x "
X
X#if ( L_SHORT == 2 )
X#define Sb_fmt "0b%s,%s " /* Args are 1 string per byte */
X#endif
X#if ( L_SHORT == 3 )
X#define Sb_fmt "0b%s,%s,%s "
X#endif
X#if ( L_SHORT == 4 )
X#define Sb_fmt "0b%s,%s,%s,%s "
X#endif
X#if ( L_SHORT == 5 )
X#define Sb_fmt "0b%s,%s,%s,%s,%s "
X#endif
X#if ( L_SHORT == 6 )
X#define Sb_fmt "0b%s,%s,%s,%s,%s,%s "
X#endif
X#if ( L_SHORT == 7 )
X#define Sb_fmt "0b%s,%s,%s,%s,%s,%s,%s "
X#endif
X#if ( L_SHORT == 8 )
X#define Sb_fmt "0b%s,%s,%s,%s,%s,%s,%s,%s "
X#endif
X#define So_fmt "%#8o "
X#define Sd_fmt "%6d "
X#define Su_fmt "%6u "
X#define Sx_fmt "%#7x "
X
X#if ( L_INT == 2 )
X#define Ib_fmt "0b%s,%s " /* Args are 1 string per byte */
X#endif
X#if ( L_INT == 3 )
X#define Ib_fmt "0b%s,%s,%s "
X#endif
X#if ( L_INT == 4 )
X#define Ib_fmt "0b%s,%s,%s,%s "
X#endif
X#if ( L_INT == 5 )
X#define Ib_fmt "0b%s,%s,%s,%s,%s "
X#endif
X#if ( L_INT == 6 )
X#define Ib_fmt "0b%s,%s,%s,%s,%s,%s "
X#endif
X#if ( L_INT == 7 )
X#define Ib_fmt "0b%s,%s,%s,%s,%s,%s,%s "
X#endif
X#if ( L_INT == 8 )
X#define Ib_fmt "0b%s,%s,%s,%s,%s,%s,%s,%s "
X#endif
X#define Io_fmt "%#14o "
X#define Id_fmt "%12d "
X#define Iu_fmt "%12u "
X#define Ix_fmt "%#10x "
X
X#if ( L_LONG == 2 )
X#define Lb_fmt "0b%s,%s " /* Args are 1 string per byte */
X#endif
X#if ( L_LONG == 3 )
X#define Lb_fmt "0b%s,%s,%s "
X#endif
X#if ( L_LONG == 4 )
X#define Lb_fmt "0b%s,%s,%s,%s "
X#endif
X#if ( L_LONG == 5 )
X#define Lb_fmt "0b%s,%s,%s,%s,%s "
X#endif
X#if ( L_LONG == 6 )
X#define Lb_fmt "0b%s,%s,%s,%s,%s,%s "
X#endif
X#if ( L_LONG == 7 )
X#define Lb_fmt "0b%s,%s,%s,%s,%s,%s,%s "
X#endif
X#if ( L_LONG == 8 )
X#define Lb_fmt "0b%s,%s,%s,%s,%s,%s,%s,%s "
X#endif
X#define Lo_fmt "%#14lo "
X#define Ld_fmt "%12ld "
X#define Lu_fmt "%12lu "
X#define Lx_fmt "%#10lx "
X
X#define Ff_fmt "%7f "
X#define Fg_fmt "%7g "
X
X#define Df_fmt "%.16f "
X#define Dg_fmt "%.16g "
X
X/* Buffer size for fread */
X#define BUFFERSIZE 8192
END_OF_FILE
if test 7927 -ne `wc -c <'viz-1.1.0/viz.h'`; then
echo shar: \"'viz-1.1.0/viz.h'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/viz.h'
fi
if test -f 'viz-1.1.0/vizgrammar.y' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/vizgrammar.y'\"
else
echo shar: Extracting \"'viz-1.1.0/vizgrammar.y'\" \(16223 characters\)
sed "s/^X//" >'viz-1.1.0/vizgrammar.y' <<'END_OF_FILE'
X%{
X/*
X * Turns format specifications into internal list representation.
X
X * Formats are lists of items:
X * format := [count] item | [count] '(' format ')' | format format
X
X * where an item is:
X * item := [count] insize outform [ '>' c ] ...
X * | [count] insize [ '>' c ]
X * | [count] outform [ '>' c ]
X * | [count] '[' copyout_string ']'
X * | [count] !0|!1|!2 or seek0|seek1|seek2 (seeks)
X * | [count] `n' or `;' (adds newline)
X * | $c ({+-/*=} number)+ (does math on registers)
X * | $c P (prints register in %ld fmt)
X
X * and a count is:
X * count := positive decimal number | $c | $$
X * Here, c is any non-null, non-'$' character; it names a register
X
X
X * insize := C | S | I | L | F | D | Z
X * | | | | | | zero-terminated string
X * | | | | | double
X * | | | | float
X * | | | long
X * | | int
X * | short
X * char
X * -or-
X * char short int integer long float real double string
X
X * outform := a | b | c | d | u | o | h | f | g | ~ | "(printf fmt string)"
X * | | | | | | | | | ignore (no output)
X * | | | | | | | | float
X * | | | | | | | float
X * | | | | | | hex (unsigned)
X * | | | | | octal (unsigned)
X * | | | | unsigned decimal
X * | | | signed decimal
X * | | octal for non-printing characters; ascii for printing
X * | binary (unsigned)
X * ascii characters
X
X * default pairings: C->a, S->o, I->d, L->d, [FD]->g, Z->a
X * a->C, b->C, c->C, [duohx]->I, g->F
X
X * illegal pairings: [CSILZ]-fg, [FD]-[abcduohx], [SILFD]-ac
X


X
X * Filters the named files; if there are no files, stdin is used.
X

X * Ascii formatting:
X * null -> \@
X * percent -> \%


X * backspace -> \b
X * formfeed -> \f
X * newline -> \n
X * return -> \r
X * tab -> \t

X * backslash -> \\


X * all other printing characters (octal 040 - 177): unchanged

X * all others -> \nnn
X * In addition, after transforming newline to \n, a true newline is printed.
X
X */
X
X
X#include <stdio.h>
X#include <ctype.h>
X#include "string.h"

X#include <errno.h>
X
X#include "viz.h"
X
Xextern errno;
Xextern char *malloc();
Xextern int do_condense;
X
Xstatic mathreg = 0; /* For handling multiple-term math expressions */
X
X%}
X
X%token <ival> INCHAR OUTCHAR REG STORE LEXERROR NEWLINE EOF_COUNT SEEK
X
X%token <lval> NUMBER
X
X%token <sval> COPYOUT PCTSTRING
X
X%token <ival> MATHOP U_MATHOP
X
X%type <lval> count /* repetition count */
X
X%type <item> copyout /* An item with the copyout field filled */
X
X%type <item> seek /* Seek on input stream */
X
X%type <item> math /* Math operation on a register */
X
X%type <item> iocore /* An ioformat with the core of the iospec
X * filled: size + ichar + ochar are filled,
X * but fmt ptr & reg_no not filled in.
X */
X
X%type <item> iosingle /* iocore + reg_no info */
X
X%type <memp> iounion /* iosingle | copyout | NEWLINE | math | SEEK;
X * type field filled, but not count field. */
X
X%type <memp> iogroup /* [count] iounion */
X
X%type <memp> list member /* pointers to list and member of list */
X
X%type <memp> lexerr /* For handling lex-found errors */
X
X%%
X
Xlist : member
X {
X if (debug)
X (void) fprintf(stderr, "list = member; making newlist");
X rootlist = $$ = newlist($1);
X if (debug) {
X (void) fprintf(stderr, " ...list is now:\n");
X printlist(0, $$);
X }
X }
X | list member
X {
X if (debug)
X (void) fprintf(stderr, "list = list member");
X rootlist = $$ = addmember( $1, $2 );
X if (debug) {
X (void) fprintf(stderr, " ...list is now:\n");
X printlist(0, $$);
X }
X }
X | lexerr
X ;
X
Xmember : iogroup
X {
X if (debug)
X (void) fprintf(stderr, "member: iogroup\n");
X $$ = $1;
X if ($$ == NIL) {
X (void) fprintf(stderr, "%s: malloc failed\n", prog);
X YYERROR;
X }
X }
X
X | '(' list ')'
X {
X if (debug)
X (void) fprintf(stderr, "member: ( list )\n");
X $$ = $2;
X $$->count = 1;
X }
X | count '(' list ')'
X {
X if (debug)
X (void) fprintf(stderr, "member: %d ( list )\n", $1);
X $3->count = $1 ;
X $$ = $3;
X }
X ;
X
Xiogroup : iounion
X {
X $$ = $1;
X $$->count = 1;
X $$->next = NIL;
X }
X | count iounion
X {
X $$ = $2;
X $$->count = $1;
X $$->next = NIL;
X }
X ;
X
Xiounion : iosingle
X {
X $$ = (MEMBER *) malloc(sizeof(MEMBER));
X if ($$ == (MEMP) NULL) {
X (void) fprintf(stderr, "%s: malloc failed.\n", prog);
X YYERROR;
X }
X $$->type = T_IOSPEC;
X $$->u = $1;
X mathreg = 0;
X }
X | seek
X {
X $$ = (MEMBER *) malloc(sizeof(MEMBER));
X if ($$ == (MEMP) NULL) {
X (void) fprintf(stderr, "%s: malloc failed.\n", prog);
X YYERROR;
X }
X $$->type = T_SEEK;
X $$->u = $1;
X }
X | copyout
X {
X $$ = (MEMBER *) malloc(sizeof(MEMBER));
X if ($$ == (MEMP) NULL) {
X (void) fprintf(stderr, "%s: malloc failed.\n", prog);
X YYERROR;
X }
X $$->type = T_COPYOUT;
X $$->u = $1;
X mathreg = 0;
X }
X | NEWLINE
X {
X $$ = (MEMBER *) malloc(sizeof(MEMBER));
X if ($$ == (MEMP) NULL) {
X (void) fprintf(stderr, "%s: malloc failed.\n", prog);
X YYERROR;
X }
X $$->type = T_NEWLINE;
X mathreg = 0;
X }
X | math
X {
X $$ = (MEMBER *) malloc(sizeof(MEMBER));
X if ($$ == (MEMP) NULL) {
X (void) fprintf(stderr, "%s: malloc failed.\n", prog);
X YYERROR;
X }
X $$->type = T_MATH;
X $$->u = $1;
X }
X ;
X
Xcopyout : COPYOUT
X {
X $$.copyout = malloc((unsigned) (strlen($1) + 1));
X if ($$.copyout == NULL) {
X (void) fprintf(stderr, "%s: malloc failed.\n", prog);
X YYERROR;
X }
X (void) strcpy($$.copyout, $1);
X }
X ;
X
Xseek : count SEEK count
X {
X $$.seek.count = $1;
X $$.seek.direction = $3;
X }
X | MATHOP count SEEK count
X {
X if ($1 != '-' && $1 != '+') {
X (void) fprintf(stderr,
X "%s: invalid seek offset: %c%d\n",
X prog, $1, $2);
X YYERROR;
X } else if ($1 == '-') {
X $$.seek.count = -$2;
X } else {
X $$.seek.count = $2;
X }
X $$.seek.direction = $4;
X }
X ;
X
X
Xmath : REG MATHOP count
X {
X $$.math.reg_no = mathreg = $1;
X $$.math.operator = $2;
X $$.math.operand = $3;
X }
X | MATHOP count
X {
X if (mathreg == 0) {
X (void) fprintf(stderr,
X "%s: Math operator outside math expression\n",
X prog);
X YYERROR;
X }
X $$.math.reg_no = mathreg;
X $$.math.operator = $1;
X $$.math.operand = $2;
X }
X | REG U_MATHOP
X {
X $$.math.reg_no = mathreg = $1;
X $$.math.operator = $2;
X $$.math.operand = 0;
X }
X | U_MATHOP
X {
X if (mathreg == 0) {
X (void) fprintf(stderr,
X "%s: Register print operator w/o register\n",
X prog);
X YYERROR;
X }
X $$.math.reg_no = mathreg;
X $$.math.operator = $1;
X $$.math.operand = 0;
X }
X | REG MATHOP INCHAR
X {
X $$.math.reg_no = mathreg = $1;
X $$.math.operator = $2;
X switch ($3) {
X case 'C':
X $$.math.operand = sizeof(char);


X break;
X case 'S':

X $$.math.operand = sizeof(short);


X break;
X case 'I':

X $$.math.operand = sizeof(int);


X break;
X case 'L':

X $$.math.operand = sizeof(long);


X break;
X case 'F':

X $$.math.operand = sizeof(float);


X break;
X case 'D':

X $$.math.operand = sizeof(double);


X break;
X default:
X (void) fprintf(stderr,

X "%s: illegal math sizing char %c\n", prog, $3);
X YYERROR;
X }
X }
X | MATHOP INCHAR
X {
X if (mathreg == 0) {
X (void) fprintf(stderr,
X "%s: Math operator outside math expression\n",
X prog);
X YYERROR;
X }
X $$.math.reg_no = mathreg;
X $$.math.operator = $1;
X switch ($2) {
X case 'C':
X $$.math.operand = sizeof(char);


X break;
X case 'S':

X $$.math.operand = sizeof(short);


X break;
X case 'I':

X $$.math.operand = sizeof(int);


X break;
X case 'L':

X $$.math.operand = sizeof(long);


X break;
X case 'F':

X $$.math.operand = sizeof(float);


X break;
X case 'D':

X $$.math.operand = sizeof(double);


X break;
X default:
X (void) fprintf(stderr,

X "%s: illegal math sizing char %c\n", prog, $2);
X YYERROR;


X }
X }
X ;
X
X

Xiosingle : iocore STORE
X {
X $$ = $1;
X $$.iospec.reg_no = $2;
X if ( inval4reg($$.iospec.ochar) ) {
X (void) fprintf(stderr,
X "%s: Only integer types can be put in a $x register.\n",
X prog);
X YYERROR;
X }
X }
X | iocore
X {
X $$ = $1;
X $$.iospec.reg_no = 0;
X }
X ;
X
Xiocore : INCHAR OUTCHAR
X {
X $$.iospec = makecore($1, $2);
X if (badiopair($$.iospec.ichar, $$.iospec.ochar)) {
X (void) fprintf(stderr,
X "%s: input size `%c' and output format `%c' cannot go together.\n",
X prog, $$.iospec.ichar, $$.iospec.ochar);
X YYERROR;
X }
X }
X | INCHAR
X {
X $$.iospec = makecore($1, 0);
X if (badiopair($$.iospec.ichar, $$.iospec.ochar)) {
X (void) fprintf(stderr,
X "%s: input size `%c' and output format `%c' cannot go together.\n",
X prog, $$.iospec.ichar, $$.iospec.ochar);
X YYERROR;
X }
X }
X | OUTCHAR
X {
X $$.iospec = makecore(0, $1);
X if (badiopair($$.iospec.ichar, $$.iospec.ochar)) {
X (void) fprintf(stderr,
X "%s: input size `%c' and output format `%c' cannot go together.\n",
X prog, $$.iospec.ichar, $$.iospec.ochar);
X YYERROR;
X }
X }
X | INCHAR PCTSTRING
X {
X $$.iospec = makecorepct($1, $2);
X }
X | PCTSTRING
X {
X $$.iospec = makecorepct(0, $1);
X }
X ;
X
Xcount : NUMBER
X { $$ = $1 ; }
X | REG
X { $$ = 0 - $1; }
X | EOF_COUNT
X { $$ = UPTO_EOF ; }
X ;
X
Xlexerr : LEXERROR
X { YYERROR; }
X ;
X%%
X
Xyyerror(s)
Xchar *s;
X{
X (void) fprintf(stderr, "%s: %s\n", prog, s);
X}
X
Xyylex()
X{
X static char *p=NULL; /* for walking through format list */
X static char *tmpbuf; /* temporary storage for copyout text */
X
X char *b;
X
X if (p == NULL) {
X p = fmttext;
X tmpbuf = malloc((unsigned) strlen(fmttext));
X if (tmpbuf == NULL) {
X (void) fprintf(stderr,
X "%s: Can't malloc buffer space in yylex().\n", prog);
X exit(1);
X }
X /* Eat leading whitespace */
Xeatws1: while (isspace(*p))
X p++;
X if (*p == '#') {
X /* Comment embedded in format; discard text through newline */
X while (*p && *p != '\n')
X p++;
X goto eatws1;
X }
X /* If the first non-whitespace character is a digit,
X * then the count is specified; don't process to eof.
X */
X if ( isdigit(*p) )
X process_to_eof = 0;
X else
X process_to_eof = 1;
X }
X
X /* Eat whitespace */
Xeatws2: while (isspace(*p))
X p++;
X
X if (*p == '#') {
X /* Comment embedded in format; discard text through newline */
X while (*p && *p != '\n')
X p++;
X goto eatws2;
X }
X
X
X /* Special processing: support {char short int integer long
X * float real double} for data sizes {C S I I L F F D}, by replacing the
X * word with the equivalent single-character form.
X
X * Likewise map {seek} to {!}.
X
X * Likewise allow "print" for P.
X */
X {
X#define ifname(longname, shortname) \
X if (strncmp(p, longname, sizeof(longname)-1) == 0 && \
X !isalpha(*(p+sizeof(longname)-1))) { \
X p += sizeof(longname) - 2; \
X *p = shortname; \
X }
X
X ifname("char", 'C')
X else ifname("short", 'S')
X else ifname("int", 'I')
X else ifname("long", 'L')
X else ifname("float", 'F')
X else ifname("real", 'F')
X else ifname("double", 'D')
X else ifname("seek", '!')
X else ifname("print", 'P')
X
X }
X if (debug)
X fprintf(stderr, "(dbg) fmt = `%s'\n", p);
X
X /* Now check for usual forms */
X switch (*p) {
X case '\0':
X return 0;
X break;
X case '0':
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 /* require count base to be 10; if we allow strtol to interpret
X * hex, we'll have to interpret 10a (10 ascii) as count=266.
X */
X yylval.lval = strtol(p, &b, 10);
X if (b == p) {
X fprintf(stderr, "%s: severe error: strtol(\"%s\",...) failed\n");
X exit(1);
X }
X p = b;
X return NUMBER;
X break;
X case 'C':
X case 'S':
X case 'I':
X case 'L':
X case 'F':
X case 'D':
X case 'Z':
X yylval.ival = *p++;
X return INCHAR;


X break;
X case '~':

X case 'a':
X case 'b':
X case 'c':
X case 'd':
X case 'u':
X case 'o':
X case 'x':
X case 'f':
X case 'g':
X yylval.ival = *p++;
X return OUTCHAR;


X break;
X case 'h':

X yylval.ival = 'x';
X p++;
X return OUTCHAR;
X break;
X case '[':
X for (b = tmpbuf, p++; *p && *p != ']'; ) {
X if (*p == '\\' && *(p+1) == ']')
X { *b++ = *++p; p++; }
X else
X *b++ = *p++;
X }
X if (*p++ != ']') {
X (void) fprintf(stderr, "%s: Unterminated comment.\n", prog);
X return LEXERROR;
X }
X *b = '\0';
X yylval.sval = tmpbuf;
X if (strstr(yylval.sval, "$("))
X do_condense=0; /* don't condense list, so that $( gives
X * a count correct from user's perspective.
X */
X return COPYOUT;
X break;
X case ';':
X ++p;
X return NEWLINE;
X break;
X case '\\':
X ++p;
X switch (*p) {
X case 'n':
X ++p;
X return NEWLINE;
X break;
X default:
X (void) fprintf(stderr, "%s: unrecognized backslash sequence.\n");
X }
X case 'n':
X ++p;
X return NEWLINE;
X break;
X case '(':
X case ')':
X return (*p++);
X break;
X case '!':
X ++p;
X return SEEK;
X break;
X case '$':
X yylval.ival = *++p;
X if (*p == '\0') {
X (void) fprintf(stderr,
X "%s: `$' cannot end the format.\n", prog);
X return LEXERROR;
X }
X p++;
X if (yylval.ival == '$')
X return EOF_COUNT; /* $$ is special: a count that means up-to-eof */
X
X if (yylval.ival == '(')
X do_condense=0; /* don't condense list, so that $( gives
X * a count correct from user's perspective.
X */
X return REG;
X break;
X case '>':
X yylval.ival = *++p;
X if (*p == '\0') {
X (void) fprintf(stderr,
X "%s: `>' must precede a register character.\n", prog);
X return LEXERROR;
X }
X p++;
X return STORE;
X break;
X case '+':
X case '-':
X case '*':
X case '/':
X case '%':
X case '=':
X yylval.ival = *p++;
X return MATHOP;


X break;
X case '?':

X case ':':
X /* Used to form tests */
X return *p++;


X break;
X case 'P':

X yylval.ival = *p++;
X return U_MATHOP;
X break;
X case '"':
X /* User-entered format. Terminate it at '"'. */
X p++;
X for (b = tmpbuf; *p && *p != '"'; )
X *b++ = *p++;
X if (*p == '\0') {
X (void) fprintf(stderr, "%s: Unterminated printf-fmt.\n", prog);
X return LEXERROR;
X }
X *b = '\0';
X p++;
X yylval.sval = tmpbuf;
X return PCTSTRING;


X break;
X default:
X (void) fprintf(stderr,

X "%s: Invalid character `%c' in format.\n", prog, *p);
X return LEXERROR;
X }


X /* NOTREACHED */
X}

X
Xint
Xdefaultichar(ochar)
Xint ochar; /* Specifies the output character */
X{
X
X switch (ochar) {
X case 'a':
X case 'b':
X case 'c':
X case '~':
X return 'C';
X break;
X case 'd':
X case 'u':
X case 'o':
X case 'h':
X case 'x':
X return 'I';


X break;
X case 'f':

X case 'g':
X return 'F';
X break;
X default:
X return '\0';
X break;
X }


X /* NOTREACHED */
X}

X
Xint
Xdefaultochar(ichar)
Xint ichar; /* Specifies the input character */


X{
X switch (ichar) {
X case 'C':

X return 'a';


X break;
X case 'Z':

X return 'a';


X break;
X case 'S':

X return 'o';


X break;
X case 'I':

X return 'd';


X break;
X case 'L':

X return 'd';


X break;
X case 'F':

X case 'D':
X return 'g';
X break;
X default:
X return '\0';
X break;
X }


X /* NOTREACHED */
X}

X
Xint
Xgetsize(ichar)
Xint ichar;
X{
X
X switch (ichar) {
X case ';':
X return 0;
X break;


X case 'C':
X case 'Z':

X return sizeof(char);


X break;
X case 'S':

X return sizeof(short);


X break;
X case 'I':

X return sizeof(int);


X break;
X case 'L':

X return sizeof(long);


X break;
X case 'F':

X return sizeof(float);


X break;
X case 'D':

X return sizeof(double);
X break;
X default:
X return 0;
X }


X /* NOTREACHED */
X}

X
Xbadiopair(ic, oc)
Xint ic, oc;
X{
X /* illegal pairings: [CSILZ]-fg, [FD]-[abduohx], [SILFD]-ac */
X
X if (strchr("fg", oc) && strchr("CSILZ", ic))
X return 1;
X else if (strchr("abduohx", oc) && strchr("FD", ic))
X return 1;
X else if (strchr("ac", oc) && strchr("SILFD", ic))
X return 1;
X else


X return 0;
X}
X
X

Xinval4reg(oc)
Xint oc;
X{
X /* Illegal to use ">x" notation if data are float types */
X if (oc == 'g' || oc == 'f')
X return 1;
X else
X return 0;
X}
END_OF_FILE
if test 16223 -ne `wc -c <'viz-1.1.0/vizgrammar.y'`; then
echo shar: \"'viz-1.1.0/vizgrammar.y'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/vizgrammar.y'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone

wde...@nfra.nl

unread,
Mar 27, 1995, 1:28:35 PM3/27/95
to
Submitted-by: wde...@nfra.nl
Posting-number: Volume 47, Issue 106
Archive-name: viz/part03
Environment: UNIX

#! /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".

# Contents: viz-1.1.0/INSTALL viz-1.1.0/Makefile viz-1.1.0/README
# viz-1.1.0/inviz.1 viz-1.1.0/inviz.c viz-1.1.0/inviz_num.c
# viz-1.1.0/inviz_text.c viz-1.1.0/loadfile.c viz-1.1.0/memory.h
# viz-1.1.0/string.h viz-1.1.0/strtod.c viz-1.1.0/strtou.c
# viz-1.1.0/version.h viz-1.1.0/viz_decode.c
# Wrapped by kent@ftp on Sat Mar 25 15:26:14 1995


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 3 (of 3)."'
if test -f 'viz-1.1.0/INSTALL' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/INSTALL'\"
else
echo shar: Extracting \"'viz-1.1.0/INSTALL'\" \(322 characters\)
sed "s/^X//" >'viz-1.1.0/INSTALL' <<'END_OF_FILE'
XBuilding and Installing viz
X---------------------------
X
X1. Set the Makefile variables BINDIR, MANDIR, MANEXT,
X CC, DEFS, SIZES, CFLAGS, LDFLAGS, LDLIBS.
X
X2. Edit dep.h and adjust the "aligned" macro to suit your machine.
X
X3. Type "make" to make the program, and "make install" to install
X binaries and executables.
END_OF_FILE
if test 322 -ne `wc -c <'viz-1.1.0/INSTALL'`; then
echo shar: \"'viz-1.1.0/INSTALL'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/INSTALL'
fi
if test -f 'viz-1.1.0/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/Makefile'\"
else
echo shar: Extracting \"'viz-1.1.0/Makefile'\" \(2968 characters\)
sed "s/^X//" >'viz-1.1.0/Makefile' <<'END_OF_FILE'
X#######
X# Where the executable goes
XBINDIR=/usr/local/bin
X
X#######
X# Man pages
X
XMANDIR=/usr/local/man/man1
XMANEXT=1
X
X#######
X# CC
XCC=gcc
X
X#######
X# Define's
X# Define STRINGS if <strings.h> is to be used in place of <string.h>
X# Define NOMEM if <memory.h> isn't available.
X# Define EBCDIC if that character set is used.
XDEFS = -D_HPUX_SOURCE # -DNOMEM -DSTRINGS # -DEBCDIC
X
X# Sizes of shorts, ints, longs. (This has to be a #define: the sizeof
X# operator isn't sufficient because we need to use the sizes in the argument
X# to a #if expression.)
XSIZES = -DL_SHORT=2 -DL_INT=4 -DL_LONG=4
X
X
X#######
X# CFLAGS
X# Always keep $(DEFS) and $(SIZES) in CFLAGS
XCFLAGS = $(DEFS) $(SIZES)
X
X#######
X# LDFLAGS,LDLIBS
X
XLDFLAGS=
XLDLIBS=
X
X
X####################################################################
X# You shouldn't have to modify anything below this line.
X####################################################################
X
XVIZOBJS = viz.o vizgrammar.o lists.o loadfile.o viz_decode.o
XVIZ_H = viz.h translate.h string.h memory.h version.h
XVIZSRC = viz.c vizgrammar.y lists.c loadfile.c viz_decode.c
XVIZSRC_C = viz.c vizgrammar.c lists.c loadfile.c viz_decode.c
X
XINVIZOBJS = inviz.o strtou.o strtod.o inviz_text.o inviz_num.o
XINVIZSRC = inviz.c strtou.c strtod.c inviz_text.c inviz_num.c
X
XALL = README INSTALL Artistic Copying Makefile viz.1 inviz.1 $(VIZSRC) $(INVIZSRC) $(VIZ_H)
X
Xall: viz inviz
X
Xlint: $(VIZSRC_C)
X lint -h $(VIZSRC_C) > lint.out
X
Xviz: $(VIZOBJS)
X $(CC) $(LDFLAGS) $(DEFS) $(VIZOBJS) -o viz
X
Xviz.o: viz.h translate.h
X
Xvizgrammar.o: viz.h
X
X# For producing a .c file for lint to work on.
Xvizgrammar.c: vizgrammar.y
X @ echo "** Expect 4 shift/reduce conflicts **"
X yacc vizgrammar.y
X mv y.tab.c vizgrammar.c
X
Xlists.o: viz.h
X
Xviz.h: dep.h
X @ touch viz.h
X
Xinviz: $(INVIZOBJS)
X $(CC) $(LDFLAGS) $(INVIZOBJS) -lm -o inviz
X
Xinviz.o: viz.h translate.h
X
Xviz_decode.o: viz.h translate.h
X $(CC) $(CFLAGS) -DVIZ -c viz_decode.c
X
Xinviz_text.o: viz.h translate.h
X $(CC) $(CFLAGS) -c inviz_text.c
X
Xinviz_num.o: viz.h translate.h
X $(CC) $(CFLAGS) -c inviz_num.c
X
Xinstall: viz inviz
X cp viz $(DESTDIR) && chmod 755 $(DESTDIR)/viz
X cp inviz $(DESTDIR) && chmod 755 $(DESTDIR)/inviz
X cp viz.1 $(MANDIR)/viz.$(MANEXT) && \
X chmod 644 $(MANDIR)/viz.$(MANEXT)
X cp inviz.1 $(MANDIR)/inviz.$(MANEXT) && \
X chmod 644 $(MANDIR)/inviz.$(MANEXT)
X
Xclean:
X rm -f *.o viz inviz y.tab.c y.tab.h
X
X# Because of the wide variation in shar commands, the shar arguments
X# used below sticks to a minimal set, and we generate various shar file
X# headers by hand.
Xshar: $(ALL)
X ( echo "#include <stdio.h>" ; \
X echo '#include "version.h"' ; \
X echo 'main() {printf("%s.%s\\n",Version,Patchlevel);exit(0);}') > temp.c
X cc temp.c
X V=viz-`a.out`; mkdir $$V && cp $(ALL) $$V && \
X (echo "Submitted-by: wi...@nfra.nl" ; \
X echo "Archive-name: $$V/part01" ; echo "" ; \
X echo "---- Cut Here and feed the following to sh ----" ; \
X shar $$V ) > $$V.shar && rm -rf $$V
X rm a.out temp.c
END_OF_FILE
if test 2968 -ne `wc -c <'viz-1.1.0/Makefile'`; then
echo shar: \"'viz-1.1.0/Makefile'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/Makefile'
fi
if test -f 'viz-1.1.0/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/README'\"
else
echo shar: Extracting \"'viz-1.1.0/README'\" \(2015 characters\)
sed "s/^X//" >'viz-1.1.0/README' <<'END_OF_FILE'
XViz copies its input to its output, converting invisible characters
Xto a visible form. If the -t option is used, the output is
Xformatted in a form that can be completely inverted by inviz,
Xwhich allows a binary file to be converted to a text form and then back.
XIt is much more flexible than either cat -v or od (either old or
XPOSIX od), and it is also 2\-4 times faster.
X


XBy default, the input is treated as a sequence of characters.

XHowever, a file format may be specified, in which case
Xviz can handle files containing a mixture of data of arbitrary types.
X
XThe format can include repeat counts
Xand comments that are embedded in the output stream.
X


XUninteresting data can be skipped over and not printed on stdout.
X

XAdditional flexibility is provided through user-settable variables,

Xwhich can be used as repeat counts. Simple math can be done on the
Xvariables, and chars, shorts, or integers from the input stream
Xcan be stored in them.
X
X--------------------
X
X Copyright (c) 1989-1994 by William Deich.
X Not derived from licensed software.


X
X This program is free software; you can redistribute it and/or modify

X it under the terms of either:
X
X a) the GNU General Public License as published by the Free
X Software Foundation; either version 1, or (at your option) any
X later version, or
X
X b) the "Artistic License" (from Larry Wall).


X
X This program is distributed in the hope that it will be useful,
X but WITHOUT ANY WARRANTY; without even the implied warranty of

X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either
X the GNU General Public License or the Artistic License for more details.
X
X You should have received a copy of the Artistic License with this
X Kit, in the file named "Artistic". If not, I'll be glad to provide one.
X
X You should also have received a copy of the GNU General Public License


X along with this program; if not, write to the Free Software
X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X

END_OF_FILE
if test 2015 -ne `wc -c <'viz-1.1.0/README'`; then
echo shar: \"'viz-1.1.0/README'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/README'
fi
if test -f 'viz-1.1.0/inviz.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/inviz.1'\"
else
echo shar: Extracting \"'viz-1.1.0/inviz.1'\" \(2859 characters\)
sed "s/^X//" >'viz-1.1.0/inviz.1' <<'END_OF_FILE'
X.TH UNWIZ 1 local
X.SH NAME
Xinviz \- Converts escape sequences to binary; reverses viz(1)
X.SH SYNOPSIS
X.B inviz


X[
X.I file ...
X]
X.SH DESCRIPTION

X.I Inviz
Xcopies its input to its output, translating escape sequences
Xthat are found. It will properly invert the output of
X.IR viz\ \-t ,
Xthus recreating the original file. For example, typing
X.ti +.5i
Xviz < \fIinfile\fP | inviz > \fIcopy_of_infile\fP
Xwill create an exact copy of \fIinfile\fP.
X.PP
X.I Inviz
Xcopies from
X.I file
X(or from
X.IR stdin ,
Xif there is no
X.I file
Xgiven) and writes to
X.IR stdout .
XThese escape sequences are of the form
X.ti +1i
X\fB\\\fP\fIc\fP
X.br
Xor
X.ti +1i
X\fB\\\fP\fInnn\fP
X.br
XIt also specially treats lines that begin
X.ti +1i
X\fB\\#\fIdatatype\fR ...
X.br
Xwhich are lines containing text to convert to binary numbers
X(chars, shorts, ints, longs, doubles, or floats).
X.PP
XBackslash sequences
X\fB\\\fP\fIc\fP and
X\fB\\\fP\fInnn\fP
Xare used to produce the
Xusual C escapes, with the addition of \fB\\@\fP translating to null.
X.PP
XThe complete set of `backslash' escape sequences is:
X.in +.5i
X.nf
X`\\\\' \(-> `\\'
X`\\@' \(-> null
X`\\%' \(-> percent
X`\\b' \(-> backspace
X`\\f' \(-> formfeed
X`\\n' \(-> newline
X`\\r' \(-> return
X`\\t' \(-> tab
X`\\\fInnn\fP' \(-> ascii character with this octal value
X`\\\fxInnn...\fP' \(-> ascii character with this hex value
X.fi
X.in -.5i
XEmbedded newlines are discarded; to produce a newline
Xin the output, the escape sequence
X`\\n' must appear in the input.
X.PP
XLines that begin
X.ti +1i
X\fB\\#\fIdatatype\fR
X.br
Xare to be translated into binary numbers.
XHere the
X.I datatype
Xis one of
X{\fBC\fP,\fBS\fP,\fBI\fP,\fBL\fP,\fBF\fP,\fBD\fP},
Xand means, respectively, that the text on the rest of the line is
Xto be translated into chars, shorts, ints, longs, floats, or doubles.
XThe rest of the line is made up of the usual sort
Xof text representations of numbers, separated by whitespace.
XWhen the datavalue is an integer
Xvalue (whether char, short, int, or long)
Xmay be expressed in octal
X.RI (0 nnn ),
Xhex
X.RI (0x nnn
Xor
X.RI 0X nnn ),
Xor decimal. If the value is octal or hex, the corresponding output value
Xwill be unsigned.
XIf decimal, the type is unsigned unless the number begins with
X.RB ` + "' or `" - ',
Xin which case a signed number is output.
XIn all cases, sscanf(3) is initially
Xused to convert the text to a long int or double value,
Xso any restrictions that apply to sscanf(3) conversions also apply
Xhere.
X.SH EXAMPLES
X1. To output the two integers 234 (hex) and 2345 (decimal),
Xfollowed by the float value 6.4, the input text could be:
X.sp
X.in +.5i
X.nf
X\\#I 0x234 2345
X\\#F 6.4
X.fi
X.in i.5i
X.PP
X2. To output a form feed followed by the integers 5 and 124,
Xthe short -16, and finally a string "456abc%" on a new line, use
Xinput like:
X.sp
X.in +.5i
X.nf
X\\f
X\\#I 5 124
X\\#S -16
X\\n456abc%
X.fi
X.in -.5i
X.SH AUTHOR
XWill Deich
X.SH "SEE ALSO"
X.I viz(1)
END_OF_FILE
if test 2859 -ne `wc -c <'viz-1.1.0/inviz.1'`; then
echo shar: \"'viz-1.1.0/inviz.1'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/inviz.1'
fi
if test -f 'viz-1.1.0/inviz.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/inviz.c'\"
else
echo shar: Extracting \"'viz-1.1.0/inviz.c'\" \(1474 characters\)
sed "s/^X//" >'viz-1.1.0/inviz.c' <<'END_OF_FILE'
X/* Input:
X * 1. Everything up to the last tab on a line is skipped over.
X * 2. The sequence \# indicates the rest of the line is numeric mode.
X * 3. In text mode, all C escapes are accepted, and ^c
X * stands for the code (c+1-'A').
X * 4. In numeric mode, c/C/S/I/L/F/D is used to give sufficient
X * type/size information to properly convert input.


X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include "string.h"

X#include "viz.h"
X#include "version.h"
X#include "translate.h"
X
Xchar *prog;
X
Xvoid inviz_text();
Xvoid inviz_num();


X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X

X int i=1;


X
X prog = argv[0];
X

X if (argc == 1) {
X (void) inviz();


X } else {
X do {
X if (freopen(argv[i], "r", stdin) == (FILE *) NULL) {
X (void) fprintf(stderr, "%s: failed to open %s: ",prog, argv[i]);
X perror("");
X } else {

X clearerr(stdin);
X (void) inviz();


X }
X
X } while (++i < argc);
X }
X

X return 0;
X}
Xinviz()
X{
X char *s;
X char inbuf[BUFFERSIZE];
X char outbuf[BUFFERSIZE];
X int line, n;
X
X for (line = 1; fgets(inbuf, BUFFERSIZE, stdin) != NULL; line++) {
X n = strlen(inbuf);
X /* Remove newline left on by fgets */
X if (inbuf[n-1] == '\n')
X inbuf[n-1] = '\0';
X
X /* Discard everything up to the last tab */
X s = strrchr(inbuf, '\t');
X if (s)
X s++;
X else
X s = inbuf;
X
X
X /* Determine mode and call appropriate processing function */
X if (strncmp(s, "\\#", 2) == 0)
X inviz_num(s + 2, line);
X else
X inviz_text(s, 'a', outbuf);
X }
X}
END_OF_FILE
if test 1474 -ne `wc -c <'viz-1.1.0/inviz.c'`; then
echo shar: \"'viz-1.1.0/inviz.c'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/inviz.c'
fi
if test -f 'viz-1.1.0/inviz_num.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/inviz_num.c'\"
else
echo shar: Extracting \"'viz-1.1.0/inviz_num.c'\" \(3169 characters\)
sed "s/^X//" >'viz-1.1.0/inviz_num.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <ctype.h>
X#include "translate.h"
X
Xextern char *prog;
X
Xvoid
Xinviz_num(str, line)
Xregister char *str;
Xint line;
X{
X typedef union {
X char c; unsigned char uc;
X short s; unsigned short us;
X int i; unsigned int ui;
X long l; unsigned long ul;
X float f;
X double d;
X } ANYVAL;
X register ANYVAL rv;
X ANYVAL v;
X float f;
X
X register j;
X char *next;
X register char *p;
X
X int negative;
X
X char mode = 'I';
X char outbuf[1000];
X
X double strtod();
X unsigned long strtou();
X
X while (*str) {
X if (isspace(*str)) {
X str++;
X continue;
X }
X
X switch (*str) {
X case 'C':


X case 'S':
X case 'I':
X case 'L':
X case 'F':
X case 'D':

X mode = *str++;
X break;
X case '\\':
X str++;
X if (*str == '#' && *(str+1)) {
X mode = *++str;
X str++;
X } else if (*str == 'x') {
X str++;
X translate_hex(rv.uc, str);
X (void) putchar(rv.uc);
X } else {
X translate_octal(rv.uc, str);
X (void) putchar(rv.uc);
X }
X break;
X case '-':


X case '0':
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 /* Translate a number */
X if (mode == 'F' || mode == 'D') {
X v.d = strtod(str, &next);
X if (next == str) {
X (void) fprintf(stderr,
X "%s: Error while translating number on line %d\n.",
X prog, line);
X (void) fprintf(stderr, "Line ignored from `%s'\n", str);
X return;
X }
X str = next;
X if (mode == 'F') {
X f = v.d;
X for (j = sizeof(float), p = (char *) &f; j; --j)
X (void) putchar(*p++);
X } else {
X for (j = sizeof(double), p = (char *) &v.d; j; --j)
X (void) putchar(*p++);
X }
X } else {
X if (*str == '-') {
X str++;
X negative = 1;
X } else {
X negative = 0;
X }
X rv.ul = strtou(str, &next, 0);
X if (next == str) {
X (void) fprintf(stderr,
X "%s: Error while translating number on line %d\n.",
X prog, line);
X (void) fprintf(stderr, "Line ignored from `%s'\n", str);
X return;
X }
X str = next;
X if (negative) {
X switch (mode) {
X case 'C':
X (void) putchar((char) -rv.ul);


X break;
X case 'S':

X v.s = (short) -rv.ul;
X for (j = sizeof(short), p = (char *) &v.s; j; --j)
X (void) putchar(*p++);


X break;
X case 'I':

X v.i = (int) -rv.ul;
X for (j = sizeof(int), p = (char *) &v.i; j; --j)
X (void) putchar(*p++);


X break;
X case 'L':

X v.l = (long) -rv.ul;
X for (j = sizeof(long), p = (char *) &v.l; j; --j)
X (void) putchar(*p++);
X break;
X }
X } else {
X switch (mode) {
X case 'C':
X (void) putchar((unsigned char) rv.ul);


X break;
X case 'S':

X v.us = (unsigned short) rv.ul;
X for (j = sizeof(short), p = (char *) &v.us; j; --j)
X (void) putchar(*p++);


X break;
X case 'I':

X v.ui = (unsigned int) rv.ul;
X for (j = sizeof(int), p = (char *) &v.ui; j; --j)
X (void) putchar(*p++);


X break;
X case 'L':

X v.ul = (unsigned long) rv.ul;
X for (j = sizeof(long), p = (char *) &v.ul; j; --j)
X (void) putchar(*p++);


X break;
X }
X }
X }

X break;
X default:
X (void) fprintf(stderr, "%s: Invalid input on line %d\n",
X prog, line);


X exit(1);
X break;
X }
X }
X}

END_OF_FILE
if test 3169 -ne `wc -c <'viz-1.1.0/inviz_num.c'`; then
echo shar: \"'viz-1.1.0/inviz_num.c'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/inviz_num.c'
fi
if test -f 'viz-1.1.0/inviz_text.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/inviz_text.c'\"
else
echo shar: Extracting \"'viz-1.1.0/inviz_text.c'\" \(2138 characters\)
sed "s/^X//" >'viz-1.1.0/inviz_text.c' <<'END_OF_FILE'


X#include <stdio.h>
X#include <ctype.h>
X#include "string.h"

X#include "viz.h"
X#include "translate.h"
X
X/* Takes a line of printable text containing viz(1)-style escape
X * sequences and turns it into the (possibly binary) text represented
X * by the text. Note that non-printing characters embedded in the
X * input text aren't changed, because we are only translating the
X * printable viz(1)-style stuff.
X
X */
X
Xvoid
Xinviz_text(s, mode, outbuf)
Xregister char *s; /* line to translate. If mode is 'c', s should begin
X * after the 'c' mode character.
X */
Xregister char mode; /* 'c' or 'a'; not checked for validity */
Xchar *outbuf; /* Where the output goes; assumed long enough.
X * Note that the output will never be longer than
X * the input.
X */
X{
X register char *outbuf_p = outbuf;
X


X register unsigned char c;

X register n;
X
X for (; *s && *s != '\n'; s++) {
X if (mode == 'c' && isspace(*s)) {
X /* Eat whitespace in 'c' mode */
X continue;
X }
X
X if (*s == '\\') {
X switch (*++s) {


X#ifdef __STDC__
X case 'a':

X *outbuf_p++ = '\a';


X break;
X#endif
X case 'b':

X *outbuf_p++ = '\b';


X break;
X case 'f':

X *outbuf_p++ = '\f';


X break;
X case 'n':

X *outbuf_p++ = '\n';
X break;
X case 'r':
X *outbuf_p++ = '\r';


X break;
X case 't':

X *outbuf_p++ = '\t';


X break;
X#ifdef __STDC__
X case 'v':

X *outbuf_p++ = '\v';
X break;
X#endif
X case '\\':
X *outbuf_p++ = '\\';
X break;
X case '^':
X *outbuf_p++ = '^';
X break;
X case '\'':
X *outbuf_p++ = '\'';
X break;
X case '"':
X *outbuf_p++ = '"';


X break;
X case '?':

X *outbuf_p++ = '?';


X break;
X case '0':
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':

X translate_octal(c, s);
X s--;
X *outbuf_p++ = c;
X break;
X case 'x':
X s++;
X translate_hex(c, s);
X s--;
X *outbuf_p++ = c;
X break;
X default:
X *outbuf_p++ = *s;
X break;
X }
X } else if (*s == '^') {
X n = (int) *++s + 1 - 'A';
X *outbuf_p++ = n;
X } else {
X /* Print character literally. */
X *outbuf_p++ = *s;
X }
X }
X (void) fwrite(outbuf, 1, outbuf_p - outbuf, stdout);
X}
END_OF_FILE
if test 2138 -ne `wc -c <'viz-1.1.0/inviz_text.c'`; then
echo shar: \"'viz-1.1.0/inviz_text.c'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/inviz_text.c'
fi
if test -f 'viz-1.1.0/loadfile.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/loadfile.c'\"
else
echo shar: Extracting \"'viz-1.1.0/loadfile.c'\" \(998 characters\)
sed "s/^X//" >'viz-1.1.0/loadfile.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/fcntl.h>
X
Xextern errno;
X
Xchar *loadfile(path)
Xchar *path;
X{
X /* Opens file path, reads contents into malloc'd buffer,
X * appends null character to buffer, returns ptr to buffer.
X
X * Returns NULL if can't open/read file or can't malloc space.
X * The cases can be distinguished by errno=0 for latter case.
X
X * Comment: the file is assumed to be a "normal file"; i.e.
X * a single read will return all data in the file.
X */
X
X struct stat statbuf;
X char *data;
X char *malloc();
X int fd;
X
X if (stat(path, &statbuf) == -1)
X return NULL;
X
X data = malloc(statbuf.st_size+1);
X if (data == NULL) {
X errno = 0;
X return NULL;
X }
X data[statbuf.st_size] = '\0';
X
X fd = open(path, O_RDONLY);
X if (fd == -1) {
X (void) free(data);
X return NULL;
X }
X
X if (read(fd, data, statbuf.st_size) != statbuf.st_size) {
X (void) free(data);
X return NULL;
X }
X
X return data;
X}
END_OF_FILE
if test 998 -ne `wc -c <'viz-1.1.0/loadfile.c'`; then
echo shar: \"'viz-1.1.0/loadfile.c'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/loadfile.c'
fi
if test -f 'viz-1.1.0/memory.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/memory.h'\"
else
echo shar: Extracting \"'viz-1.1.0/memory.h'\" \(131 characters\)
sed "s/^X//" >'viz-1.1.0/memory.h' <<'END_OF_FILE'
X#ifdef NOMEM
X#define memcpy(s1, s2, n) bcopy(s2, s1, n)
X#define memcmp(s1, s2, n) bcmp(s2, s1, n)
X#else
X#include <memory.h>
X#endif
END_OF_FILE
if test 131 -ne `wc -c <'viz-1.1.0/memory.h'`; then
echo shar: \"'viz-1.1.0/memory.h'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/memory.h'
fi
if test -f 'viz-1.1.0/string.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/string.h'\"
else
echo shar: Extracting \"'viz-1.1.0/string.h'\" \(148 characters\)
sed "s/^X//" >'viz-1.1.0/string.h' <<'END_OF_FILE'
X#ifdef STRINGS
X#include <strings.h>
X#define strchr(s,c) index((s),(c))
X#define strrchr(s,c) rindex((s),(c))
X#else
X#include <string.h>
X#endif
END_OF_FILE
if test 148 -ne `wc -c <'viz-1.1.0/string.h'`; then
echo shar: \"'viz-1.1.0/string.h'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/string.h'
fi
if test -f 'viz-1.1.0/strtod.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/strtod.c'\"
else
echo shar: Extracting \"'viz-1.1.0/strtod.c'\" \(2551 characters\)
sed "s/^X//" >'viz-1.1.0/strtod.c' <<'END_OF_FILE'
X#include <ctype.h>
X#include "string.h"
X#include <math.h>
X
Xdouble
Xstrtod(str, ptr)
Xchar *str;
Xchar **ptr;
X{
X int sign = 1;
X register char c;
X register char *s = str;
X register char *p;
X register i;
X int expon, expon_s;
X double mult, mant, atof();
X
X /* Skip whitespace */
X while (isspace(*s))
X s++;
X
X /* Check for sign */
X c = *s;
X if (c == '+') {
X sign = 1;
X s++;
X } else if (c == '-') {
X sign = -1;
X s++;
X } else if (!isdigit(c)) {
X /* String has to be one of INF INFINITY NAN(string w/o ')') */
X char buf[10]; /* to make a lowercase comparison */
X double big = 1000000.0;
X int slen = strlen(s);
X
X (void) strncpy(buf, s, 10);
X for (p = buf, i=slen; i-- != 0; p++ ) {
X if (isupper(*p))
X *p = tolower(*p);
X }
X
X if (strncmp(buf, "inf", 3) == 0) {
X if (ptr)
X *ptr = s+3;
X return (sign * exp(big));
X } else if (strncmp(buf, "infinity",8) == 0) {
X if (ptr)
X *ptr = s+8;
X return (sign * exp(big));
X } else if (strncmp(buf, "nan",3) == 0 && *(buf+3) != '(') {
X if (ptr)
X *ptr = s+3;
X return (sign * exp(big)) / exp(big);
X } else if (strncmp(buf, "nan(", 4) == 0) {
X /* Rest has to end in ')' and not include ')' */
X p = strchr(buf, ')');
X if (p == (char *) 0) {
X /* No closing ')' */
X if (ptr)
X *ptr = str;
X return 0.0;
X }
X if (ptr)
X *ptr = s + (p + 1 - buf);
X return exp(big) / exp(big);
X }
X }
X
X /* To get here: we've got a sign, now need mantissa[+exponent] */
X for (mant = 0.0; isdigit(*s);)
X mant = (mant * 10.0) + (*s++ - '0');
X if (*s == '.') {
X /* Collect fraction */
X s++;
X for ( mult = 0.1; isdigit(*s); mult *= 0.1 )
X mant += (*s++ - '0') * mult;
X }
X /* Check for exponent character */
X c = *s;
X if (c != 'e' && c != 'E' && c != 'd' && c != 'D') {
X if (ptr)
X *ptr = s;
X return sign * mant;
X }
X /* Check for <sign><digit> or <digit> following exponent character */
X c = *(s+1);
X if (c == '+' || c == '-') {
X if (!isdigit(*(s+2))) {
X if (ptr)
X *ptr = s;
X return sign * mant;
X }
X } else if (!isdigit(c)) {
X if (ptr)
X *ptr = s;
X return sign * mant;
X }
X /* Move past exponent character */
X s++;
X /* Check for sign */
X switch (*s) {
X case '+':
X expon_s = 1;
X s++;


X break;
X case '-':

X expon_s = -1;
X s++;
X break;
X default:
X expon_s = 1;
X }
X /* Collect exponent */
X for (expon = 0; isdigit(*s);)
X expon = (expon * 10) + (*s++ - '0');
X if (expon_s == -1)
X expon = -expon;
X if (ptr)
X *ptr = s;
X return sign * mant * pow(10.0, (double) expon);
X}
END_OF_FILE
if test 2551 -ne `wc -c <'viz-1.1.0/strtod.c'`; then
echo shar: \"'viz-1.1.0/strtod.c'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/strtod.c'
fi
if test -f 'viz-1.1.0/strtou.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/strtou.c'\"
else
echo shar: Extracting \"'viz-1.1.0/strtou.c'\" \(3490 characters\)
sed "s/^X//" >'viz-1.1.0/strtou.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <ctype.h>
X
X/*
X * digit_a2d[c] maps ascii characters 0..9, a-f, A-F into the corresponding
X * integer digits. It is NOT ok to give it anything but a digit character
X * as an argument.
X */
Xstatic int digit_a2d[104] = {
X 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 7 */
X 0, 0, 0, 0, 0, 0, 0, 0, /* 8 - 15 */
X 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 23 */
X 0, 0, 0, 0, 0, 0, 0, 0, /* 24 - 31 */
X 0, 0, 0, 0, 0, 0, 0, 0, /* 32 - 39 */
X 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 47 */
X 0, 1, 2, 3, 4, 5, 6, 7, /* 48 - 55 */
X 8, 9, 0, 0, 0, 0, 0, 0, /* 56 - 63 */
X 0,10,11,12,13,14,15, 0, /* 64 - 71 */
X 0, 0, 0, 0, 0, 0, 0, 0, /* 72 - 79 */
X 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 87 */
X 0, 0, 0, 0, 0, 0, 0, 0, /* 88 - 95 */
X 0,10,11,12,13,14,15, 0, }; /* 96 -103 */
X
Xunsigned long strtou(str, ptr, base)
X
X/* Converts a string representation of a number to an unsigned long. Leading
X * whitespace is ignored. The string is scanned up to the first character
X * inconsistent with the base. Valid numbers have one of the following
X * formats:
X * 0[xX]ddd -- hex number; ddd are 0-9, a-f, and A-F
X * 0[bB]ddd -- binary number; ddd are 0's and 1's
X * 0ddd -- octal number; ddd are octal digits
X * dddd -- decimal number; ddd are decimal digits
X */
X
Xregister char *str; /* string to be converted */
X
Xchar **ptr; /* if not (char **)NULL, ptr to char terminating scan is returned
X * in *ptr.
X */
X
Xint base; /* must be one of 0, 2, 8, 10, or 16, else function returns 0
X * If the base is zero, the correct base is determined according
X * as the string has one of the formats given above.
X */
X
X{
X unsigned long value=0;
X
X if (ptr)
X *ptr = str;
X
X /* Special case: null string */
X if (! *str)
X return 0;
X
X /* skip leading whitespace */
X while (isspace(*str))
X ++str;
X
X /* Check for end of string */
X if (*str == '\0')
X return 0;
X
X /* Determine base */
X if (base == 0) {
X if (*str != '0')
X base = 10;
X else if (*++str == 0) {
X /* Special case: string is '0' */
X if (ptr)
X *ptr = str;
X return 0;
X } else if (*str == 'x' || *str == 'X') {
X base = 16;
X ++str;
X } else if (*str == 'b' || *str == 'B') {
X base = 2;
X ++str;
X } else {
X base = 8;
X }
X }
X
X /* Convert string */
X switch (base) {
X case 2:
X /* Skip 0[bB], if present */
X if (*str == '0')
X if (*++str == 'b' || *str == 'B')
X ++str;
Xmore2: while (*str == '0' || *str == '1') {
X value = value<<1 | digit_a2d[*str];
X ++str;
X }
X if (*str == ',') { /* allow for comma-separated numbers */
X str++;
X goto more2;
X }
X break;
X case 8:
X while (*str >= '0' && *str <= '7') {
X value = value<<3 | digit_a2d[*str];
X ++str;
X }
X break;
X case 10:
X while (isdigit(*str)) {
X value = value*10 + digit_a2d[*str];
X ++str;
X }
X break;
X case 16:
X /* Skip 0[xX], if present */
X if (*str == '0')
X if (*++str == 'x' || *str == 'X')
X ++str;
X while (isxdigit(*str)) {
X value = value<<4 | digit_a2d[*str];
X ++str;


X }
X break;
X default:

X return 0;
X }
X

X if (ptr)
X *ptr = str;
X
X return value;
X}
END_OF_FILE
if test 3490 -ne `wc -c <'viz-1.1.0/strtou.c'`; then
echo shar: \"'viz-1.1.0/strtou.c'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/strtou.c'
fi
if test -f 'viz-1.1.0/version.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/version.h'\"
else
echo shar: Extracting \"'viz-1.1.0/version.h'\" \(46 characters\)
sed "s/^X//" >'viz-1.1.0/version.h' <<'END_OF_FILE'
X#define Version "1.1"
X#define Patchlevel "0"
END_OF_FILE
if test 46 -ne `wc -c <'viz-1.1.0/version.h'`; then
echo shar: \"'viz-1.1.0/version.h'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/version.h'
fi
if test -f 'viz-1.1.0/viz_decode.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'viz-1.1.0/viz_decode.c'\"
else
echo shar: Extracting \"'viz-1.1.0/viz_decode.c'\" \(2215 characters\)
sed "s/^X//" >'viz-1.1.0/viz_decode.c' <<'END_OF_FILE'


X#include <stdio.h>
X#include <ctype.h>
X#include "string.h"

X#include "viz.h"
X#include "translate.h"
X
X#ifdef VIZ
Xextern long count_reg[];
X#endif
X
X/* Translates strings containing C escapes.
X * If compiled with -DVIZ, then $x has special meaning
X * as viz comment escape sequence.
X * Stops at newline or \0.
X *
X */
X
Xvoid
Xviz_decode(s, mode, outbuf)
Xregister char *s; /* line to translate. If mode is 'c', s should begin
X * after the 'c' mode character.
X */
Xregister char mode; /* 'c' or 'a' */
Xchar *outbuf; /* Output buffer; assumed long enough. Note that
X * the output will never be longer than the input.
X */
X{
X char *outbuf_p = outbuf;


X register unsigned char c;

X register n;
X
X outbuf_p = outbuf;
X
X for (; *s; s++) {
X if (mode == 'c' && isspace(*s)) {
X /* Eat whitespace in 'c' mode */
X continue;
X }
X
X if (*s == '\\') {
X switch (*++s) {


X#ifdef __STDC__
X case 'a':

X *outbuf_p++ = '\a';


X break;
X#endif
X case 'b':

X *outbuf_p++ = '\b';


X break;
X case 'f':

X *outbuf_p++ = '\f';


X break;
X case 'n':

X *outbuf_p++ = '\n';
X break;
X case 'r':
X *outbuf_p++ = '\r';


X break;
X case 't':

X *outbuf_p++ = '\t';


X break;
X#ifdef __STDC__
X case 'v':

X *outbuf_p++ = '\v';
X break;
X#endif
X case '\\':
X *outbuf_p++ = '\\';
X break;
X case '^':
X *outbuf_p++ = '^';
X break;
X case '\'':
X *outbuf_p++ = '\'';
X break;
X case '"':
X *outbuf_p++ = '"';


X break;
X case '?':

X *outbuf_p++ = '?';


X break;
X case '0':
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':

X translate_octal(c, s);
X s--;
X *outbuf_p++ = c;
X break;
X case 'x':
X s++;
X translate_hex(c, s);
X s--;
X *outbuf_p++ = c;
X break;
X default:
X *outbuf_p++ = *s;
X break;
X }
X#ifdef VIZ
X } else if (*s == '$' && *(s+1)) {
X (void) sprintf(outbuf_p, "%d", count_reg[(int) *++s]);
X outbuf_p += strlen(outbuf_p);
X#endif
X } else if (*s == '^') {
X n = (int) *++s + 1 - 'A';
X *outbuf_p++ = n;
X } else if (*s == '\n') {
X /* End of line */
X *outbuf_p = '\0';
X return;
X } else {
X /* Print character literally. */
X *outbuf_p++ = *s;
X }
X }
X *outbuf_p = '\0';
X return;
X}
END_OF_FILE
if test 2215 -ne `wc -c <'viz-1.1.0/viz_decode.c'`; then
echo shar: \"'viz-1.1.0/viz_decode.c'\" unpacked with wrong size!
fi
# end of 'viz-1.1.0/viz_decode.c'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone


MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0

exit 0 # Just in case...

0 new messages