Merge pull request #1392 from stefanrueger/save

Rewrite fileio functions to cater for a list of memory segments
This commit is contained in:
Stefan Rueger
2023-06-11 11:52:49 +01:00
committed by GitHub
3 changed files with 470 additions and 408 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -989,6 +989,7 @@ typedef enum {
FMT_IHEX,
FMT_RBIN,
FMT_IMM,
FMT_EEGG,
FMT_HEX,
FMT_DEC,
FMT_OCT,
@@ -1006,6 +1007,10 @@ struct fioparms {
unsigned int fileoffset;
};
typedef struct {
int addr, len;
} Segment_t;
enum {
FIO_READ,
FIO_WRITE,
@@ -1029,7 +1034,12 @@ int fileio_fmt_autodetect_fp(FILE *f);
int fileio_fmt_autodetect(const char *fname);
int fileio(int oprwv, const char *filename, FILEFMT format,
const AVRPART *p, const char *memtype, int size);
const AVRPART *p, const char *memtype, int size);
int segmemt_normalise(const AVRMEM *mem, Segment_t *segp);
int fileio_segments(int oprwv, const char *filename, FILEFMT format,
const AVRPART *p, const AVRMEM *mem, int n, const Segment_t *seglist);
#ifdef __cplusplus
}
@@ -1227,6 +1237,7 @@ int str_caseeq(const char *str1, const char *str2);
int str_match(const char *pattern, const char *string);
int str_casematch(const char *pattern, const char *string);
char *str_sprintf(const char *fmt, ...);
char *str_fgets(FILE *fp, const char **errpp);
char *str_lc(char *s);
char *str_uc(char *s);
char *str_lcfirst(char *s);

View File

@@ -24,6 +24,7 @@
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include "libavrdude.h"
// Return 1 if str starts with starts, 0 otherwise
@@ -236,6 +237,47 @@ char *str_sprintf(const char *fmt, ...) {
}
// Reads a potentially long line and returns it in a malloc'd buffer
char *str_fgets(FILE *fp, const char **errpp) {
int bs = 1023; // Must be 2^n - 1
char *ret = (char *) cfg_malloc(__func__, bs);
ret[bs-2] = 0;
if(!fgets(ret, bs, fp)) {
free(ret);
if(errpp)
*errpp = ferror(fp) && !feof(fp)? "I/O error": NULL;
return NULL;
}
while(ret[bs-2] != 0 && ret[bs-2] != '\n' && ret[bs-2] != '\r') {
if(bs >= INT_MAX/2) {
free(ret);
if(errpp)
*errpp = "cannot cope with lines longer than INT_MAX/2 bytes";
return NULL;
}
int was = bs;
bs = 2*bs+1;
ret = cfg_realloc(__func__, ret, bs);
ret[was-1] = ret[bs-2] = 0;
if(!fgets(ret+was-1, bs-(was-1), fp)) { // EOF? Error?
if(ferror(fp)) {
free(ret);
if(errpp)
*errpp = "I/O error";
return NULL;
}
break;
}
}
if(errpp)
*errpp = NULL;
return ret;
}
// Changes string to be all lowercase and returns original pointer
char *str_lc(char *s) {
for(char *t = s; *t; t++)
@@ -268,6 +310,30 @@ char *str_utoa(unsigned n, char *buf, int base) {
unsigned q;
char *cp;
if(base == 'r') {
const char *units = "IVXLCDMFTYHSNabcdefghijkl";
const char *rep[10] = {"", "a", "aa", "aaa", "ab", "b", "ba", "baa", "baaa", "ac"};
if(n == 0) {
strcpy(buf, "0");
return buf;
}
int i = 0;
for(unsigned u = n; u; u /= 10)
i++;
for(*buf = 0; i > 0; i--) {
unsigned u = n;
for(int j=1; j<i; j++)
u /= 10;
char *q = buf+strlen(buf);
for(const char *p = rep[u%10], *d = units + (i-1)*2; *p; p++)
*q++ = d[*p-'a'];
*q = 0;
}
return buf;
}
if(base < 2 || base > 36) {
*buf = 0;
return buf;