bug #34302: Feature request : device configuration with parent classes

(not in original patch) 
* avrpart.c: New function avr_dup_opcode. avr_dup_mem/avr_dup_part-
	functions now duplicate the opcodes in their op-array to avoid memory leaks.
* doc/avrdude.texi: Added description of part parent f

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1028 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
rliebscher 2011-12-29 16:51:44 +00:00
parent e20b95a8b0
commit 8a5c0972ab
6 changed files with 141 additions and 48 deletions

View File

@ -1,3 +1,18 @@
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
bug #34302: Feature request : device configuration with parent classes
* config_gram.y: Added part parent rule and allow overwriting existing
data at several places
* avrdude.conf.in: Added description comment and m328/m328p as example
* avrpart.c: avr_dup_mem-functions now copy buf and tags memory block
only they are already allocated.
* lexer.l: Added parent as valid token
(not in original patch)
* avrpart.c: New function avr_dup_opcode. avr_dup_mem/avr_dup_part-
functions now duplicate the opcodes in their op-array to avoid memory leaks.
* doc/avrdude.texi: Added description of part parent feature
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
patch #7687: Autogenerating programmers and parts lists for docs

View File

@ -138,6 +138,17 @@
# values. If a required parameter is left empty, AVRDUDE will
# complain.
#
# Parts can also inherit parameters from previously defined parts
# using the following syntax. In this case specified integer and
# string values override parameter values from the parent part. New
# memory definitions are added to the definitions inherited from the
# parent.
#
# part parent <id> # quoted string
# id = <id> ; # quoted string
# <any set of other parameters from the list above>
# ;
#
# NOTES:
# * 'devicecode' is the device code used by the STK500 (see codes
# listed below)
@ -9223,12 +9234,12 @@ part
;
#------------------------------------------------------------
# ATmega328P
# ATmega328
#------------------------------------------------------------
part
id = "m328p";
desc = "ATmega328P";
id = "m328";
desc = "ATmega328";
has_debugwire = yes;
flash_instr = 0xB6, 0x01, 0x11;
eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
@ -9236,7 +9247,7 @@ part
0x99, 0xF9, 0xBB, 0xAF;
stk500_devcode = 0x86;
# avr910_devcode = 0x;
signature = 0x1e 0x95 0x0F;
signature = 0x1e 0x95 0x14;
pagel = 0xd7;
bs2 = 0xc2;
chip_erase_delay = 9000;
@ -9410,6 +9421,12 @@ part
;
;
part parent "m328"
id = "m328p";
desc = "ATmega328P";
signature = 0x1e 0x95 0x0F;
;
#------------------------------------------------------------
# ATtiny2313
#------------------------------------------------------------

View File

@ -47,6 +47,26 @@ OPCODE * avr_new_opcode(void)
return m;
}
static OPCODE * avr_dup_opcode(OPCODE * op)
{
OPCODE * m;
/* this makes life easier */
if (op == NULL) {
return NULL;
}
m = (OPCODE *)malloc(sizeof(*m));
if (m == NULL) {
fprintf(stderr, "avr_dup_opcode(): out of memory\n");
exit(1);
}
memcpy(m, op, sizeof(*m));
return m;
}
/*
* avr_set_bits()
@ -248,28 +268,37 @@ int avr_initmem(AVRPART * p)
AVRMEM * avr_dup_mem(AVRMEM * m)
{
AVRMEM * n;
int i;
n = avr_new_memtype();
*n = *m;
n->buf = (unsigned char *)malloc(n->size);
if (n->buf == NULL) {
fprintf(stderr,
"avr_dup_mem(): out of memory (memsize=%d)\n",
n->size);
exit(1);
if (m->buf != NULL) {
n->buf = (unsigned char *)malloc(n->size);
if (n->buf == NULL) {
fprintf(stderr,
"avr_dup_mem(): out of memory (memsize=%d)\n",
n->size);
exit(1);
}
memcpy(n->buf, m->buf, n->size);
}
memcpy(n->buf, m->buf, n->size);
n->tags = (unsigned char *)malloc(n->size);
if (n->tags == NULL) {
fprintf(stderr,
"avr_dup_mem(): out of memory (memsize=%d)\n",
n->size);
exit(1);
if (m->tags != NULL) {
n->tags = (unsigned char *)malloc(n->size);
if (n->tags == NULL) {
fprintf(stderr,
"avr_dup_mem(): out of memory (memsize=%d)\n",
n->size);
exit(1);
}
memcpy(n->tags, m->tags, n->size);
}
for (i = 0; i < AVR_OP_MAX; i++) {
n->op[i] = avr_dup_opcode(n->op[i]);
}
memcpy(n->tags, m->tags, n->size);
return n;
}
@ -398,6 +427,7 @@ AVRPART * avr_dup_part(AVRPART * d)
AVRPART * p;
LISTID save;
LNODEID ln;
int i;
p = avr_new_part();
save = p->mem;
@ -410,6 +440,10 @@ AVRPART * avr_dup_part(AVRPART * d)
ladd(p->mem, avr_dup_mem(ldata(ln)));
}
for (i = 0; i < AVR_OP_MAX; i++) {
p->op[i] = avr_dup_opcode(p->op[i]);
}
return p;
}

View File

@ -128,6 +128,7 @@ static int pin_name;
%token K_PAGEL
%token K_PAR
%token K_PARALLEL
%token K_PARENT
%token K_PART
%token K_PGMLED
%token K_PROGRAMMER
@ -316,13 +317,7 @@ prog_decl :
part_def :
K_PART
{
current_part = avr_new_part();
strcpy(current_part->config_file, infile);
current_part->lineno = lineno;
}
part_parms
part_decl part_parms
{
LNODEID ln;
AVRMEM * m;
@ -376,6 +371,30 @@ part_def :
}
;
part_decl :
K_PART
{
current_part = avr_new_part();
strcpy(current_part->config_file, infile);
current_part->lineno = lineno;
} |
K_PART K_PARENT TKN_STRING
{
AVRPART * parent_part = locate_part(part_list, $3->value.string);
if (parent_part == NULL) {
fprintf(stderr,
"%s: error at %s:%d: can't find parent part",
progname, infile, lineno);
exit(1);
}
current_part = avr_dup_part(parent_part);
strcpy(current_part->config_file, infile);
current_part->lineno = lineno;
free_token($3);
}
;
string_list :
TKN_STRING { ladd(string_list, $1); } |
@ -632,19 +651,11 @@ part_parm :
unsigned nbytes;
int ok;
if (current_part->ctl_stack_type != CTL_STACK_NONE)
{
fprintf(stderr,
"%s: error at line %d of %s: "
"control stack already defined\n",
progname, lineno, infile);
exit(1);
}
current_part->ctl_stack_type = CTL_STACK_PP;
nbytes = 0;
ok = 1;
memset(current_part->controlstack, 0, CTL_STACK_SIZE);
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
if (nbytes < CTL_STACK_SIZE)
@ -674,19 +685,11 @@ part_parm :
unsigned nbytes;
int ok;
if (current_part->ctl_stack_type != CTL_STACK_NONE)
{
fprintf(stderr,
"%s: error at line %d of %s: "
"control stack already defined\n",
progname, lineno, infile);
exit(1);
}
current_part->ctl_stack_type = CTL_STACK_HVSP;
nbytes = 0;
ok = 1;
memset(current_part->controlstack, 0, CTL_STACK_SIZE);
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
if (nbytes < CTL_STACK_SIZE)
@ -719,6 +722,7 @@ part_parm :
nbytes = 0;
ok = 1;
memset(current_part->flash_instr, 0, FLASH_INSTR_SIZE);
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
if (nbytes < FLASH_INSTR_SIZE)
@ -751,6 +755,7 @@ part_parm :
nbytes = 0;
ok = 1;
memset(current_part->eeprom_instr, 0, EEPROM_INSTR_SIZE);
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
if (nbytes < EEPROM_INSTR_SIZE)
@ -1154,9 +1159,9 @@ part_parm :
op = avr_new_opcode();
parse_cmdbits(op);
if (current_part->op[opnum] != NULL) {
fprintf(stderr,
/*fprintf(stderr,
"%s: warning at %s:%d: operation redefined\n",
progname, infile, lineno);
progname, infile, lineno);*/
free(current_part->op[opnum]);
}
current_part->op[opnum] = op;
@ -1281,9 +1286,9 @@ mem_spec :
op = avr_new_opcode();
parse_cmdbits(op);
if (current_mem->op[opnum] != NULL) {
fprintf(stderr,
/*fprintf(stderr,
"%s: warning at %s:%d: operation redefined\n",
progname, infile, lineno);
progname, infile, lineno);*/
free(current_mem->op[opnum]);
}
current_mem->op[opnum] = op;

View File

@ -1529,13 +1529,34 @@ part
@end smallexample
@menu
* Parent Part::
* Instruction Format::
@end menu
@c
@c Node
@c
@node Instruction Format, , Part Definitions, Part Definitions
@node Parent Part, Instruction Format, Part Definitions, Part Definitions
@subsection Parent Part
@noindent
Parts can also inherit parameters from previously defined parts
using the following syntax. In this case specified integer and
string values override parameter values from the parent part. New
memory definitions are added to the definitions inherited from the
parent.
@smallexample
part parent <id> # quoted string
id = <id> ; # quoted string
<any set of other parameters from the list above>
;
@end smallexample
@c
@c Node
@c
@node Instruction Format, , Parent Part, Part Definitions
@subsection Instruction Format
@noindent

View File

@ -177,6 +177,7 @@ paged { yylval=NULL; return K_PAGED; }
pagel { yylval=NULL; return K_PAGEL; }
par { yylval=NULL; return K_PAR; }
parallel { yylval=NULL; return K_PARALLEL; }
parent { yylval=NULL; return K_PARENT; }
part { yylval=NULL; return K_PART; }
pgmled { yylval=NULL; return K_PGMLED; }
programmer { yylval=NULL; return K_PROGRAMMER; }