Files
ihex/bin2ihex.c
Kimmo Kulovesi 0a283582ce Clean up code
2015-02-27 00:46:21 +02:00

145 lines
4.2 KiB
C

/*
* bin2ihex.c: Read binary data, output in Intel HEX format.
*
* By default reads from stdin and writes to stdout. Input and
* output files can be specified with arguments `-i` and `-o`,
* respectively. Initial address offset can be set with option
* `-a` (also, `-a 0` forces output of the initial offset even
* though it is the default zero).
*
* Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com
* Provided with absolutely no warranty, use at your own risk only.
* Distribute freely, mark modified copies as such.
*/
#include "kk_ihex_write.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#ifdef IHEX_EXTERNAL_WRITE_BUFFER
char *ihex_write_buffer = NULL;
#endif
//#define IHEX_WRITE_INITIAL_EXTENDED_ADDRESS_RECORD
static FILE *outfile;
int
main (int argc, char *argv[]) {
struct ihex_state ihex;
FILE *infile = stdin;
ihex_address_t initial_address = 0;
bool write_initial_address = 0;
bool debug_enabled = 0;
ihex_count_t count;
uint8_t buf[1024];
outfile = stdout;
// spaghetti parser of args: -o outfile -i infile -a initial_address
while (--argc) {
char *arg = *(++argv);
if (arg[0] == '-' && arg[1] && arg[2] == '\0') {
switch (arg[1]) {
case 'a':
if (--argc == 0) {
goto invalid_argument;
}
++argv;
errno = 0;
initial_address = (ihex_address_t) strtoul(*argv, &arg, 0);
if (errno || arg == *argv) {
errno = errno ? errno : EINVAL;
goto argument_error;
}
write_initial_address = 1;
break;
case 'i':
if (--argc == 0) {
goto invalid_argument;
}
++argv;
if (!(infile = fopen(*argv, "rb"))) {
goto argument_error;
}
break;
case 'o':
if (--argc == 0) {
goto invalid_argument;
}
++argv;
if (!(outfile = fopen(*argv, "w"))) {
goto argument_error;
}
break;
case 'v':
debug_enabled = 1;
break;
case 'h':
case '?':
arg = NULL;
goto usage;
default:
goto invalid_argument;
}
continue;
}
invalid_argument:
(void) fprintf(stderr, "Invalid argument: %s\n", arg);
usage:
(void) fprintf(stderr, "kk_ihex " KK_IHEX_VERSION
" - Copyright (c) 2013-2015 Kimmo Kulovesi\n");
(void) fprintf(stderr, "Usage: bin2ihex [-a <address_offset>]"
" [-o <out.hex>] [-i <in.bin>] [-v]\n");
return arg ? EXIT_FAILURE : EXIT_SUCCESS;
argument_error:
perror(*argv);
return EXIT_FAILURE;
}
{
#ifdef IHEX_EXTERNAL_WRITE_BUFFER
// How to provide an external write buffer with limited duration:
char buffer[IHEX_WRITE_BUFFER_LENGTH];
ihex_write_buffer = buffer;
#endif
ihex_init(&ihex);
ihex_write_at_address(&ihex, initial_address);
if (write_initial_address) {
if (debug_enabled) {
(void) fprintf(stderr, "Address offset: 0x%lx\n",
(unsigned long) ihex.address);
}
ihex.flags |= IHEX_FLAG_ADDRESS_OVERFLOW;
}
while ((count = (ihex_count_t) fread(buf, 1, sizeof(buf), infile))) {
ihex_write_bytes(&ihex, buf, count);
}
ihex_end_write(&ihex);
}
if (outfile != stdout) {
(void) fclose(outfile);
}
if (infile != stdout) {
(void) fclose(infile);
}
if (debug_enabled) {
(void) fprintf(stderr, "%lu bytes read\n",
(unsigned long) ihex.address - initial_address);
}
return EXIT_SUCCESS;
}
#pragma clang diagnostic ignored "-Wunused-parameter"
void
ihex_flush_buffer(struct ihex_state *ihex, char *buffer, char *eptr) {
*eptr = '\0';
(void) fputs(buffer, outfile);
}