forked from Imagelibrary/rtems
tools: Remove unhex
This program has no license information and is unused in the RTEMS build. Users of HEX files should consider to use ELF instead. Remove it. Close #3378.
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
ACLOCAL_AMFLAGS = -I ../../aclocal
|
||||
|
||||
bin_PROGRAMS = packhex unhex
|
||||
bin_PROGRAMS = packhex
|
||||
|
||||
packhex_SOURCES = packhex.c
|
||||
unhex_SOURCES = unhex.c compat.c
|
||||
|
||||
bin_SCRIPTS = install-if-change
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <info@embedded-brains.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if !HAVE_STRNLEN
|
||||
size_t strnlen(const char *s, size_t maxlen)
|
||||
{
|
||||
const char *n = memchr(s, '\0', maxlen);
|
||||
|
||||
return n != NULL ? n - s : maxlen;
|
||||
}
|
||||
#endif
|
||||
@@ -1,733 +0,0 @@
|
||||
/*
|
||||
* unhex
|
||||
* convert a hex file to binary equivalent. If more than one file name
|
||||
* is given, then the output will be logically concatenated together.
|
||||
* stdin and stdout are defaults. Verbose will enable checksum output.
|
||||
*
|
||||
* Supported input formats are Intel hex, Motorola S records, and TI 'B'
|
||||
* records.
|
||||
*
|
||||
* Intel hex input format is
|
||||
* Byte
|
||||
* 1 Colon :
|
||||
* 2..3 Record length, eg: "20"
|
||||
* 4..7 load address nibbles
|
||||
* 8..9 record type: "00" (data) or "02" base addr
|
||||
* 10..x data bytes in ascii-hex
|
||||
* x+1..x+2 cksum (2's compl of (len+addr+data))
|
||||
* x+3 \n -- newline
|
||||
*/
|
||||
|
||||
char *USAGE = "\
|
||||
usage: unhex [-va] [ -o file ] [ file [file ... ] ]\n\
|
||||
-v -- verbose\n\
|
||||
-a base -- 1st byte of output corresponds to this address\n\
|
||||
-l -- linear, just writes data out\n\
|
||||
-o file -- output file; must not be input file\n\
|
||||
-F k_bits -- \"holes\" in input will be filled with 0xFF's\n\
|
||||
up to \"k_bits\" * 1024 bits\n\
|
||||
";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef VMS
|
||||
#ifndef HAVE_STRERROR
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
|
||||
#define strerror( _err ) \
|
||||
((_err) < sys_nerr) ? sys_errlist [(_err)] : "unknown error"
|
||||
|
||||
#else /* HAVE_STRERROR */
|
||||
char *strerror ();
|
||||
#endif
|
||||
#else /* VMS */
|
||||
char *strerror (int,...);
|
||||
#endif
|
||||
|
||||
|
||||
#define OK 0
|
||||
#define FAILURE (-1)
|
||||
#define Failed(x) ((x) == FAILURE)
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
typedef char bool;
|
||||
#define STREQ(a,b) (strcmp(a,b) == 0)
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned long u32;
|
||||
|
||||
/*
|
||||
* Pick out designated bytes
|
||||
*/
|
||||
|
||||
#define B0(x) (((u32)x) & 0xff)
|
||||
#define B1(x) B0(((u32)x) >> 8)
|
||||
#define B2(x) B0(((u32)x) >> 16)
|
||||
#define B3(x) B0(((u32)x) >> 24)
|
||||
|
||||
typedef struct buffer_rec {
|
||||
u32 dl_destaddr;
|
||||
u32 dl_jumpaddr;
|
||||
int dl_count;
|
||||
u8 dl_buf[512];
|
||||
} buffer_rec;
|
||||
|
||||
/*
|
||||
* vars controlled by command line options
|
||||
*/
|
||||
|
||||
bool verbose = FALSE; /* be verbose */
|
||||
bool linear = FALSE; /* just write out linear data */
|
||||
char *outfilename = "-"; /* default output is stdout */
|
||||
u32 base = 0L; /* base address */
|
||||
u32 FFfill = 0L; /* how far to fill w 0xFF's */
|
||||
|
||||
extern char *optarg; /* getopt(3) control vars */
|
||||
extern int optind;
|
||||
|
||||
char *progname; /* for error() */
|
||||
|
||||
void error(int errn, ...);
|
||||
#define ERR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
|
||||
#define ERR_FATAL (ERR_ERRNO / 2) /* error is fatal; no return */
|
||||
#define ERR_ABORT (ERR_ERRNO / 4) /* error is fatal; abort */
|
||||
#define ERR_MASK (ERR_ERRNO | ERR_FATAL | ERR_ABORT) /* all */
|
||||
|
||||
#ifdef HAVE_STRTOUL
|
||||
#define stol(p) strtoul(p, (char **) NULL, 0)
|
||||
#else
|
||||
#define stol(p) strtol(p, (char **) NULL, 0)
|
||||
#endif
|
||||
|
||||
int unhex(FILE *ifp, char *inm, FILE *ofp, char *onm);
|
||||
int convert_Intel_records(FILE *ifp, char *inm, FILE *ofp, char *onm);
|
||||
int convert_S_records(FILE *ifp, char *inm, FILE *ofp, char *onm);
|
||||
int convert_TI_records(FILE *ifp, char *inm, FILE *ofp, char *onm);
|
||||
void write_record(buffer_rec *tb, FILE *fp);
|
||||
int getnibble(char **p);
|
||||
int getbyte(char **p);
|
||||
long getNbytes(char **p, int n);
|
||||
void badformat(char *s, char *fname, char *msg);
|
||||
void fix_string_from_gets(char *s, size_t max);
|
||||
|
||||
#define get1bytes(p) (getbyte(p))
|
||||
#define get2bytes(p) getNbytes(p, 2)
|
||||
#define get3bytes(p) getNbytes(p, 3)
|
||||
#define get4bytes(p) getNbytes(p, 4)
|
||||
|
||||
char *BADADDR = "Invalid record address";
|
||||
char *BADLEN = "Invalid record length";
|
||||
char *BADBASE = "Bad base or starting address";
|
||||
char *BADFMT = "Unrecognized record type";
|
||||
char *BADDATA = "Invalid data byte";
|
||||
char *BADCSUM = "Invalid checksum";
|
||||
char *MISCSUM = "Checksum mismatch";
|
||||
char *BADTYPE = "Unrecognized record type";
|
||||
char *MISTYPE = "Incompatible record types";
|
||||
|
||||
int main(
|
||||
int argc,
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
int c;
|
||||
bool showusage = FALSE; /* usage error? */
|
||||
int rc = 0;
|
||||
FILE *outfp, *infp;
|
||||
long base_long = 0;
|
||||
|
||||
/*
|
||||
* figure out invocation leaf-name
|
||||
*/
|
||||
if ((progname = strrchr(argv[0], '/')) == (char *) NULL)
|
||||
progname = argv[0];
|
||||
else
|
||||
progname++;
|
||||
|
||||
argv[0] = progname; /* for getopt err reporting */
|
||||
|
||||
/*
|
||||
* Check options and arguments.
|
||||
*/
|
||||
progname = argv[0];
|
||||
while ((c = getopt(argc, argv, "F:a:o:vl")) != EOF) {
|
||||
switch (c) {
|
||||
case 'a': /* base address */
|
||||
base_long = stol(optarg);
|
||||
if (base_long < 0) {
|
||||
(void) fprintf(stderr, "%s", USAGE);
|
||||
(void) fprintf(stderr, "\n*** base is an illegal value\n" );
|
||||
exit(1);
|
||||
}
|
||||
base = (u32) base_long;
|
||||
|
||||
break;
|
||||
|
||||
case 'l': /* linear output */
|
||||
linear = TRUE;
|
||||
break;
|
||||
|
||||
case 'v': /* toggle verbose */
|
||||
verbose = ! verbose;
|
||||
break;
|
||||
|
||||
case 'o': /* output file */
|
||||
outfilename = optarg;
|
||||
break;
|
||||
|
||||
case 'F': /* 0xFF fill amount (bytes) */
|
||||
FFfill = stol(optarg) * 1024L / 8L;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
showusage = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (showusage) {
|
||||
(void) fprintf(stderr, "%s", USAGE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (linear && (base != 0)) {
|
||||
error(0, "-l and -a may not be specified in combination");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (STREQ(outfilename, "-")) {
|
||||
outfp = stdout;
|
||||
outfilename = "stdout";
|
||||
} else if ((outfp = fopen(outfilename, "w")) == (FILE *) NULL) {
|
||||
error(-1, "couldn't open '%s' for output", outfilename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now process the input files (or stdin, if none specified)
|
||||
*/
|
||||
if (argc == optind) /* just stdin */
|
||||
exit(unhex(stdin, "stdin", outfp, outfilename));
|
||||
else
|
||||
for (; optind < argc ; optind++) {
|
||||
optarg = argv[optind];
|
||||
if (STREQ(optarg, "-")) {
|
||||
rc += unhex(stdin, "stdin", outfp, outfilename);
|
||||
} else {
|
||||
if ((infp = fopen(optarg, "r")) == (FILE *) NULL) {
|
||||
error(-1, "couldn't open '%s' for input", optarg);
|
||||
exit(1);
|
||||
}
|
||||
rc += unhex(infp, optarg, outfp, outfilename);
|
||||
fclose(infp);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(outfp);
|
||||
return(rc);
|
||||
}
|
||||
|
||||
u16 filesum;
|
||||
|
||||
int
|
||||
unhex(FILE *ifp,
|
||||
char *inm,
|
||||
FILE *ofp,
|
||||
char *onm)
|
||||
{
|
||||
int c;
|
||||
|
||||
filesum = 0;
|
||||
|
||||
/*
|
||||
* Make sure holes will be filled with 0xFF's if requested. We
|
||||
* do this the easy way by just filling the file with FF's before
|
||||
* getting started. To do it more optimally would be quite a bit
|
||||
* more difficult since the user can skip around as much as he/she
|
||||
* likes in the input hex file addressing.
|
||||
*
|
||||
* We'll clean this up later (after this program has run) with
|
||||
* 'stripffs'
|
||||
*/
|
||||
|
||||
if (FFfill) {
|
||||
(void) fseek(ofp, 0, 0);
|
||||
for (c = FFfill; c > 0; c--)
|
||||
(void) fputc(0xFF, ofp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the first char from file and determine record types
|
||||
*/
|
||||
|
||||
if ((c = getc(ifp)) != EOF) {
|
||||
ungetc(c, ifp);
|
||||
switch(c) {
|
||||
case 'S':
|
||||
convert_S_records(ifp, inm, ofp, onm);
|
||||
break;
|
||||
|
||||
case ':':
|
||||
convert_Intel_records(ifp, inm, ofp, onm);
|
||||
break;
|
||||
|
||||
case '9':
|
||||
case 'B':
|
||||
convert_TI_records(ifp, inm, ofp, onm);
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
char tmp[2];
|
||||
tmp[0] = (char) (c & 0x7f);
|
||||
tmp[1] = 0;
|
||||
badformat(tmp, inm, BADFMT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "'%s' checksum is 0x%04x\n", inm, filesum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
convert_Intel_records(
|
||||
FILE *ifp,
|
||||
char *inm,
|
||||
FILE *ofp,
|
||||
char *onm)
|
||||
{
|
||||
char buff[512];
|
||||
char *p;
|
||||
u8 cksum;
|
||||
int incksum;
|
||||
int c;
|
||||
int rectype; /* record type */
|
||||
long len; /* data length of current line */
|
||||
u32 addr;
|
||||
u32 base_address = 0;
|
||||
bool endrecord = FALSE;
|
||||
buffer_rec tb;
|
||||
long getBytesStatus;
|
||||
|
||||
while ( !endrecord && (fgets(buff, sizeof(buff), ifp)) ) {
|
||||
p = &buff[0];
|
||||
|
||||
fix_string_from_gets(p, sizeof(buff));
|
||||
|
||||
tb.dl_count = 0;
|
||||
|
||||
if (*p != ':')
|
||||
badformat(p, inm, BADFMT);
|
||||
p++;
|
||||
|
||||
if ((len = getbyte(&p)) == -1) /* record len */
|
||||
badformat(buff, inm, BADLEN);
|
||||
|
||||
if ((getBytesStatus = get2bytes(&p)) == -1L) /* record addr */
|
||||
badformat(buff, inm, BADADDR);
|
||||
addr = (u32) getBytesStatus;
|
||||
|
||||
rectype = getbyte(&p);
|
||||
|
||||
cksum = len + B0(addr) + B1(addr) + rectype;
|
||||
|
||||
switch (rectype) {
|
||||
case 0x00: /* normal data record */
|
||||
tb.dl_destaddr = (u32) base_address + addr;
|
||||
while (len--)
|
||||
{
|
||||
if ((c = getbyte(&p)) == -1)
|
||||
badformat(buff, inm, BADDATA);
|
||||
cksum += c;
|
||||
filesum += c;
|
||||
tb.dl_buf[tb.dl_count++] = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x01: /* execution start address */
|
||||
base_address = addr;
|
||||
endrecord = TRUE;
|
||||
break;
|
||||
|
||||
case 0x02: /* new base */
|
||||
{
|
||||
long blong;
|
||||
if ((blong = get2bytes(&p)) == -1L)
|
||||
badformat(buff, inm, BADBASE);
|
||||
base_address = (u32) blong;
|
||||
cksum += B0(base_address) + B1(base_address);
|
||||
base_address <<= 4;
|
||||
break;
|
||||
}
|
||||
case 0x03: /* seg/off execution start address */
|
||||
{
|
||||
long seg, off;
|
||||
|
||||
seg = get2bytes(&p);
|
||||
off = get2bytes(&p);
|
||||
if ((seg == -1L) || (off == -1L))
|
||||
badformat(buff, inm, BADADDR);
|
||||
|
||||
cksum += B0(seg) + B1(seg) + B0(off) + B1(off);
|
||||
|
||||
tb.dl_jumpaddr = (seg << 4) + off;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
error(0, "unknown Intel-hex record type: 0x%02x", rectype);
|
||||
badformat(buff, inm, BADTYPE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify checksums are correct in file.
|
||||
*/
|
||||
|
||||
cksum = (-cksum) & 0xff;
|
||||
if ((incksum = getbyte(&p)) == -1)
|
||||
badformat(buff, inm, BADCSUM);
|
||||
if (((u8) incksum) != cksum)
|
||||
badformat(buff, inm, MISCSUM);
|
||||
|
||||
if (tb.dl_count)
|
||||
write_record(&tb, ofp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
convert_S_records(
|
||||
FILE *ifp,
|
||||
char *inm,
|
||||
FILE *ofp,
|
||||
char *onm)
|
||||
{
|
||||
char buff[512];
|
||||
char *p;
|
||||
u8 cksum;
|
||||
int incksum;
|
||||
int c;
|
||||
long len; /* data length of current line */
|
||||
int rectype; /* record type */
|
||||
long addr;
|
||||
bool endrecord = FALSE;
|
||||
buffer_rec tb;
|
||||
|
||||
while ( !endrecord && (fgets(buff, sizeof(buff), ifp)) ) {
|
||||
p = &buff[0];
|
||||
|
||||
fix_string_from_gets(p, sizeof(buff));
|
||||
|
||||
tb.dl_count = 0;
|
||||
|
||||
if (*p != 'S')
|
||||
badformat(p, inm, BADFMT);
|
||||
p++;
|
||||
|
||||
if ((rectype = getnibble(&p)) == -1) /* record type */
|
||||
badformat(buff, inm, BADTYPE);
|
||||
|
||||
if ((len = getbyte(&p)) == -1) /* record len */
|
||||
badformat(buff, inm, BADLEN);
|
||||
cksum = len;
|
||||
|
||||
switch (rectype) {
|
||||
case 0x00: /* comment field, ignored */
|
||||
goto write_it;
|
||||
|
||||
case 0x01: /* data record, 16 bit addr */
|
||||
if ((addr = get2bytes(&p)) == -1L)
|
||||
badformat(buff, inm, BADADDR);
|
||||
len -= 3;
|
||||
goto doit;
|
||||
|
||||
case 0x02: /* ... 24 bit addr */
|
||||
if ((addr = get3bytes(&p)) == -1L)
|
||||
badformat(buff, inm, BADADDR);
|
||||
len -= 4;
|
||||
goto doit;
|
||||
|
||||
case 0x03: /* ... 32 bit addr */
|
||||
if ((addr = get4bytes(&p)) == -1L)
|
||||
badformat(buff, inm, BADADDR);
|
||||
len -= 5;
|
||||
doit:
|
||||
cksum += B0(addr) + B1(addr) + B2(addr) + B3(addr);
|
||||
|
||||
tb.dl_destaddr = (u32) addr;
|
||||
while (len--) {
|
||||
if ((c = getbyte(&p)) == -1)
|
||||
badformat(buff, inm, BADDATA);
|
||||
cksum += c;
|
||||
filesum += c;
|
||||
tb.dl_buf[tb.dl_count++] = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x07: /* 32 bit end record */
|
||||
if ((addr = get4bytes(&p)) == -1L)
|
||||
badformat(buff, inm, BADADDR);
|
||||
goto end_rec;
|
||||
|
||||
case 0x08: /* 24 bit end record */
|
||||
if ((addr = get3bytes(&p)) == -1L)
|
||||
badformat(buff, inm, BADADDR);
|
||||
goto end_rec;
|
||||
|
||||
case 0x09: /* 16 bit end record */
|
||||
if ((addr = get2bytes(&p)) == -1L)
|
||||
badformat(buff, inm, BADADDR);
|
||||
|
||||
end_rec:
|
||||
cksum += B0(addr) + B1(addr) + B2(addr) + B3(addr);
|
||||
tb.dl_jumpaddr = addr;
|
||||
break;
|
||||
|
||||
default:
|
||||
error(0, "unknown Motorola-S record type: 0x%02x", rectype);
|
||||
badformat(buff, inm, BADTYPE);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify checksums are correct in file.
|
||||
*/
|
||||
|
||||
cksum = (~cksum) & 0xff;
|
||||
if ((incksum = getbyte(&p)) == -1)
|
||||
badformat(buff, inm, BADCSUM);
|
||||
if (((u8) incksum) != cksum)
|
||||
badformat(buff, inm, MISCSUM);
|
||||
|
||||
write_it:
|
||||
if (tb.dl_count)
|
||||
write_record(&tb, ofp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
convert_TI_records(
|
||||
FILE *ifp,
|
||||
char *inm,
|
||||
FILE *ofp,
|
||||
char *onm)
|
||||
{
|
||||
char buff[512];
|
||||
char *p;
|
||||
int c;
|
||||
bool endrecord = FALSE;
|
||||
bool eol;
|
||||
buffer_rec tb;
|
||||
|
||||
while ( ! endrecord && (fgets(buff, sizeof(buff), ifp))) {
|
||||
p = &buff[0];
|
||||
fix_string_from_gets(p, sizeof(buff));
|
||||
|
||||
tb.dl_count = 0;
|
||||
|
||||
eol = FALSE;
|
||||
while ( ! eol && ! endrecord) {
|
||||
switch (*p++) {
|
||||
case '9':
|
||||
if (tb.dl_count)
|
||||
write_record(&tb, ofp);
|
||||
tb.dl_destaddr = (u32) get2bytes(&p);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
c = getbyte(&p);
|
||||
assert( c != -1 );
|
||||
filesum += c;
|
||||
tb.dl_buf[tb.dl_count++] = c;
|
||||
|
||||
c = getbyte(&p);
|
||||
assert( c != -1 );
|
||||
filesum += c;
|
||||
tb.dl_buf[tb.dl_count++] = c;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
eol = TRUE;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
endrecord = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
badformat(p, inm, BADFMT);
|
||||
}
|
||||
}
|
||||
if (tb.dl_count)
|
||||
write_record(&tb, ofp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
write_record(buffer_rec *tb,
|
||||
FILE *fp)
|
||||
{
|
||||
if ( ! linear) {
|
||||
if (tb->dl_destaddr < base)
|
||||
error(ERR_FATAL, "record at address 0x%x precedes base of 0x%x",
|
||||
tb->dl_destaddr, base);
|
||||
(void) fseek(fp, tb->dl_destaddr - base, 0);
|
||||
}
|
||||
|
||||
(void) fwrite(tb->dl_buf, tb->dl_count, 1, fp);
|
||||
tb->dl_destaddr += tb->dl_count;
|
||||
tb->dl_count = 0;
|
||||
}
|
||||
|
||||
int
|
||||
getnibble(char **p)
|
||||
{
|
||||
register int val;
|
||||
|
||||
**p = toupper(**p);
|
||||
switch (**p) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
val = **p - '0';
|
||||
break;
|
||||
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
val = 10 + (**p - 'A');
|
||||
break;
|
||||
|
||||
default:
|
||||
return(-1);
|
||||
}
|
||||
*p += 1;
|
||||
|
||||
return(val & 0x0f);
|
||||
}
|
||||
|
||||
int
|
||||
getbyte(char **p)
|
||||
{
|
||||
int n0, n1;
|
||||
|
||||
if ((n0 = getnibble(p)) == -1)
|
||||
return(-1);
|
||||
if ((n1 = getnibble(p)) == -1)
|
||||
return(-1);
|
||||
|
||||
return(((n0 << 4) + n1) & 0xff);
|
||||
}
|
||||
|
||||
long
|
||||
getNbytes(char **p,
|
||||
int n)
|
||||
{
|
||||
long t;
|
||||
u32 val = 0;
|
||||
|
||||
while (n--) {
|
||||
if ((t = getbyte(p)) == -1)
|
||||
return(-1L);
|
||||
val <<= 8;
|
||||
val += (u32) t;
|
||||
}
|
||||
|
||||
return(val);
|
||||
}
|
||||
|
||||
void
|
||||
badformat(char *s,
|
||||
char *fname,
|
||||
char *msg)
|
||||
{
|
||||
if ( *s != '\0' ) {
|
||||
if (s[strlen(s)-1] == '\n') /* get rid of newline */
|
||||
s[strlen(s)-1] = '\0';
|
||||
}
|
||||
error(0, "line '%s'::\n\tfrom file '%s'; %s", s, fname, msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* error(errn, arglist)
|
||||
* report an error to stderr using printf(3) conventions.
|
||||
* Any output is preceded by '<progname>: '
|
||||
*
|
||||
* Uses ERR_EXIT bit to request exit(errn)
|
||||
* ERR_ABORT to request abort()
|
||||
* ERR_ERRNO to indicate use of errno instead of argument.
|
||||
*
|
||||
* If resulting 'errn' is non-zero, it is assumed to be an 'errno' and its
|
||||
* associated error message is appended to the output.
|
||||
*/
|
||||
|
||||
/*VARARGS*/
|
||||
|
||||
void
|
||||
error(int error_flag, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
register char *format;
|
||||
int local_errno;
|
||||
|
||||
(void) fflush(stdout); /* in case stdout/stderr same */
|
||||
|
||||
local_errno = error_flag & ~ERR_MASK;
|
||||
if (error_flag & ERR_ERRNO) /* use errno? */
|
||||
local_errno = errno;
|
||||
|
||||
va_start(arglist, error_flag);
|
||||
format = va_arg(arglist, char *);
|
||||
(void) fprintf(stderr, "%s: ", progname);
|
||||
(void) vfprintf(stderr, format, arglist);
|
||||
va_end(arglist);
|
||||
|
||||
if (local_errno)
|
||||
(void) fprintf(stderr, " (%s)\n", strerror(local_errno));
|
||||
else
|
||||
(void) fprintf(stderr, "\n");
|
||||
|
||||
(void) fflush(stderr);
|
||||
|
||||
if (error_flag & (ERR_FATAL | ERR_ABORT)) {
|
||||
if (error_flag & ERR_FATAL) {
|
||||
error(0, "fatal error, exiting");
|
||||
exit(local_errno ? local_errno : 1);
|
||||
} else {
|
||||
error(0, "fatal error, aborting");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fix_string_from_gets(char *s, size_t max)
|
||||
{
|
||||
size_t len;
|
||||
assert( s );
|
||||
|
||||
if ( *s == '\0' )
|
||||
return;
|
||||
|
||||
len = strnlen( s, max );
|
||||
|
||||
if ( s[len - 1] == '\n') /* get rid of newline */
|
||||
s[len - 1] = '\0';
|
||||
|
||||
if ( s[len - 1] == '\r') /* get rid of any CR */
|
||||
s[len - 1] = '\0';
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user