mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-30 04:49:14 +03:00
Merge pull request #1392 from stefanrueger/save
Rewrite fileio functions to cater for a list of memory segments
This commit is contained in:
799
src/fileio.c
799
src/fileio.c
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user