bug #34302: Feature request : device configuration with parent classes
* config_gram.y: if memory section is overwritten old entry is removed (not in original patch) * config_gram.y: if programmer or part is defined twice, a warning is output and the first instance is removed General cleanup and free functions, so valgrind does not report any lost blocks at program end. * avrpart.[hc]: added avr_free_(opcode|mem|part) functions * pgm.[hc]: added pgm_free function * update.[hc]: added free_update functions * config.[hc]: added cleanup_config function, use yylex_destroy to reset the lexer after usage. (So it can be reused.) * main.c: add cleanup_main function which is called by atexit() (This frees all lists so that at program exit only really lost memory is reported by valgrind.) * usbasp.c: added libusb_free_device_list() and libusb_exit() calls to avoid lost memory * buspirate.c: moved memory allocation from initpgm to setup and added free in teardown * configure.ac: add definition of HAVE_YYLEX_DESTROY if $LEX is flex. * Makefile.am: added . in front of SUBDIRS to build avrdude before trying to use it for creating the part list for the docs. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1041 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
fbb740ffdf
commit
4976fcf88e
27
ChangeLog
27
ChangeLog
|
@ -1,3 +1,30 @@
|
|||
2012-01-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34302: Feature request : device configuration with parent classes
|
||||
* config_gram.y: if memory section is overwritten old entry is removed
|
||||
|
||||
(not in original patch)
|
||||
* config_gram.y: if programmer or part is defined twice, a warning is
|
||||
output and the first instance is removed
|
||||
|
||||
General cleanup and free functions, so valgrind does not report any lost
|
||||
blocks at program end.
|
||||
* avrpart.[hc]: added avr_free_(opcode|mem|part) functions
|
||||
* pgm.[hc]: added pgm_free function
|
||||
* update.[hc]: added free_update functions
|
||||
* config.[hc]: added cleanup_config function, use yylex_destroy to reset
|
||||
the lexer after usage. (So it can be reused.)
|
||||
* main.c: add cleanup_main function which is called by atexit() (This
|
||||
frees all lists so that at program exit only really lost memory is
|
||||
reported by valgrind.)
|
||||
* usbasp.c: added libusb_free_device_list() and libusb_exit() calls to
|
||||
avoid lost memory
|
||||
* buspirate.c: moved memory allocation from initpgm to setup and added
|
||||
free in teardown
|
||||
* configure.ac: add definition of HAVE_YYLEX_DESTROY if $LEX is flex.
|
||||
* Makefile.am: added . in front of SUBDIRS to build avrdude before trying
|
||||
to use it for creating the part list for the docs.
|
||||
|
||||
2012-01-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* usbasp.c: USB vid/pid/vendor/product from config file are used, for
|
||||
|
|
|
@ -44,7 +44,10 @@ BUILT_SOURCES = $(CLEANFILES)
|
|||
#SUBDIRS = doc @WINDOWS_DIRS@
|
||||
#DIST_SUBDIRS = doc windows
|
||||
|
||||
SUBDIRS = @SUBDIRS_AC@
|
||||
# . lets build this directory before the following in SUBDIRS
|
||||
SUBDIRS = .
|
||||
# doc comes here, and we want to use the built avrdude to generate the parts list
|
||||
SUBDIRS += @SUBDIRS_AC@
|
||||
SUBDIRS += @WINDOWS_DIRS@
|
||||
DIST_SUBDIRS = @DIST_SUBDIRS_AC@
|
||||
|
||||
|
|
40
avrpart.c
40
avrpart.c
|
@ -67,6 +67,10 @@ static OPCODE * avr_dup_opcode(OPCODE * op)
|
|||
return m;
|
||||
}
|
||||
|
||||
void avr_free_opcode(OPCODE * op)
|
||||
{
|
||||
free(op);
|
||||
}
|
||||
|
||||
/*
|
||||
* avr_set_bits()
|
||||
|
@ -303,6 +307,27 @@ AVRMEM * avr_dup_mem(AVRMEM * m)
|
|||
return n;
|
||||
}
|
||||
|
||||
void avr_free_mem(AVRMEM * m)
|
||||
{
|
||||
int i;
|
||||
if (m->buf != NULL) {
|
||||
free(m->buf);
|
||||
m->buf = NULL;
|
||||
}
|
||||
if (m->tags != NULL) {
|
||||
free(m->tags);
|
||||
m->tags = NULL;
|
||||
}
|
||||
for(i=0;i<sizeof(m->op)/sizeof(m->op[0]);i++)
|
||||
{
|
||||
if (m->op[i] != NULL)
|
||||
{
|
||||
avr_free_opcode(m->op[i]);
|
||||
m->op[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(m);
|
||||
}
|
||||
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
|
||||
{
|
||||
|
@ -447,6 +472,21 @@ AVRPART * avr_dup_part(AVRPART * d)
|
|||
return p;
|
||||
}
|
||||
|
||||
void avr_free_part(AVRPART * d)
|
||||
{
|
||||
int i;
|
||||
ldestroy_cb(d->mem,avr_free_mem);
|
||||
d->mem = NULL;
|
||||
for(i=0;i<sizeof(d->op)/sizeof(d->op[0]);i++)
|
||||
{
|
||||
if (d->op[i] != NULL)
|
||||
{
|
||||
avr_free_opcode(d->op[i]);
|
||||
d->op[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(d);
|
||||
}
|
||||
|
||||
AVRPART * locate_part(LISTID parts, char * partdesc)
|
||||
{
|
||||
|
|
|
@ -198,6 +198,7 @@ extern "C" {
|
|||
|
||||
/* Functions for OPCODE structures */
|
||||
OPCODE * avr_new_opcode(void);
|
||||
void avr_free_opcode(OPCODE * op);
|
||||
int avr_set_bits(OPCODE * op, unsigned char * cmd);
|
||||
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr);
|
||||
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data);
|
||||
|
@ -207,6 +208,7 @@ int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data);
|
|||
AVRMEM * avr_new_memtype(void);
|
||||
int avr_initmem(AVRPART * p);
|
||||
AVRMEM * avr_dup_mem(AVRMEM * m);
|
||||
void avr_free_mem(AVRMEM * m);
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
|
||||
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
|
||||
int verbose);
|
||||
|
@ -214,6 +216,7 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
|
|||
/* Functions for AVRPART structures */
|
||||
AVRPART * avr_new_part(void);
|
||||
AVRPART * avr_dup_part(AVRPART * d);
|
||||
void avr_free_part(AVRPART * d);
|
||||
AVRPART * locate_part(LISTID parts, char * partdesc);
|
||||
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode);
|
||||
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose);
|
||||
|
|
24
buspirate.c
24
buspirate.c
|
@ -760,6 +760,22 @@ static int buspirate_chip_erase(struct programmer_t *pgm, AVRPART * p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Interface - management */
|
||||
static void buspirate_setup(struct programmer_t *pgm)
|
||||
{
|
||||
/* Allocate private data */
|
||||
if ((pgm->cookie = calloc(1, sizeof(struct pdata))) == 0) {
|
||||
fprintf(stderr, "%s: buspirate_initpgm(): Out of memory allocating private data\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void buspirate_teardown(struct programmer_t *pgm)
|
||||
{
|
||||
free(pgm->cookie);
|
||||
}
|
||||
|
||||
void buspirate_initpgm(struct programmer_t *pgm)
|
||||
{
|
||||
strcpy(pgm->type, "BusPirate");
|
||||
|
@ -785,11 +801,7 @@ void buspirate_initpgm(struct programmer_t *pgm)
|
|||
/* Support functions */
|
||||
pgm->parseextparams = buspirate_parseextparms;
|
||||
|
||||
/* Allocate private data */
|
||||
if ((pgm->cookie = calloc(1, sizeof(struct pdata))) == 0) {
|
||||
fprintf(stderr, "%s: buspirate_initpgm(): Out of memory allocating private data\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
pgm->setup = buspirate_setup;
|
||||
pgm->teardown = buspirate_teardown;
|
||||
}
|
||||
|
||||
|
|
14
config.c
14
config.c
|
@ -55,6 +55,13 @@ extern char * yytext;
|
|||
|
||||
#define DEBUG 0
|
||||
|
||||
void cleanup_config(void)
|
||||
{
|
||||
ldestroy_cb(part_list,avr_free_part);
|
||||
ldestroy_cb(programmers,pgm_free);
|
||||
ldestroy_cb(string_list,free_token);
|
||||
ldestroy_cb(number_list,free_token);
|
||||
}
|
||||
|
||||
int init_config(void)
|
||||
{
|
||||
|
@ -62,7 +69,7 @@ int init_config(void)
|
|||
number_list = lcreat(NULL, 0);
|
||||
current_prog = NULL;
|
||||
current_part = NULL;
|
||||
current_mem = 0;
|
||||
current_mem = NULL;
|
||||
part_list = lcreat(NULL, 0);
|
||||
programmers = lcreat(NULL, 0);
|
||||
|
||||
|
@ -301,6 +308,11 @@ int read_config(const char * file)
|
|||
|
||||
yyparse();
|
||||
|
||||
#ifdef HAVE_YYLEX_DESTROY
|
||||
/* reset lexer and free any allocated memory */
|
||||
yylex_destroy();
|
||||
#endif
|
||||
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
|
|
2
config.h
2
config.h
|
@ -78,6 +78,8 @@ int yyparse(void);
|
|||
|
||||
int init_config(void);
|
||||
|
||||
void cleanup_config(void);
|
||||
|
||||
TOKEN * new_token(int primary);
|
||||
|
||||
void free_token(TOKEN * tkn);
|
||||
|
|
|
@ -290,6 +290,8 @@ def :
|
|||
prog_def :
|
||||
prog_decl prog_parms
|
||||
{
|
||||
PROGRAMMER * existing_prog;
|
||||
char * id;
|
||||
if (lsize(current_prog->id) == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: error at %s:%d: required parameter id not specified\n",
|
||||
|
@ -301,6 +303,16 @@ prog_def :
|
|||
progname, infile, lineno);
|
||||
exit(1);
|
||||
}
|
||||
id = ldata(lfirst(current_prog->id));
|
||||
existing_prog = locate_programmer(programmers, id);
|
||||
if (existing_prog) {
|
||||
fprintf(stderr, "%s: warning at %s:%d: programmer %s overwrites "
|
||||
"previous definition %s:%d.\n",
|
||||
progname, infile, current_prog->lineno,
|
||||
id, existing_prog->config_file, existing_prog->lineno);
|
||||
lrmv_d(programmers, existing_prog);
|
||||
pgm_free(existing_prog);
|
||||
}
|
||||
PUSH(programmers, current_prog);
|
||||
current_prog = NULL;
|
||||
}
|
||||
|
@ -321,6 +333,7 @@ part_def :
|
|||
{
|
||||
LNODEID ln;
|
||||
AVRMEM * m;
|
||||
AVRPART * existing_part;
|
||||
|
||||
if (current_part->id[0] == 0) {
|
||||
fprintf(stderr,
|
||||
|
@ -366,6 +379,15 @@ part_def :
|
|||
}
|
||||
}
|
||||
|
||||
existing_part = locate_part(part_list, current_part->id);
|
||||
if (existing_part) {
|
||||
fprintf(stderr, "%s: warning at %s:%d: part %s overwrites "
|
||||
"previous definition %s:%d.\n",
|
||||
progname, infile, current_part->lineno, current_part->id,
|
||||
existing_part->config_file, existing_part->lineno);
|
||||
lrmv_d(part_list, existing_part);
|
||||
avr_free_part(existing_part);
|
||||
}
|
||||
PUSH(part_list, current_part);
|
||||
current_part = NULL;
|
||||
}
|
||||
|
@ -1146,6 +1168,13 @@ part_parm :
|
|||
}
|
||||
mem_specs
|
||||
{
|
||||
AVRMEM * existing_mem;
|
||||
|
||||
existing_mem = avr_locate_mem(current_part, current_mem->desc);
|
||||
if (existing_mem != NULL) {
|
||||
lrmv_d(current_part->mem, existing_mem);
|
||||
avr_free_mem(existing_mem);
|
||||
}
|
||||
ladd(current_part->mem, current_mem);
|
||||
current_mem = NULL;
|
||||
} |
|
||||
|
@ -1162,7 +1191,7 @@ part_parm :
|
|||
/*fprintf(stderr,
|
||||
"%s: warning at %s:%d: operation redefined\n",
|
||||
progname, infile, lineno);*/
|
||||
free(current_part->op[opnum]);
|
||||
avr_free_opcode(current_part->op[opnum]);
|
||||
}
|
||||
current_part->op[opnum] = op;
|
||||
|
||||
|
@ -1289,7 +1318,7 @@ mem_spec :
|
|||
/*fprintf(stderr,
|
||||
"%s: warning at %s:%d: operation redefined\n",
|
||||
progname, infile, lineno);*/
|
||||
free(current_mem->op[opnum]);
|
||||
avr_free_opcode(current_mem->op[opnum]);
|
||||
}
|
||||
current_mem->op[opnum] = op;
|
||||
|
||||
|
|
|
@ -40,6 +40,12 @@ AC_PROG_INSTALL
|
|||
AC_PROG_YACC
|
||||
AC_PROG_LEX
|
||||
AC_PROG_RANLIB
|
||||
AH_TEMPLATE([HAVE_YYLEX_DESTROY],
|
||||
[Define if lex/flex has yylex_destroy])
|
||||
# flex should have this
|
||||
if test "x$LEX" == xflex; then
|
||||
AC_DEFINE([HAVE_YYLEX_DESTROY])
|
||||
fi
|
||||
|
||||
dnl Makefile.am:77: compiling `config_gram.c' with per-target flags requires `AM_PROG_CC_C_O' in `configure.ac'
|
||||
AM_PROG_CC_C_O
|
||||
|
|
26
main.c
26
main.c
|
@ -71,11 +71,11 @@ struct list_walk_cookie
|
|||
const char *prefix;
|
||||
};
|
||||
|
||||
static LISTID updates;
|
||||
static LISTID updates = NULL;
|
||||
|
||||
static LISTID extended_params;
|
||||
static LISTID extended_params = NULL;
|
||||
|
||||
static LISTID additional_config_files;
|
||||
static LISTID additional_config_files = NULL;
|
||||
|
||||
static PROGRAMMER * pgm;
|
||||
|
||||
|
@ -254,6 +254,24 @@ static void exithook(void)
|
|||
pgm->teardown(pgm);
|
||||
}
|
||||
|
||||
static void cleanup_main(void)
|
||||
{
|
||||
if (updates) {
|
||||
ldestroy_cb(updates,free_update);
|
||||
updates = NULL;
|
||||
}
|
||||
if (extended_params) {
|
||||
ldestroy(extended_params);
|
||||
extended_params = NULL;
|
||||
}
|
||||
if (additional_config_files) {
|
||||
ldestroy(additional_config_files);
|
||||
additional_config_files = NULL;
|
||||
}
|
||||
|
||||
cleanup_config();
|
||||
}
|
||||
|
||||
/*
|
||||
* main routine
|
||||
*/
|
||||
|
@ -332,6 +350,8 @@ int main(int argc, char * argv [])
|
|||
|
||||
init_config();
|
||||
|
||||
atexit(cleanup_main);
|
||||
|
||||
updates = lcreat(NULL, 0);
|
||||
if (updates == NULL) {
|
||||
fprintf(stderr, "%s: cannot initialize updater list\n", progname);
|
||||
|
|
11
pgm.c
11
pgm.c
|
@ -135,6 +135,17 @@ PROGRAMMER * pgm_new(void)
|
|||
return pgm;
|
||||
}
|
||||
|
||||
void pgm_free(PROGRAMMER * const p)
|
||||
{
|
||||
ldestroy_cb(p->id,free);
|
||||
p->id = NULL;
|
||||
/* this is done by pgm_teardown, but usually cookie is not set to NULL */
|
||||
/* if (p->cookie !=NULL) {
|
||||
free(p->cookie);
|
||||
p->cookie = NULL;
|
||||
}*/
|
||||
free(p);
|
||||
}
|
||||
|
||||
static void pgm_default(void)
|
||||
{
|
||||
|
|
1
pgm.h
1
pgm.h
|
@ -131,6 +131,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
PROGRAMMER * pgm_new(void);
|
||||
void pgm_free(PROGRAMMER * const p);
|
||||
|
||||
void programmer_display(PROGRAMMER * pgm, const char * p);
|
||||
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid);
|
||||
|
|
16
update.c
16
update.c
|
@ -200,6 +200,22 @@ UPDATE * new_update(int op, char * memtype, int filefmt, char * filename)
|
|||
return u;
|
||||
}
|
||||
|
||||
void free_update(UPDATE * u)
|
||||
{
|
||||
if (u != NULL) {
|
||||
if(u->memtype != NULL) {
|
||||
free(u->memtype);
|
||||
u->memtype = NULL;
|
||||
}
|
||||
if(u->filename != NULL) {
|
||||
free(u->filename);
|
||||
u->filename = NULL;
|
||||
}
|
||||
free(u);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite)
|
||||
{
|
||||
struct avrpart * v;
|
||||
|
|
1
update.h
1
update.h
|
@ -45,6 +45,7 @@ extern UPDATE * parse_op(char * s);
|
|||
extern UPDATE * dup_update(UPDATE * upd);
|
||||
extern UPDATE * new_update(int op, char * memtype, int filefmt,
|
||||
char * filename);
|
||||
extern void free_update(UPDATE * upd);
|
||||
extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd,
|
||||
int nowrite);
|
||||
|
||||
|
|
12
usbasp.c
12
usbasp.c
|
@ -305,6 +305,7 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
|
|||
handle = NULL;
|
||||
}
|
||||
}
|
||||
libusb_free_device_list(dev_list,1);
|
||||
if (handle != NULL){
|
||||
errorCode = 0;
|
||||
*device = handle;
|
||||
|
@ -401,11 +402,7 @@ static int didUsbInit = 0;
|
|||
/* Interface - prog. */
|
||||
static int usbasp_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
#ifdef USE_LIBUSB_1_0
|
||||
libusb_init(&ctx);
|
||||
#else
|
||||
usb_init();
|
||||
#endif
|
||||
/* usb_init will be done in usbOpenDevice */
|
||||
if (usbOpenDevice(&PDATA(pgm)->usbhandle, pgm->usbvid, pgm->usbvendor,
|
||||
pgm->usbpid, pgm->usbproduct) != 0) {
|
||||
/* try alternatives */
|
||||
|
@ -474,6 +471,11 @@ static void usbasp_close(PROGRAMMER * pgm)
|
|||
usb_close(PDATA(pgm)->usbhandle);
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_LIBUSB_1_0
|
||||
libusb_exit(ctx);
|
||||
#else
|
||||
/* nothing for usb 0.1 ? */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue