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/avrdude@654 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
17d4c26550
commit
92cbfc744a
13
ChangeLog
13
ChangeLog
|
@ -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>
|
2006-09-08 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||||
|
|
||||||
* fileio.c: CPP statements start in column #1.
|
* fileio.c: CPP statements start in column #1.
|
||||||
|
|
18
avrdude.1
18
avrdude.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
|
auto detect; valid for input only, and only if the input is not
|
||||||
provided at
|
provided at
|
||||||
.Em stdin .
|
.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
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The default is to use auto detection for input files, and raw binary
|
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
|
auto detect; valid for input only, and only if the input is not provided
|
||||||
at stdin.
|
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
|
@end table
|
||||||
|
|
||||||
The default is to use auto detection for input files, and raw binary
|
The default is to use auto detection for input files, and raw binary
|
||||||
|
|
122
fileio.c
122
fileio.c
|
@ -77,6 +77,10 @@ int fileio_ihex(struct fioparms * fio,
|
||||||
int fileio_srec(struct fioparms * fio,
|
int fileio_srec(struct fioparms * fio,
|
||||||
char * filename, FILE * f, unsigned char * buf, int size);
|
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);
|
int fmt_autodetect(char * fname);
|
||||||
|
|
||||||
|
|
||||||
|
@ -658,6 +662,45 @@ int srec2b(char * infile, FILE * inf,
|
||||||
return maxaddr;
|
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,
|
int fileio_rbin(struct fioparms * fio,
|
||||||
char * filename, FILE * f, unsigned char * buf, int size)
|
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)
|
int fileio_setparms(int op, struct fioparms * fp)
|
||||||
{
|
{
|
||||||
fp->op = op;
|
fp->op = op;
|
||||||
|
@ -1005,6 +1120,13 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||||
rc = fileio_imm(&fio, fname, f, buf, size);
|
rc = fileio_imm(&fio, fname, f, buf, size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FMT_HEX:
|
||||||
|
case FMT_DEC:
|
||||||
|
case FMT_OCT:
|
||||||
|
case FMT_BIN:
|
||||||
|
rc = fileio_num(&fio, fname, f, buf, size, format);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: invalid %s file format: %d\n",
|
fprintf(stderr, "%s: invalid %s file format: %d\n",
|
||||||
progname, fio.iodesc, format);
|
progname, fio.iodesc, format);
|
||||||
|
|
6
fileio.h
6
fileio.h
|
@ -27,7 +27,11 @@ typedef enum {
|
||||||
FMT_SREC,
|
FMT_SREC,
|
||||||
FMT_IHEX,
|
FMT_IHEX,
|
||||||
FMT_RBIN,
|
FMT_RBIN,
|
||||||
FMT_IMM
|
FMT_IMM,
|
||||||
|
FMT_HEX,
|
||||||
|
FMT_DEC,
|
||||||
|
FMT_OCT,
|
||||||
|
FMT_BIN
|
||||||
} FILEFMT;
|
} FILEFMT;
|
||||||
|
|
||||||
struct fioparms {
|
struct fioparms {
|
||||||
|
|
4
main.c
4
main.c
|
@ -414,6 +414,10 @@ UPDATE * parse_op(char * s)
|
||||||
case 'i': upd->format = FMT_IHEX; break;
|
case 'i': upd->format = FMT_IHEX; break;
|
||||||
case 'r': upd->format = FMT_RBIN; break;
|
case 'r': upd->format = FMT_RBIN; break;
|
||||||
case 'm': upd->format = FMT_IMM; 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:
|
default:
|
||||||
fprintf(stderr, "%s: invalid file format '%s' in update specifier\n",
|
fprintf(stderr, "%s: invalid file format '%s' in update specifier\n",
|
||||||
progname, p);
|
progname, p);
|
||||||
|
|
Loading…
Reference in New Issue