From 282d3e8aa699e9a09d04e153ee87fd7328c0bf2a Mon Sep 17 00:00:00 2001
From: Michel Pollet <buserror@gmail.com>
Date: Wed, 18 Apr 2012 10:46:35 +0100
Subject: [PATCH] ihex: Made read_ihexq_chunks allocare the table

The table is allocared and returned as the result

Signed-off-by: Michel Pollet <buserror@gmail.com>
---
 simavr/sim/sim_hex.c | 33 +++++++++++++++++++--------------
 simavr/sim/sim_hex.h | 28 +++++++++++++++++++++-------
 2 files changed, 40 insertions(+), 21 deletions(-)

diff --git a/simavr/sim/sim_hex.c b/simavr/sim/sim_hex.c
index 05c6e9c..7ded34a 100644
--- a/simavr/sim/sim_hex.c
+++ b/simavr/sim/sim_hex.c
@@ -139,19 +139,21 @@ uint8_t * read_ihex_file(const char * fname, uint32_t * dsize, uint32_t * start)
 }
 
 
-int read_ihex_chunks(const char * fname, struct ihex_chunk_t * chunks, int max_chunks)
+int
+read_ihex_chunks(
+		const char * fname,
+		ihex_chunk_p * chunks )
 {
-	if (!fname || !chunks || !max_chunks)
+	if (!fname || !chunks)
 		return -1;
-	memset((void*)chunks, 0, sizeof(chunks[0]) * max_chunks);
 	FILE * f = fopen(fname, "r");
 	if (!f) {
 		perror(fname);
 		return -1;
 	}
 	uint32_t segment = 0;	// segment address
-	int chunk = 0;
-	chunks[0].baseaddr = ~0;
+	int chunk = 0, max_chunks = 0;
+	*chunks = NULL;
 
 	while (!feof(f)) {
 		char line[128];
@@ -196,19 +198,22 @@ int read_ihex_chunks(const char * fname, struct ihex_chunk_t * chunks, int max_c
 				fprintf(stderr, "%s: %s, unsupported check type %02x\n", __FUNCTION__, fname, bline[3]);
 				continue;
 		}
-		if (addr != chunks[chunk].baseaddr + chunks[chunk].size) {
-			if (chunks[chunk].size)
+		if (chunk < max_chunks && addr != ((*chunks)[chunk].baseaddr + (*chunks)[chunk].size)) {
+			if ((*chunks)[chunk].size)
 				chunk++;
-			chunks[chunk].baseaddr = addr;
 		}
-		chunks[chunk].data = realloc(chunks[chunk].data, chunks[chunk].size + bline[0]);
-		memcpy(chunks[chunk].data + chunks[chunk].size, bline + 4, bline[0]);
-		chunks[chunk].size += bline[0];
+		if (chunk >= max_chunks) {
+			max_chunks++;
+			*chunks = realloc(*chunks, max_chunks * sizeof(ihex_chunk_t));
+			memset(*chunks + chunk, 0, (max_chunks - chunk) * sizeof(ihex_chunk_t));
+			(*chunks)[chunk].baseaddr = addr;
+		}
+		(*chunks)[chunk].data = realloc((*chunks)[chunk].data, (*chunks)[chunk].size + bline[0]);
+		memcpy((*chunks)[chunk].data + (*chunks)[chunk].size, bline + 4, bline[0]);
+		(*chunks)[chunk].size += bline[0];
 	}
-	if (chunks[chunk].size)
-		chunk++;
 	fclose(f);
-	return chunk;
+	return max_chunks;
 }
 
 
diff --git a/simavr/sim/sim_hex.h b/simavr/sim/sim_hex.h
index f187c38..89ba939 100644
--- a/simavr/sim/sim_hex.h
+++ b/simavr/sim/sim_hex.h
@@ -30,28 +30,42 @@ extern "C" {
 #endif
 
 // parses a hex text string 'src' of at max 'maxlen' characters, decodes it into 'buffer'
-int read_hex_string(const char * src, uint8_t * buffer, int maxlen);
+int
+read_hex_string(
+		const char * src,
+		uint8_t * buffer,
+		int maxlen);
 
 // a .hex file chunk (base address + size)
-struct ihex_chunk_t {
+typedef struct ihex_chunk_t {
 	uint32_t baseaddr;	// offset it started at in the .hex file
 	uint8_t * data;		// read data
 	uint32_t size;		// read data size
-};
+} ihex_chunk_t, *ihex_chunk_p;
 
 /*
  * Read a .hex file, detects the various different chunks in it from their starting
- * addresses and fills up the chunks passed as arguments up to max_chunks.
+ * addresses and allocate an array of ihex_chunk_t returned in 'chunks'.
  * Returns the number of chunks found, or -1 if an error occurs.
  */
-int read_ihex_chunks(const char * fname, struct ihex_chunk_t * chunks, int max_chunks);
+int
+read_ihex_chunks(
+		const char * fname,
+		ihex_chunk_p * chunks );
 
 // reads IHEX file 'fname', puts it's decoded size in *'dsize' and returns
 // a newly allocated buffer with the binary data (or NULL, if error)
-uint8_t * read_ihex_file(const char * fname, uint32_t * dsize, uint32_t * start);
+uint8_t *
+read_ihex_file(
+		const char * fname,
+		uint32_t * dsize,
+		uint32_t * start);
 
 // hex dump from pointer 'b' for 'l' bytes with string prefix 'w'
-void hdump(const char *w, uint8_t *b, size_t l);
+void
+hdump(
+		const char *w,
+		uint8_t *b, size_t l);
 
 #ifdef __cplusplus
 };
-- 
2.39.5