Implement numerical output formats for decimal, hexadecimal, octal,
and binary numbers. Closes bug #16129: more output formats for fuse bits (avrdude enhancement request) * fileio.c: Implement fileio_num() and the itoa_simple() helper function. * fileio.h: Add new file formats to FILEFMT. * main.c: Parse the new file formats. * avrdude.1: Document all this. * doc/avrdude.texi: (Ditto.) git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@654 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
ac7bf0624c
commit
16c7a11538
|
@ -1,3 +1,16 @@
|
|||
2006-09-08 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Implement numerical output formats for decimal, hexadecimal,
|
||||
octal, and binary numbers.
|
||||
Closes bug #16129: more output formats for fuse bits
|
||||
(avrdude enhancement request)
|
||||
* fileio.c: Implement fileio_num() and the itoa_simple()
|
||||
helper function.
|
||||
* fileio.h: Add new file formats to FILEFMT.
|
||||
* main.c: Parse the new file formats.
|
||||
* avrdude.1: Document all this.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2006-09-08 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c: CPP statements start in column #1.
|
||||
|
|
|
@ -505,6 +505,24 @@ having to create a single-byte file or enter terminal mode.
|
|||
auto detect; valid for input only, and only if the input is not
|
||||
provided at
|
||||
.Em stdin .
|
||||
.It Ar d
|
||||
decimal; this and the following formats are only valid on output.
|
||||
They generate one line of output for the respective memory section,
|
||||
forming a comma-separated list of the values.
|
||||
This can be particularly useful for subsequent processing, like for
|
||||
fuse bit settings.
|
||||
.It Ar h
|
||||
hexadecimal; each value will get the string
|
||||
.Em 0x
|
||||
prepended.
|
||||
.It Ar o
|
||||
octal; each value will get a
|
||||
.Em 0
|
||||
prepended unless it is less than 8 in which case it gets no prefix.
|
||||
.It Ar b
|
||||
binary; each value will get the string
|
||||
.Em 0b
|
||||
prepended.
|
||||
.El
|
||||
.Pp
|
||||
The default is to use auto detection for input files, and raw binary
|
||||
|
|
|
@ -749,6 +749,23 @@ treated as decimal.
|
|||
auto detect; valid for input only, and only if the input is not provided
|
||||
at stdin.
|
||||
|
||||
@itemx d
|
||||
decimal; this and the following formats are only valid on output.
|
||||
They generate one line of output for the respective memory section,
|
||||
forming a comma-separated list of the values.
|
||||
This can be particularly useful for subsequent processing, like for
|
||||
fuse bit settings.
|
||||
|
||||
@itemx h
|
||||
hexadecimal; each value will get the string @emph{0x} prepended.
|
||||
|
||||
@itemx o
|
||||
octal; each value will get a @emph{0}
|
||||
prepended unless it is less than 8 in which case it gets no prefix.
|
||||
|
||||
@itemx b
|
||||
binary; each value will get the string @emph{0b} prepended.
|
||||
|
||||
@end table
|
||||
|
||||
The default is to use auto detection for input files, and raw binary
|
||||
|
|
122
avrdude/fileio.c
122
avrdude/fileio.c
|
@ -77,6 +77,10 @@ int fileio_ihex(struct fioparms * fio,
|
|||
int fileio_srec(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size);
|
||||
|
||||
int fileio_num(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size,
|
||||
FILEFMT fmt);
|
||||
|
||||
int fmt_autodetect(char * fname);
|
||||
|
||||
|
||||
|
@ -658,6 +662,45 @@ int srec2b(char * infile, FILE * inf,
|
|||
return maxaddr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple itoa() implementation. Caller needs to allocate enough
|
||||
* space in buf. Only positive integers are handled.
|
||||
*/
|
||||
static char *itoa_simple(int n, char *buf, int base)
|
||||
{
|
||||
div_t q;
|
||||
char c, *cp, *cp2;
|
||||
|
||||
cp = buf;
|
||||
/*
|
||||
* Divide by base until the number disappeared, but ensure at least
|
||||
* one digit will be emitted.
|
||||
*/
|
||||
do {
|
||||
q = div(n, base);
|
||||
n = q.quot;
|
||||
if (q.rem >= 10)
|
||||
c = q.rem - 10 + 'a';
|
||||
else
|
||||
c = q.rem + '0';
|
||||
*cp++ = c;
|
||||
} while (q.quot != 0);
|
||||
|
||||
/* Terminate the string. */
|
||||
*cp-- = '\0';
|
||||
|
||||
/* Now revert the result string. */
|
||||
cp2 = buf;
|
||||
while (cp > cp2) {
|
||||
c = *cp;
|
||||
*cp-- = *cp2;
|
||||
*cp2++ = c;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int fileio_rbin(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size)
|
||||
|
@ -793,6 +836,78 @@ int fileio_srec(struct fioparms * fio,
|
|||
}
|
||||
|
||||
|
||||
int fileio_num(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size,
|
||||
FILEFMT fmt)
|
||||
{
|
||||
const char *prefix;
|
||||
char cbuf[20];
|
||||
int base, i, num;
|
||||
|
||||
switch (fmt) {
|
||||
case FMT_HEX:
|
||||
prefix = "0x";
|
||||
base = 16;
|
||||
break;
|
||||
|
||||
default:
|
||||
case FMT_DEC:
|
||||
prefix = "";
|
||||
base = 10;
|
||||
break;
|
||||
|
||||
case FMT_OCT:
|
||||
prefix = "0";
|
||||
base = 8;
|
||||
break;
|
||||
|
||||
case FMT_BIN:
|
||||
prefix = "0b";
|
||||
base = 2;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
switch (fio->op) {
|
||||
case FIO_WRITE:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: fileio: invalid operation=%d\n",
|
||||
progname, fio->op);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (i > 0) {
|
||||
if (putc(',', f) == EOF)
|
||||
goto writeerr;
|
||||
}
|
||||
num = (unsigned int)buf[i];
|
||||
/*
|
||||
* For a base of 8 and a value < 8 to convert, don't write the
|
||||
* prefix. The conversion will be indistinguishable from a
|
||||
* decimal one then.
|
||||
*/
|
||||
if (prefix[0] != '\0' && !(base == 8 && num < 8)) {
|
||||
if (fputs(prefix, f) == EOF)
|
||||
goto writeerr;
|
||||
}
|
||||
itoa_simple(num, cbuf, base);
|
||||
if (fputs(cbuf, f) == EOF)
|
||||
goto writeerr;
|
||||
}
|
||||
if (putc('\n', f) == EOF)
|
||||
goto writeerr;
|
||||
|
||||
return 0;
|
||||
|
||||
writeerr:
|
||||
fprintf(stderr, "%s: error writing to %s: %s\n",
|
||||
progname, filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int fileio_setparms(int op, struct fioparms * fp)
|
||||
{
|
||||
fp->op = op;
|
||||
|
@ -1005,6 +1120,13 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||
rc = fileio_imm(&fio, fname, f, buf, size);
|
||||
break;
|
||||
|
||||
case FMT_HEX:
|
||||
case FMT_DEC:
|
||||
case FMT_OCT:
|
||||
case FMT_BIN:
|
||||
rc = fileio_num(&fio, fname, f, buf, size, format);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: invalid %s file format: %d\n",
|
||||
progname, fio.iodesc, format);
|
||||
|
|
|
@ -27,7 +27,11 @@ typedef enum {
|
|||
FMT_SREC,
|
||||
FMT_IHEX,
|
||||
FMT_RBIN,
|
||||
FMT_IMM
|
||||
FMT_IMM,
|
||||
FMT_HEX,
|
||||
FMT_DEC,
|
||||
FMT_OCT,
|
||||
FMT_BIN
|
||||
} FILEFMT;
|
||||
|
||||
struct fioparms {
|
||||
|
|
|
@ -414,6 +414,10 @@ UPDATE * parse_op(char * s)
|
|||
case 'i': upd->format = FMT_IHEX; break;
|
||||
case 'r': upd->format = FMT_RBIN; break;
|
||||
case 'm': upd->format = FMT_IMM; break;
|
||||
case 'b': upd->format = FMT_BIN; break;
|
||||
case 'd': upd->format = FMT_DEC; break;
|
||||
case 'h': upd->format = FMT_HEX; break;
|
||||
case 'o': upd->format = FMT_OCT; break;
|
||||
default:
|
||||
fprintf(stderr, "%s: invalid file format '%s' in update specifier\n",
|
||||
progname, p);
|
||||
|
|
Loading…
Reference in New Issue