1.4
This commit is contained in:
commit
6a4b7a68fa
149
Makefile
Normal file
149
Makefile
Normal file
@ -0,0 +1,149 @@
|
||||
|
||||
# Unix Makefile for xd
|
||||
|
||||
VERSION = 1.4
|
||||
|
||||
# C compiler
|
||||
CC = gcc
|
||||
|
||||
# For production
|
||||
CFLAGS = -O -Wall
|
||||
|
||||
# For debugging
|
||||
#CFLAGS = -g -Wall
|
||||
|
||||
xd: xd.o
|
||||
$(CC) $(CFLAGS) xd.o -o xd
|
||||
|
||||
clean:
|
||||
rm -f xd *.bak *.cat core *.out *.o *.shar *.gz *.tar *.zip *.opt *.ncb *.plg
|
||||
|
||||
RELEASE = Makefile xd.1 xd.c index.html log.txt images
|
||||
|
||||
dist:
|
||||
rm -f *.tar *.tar.gz
|
||||
tar cfvz xd-$(VERSION).tar.gz $(RELEASE)
|
||||
|
||||
manpage:
|
||||
nroff -man xd.1 | more
|
||||
|
||||
printman:
|
||||
ptroff -man xd.1
|
||||
|
||||
catman:
|
||||
nroff -man xd.1 | col -b >xd.cat
|
||||
|
||||
# The following tests should produce no error messages from XD or CMP
|
||||
|
||||
check: testb testad testao testdd testdo
|
||||
|
||||
testb: xd
|
||||
xd xd xd1.bak
|
||||
xd -l xd1.bak xd2.bak
|
||||
cmp xd2.bak xd
|
||||
xd -c xd xd3.bak
|
||||
xd -l xd3.bak xd4.bak
|
||||
cmp xd4.bak xd
|
||||
xd -l -s xd3.bak xd4.bak
|
||||
cmp xd4.bak xd
|
||||
sed 's/........//' xd3.bak >xd5.bak
|
||||
xd -l -s xd5.bak xd6.bak
|
||||
cmp xd6.bak xd
|
||||
echo Hello there >xd10.bak
|
||||
xd xd10.bak >xd7.bak
|
||||
sed '1d' xd3.bak >>xd7.bak
|
||||
xd -l -s xd7.bak xd8.bak
|
||||
cp xd10.bak xd9.bak
|
||||
tail --bytes=+17 xd >>xd9.bak
|
||||
cmp xd8.bak xd9.bak
|
||||
cat xd | xd -dDeFile >xd10.c
|
||||
echo "#include <unistd.h>\nint main() {write(1,DeFile,sizeof DeFile); return 0;}" >>xd10.c
|
||||
$(CC) xd10.c -o xd10.bak
|
||||
chmod 755 xd10.bak
|
||||
./xd10.bak >xd11.bak
|
||||
cmp xd11.bak xd
|
||||
rm xd*.bak xd10.c
|
||||
|
||||
testad: xd
|
||||
xd -ad xd xd1.bak
|
||||
xd -ad -l xd1.bak xd2.bak
|
||||
cmp xd2.bak xd
|
||||
xd -ad -c xd xd3.bak
|
||||
xd -ad -l xd3.bak xd4.bak
|
||||
cmp xd4.bak xd
|
||||
xd -ad -l -s xd3.bak xd4.bak
|
||||
cmp xd4.bak xd
|
||||
sed 's/........//' xd3.bak >xd5.bak
|
||||
xd -ad -l -s xd5.bak xd6.bak
|
||||
cmp xd6.bak xd
|
||||
echo Hello there >xd10.bak
|
||||
xd -ad xd10.bak >xd7.bak
|
||||
sed '1d' xd3.bak >>xd7.bak
|
||||
xd -ad -l -s xd7.bak xd8.bak
|
||||
cp xd10.bak xd9.bak
|
||||
tail --bytes=+17 xd >>xd9.bak
|
||||
cmp xd8.bak xd9.bak
|
||||
rm xd*.bak
|
||||
|
||||
testao: xd
|
||||
xd -ao xd xd1.bak
|
||||
xd -ao -l xd1.bak xd2.bak
|
||||
cmp xd2.bak xd
|
||||
xd -ao -c xd xd3.bak
|
||||
xd -ao -l xd3.bak xd4.bak
|
||||
cmp xd4.bak xd
|
||||
xd -ao -l -s xd3.bak xd4.bak
|
||||
cmp xd4.bak xd
|
||||
sed 's/........//' xd3.bak >xd5.bak
|
||||
xd -ao -l -s xd5.bak xd6.bak
|
||||
cmp xd6.bak xd
|
||||
echo Hello there >xd10.bak
|
||||
xd -ao xd10.bak >xd7.bak
|
||||
sed '1d' xd3.bak >>xd7.bak
|
||||
xd -ao -l -s xd7.bak xd8.bak
|
||||
cp xd10.bak xd9.bak
|
||||
tail --bytes=+17 xd >>xd9.bak
|
||||
cmp xd8.bak xd9.bak
|
||||
rm xd*.bak
|
||||
|
||||
testdd: xd
|
||||
xd -nd -ad xd xd1.bak
|
||||
xd -nd -ad -l xd1.bak xd2.bak
|
||||
cmp xd2.bak xd
|
||||
xd -nd -ad -c xd xd3.bak
|
||||
xd -nd -ad -l xd3.bak xd4.bak
|
||||
cmp xd4.bak xd
|
||||
xd -nd -ad -l -s xd3.bak xd4.bak
|
||||
cmp xd4.bak xd
|
||||
sed 's/........//' xd3.bak >xd5.bak
|
||||
xd -nd -ad -l -s xd5.bak xd6.bak
|
||||
cmp xd6.bak xd
|
||||
echo Hello there >xd10.bak
|
||||
xd -nd -ad xd10.bak >xd7.bak
|
||||
sed '1d' xd3.bak >>xd7.bak
|
||||
xd -nd -ad -l -s xd7.bak xd8.bak
|
||||
cp xd10.bak xd9.bak
|
||||
tail --bytes=+17 xd >>xd9.bak
|
||||
cmp xd8.bak xd9.bak
|
||||
rm xd*.bak
|
||||
|
||||
testdo: xd
|
||||
xd -no -ah xd xd1.bak
|
||||
xd -no -ah -l xd1.bak xd2.bak
|
||||
cmp xd2.bak xd
|
||||
xd -no -ah -c xd xd3.bak
|
||||
xd -no -ah -l xd3.bak xd4.bak
|
||||
cmp xd4.bak xd
|
||||
xd -no -ah -l -s xd3.bak xd4.bak
|
||||
cmp xd4.bak xd
|
||||
sed 's/........//' xd3.bak >xd5.bak
|
||||
xd -no -ah -l -s xd5.bak xd6.bak
|
||||
cmp xd6.bak xd
|
||||
echo Hello there >xd10.bak
|
||||
xd -no -ah xd10.bak >xd7.bak
|
||||
sed '1d' xd3.bak >>xd7.bak
|
||||
xd -no -ah -l -s xd7.bak xd8.bak
|
||||
cp xd10.bak xd9.bak
|
||||
tail --bytes=+17 xd >>xd9.bak
|
||||
cmp xd8.bak xd9.bak
|
||||
rm xd*.bak
|
BIN
images/xd.png
Normal file
BIN
images/xd.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.2 KiB |
237
index.html
Normal file
237
index.html
Normal file
@ -0,0 +1,237 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>xd: Extended Dump and Load Utility</title>
|
||||
<meta name="keywords" content="xd, dump, hexadecimal, octal, decimal, ASCII, ISO" />
|
||||
<meta name="description" content="xd: Extended Dump and Load Utility" />
|
||||
<meta name="author" content="John Walker" />
|
||||
<meta name="robots" content="index" />
|
||||
<link rel="stylesheet" href="https://www.fourmilab.ch/documents/styles/standard_screen.css"
|
||||
type="text/css" />
|
||||
<style type="text/css">
|
||||
blockquote.rights {
|
||||
text-align: justify;
|
||||
font-size: smaller;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
dl.options :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
dl.options dd {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
dl.options dt {
|
||||
margin-top: 1ex;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
h3.subtitle {
|
||||
color: #0000FF;
|
||||
font-style: italic;
|
||||
margin-top: 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: justify;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="standard">
|
||||
|
||||
<h1 class="c" style="margin-bottom: 0px;"><img src="images/xd.png"
|
||||
width="257" height="123" alt="XD" /></h1>
|
||||
<h3 class="subtitle">Extended Dump and Load Utility</h3>
|
||||
|
||||
<hr />
|
||||
|
||||
<p>
|
||||
This page describes, in Unix manual page style,
|
||||
<b>xd</b>, a utility which dumps files in hexadecimal,
|
||||
decimal, or octal, with file addresses shown in any of
|
||||
those formats. <b>xd</b> can read files in any of the
|
||||
formats it writes, recreating binary files, including
|
||||
modifications made by editing the dump with any text
|
||||
editor. In addition, <b>xd</b> can transform a binary
|
||||
file into a C data declaration which permits embedding
|
||||
its contents into a program. <b>xd</b> is available as
|
||||
C source code compatible with most Unix systems.
|
||||
</p>
|
||||
|
||||
<h3>NAME</h3>
|
||||
<p>
|
||||
<b>xd</b> – extended dump and load utility
|
||||
</p>
|
||||
|
||||
<h3>SYNOPSIS</h3>
|
||||
<p>
|
||||
<b>xd</b> [ <b>−a</b><i>addrfmt</i> <b>−c</b>
|
||||
<b>−d</b><i>label</i> <b>−l</b> <b>−n</b><i>datafmt</i>
|
||||
<b>−s</b> ] [ <i>infile</i> [ <i>outfile</i> ] ]
|
||||
</p>
|
||||
|
||||
<h3>DESCRIPTION</h3>
|
||||
<p>
|
||||
<b>xd</b> dumps files in hexadecimal, decimal, or octal, optionally with
|
||||
ISO characters side by side. File addresses can likewise be
|
||||
displayed in hex, decimal, or octal notation.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>xd</b> can <em>read</em> dump files in the same formats it writes and create
|
||||
binary files from the data therein. This allows you to dump a
|
||||
binary file with <b>xd</b>, edit it with your favourite text editor,
|
||||
then make a new binary file containing whatever changes you've
|
||||
made. When creating a binary file, <b>xd</b> normally assumes you've
|
||||
only modified data in place (neither expanding nor contracting
|
||||
the file) and verifies file addresses to guarantee this.
|
||||
However, a "stream" option is available which ignores file
|
||||
addresses so you're free to insert and delete bytes at will. <b>xd</b>
|
||||
thus turns your existing text editor into a binary file editor
|
||||
without requiring you to learn any new commands.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Finally, <b>xd</b> can read a binary file and emit a C language data
|
||||
declaration which contains the data from the file. This is handy
|
||||
when you wish to embed binary data within C programs.
|
||||
</p>
|
||||
|
||||
<h3>OPTIONS</h3>
|
||||
|
||||
<dl class="options">
|
||||
<dt><b>−a</b><i>addrfmt</i></dt>
|
||||
<dd>Displays addresses in the dumped file as specified by
|
||||
<i>addrfmt</i>: <b>d</b> for decimal, <b>h</b> or
|
||||
<b>x</b> for hexadecimal, and <b>o</b> for octal. By
|
||||
default, addresses are shown in hexadecimal.</dd>
|
||||
|
||||
<dt><b>−c</b></dt>
|
||||
<dd>Display ISO characters alongside the numeric
|
||||
dump. Non-printing characters (according to ISO
|
||||
8859/1) are shown as periods. The ISO characters are
|
||||
separated from the dump by vertical bar characters,
|
||||
which <b>xd</b> treats as comment delimiters when loading a
|
||||
file.</dd>
|
||||
|
||||
<dt><b>−d</b><i>label</i></dt>
|
||||
<dd>Dumps the file as a C language declaration of an array
|
||||
of <tt>unsigned char</tt> which, when compiled, will
|
||||
contain the same data as the binary input file. The C
|
||||
array declaration is given the variable name
|
||||
<i>label</i>, or <tt>xd_data</tt> if no label
|
||||
specification is given. Data are declared as individual
|
||||
bytes to guarantee portability across architectures with
|
||||
different byte ordering conventions, and are expressed
|
||||
as decimal numbers in lines of less than 80 characters
|
||||
for maximum portability among compilers. The C operator
|
||||
<tt>sizeof</tt> may be applied to the array <i>label</i>
|
||||
to obtain its length in bytes.</dd>
|
||||
|
||||
<dt><b>−l</b></dt>
|
||||
<dd>Load file from dump. <b>xd</b> reads a file in the same
|
||||
format it writes, creating a binary output file. Each
|
||||
line is assumed to begin with a file address terminated
|
||||
by a colon. Data bytes are separated by white space,
|
||||
and any characters after a vertical bar are ignored
|
||||
(thus discarding any ISO characters included in the dump
|
||||
with the <b>−c</b> option). If the
|
||||
<b>−s</b> option is not specified, each file
|
||||
address is checked against the number of bytes written
|
||||
so far to guarantee that no bytes have been added or
|
||||
deleted. Files must be loaded with the <b>−a</b>
|
||||
and <b>−n</b> options set the same as when the
|
||||
file was dumped.</dd>
|
||||
|
||||
<dt><b>−n</b><i>datafmt</i></dt>
|
||||
<dd>Edits bytes in the dumped file as specified by
|
||||
<i>datafmt</i>: <b>d</b> for decimal, <b>h</b> or
|
||||
<b>x</b> for hexadecimal, and <b>o</b> for octal. By
|
||||
default, bytes are shown in hexadecimal.</dd>
|
||||
|
||||
<dt><b>−s</b></dt>
|
||||
<dd>Stream input when loading file. If this option is
|
||||
specified in conjunction with the <b>−l</b> option, file
|
||||
addresses are not verified when loading a file and, in
|
||||
fact, need not be specified at all. The input file is
|
||||
treated as a stream of byte values separated by white
|
||||
space. This option allows you to create a dump with
|
||||
<b>xd</b>, edit it as you wish with any text editor,
|
||||
inserting and deleting bytes in the file wherever you
|
||||
like, then create a binary file from the modified dump
|
||||
with the command <b>xd −l −s</b> <i>dumpfile
|
||||
outfile</i>.</dd>
|
||||
|
||||
<dt><b>−u</b></dt>
|
||||
<dd>Print how-to-call information.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>FILES</h3>
|
||||
<p>
|
||||
If no <i>infile</i> is specified, <b>xd</b> obtains its
|
||||
input from standard input; if no <i>outfile</i> is given,
|
||||
output is sent to standard output. The input and output are
|
||||
processed in a strictly serial manner regardless of
|
||||
options; consequently <b>xd</b> may be used in pipelines
|
||||
without restrictions.
|
||||
</p>
|
||||
|
||||
<h3>BUGS</h3>
|
||||
<p>
|
||||
Input error checking in load mode might be improved. Note
|
||||
that each byte in load mode must be specified as a number
|
||||
in the same format selected by the <b>−n</b> option
|
||||
when the file was dumped, separated by white space, and
|
||||
that the <b>−a</b> and <b>−n</b> options must
|
||||
be set the same when loading a file as when it was dumped.
|
||||
</p>
|
||||
|
||||
<h3>SEE ALSO</h3>
|
||||
<p>
|
||||
<b>cc</b>(1), <b>od</b>(1), <b>iso_8859_1</b>(7)
|
||||
</p>
|
||||
|
||||
<h2><a href="xd-1.4.tar.gz"><img src="https://www.fourmilab.ch/images/icons/file.png"
|
||||
alt="[download]" class="button" width="40" height="40" /></a>
|
||||
<a href="xd-1.4.tar.gz">Download xd-1.4.tar.gz</a> (Gzipped TAR archive)</h2>
|
||||
|
||||
<p>
|
||||
The release archive contains source code, a <tt>Makefile</tt>
|
||||
for building the program, and documentation in manual page and
|
||||
HTML form.
|
||||
</p>
|
||||
|
||||
<h3>COPYING</h3>
|
||||
|
||||
<blockquote class="rights">
|
||||
<p>
|
||||
This software is in the public domain. Permission to use,
|
||||
copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby
|
||||
granted, without any conditions or restrictions. This
|
||||
software is provided “as is” without express or
|
||||
implied warranty.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<h3 class="nav"><a href="http://www.fourmilab.ch/?topic=unix">Other
|
||||
Unix Utilities at Fourmilab</a></h3>
|
||||
<h3 class="nav"><a href="http://www.fourmilab.ch/">Fourmilab Home Page</a></h3>
|
||||
|
||||
<p />
|
||||
<hr />
|
||||
|
||||
<address>
|
||||
by <a href="http://www.fourmilab.ch/">John Walker</a><br />
|
||||
Version 1.4<br />
|
||||
October, 2017
|
||||
</address>
|
||||
|
||||
</body>
|
||||
</html>
|
49
log.txt
Normal file
49
log.txt
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
XD
|
||||
Development Log
|
||||
|
||||
2000 August 29
|
||||
|
||||
Added _WIN32 code to xd.c to set input and output text/binary
|
||||
modes and force modes of standard input and output depending on
|
||||
the operation being performed. Input is set to binary except
|
||||
when a "-l" option load is selected, in which case the input
|
||||
file is text mode and the output is binary.
|
||||
|
||||
2000 September 10
|
||||
|
||||
Remade logo using Snap ITC font as before, changing background
|
||||
colour to be white as used in the updated HTML file. Note that
|
||||
due to an error in this font's bounding box calculation one
|
||||
must prefix "XD" with a space to avoid truncation of the left
|
||||
part of the "X".
|
||||
|
||||
2000 September 10
|
||||
|
||||
Version 1.3.
|
||||
|
||||
2017 October 16
|
||||
|
||||
Updated Makefile so that the test target works with current versions
|
||||
of Linux. The options on "tail" have changed since Solaris days in
|
||||
2000, and we need to include <unistd.h> in the embedded test program
|
||||
to avoid natters from GCC. Added -Wall to C compiler options.
|
||||
|
||||
Eliminated Win32 binaries from the release. They, like the operating
|
||||
system on which they ran and its regrettable vendor, are impotent and
|
||||
obsolete.
|
||||
|
||||
Removed "lint" target from Makefile. It's obsolete.
|
||||
|
||||
Removed "zip" target. We don't support legacy systems.
|
||||
|
||||
Cleaned up "tar" target to use tar's built in gzip and renamed
|
||||
to "dist".
|
||||
|
||||
Renamed the "test" target to the more standard "check".
|
||||
|
||||
Modified the individual test targets to create their temporary
|
||||
files in the working directory instead of /tmp, and to clean
|
||||
up the temporary files at the end of each test.
|
||||
|
||||
Version 1.4.
|
182
xd.1
Normal file
182
xd.1
Normal file
@ -0,0 +1,182 @@
|
||||
'\" t
|
||||
.TH XD 1 "29 AUG 2000"
|
||||
.UC 4
|
||||
.SH NAME
|
||||
xd \- extended dump and load utility
|
||||
.SH SYNOPSIS
|
||||
.B xd
|
||||
[
|
||||
.BI \-a addrfmt
|
||||
.B \-c
|
||||
.BI \-d label
|
||||
.B \-l
|
||||
.BI \-n datafmt
|
||||
.B \-s
|
||||
] [
|
||||
.I infile
|
||||
[
|
||||
.I outfile
|
||||
] ]
|
||||
.SH DESCRIPTION
|
||||
.B xd
|
||||
dumps files in hexadecimal, decimal, or octal, optionally with ISO characters side by
|
||||
side.
|
||||
File addresses can likewise be displayed in hex, decimal, or octal notation.
|
||||
.PP
|
||||
.B xd
|
||||
can
|
||||
.I read
|
||||
dump files in the same formats it writes and create binary files from
|
||||
the data therein. This allows you to dump a binary file with
|
||||
.BR xd ,
|
||||
edit it with your favourite text editor, then
|
||||
make a new binary file containing whatever changes you've made. When
|
||||
creating a binary file,
|
||||
.B xd
|
||||
normally assumes you've only modified data in place (neither expanding
|
||||
nor contracting the file) and verifies file addresses to guarantee
|
||||
this. However, a ``stream'' option is available which ignores file
|
||||
addresses so you're free to insert and delete bytes at
|
||||
will.
|
||||
.B xd
|
||||
thus turns your existing text editor into a binary file editor without
|
||||
requiring you to learn any new commands.
|
||||
.PP
|
||||
Finally,
|
||||
.B xd
|
||||
can read a binary file and emit a C language data declaration which
|
||||
contains the data from the file. This is handy when you wish to embed
|
||||
binary data within C programs.
|
||||
.SH OPTIONS
|
||||
.TP 10
|
||||
.BI \-a addrfmt
|
||||
Displays addresses in the dumped file as specified by
|
||||
.IR addrfmt :
|
||||
.B d
|
||||
for decimal,
|
||||
.B h
|
||||
or
|
||||
.B x
|
||||
for hexadecimal, and
|
||||
.B o
|
||||
for octal. By default, addresses are shown in hexadecimal.
|
||||
.TP
|
||||
.B \-c
|
||||
Display ISO characters alongside the numeric dump. Non-printing
|
||||
characters (according to ISO 8859/1) are shown as periods. The ISO
|
||||
characters are separated from the dump by vertical bar
|
||||
characters, which
|
||||
.B xd
|
||||
treats as comment delimiters when loading a file.
|
||||
.TP
|
||||
.BI \-d label
|
||||
Dumps the file as a C language declaration of an array of
|
||||
.B unsigned char
|
||||
which, when compiled, will contain the same data as the binary input file.
|
||||
The C array declaration is given the variable name
|
||||
.IR label ,
|
||||
or
|
||||
.B xd_data
|
||||
if no
|
||||
.I label
|
||||
specification is given. Data are declared as individual bytes to
|
||||
guarantee portability across architectures with different byte ordering
|
||||
conventions, and are expressed as decimal numbers in lines of less than
|
||||
80 characters for maximum portability among compilers. The
|
||||
C operator
|
||||
.B sizeof
|
||||
may be applied to the array
|
||||
.I label
|
||||
to obtain its length in bytes.
|
||||
.TP
|
||||
.B \-l
|
||||
Load file from dump.
|
||||
.B xd
|
||||
reads a file in the same format it writes, creating a binary output
|
||||
file. Each line is assumed to begin with a file address terminated by
|
||||
a colon. Data bytes are separated by white space,
|
||||
and any characters after a vertical bar
|
||||
are ignored (thus discarding any ISO characters included in the
|
||||
dump with the
|
||||
.B \-c
|
||||
option). If the
|
||||
.B \-s
|
||||
option is not specified, each file address is checked against the
|
||||
number of bytes written so far to guarantee that no bytes have been
|
||||
added or deleted.
|
||||
Files must be loaded with the
|
||||
.B \-a
|
||||
and
|
||||
.B \-n
|
||||
options set the same as when the file was dumped.
|
||||
.TP
|
||||
.BI \-n datafmt
|
||||
Edits bytes in the dumped file as specified by
|
||||
.IR datafmt :
|
||||
.B d
|
||||
for decimal,
|
||||
.B h
|
||||
or
|
||||
.B x
|
||||
for hexadecimal, and
|
||||
.B o
|
||||
for octal. By default, bytes are shown in hexadecimal.
|
||||
.TP
|
||||
.B \-s
|
||||
Stream input when loading file. If this option is specified in conjunction
|
||||
with the
|
||||
.B \-l
|
||||
option, file addresses are not verified when loading a file and, in fact,
|
||||
need not be specified at all. The input file is treated as a stream
|
||||
of byte values separated by white space. This option allows
|
||||
you to create a dump with
|
||||
.BR xd ,
|
||||
edit it as you wish with any text editor, inserting and deleting bytes
|
||||
in the file wherever you like, then create a binary file from the
|
||||
modified dump with the command
|
||||
.B xd \-l \-s
|
||||
.IR "dumpfile outfile" .
|
||||
.TP
|
||||
.B \-u
|
||||
Print how-to-call information.
|
||||
.SH FILES
|
||||
If no
|
||||
.I infile
|
||||
is specified,
|
||||
.B xd
|
||||
obtains its input from standard input; if no
|
||||
.I outfile
|
||||
is given, output is sent to standard output. The input and
|
||||
output are processed in a strictly serial manner regardless
|
||||
of options; consequently
|
||||
.B xd
|
||||
may be used in pipelines without restrictions.
|
||||
.SH BUGS
|
||||
.PP
|
||||
Input error checking in load mode might be improved. Note that each
|
||||
byte in load mode must be specified as a number in the same format
|
||||
selected by the
|
||||
.B \-n
|
||||
option when the file was dumped,
|
||||
separated by white space, and that the
|
||||
.B \-a
|
||||
and
|
||||
.B \-n
|
||||
options must be set the same when loading a file as
|
||||
when it was dumped.
|
||||
.SH "SEE ALSO"
|
||||
.PD
|
||||
.BR cc (1),
|
||||
.BR od (1),
|
||||
.BR iso_8859_1 (7)
|
||||
.ne 10
|
||||
.SH AUTHOR
|
||||
.ce 2
|
||||
John Walker
|
||||
http://www.fourmilab.ch/
|
||||
.PP
|
||||
This software is in the public domain.
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
without any conditions or restrictions. This software is provided ``as
|
||||
is'' without express or implied warranty.
|
407
xd.c
Normal file
407
xd.c
Normal file
@ -0,0 +1,407 @@
|
||||
/*
|
||||
|
||||
Extended dump and load utility
|
||||
|
||||
by John Walker
|
||||
http://www.fourmilab.ch/
|
||||
|
||||
This program is in the public domain.
|
||||
|
||||
*/
|
||||
|
||||
#define Version \
|
||||
"1.4 -- October 2017"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define EOS '\0'
|
||||
|
||||
static char addrformat[80] = "%6X";
|
||||
static char scanaddr[80] = "%lx%c";
|
||||
|
||||
static char dataformat1[80] = "%02X";
|
||||
static char scandata[80] = "%x%n%c";
|
||||
|
||||
static int bytesperline = 16, doublechar = FALSE,
|
||||
dflen = 2, loading = FALSE, streaming = FALSE;
|
||||
static unsigned long fileaddr;
|
||||
static unsigned char lineecho[32];
|
||||
|
||||
/* OUTLINE -- Edit a line of binary data into the selected output
|
||||
format. */
|
||||
|
||||
static void outline(out, dat, len)
|
||||
FILE *out;
|
||||
unsigned char *dat;
|
||||
int len;
|
||||
{
|
||||
char oline[132];
|
||||
int i;
|
||||
|
||||
sprintf(oline, addrformat, fileaddr);
|
||||
strcat(oline, ":");
|
||||
for (i = 0; i < len; i++) {
|
||||
char outedit[80];
|
||||
|
||||
sprintf(outedit, dataformat1, dat[i]);
|
||||
strcat(oline, (i == (bytesperline / 2)) ? " " : " ");
|
||||
strcat(oline, outedit);
|
||||
}
|
||||
|
||||
if (doublechar) {
|
||||
char oc[2];
|
||||
int shortfall = ((bytesperline - len) * (dflen + 1)) +
|
||||
(len <= (bytesperline / 2) ? 1 : 0);
|
||||
|
||||
while (shortfall-- > 0) {
|
||||
strcat(oline, " ");
|
||||
}
|
||||
oc[1] = EOS;
|
||||
strcat(oline, " | ");
|
||||
for (i = 0; i < len; i++) {
|
||||
int b = dat[i];
|
||||
|
||||
/* Map non-printing characters to "." according to the
|
||||
definitions for ISO 8859/1 Latin-1. */
|
||||
|
||||
if ((b < ' ') || (b > '~' && b < 160)) {
|
||||
b = '.';
|
||||
}
|
||||
|
||||
/* Many existing systems which support Latin-1 lack
|
||||
a definition for character 160, the non-breaking
|
||||
space. Translate this to a space to avoid
|
||||
confusion. */
|
||||
|
||||
if (b == 160) {
|
||||
b = ' ';
|
||||
}
|
||||
oc[0] = (char) b;
|
||||
strcat(oline, oc);
|
||||
}
|
||||
}
|
||||
strcat(oline, "\n");
|
||||
fputs(oline, out);
|
||||
}
|
||||
|
||||
/* INTERPLINE -- Interpret a line of input. */
|
||||
|
||||
static int interpline(line, lineno, out)
|
||||
char *line;
|
||||
int lineno;
|
||||
FILE *out;
|
||||
{
|
||||
char *cp = line;
|
||||
char c;
|
||||
unsigned long lfaddr;
|
||||
int gfaddr = FALSE;
|
||||
|
||||
/* Scan the line for a possible alternative format information
|
||||
following a vertical bar and delete it. */
|
||||
|
||||
while ((c = *cp++) != EOS) {
|
||||
if (c == '|') {
|
||||
cp[-1] = EOS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan the line for a file address terminated by a colon. Save
|
||||
the file address. */
|
||||
|
||||
cp = line;
|
||||
|
||||
while ((c = *cp++) != EOS) {
|
||||
if (c == ':') {
|
||||
int sa;
|
||||
char tchar;
|
||||
|
||||
cp[-1] = EOS;
|
||||
sa = sscanf(line, scanaddr, &lfaddr, &tchar);
|
||||
if (sa == 0 || (sa > 1 && tchar != EOS)) {
|
||||
fprintf(stderr,
|
||||
"Bad file address \"%s\" on line %d:\n",
|
||||
line, lineno);
|
||||
return FALSE;
|
||||
}
|
||||
gfaddr = TRUE;
|
||||
cp[-1] = ':';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!gfaddr) {
|
||||
cp = line;
|
||||
}
|
||||
if (!streaming) {
|
||||
if (!gfaddr) {
|
||||
fprintf(stderr, "File address missing on line %d:\n", lineno);
|
||||
fprintf(stderr, "%s\n", line);
|
||||
return FALSE;
|
||||
}
|
||||
if (lfaddr != fileaddr) {
|
||||
fprintf(stderr, "File address sequence error on line %d.\n",
|
||||
lineno);
|
||||
fprintf(stderr, " Expected ");
|
||||
fprintf(stderr, addrformat, fileaddr);
|
||||
fprintf(stderr, ", received ");
|
||||
fprintf(stderr, addrformat, lfaddr);
|
||||
fprintf(stderr, ".\n");
|
||||
fprintf(stderr, "%s\n", line);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
while ((c = *cp++) != EOS) {
|
||||
if (!isspace(c)) {
|
||||
int scanl, nscan, dvalue;
|
||||
char termchar;
|
||||
|
||||
if (((scanl = sscanf(cp - 1, scandata, &dvalue, &nscan, &termchar)) == 0) ||
|
||||
(dvalue < 0) || (dvalue > 255) ||
|
||||
(scanl == 2 && !isspace(termchar))) {
|
||||
fprintf(stderr, "Improper value, \"%s\" on line %d:\n",
|
||||
cp - 1, lineno);
|
||||
fprintf(stderr, "%s\n", line);
|
||||
fprintf(stderr, "Bytes must be specified as digits separated by white space.\n");
|
||||
return FALSE;
|
||||
}
|
||||
putc((char) dvalue, out);
|
||||
fileaddr++;
|
||||
cp += nscan;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Main program */
|
||||
|
||||
int main(argc, argv)
|
||||
int argc; char *argv[];
|
||||
{
|
||||
int i, b, bp, cdata = FALSE, f = 0;
|
||||
char *cp, *clabel, opt;
|
||||
FILE *in = stdin, *out = stdout;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
cp = argv[i];
|
||||
if (*cp == '-') {
|
||||
opt = *(++cp);
|
||||
if (islower(opt)) {
|
||||
opt = (char) toupper(opt);
|
||||
}
|
||||
switch (opt) {
|
||||
|
||||
case 'A': /* -Af -- Set address format */
|
||||
opt = cp[1];
|
||||
if (islower(opt)) {
|
||||
opt = (char) toupper(opt);
|
||||
}
|
||||
switch (opt) {
|
||||
case 'D':
|
||||
strcpy(addrformat, "%8d");
|
||||
strcpy(scanaddr, "%ld%c");
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
case 'X':
|
||||
strcpy(addrformat, "%6X");
|
||||
strcpy(scanaddr, "%lx%c");
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
strcpy(addrformat, "%8o");
|
||||
strcpy(scanaddr, "%lo%c");
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"Invalid address format '%c'. Must be D, H, or O.\n", cp[1]);
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
doublechar = TRUE;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
cdata = TRUE;
|
||||
clabel = cp + 1;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
loading = TRUE;
|
||||
break;
|
||||
|
||||
case 'N': /* -Nf -- Set numeric dump format */
|
||||
opt = cp[1];
|
||||
if (islower(opt)) {
|
||||
opt = (char) toupper(opt);
|
||||
}
|
||||
switch (opt) {
|
||||
case 'D':
|
||||
strcpy(dataformat1, "%3d");
|
||||
strcpy(scandata, "%d%n%c");
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
case 'X':
|
||||
strcpy(dataformat1, "%02X");
|
||||
strcpy(scandata, "%x%n%c");
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
strcpy(dataformat1, "%03o");
|
||||
strcpy(scandata, "%o%n%c");
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"Invalid numeric dump format '%c'. Must be D, H, or O.\n", cp[1]);
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
streaming = TRUE;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
case 'H':
|
||||
case 'U':
|
||||
fprintf(stderr, "XD -- Extended dump. Call with xd [input [output]]\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " Options:\n");
|
||||
fprintf(stderr, " -af Print addresses in f = Decimal, Hex, or Octal\n");
|
||||
fprintf(stderr, " -c Dump as ISO characters\n");
|
||||
fprintf(stderr, " -dlabel Dump as a C data declaration\n");
|
||||
fprintf(stderr, " -l Load file from hex dump\n");
|
||||
fprintf(stderr, " -nf Numeric dump in f = Decimal, Hex, or Octal\n");
|
||||
fprintf(stderr, " -s Stream load (don't check file addresses)\n");
|
||||
fprintf(stderr, " -u Print this message\n");
|
||||
fprintf(stderr, "\nBy John Walker, http://www.fourmilab.ch/\n");
|
||||
fprintf(stderr,"Version %s\n", Version);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
switch (f) {
|
||||
case 0:
|
||||
|
||||
/** Warning! On systems which distinguish text mode and
|
||||
binary I/O (MS-DOS, Macintosh, etc.) the modes in these
|
||||
open statements will have to be made conditional based
|
||||
upon whether an encode or decode is being done, which
|
||||
will have to be specified earlier. But it's worse: if
|
||||
input or output is from standard input or output, the
|
||||
mode will have to be changed on the fly, which is
|
||||
generally system and compiler dependent. 'Twasn't me
|
||||
who couldn't conform to Unix CR/LF convention, so
|
||||
don't ask me to write the code to work around
|
||||
Apple and Microsoft's incompatible standards.
|
||||
|
||||
This file contains code, conditional on _WIN32, which
|
||||
sets binary mode using the method prescribed by
|
||||
Microsoft Visual C 1.52 ("Monkey C"); this may
|
||||
require modification if you're using a different
|
||||
compiler or release of Monkey C. */
|
||||
|
||||
if ((in = fopen(cp, loading ? "r" : "rb")) == NULL) {
|
||||
fprintf(stderr, "Cannot open input file %s\n", cp);
|
||||
return 2;
|
||||
}
|
||||
f++;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if ((out = fopen(cp, loading ? "wb" : "w")) == NULL) {
|
||||
fprintf(stderr, "Cannot open output file %s\n", cp);
|
||||
return 2;
|
||||
}
|
||||
f++;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Too many file names specified.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* If input is from standard input and we aren't loading
|
||||
from a dump file, set the input file mode to binary. */
|
||||
|
||||
if ((in == stdin) && (!loading)) {
|
||||
_setmode(_fileno(in), _O_BINARY);
|
||||
}
|
||||
|
||||
/* If output is to standard output and we're loading a
|
||||
binary file from a dump, set the output file mode to
|
||||
binary. */
|
||||
|
||||
if ((out == stdout) && (loading)) {
|
||||
_setmode(_fileno(out), _O_BINARY);
|
||||
}
|
||||
#endif
|
||||
|
||||
bp = 0;
|
||||
fileaddr = 0;
|
||||
|
||||
if (loading) {
|
||||
char in_line[256];
|
||||
int lineno = 0;
|
||||
|
||||
while (fgets(in_line, (sizeof in_line) - 2, in)) {
|
||||
lineno++;
|
||||
if (!interpline(in_line, lineno, out)) {
|
||||
fclose(out);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cdata) {
|
||||
char cout[80];
|
||||
|
||||
fprintf(out, "unsigned char %s[] = {\n",
|
||||
clabel[0] == EOS ? "xd_data" : clabel);
|
||||
strcpy(cout, " ");
|
||||
|
||||
while ((b = getc(in)) != EOF) {
|
||||
if (strlen(cout) > 72) {
|
||||
fprintf(out, "%s\n", cout);
|
||||
strcpy(cout, " ");
|
||||
}
|
||||
sprintf(cout + strlen(cout), "%d,", b);
|
||||
}
|
||||
if (strlen(cout) > 4) {
|
||||
cout[strlen(cout) - 1] = EOS; /* Strip trailing comma */
|
||||
fprintf(out, "%s\n", cout);
|
||||
}
|
||||
fprintf(out, "};\n");
|
||||
} else {
|
||||
while ((b = getc(in)) != EOF) {
|
||||
if (bp >= bytesperline) {
|
||||
outline(out, lineecho, bp);
|
||||
bp = 0;
|
||||
fileaddr += bytesperline;
|
||||
}
|
||||
lineecho[bp++] = (char) b;
|
||||
}
|
||||
|
||||
if (bp > 0) {
|
||||
outline(out, lineecho, bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user