diff --git a/src/avrpart.c b/src/avrpart.c index 40baa449..526d0503 100644 --- a/src/avrpart.c +++ b/src/avrpart.c @@ -1,4 +1,3 @@ - /* * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2000-2004 Brian S. Dean @@ -31,44 +30,23 @@ *** Elementary functions dealing with OPCODE structures ***/ -OPCODE * avr_new_opcode(void) -{ - OPCODE * m; - - m = (OPCODE *)malloc(sizeof(*m)); - if (m == NULL) { - avrdude_message(MSG_INFO, "avr_new_opcode(): out of memory\n"); - exit(1); - } - - memset(m, 0, sizeof(*m)); - - return m; +OPCODE *avr_new_opcode(void) { + return (OPCODE *) cfg_malloc("avr_new_opcode()", sizeof(OPCODE)); } -static OPCODE * avr_dup_opcode(OPCODE * op) -{ - OPCODE * m; - - /* this makes life easier */ - if (op == NULL) { +static OPCODE *avr_dup_opcode(const OPCODE *op) { + if(op == NULL) // Caller wants NULL if op == NULL return NULL; - } - - m = (OPCODE *)malloc(sizeof(*m)); - if (m == NULL) { - avrdude_message(MSG_INFO, "avr_dup_opcode(): out of memory\n"); - exit(1); - } + OPCODE *m = (OPCODE *) cfg_malloc("avr_dup_opcode()", sizeof(*m)); memcpy(m, op, sizeof(*m)); return m; } -void avr_free_opcode(OPCODE * op) -{ - free(op); +void avr_free_opcode(OPCODE *op) { + if(op) + free(op); } @@ -268,11 +246,10 @@ int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data) /* * avr_get_output() * - * Retreive output data bits from the command results based on the + * Retrieve output data bits from the command results based on the * opcode data. */ -int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data) -{ +int avr_get_output(const OPCODE *op, const unsigned char *res, unsigned char *data) { int i, j, bit; unsigned char value; unsigned char mask; @@ -301,8 +278,7 @@ int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data) * Calculate the byte number of the output data based on the * opcode data. */ -int avr_get_output_index(OPCODE * op) -{ +int avr_get_output_index(const OPCODE *op) { int i, j; for (i=0; i<32; i++) { @@ -353,34 +329,17 @@ static char * bittype(int type) *** Elementary functions dealing with AVRMEM structures ***/ -AVRMEM * avr_new_memtype(void) -{ - AVRMEM * m; - - m = (AVRMEM *)malloc(sizeof(*m)); - if (m == NULL) { - avrdude_message(MSG_INFO, "avr_new_memtype(): out of memory\n"); - exit(1); - } - - memset(m, 0, sizeof(*m)); +AVRMEM *avr_new_memtype(void) { + AVRMEM *m = (AVRMEM *) cfg_malloc("avr_new_memtype()", sizeof(*m)); + m->desc = cache_string(""); m->page_size = 1; // ensure not 0 return m; } -AVRMEM_ALIAS * avr_new_memalias(void) -{ - AVRMEM_ALIAS * m; - - m = (AVRMEM_ALIAS *)malloc(sizeof(*m)); - if (m == NULL) { - avrdude_message(MSG_INFO, "avr_new_memalias(): out of memory\n"); - exit(1); - } - - memset(m, 0, sizeof(*m)); - +AVRMEM_ALIAS *avr_new_memalias(void) { + AVRMEM_ALIAS *m = (AVRMEM_ALIAS *) cfg_malloc("avr_new_memalias()", sizeof*m); + m->desc = cache_string(""); return m; } @@ -389,106 +348,79 @@ AVRMEM_ALIAS * avr_new_memalias(void) * Allocate and initialize memory buffers for each of the device's * defined memory regions. */ -int avr_initmem(AVRPART * p) -{ - LNODEID ln; - AVRMEM * m; +int avr_initmem(const AVRPART *p) { + if(p == NULL || p->mem == NULL) + return -1; - for (ln=lfirst(p->mem); ln; ln=lnext(ln)) { - m = ldata(ln); - m->buf = (unsigned char *) malloc(m->size); - if (m->buf == NULL) { - avrdude_message(MSG_INFO, "%s: can't alloc buffer for %s size of %d bytes\n", - progname, m->desc, m->size); - return -1; - } - m->tags = (unsigned char *) malloc(m->size); - if (m->tags == NULL) { - avrdude_message(MSG_INFO, "%s: can't alloc buffer for %s size of %d bytes\n", - progname, m->desc, m->size); - return -1; - } + for (LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) { + AVRMEM *m = ldata(ln); + m->buf = (unsigned char *) cfg_malloc("avr_initmem()", m->size); + m->tags = (unsigned char *) cfg_malloc("avr_initmem()", m->size); } return 0; } -AVRMEM * avr_dup_mem(AVRMEM * m) -{ - AVRMEM * n; - int i; +AVRMEM *avr_dup_mem(const AVRMEM *m) { + AVRMEM *n = avr_new_memtype(); - n = avr_new_memtype(); + if(m) { + *n = *m; - *n = *m; - - if (m->buf != NULL) { - n->buf = (unsigned char *)malloc(n->size); - if (n->buf == NULL) { - avrdude_message(MSG_INFO, "avr_dup_mem(): out of memory (memsize=%d)\n", - n->size); - exit(1); + if(m->buf) { + n->buf = (unsigned char *) cfg_malloc("avr_dup_mem()", n->size); + memcpy(n->buf, m->buf, n->size); } - memcpy(n->buf, m->buf, n->size); - } - if (m->tags != NULL) { - n->tags = (unsigned char *)malloc(n->size); - if (n->tags == NULL) { - avrdude_message(MSG_INFO, "avr_dup_mem(): out of memory (memsize=%d)\n", - n->size); - exit(1); + if(m->tags) { + n->tags = (unsigned char *) cfg_malloc("avr_dup_mem()", n->size); + memcpy(n->tags, m->tags, n->size); } - memcpy(n->tags, m->tags, n->size); - } - for (i = 0; i < AVR_OP_MAX; i++) { - n->op[i] = avr_dup_opcode(n->op[i]); + for(int i = 0; i < AVR_OP_MAX; i++) + n->op[i] = avr_dup_opcode(n->op[i]); } return n; } -AVRMEM_ALIAS * avr_dup_memalias(AVRMEM_ALIAS * m) -{ - AVRMEM_ALIAS * n; +AVRMEM_ALIAS *avr_dup_memalias(const AVRMEM_ALIAS *m) { + AVRMEM_ALIAS *n = avr_new_memalias(); - n = avr_new_memalias(); - - *n = *m; + if(m) + *n = *m; return n; } -void avr_free_mem(AVRMEM * m) -{ - if (m->buf != NULL) { - free(m->buf); - m->buf = NULL; - } - if (m->tags != NULL) { - free(m->tags); - m->tags = NULL; - } - for(size_t i=0; iop)/sizeof(m->op[0]); i++) - { - if (m->op[i] != NULL) - { - avr_free_opcode(m->op[i]); - m->op[i] = NULL; - } - } - free(m); -} +void avr_free_mem(AVRMEM * m) { + if(m == NULL) + return; -void avr_free_memalias(AVRMEM_ALIAS * m) -{ + if(m->buf) { + free(m->buf); + m->buf = NULL; + } + if(m->tags) { + free(m->tags); + m->tags = NULL; + } + for(size_t i=0; iop)/sizeof(m->op[0]); i++) { + if(m->op[i]) { + avr_free_opcode(m->op[i]); + m->op[i] = NULL; + } + } free(m); } -AVRMEM_ALIAS * avr_locate_memalias(AVRPART * p, const char * desc) -{ +void avr_free_memalias(AVRMEM_ALIAS *m) { + if(m) + free(m); +} + +AVRMEM_ALIAS *avr_locate_memalias(const AVRPART *p, const char *desc) { AVRMEM_ALIAS * m, * match; LNODEID ln; int matches; @@ -514,8 +446,7 @@ AVRMEM_ALIAS * avr_locate_memalias(AVRPART * p, const char * desc) return NULL; } -AVRMEM * avr_locate_mem_noalias(AVRPART * p, const char * desc) -{ +AVRMEM *avr_locate_mem_noalias(const AVRPART *p, const char *desc) { AVRMEM * m, * match; LNODEID ln; int matches; @@ -542,8 +473,7 @@ AVRMEM * avr_locate_mem_noalias(AVRPART * p, const char * desc) } -AVRMEM * avr_locate_mem(AVRPART * p, const char * desc) -{ +AVRMEM *avr_locate_mem(const AVRPART *p, const char *desc) { AVRMEM * m, * match; AVRMEM_ALIAS * alias; LNODEID ln; @@ -577,24 +507,20 @@ AVRMEM * avr_locate_mem(AVRPART * p, const char * desc) return NULL; } -AVRMEM_ALIAS * avr_find_memalias(AVRPART * p, AVRMEM * m_orig) -{ - AVRMEM_ALIAS * m; - LNODEID ln; - - for (ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) { - m = ldata(ln); - if (m->aliased_mem == m_orig) - return m; - } +AVRMEM_ALIAS *avr_find_memalias(const AVRPART *p, const AVRMEM *m_orig) { + if(p && p->mem_alias && m_orig) + for(LNODEID ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) { + AVRMEM_ALIAS *m = ldata(ln); + if(m->aliased_mem == m_orig) + return m; + } return NULL; } -void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p, - int type, int verbose) -{ +void avr_mem_display(const char *prefix, FILE *f, const AVRMEM *m, + const AVRPART *p, int verbose) { static unsigned int prev_mem_offset; static int prev_mem_size; int i, j; @@ -623,7 +549,7 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p, AVRMEM_ALIAS *ap = avr_find_memalias(p, m); /* Show alias if the current and the next memory section has the same offset and size, we're not out of band and a family_id is present */ - char * mem_desc_alias = ap? ap->desc: ""; + const char *mem_desc_alias = ap? ap->desc: ""; fprintf(f, "%s%-11s %-8s %4d %5d %5d %4d %-6s %6d %4d %6d %5d %5d 0x%02x 0x%02x\n", prefix, @@ -669,74 +595,63 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p, * Elementary functions dealing with AVRPART structures */ -AVRPART * avr_new_part(void) -{ - AVRPART * p; +AVRPART *avr_new_part(void) { + AVRPART *p = (AVRPART *) cfg_malloc("avr_new_part()", sizeof(AVRPART)); const char *nulp = cache_string(""); - p = (AVRPART *)malloc(sizeof(AVRPART)); - if (p == NULL) { - avrdude_message(MSG_INFO, "new_part(): out of memory\n"); - exit(1); - } - memset(p, 0, sizeof(*p)); - p->id[0] = 0; - p->desc[0] = 0; + // Initialise const char * and LISTID entities + p->desc = nulp; + p->id = nulp; + p->parent_id = nulp; + p->family_id = nulp; + p->config_file = nulp; + p->mem = lcreat(NULL, 0); + p->mem_alias = lcreat(NULL, 0); + + // Default values + p->hvupdi_variant = -1; + memset(p->signature, 0xFF, 3); p->reset_disposition = RESET_DEDICATED; p->retry_pulse = PIN_AVR_SCK; p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK | AVRPART_ENABLEPAGEPROGRAMMING; - p->parent_id = nulp; - p->config_file = nulp; - p->lineno = 0; - memset(p->signature, 0xFF, 3); p->ctl_stack_type = CTL_STACK_NONE; p->ocdrev = -1; - p->hvupdi_variant = -1; - - p->mem = lcreat(NULL, 0); - p->mem_alias = lcreat(NULL, 0); + p->lineno = 0; return p; } -AVRPART * avr_dup_part(AVRPART * d) -{ - AVRPART * p; - LISTID save, save2; - LNODEID ln, ln2; - int i; +AVRPART *avr_dup_part(const AVRPART *d) { + AVRPART *p = avr_new_part(); - p = avr_new_part(); - save = p->mem; - save2 = p->mem_alias; + if(d) { + *p = *d; - *p = *d; + // Duplicate the memory and alias chains + p->mem = lcreat(NULL, 0); + p->mem_alias = lcreat(NULL, 0); - p->mem = save; - p->mem_alias = save2; - for (ln=lfirst(d->mem); ln; ln=lnext(ln)) { - AVRMEM *m = ldata(ln); - AVRMEM *m2 = avr_dup_mem(m); - ladd(p->mem, m2); - // see if there is any alias for it - for (ln2=lfirst(d->mem_alias); ln2; ln2=lnext(ln2)) { - AVRMEM_ALIAS *a = ldata(ln2); - if (a->aliased_mem == m) { - // yes, duplicate it - AVRMEM_ALIAS *a2 = avr_dup_memalias(a); - // ... adjust the pointer ... - a2->aliased_mem = m2; - // ... and add to new list - ladd(p->mem_alias, a2); + for(LNODEID ln=lfirst(d->mem); ln; ln=lnext(ln)) { + AVRMEM *m = ldata(ln); + AVRMEM *m2 = avr_dup_mem(m); + ladd(p->mem, m2); + // See if there is any alias for it + for(LNODEID ln2=lfirst(d->mem_alias); ln2; ln2=lnext(ln2)) { + AVRMEM_ALIAS *a = ldata(ln2); + if (a->aliased_mem == m) { + // Yes, duplicate it, adjust the pointer and add to new list + AVRMEM_ALIAS *a2 = avr_dup_memalias(a); + a2->aliased_mem = m2; + ladd(p->mem_alias, a2); + } } } - } - for (i = 0; i < AVR_OP_MAX; i++) { - p->op[i] = avr_dup_opcode(p->op[i]); + for(int i = 0; i < AVR_OP_MAX; i++) + p->op[i] = avr_dup_opcode(p->op[i]); } return p; @@ -758,61 +673,45 @@ void avr_free_part(AVRPART * d) free(d); } -AVRPART * locate_part(LISTID parts, const char * partdesc) -{ - LNODEID ln1; +AVRPART *locate_part(const LISTID parts, const char *partdesc) { AVRPART * p = NULL; - int found; + int found = 0; if(!parts || !partdesc) return NULL; - found = 0; - - for (ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) { + for (LNODEID ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) { p = ldata(ln1); if ((strcasecmp(partdesc, p->id) == 0) || (strcasecmp(partdesc, p->desc) == 0)) found = 1; } - if (found) - return p; - - return NULL; + return found? p: NULL; } -AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode) -{ - LNODEID ln1; - AVRPART * p = NULL; - - for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) { - p = ldata(ln1); - if (p->avr910_devcode == devcode) - return p; - } - - return NULL; -} - -AVRPART * locate_part_by_signature(LISTID parts, unsigned char * sig, - int sigsize) -{ - LNODEID ln1; - AVRPART * p = NULL; - int i; - - if (sigsize == 3) { - for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) { - p = ldata(ln1); - for (i=0; i<3; i++) - if (p->signature[i] != sig[i]) - break; - if (i == 3) +AVRPART *locate_part_by_avr910_devcode(const LISTID parts, int devcode) { + if(parts) + for (LNODEID ln1=lfirst(parts); ln1; ln1=lnext(ln1)) { + AVRPART * p = ldata(ln1); + if (p->avr910_devcode == devcode) + return p; + } + + return NULL; +} + +AVRPART *locate_part_by_signature(const LISTID parts, unsigned char *sig, int sigsize) { + if(parts && sigsize == 3) + for(LNODEID ln1=lfirst(parts); ln1; ln1=lnext(ln1)) { + AVRPART *p = ldata(ln1); + int i; + for(i=0; i<3; i++) + if(p->signature[i] != sig[i]) + break; + if(i == 3) return p; } - } return NULL; } @@ -841,12 +740,11 @@ void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie) /* * Compare function to sort the list of programmers */ -static int sort_avrparts_compare(AVRPART * p1,AVRPART * p2) -{ - if(p1 == NULL || p2 == NULL) { +static int sort_avrparts_compare(const AVRPART *p1, const AVRPART *p2) { + if(p1 == NULL || p1->desc == NULL || p2 == NULL || p2->desc == NULL) return 0; - } - return strncasecmp(p1->desc,p2->desc,AVR_DESCLEN); + + return strcasecmp(p1->desc, p2->desc); } /* @@ -868,9 +766,7 @@ static char * reset_disp_str(int r) } -void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose) -{ - int i; +void avr_display(FILE *f, const AVRPART *p, const char *prefix, int verbose) { char * buf; const char * px; LNODEID ln; @@ -905,23 +801,17 @@ void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose) fprintf( f, "%sMemory Detail :\n\n", prefix); px = prefix; - i = strlen(prefix) + 5; - buf = (char *)malloc(i); - if (buf == NULL) { - /* ugh, this is not important enough to bail, just ignore it */ - } - else { - strcpy(buf, prefix); - strcat(buf, " "); - px = buf; - } + buf = (char *)cfg_malloc("avr_display()", strlen(prefix) + 5); + strcpy(buf, prefix); + strcat(buf, " "); + px = buf; + + if (verbose <= 2) + avr_mem_display(px, f, NULL, p, verbose); - if (verbose <= 2) { - avr_mem_display(px, f, NULL, p, 0, verbose); - } for (ln=lfirst(p->mem); ln; ln=lnext(ln)) { m = ldata(ln); - avr_mem_display(px, f, m, p, i, verbose); + avr_mem_display(px, f, m, p, verbose); } if (buf) diff --git a/src/config.c b/src/config.c index f0b65822..ac712b17 100644 --- a/src/config.c +++ b/src/config.c @@ -83,13 +83,24 @@ int init_config(void) void *cfg_malloc(const char *funcname, size_t n) { void *ret = malloc(n); if(!ret) { - avrdude_message(MSG_INFO, "%s: out of memory in %s\n", progname, funcname); + avrdude_message(MSG_INFO, "%s: out of memory in %s (needed %lu bytes)\n", progname, funcname, (unsigned long) n); exit(1); } memset(ret, 0, n); return ret; } +void *cfg_realloc(const char *funcname, void *p, size_t n) { + void *ret; + + if(!(ret = p? realloc(p, n): calloc(1, n))) { + avrdude_message(MSG_INFO, "%s: out of memory in %s (needed %lu bytes)\n", progname, funcname, (unsigned long) n); + exit(1); + } + + return ret; +} + char *cfg_strdup(const char *funcname, const char *s) { char *ret = strdup(s); @@ -323,35 +334,45 @@ int read_config(const char * file) } -// Linear-search cache for a few often-referenced strings -const char *cache_string(const char *file) { - static char **fnames; - static int n=0; +// Adapted version of a neat empirical hash function from comp.lang.c by Daniel Bernstein +unsigned strhash(const char *str) { + unsigned c, hash = 5381, n = 0; - if(!file) - return NULL; + while((c = (unsigned char) *str++) && n++ < 20) + hash = 33*hash ^ c; - // Exists in cache? - for(int i=0; iconfig_file = cache_string(cfg_infile); current_prog->lineno = cfg_lineno; } @@ -325,11 +321,6 @@ prog_decl : YYABORT; } current_prog = pgm_dup(pgm); - if (current_prog == NULL) { - yyerror("could not duplicate pgm instance"); - free_token($3); - YYABORT; - } current_prog->parent_id = cache_string($3->value.string); current_prog->config_file = cache_string(cfg_infile); current_prog->lineno = cfg_lineno; @@ -400,10 +391,6 @@ part_decl : K_PART { current_part = avr_new_part(); - if (current_part == NULL) { - yyerror("could not create part instance"); - YYABORT; - } current_part->config_file = cache_string(cfg_infile); current_part->lineno = cfg_lineno; } | @@ -417,11 +404,6 @@ part_decl : } current_part = avr_dup_part(parent_part); - if (current_part == NULL) { - yyerror("could not duplicate part instance"); - free_token($3); - YYABORT; - } current_part->parent_id = cache_string($3->value.string); current_part->config_file = cache_string(cfg_infile); current_part->lineno = cfg_lineno; @@ -465,8 +447,7 @@ prog_parm : prog_parm_conntype | K_DESC TKN_EQUAL TKN_STRING { - strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN); - current_prog->desc[PGM_DESCLEN-1] = 0; + current_prog->desc = cache_string($3->value.string); free_token($3); } | K_BAUDRATE TKN_EQUAL TKN_NUMBER { @@ -686,22 +667,19 @@ retry_lines : part_parm : K_ID TKN_EQUAL TKN_STRING { - strncpy(current_part->id, $3->value.string, AVR_IDLEN); - current_part->id[AVR_IDLEN-1] = 0; + current_part->id = cache_string($3->value.string); free_token($3); } | K_DESC TKN_EQUAL TKN_STRING { - strncpy(current_part->desc, $3->value.string, AVR_DESCLEN - 1); - current_part->desc[AVR_DESCLEN-1] = 0; + current_part->desc = cache_string($3->value.string); free_token($3); } | K_FAMILY_ID TKN_EQUAL TKN_STRING { - strncpy(current_part->family_id, $3->value.string, AVR_FAMILYIDLEN); - current_part->family_id[AVR_FAMILYIDLEN] = 0; + current_part->family_id = cache_string($3->value.string); free_token($3); } | @@ -1289,13 +1267,8 @@ part_parm : { /* select memory for extension or create if not there */ AVRMEM *mem = avr_locate_mem_noalias(current_part, $2->value.string); if(!mem) { - if(!(mem = avr_new_memtype())) { - yyerror("could not create mem instance"); - free_token($2); - YYABORT; - } - strncpy(mem->desc, $2->value.string, AVR_MEMDESCLEN - 1); - mem->desc[AVR_MEMDESCLEN-1] = 0; + mem = avr_new_memtype(); + mem->desc = cache_string($2->value.string); ladd(current_part->mem, mem); } avr_add_mem_order($2->value.string); @@ -1339,11 +1312,6 @@ part_parm : opnum = which_opcode($1); if (opnum < 0) YYABORT; op = avr_new_opcode(); - if (op == NULL) { - yyerror("could not create opcode instance"); - free_token($1); - YYABORT; - } if(0 != parse_cmdbits(op, opnum)) YYABORT; if (current_part->op[opnum] != NULL) { @@ -1500,11 +1468,6 @@ mem_spec : opnum = which_opcode($1); if (opnum < 0) YYABORT; op = avr_new_opcode(); - if (op == NULL) { - yyerror("could not create opcode instance"); - free_token($1); - YYABORT; - } if(0 != parse_cmdbits(op, opnum)) YYABORT; if (current_mem->op[opnum] != NULL) { @@ -1553,10 +1516,7 @@ mem_alias : is_alias = true; alias = avr_new_memalias(); - - // alias->desc and current_mem->desc have the same length - // definition, thus no need to check for length here - strcpy(alias->desc, current_mem->desc); + alias->desc = current_mem->desc; alias->aliased_mem = existing_mem; ladd(current_part->mem_alias, alias); diff --git a/src/developer_opts.c b/src/developer_opts.c index 6cbfa4f2..f176563e 100644 --- a/src/developer_opts.c +++ b/src/developer_opts.c @@ -222,7 +222,7 @@ int dev_message(int msglvl, const char *fmt, ...) { -static int dev_part_strct_entry(bool tsv, char *col0, char *col1, char *col2, const char *name, char *cont) { +static int dev_part_strct_entry(bool tsv, const char *col0, const char *col1, const char *col2, const char *name, char *cont) { const char *n = name? name: "name_error"; const char *c = cont? cont: "cont_error"; @@ -286,23 +286,22 @@ static int intcmp(int a, int b) { // Deep copies for comparison and raw output typedef struct { + char descbuf[32]; AVRMEM base; OPCODE ops[AVR_OP_MAX]; } AVRMEMdeep; static int avrmem_deep_copy(AVRMEMdeep *d, AVRMEM *m) { - size_t len; - d->base = *m; - // Zap all bytes beyond terminating nul of desc array - len = strlen(m->desc)+1; - if(len < sizeof m->desc) - memset(d->base.desc + len, 0, sizeof m->desc - len); + // Note memory desc (name, really) is limited to 31 char here + memset(d->descbuf, 0, sizeof d->descbuf); + strncpy(d->descbuf, m->desc, sizeof d->descbuf-1); // Zap address values d->base.buf = NULL; d->base.tags = NULL; + d->base.desc = NULL; for(int i=0; ibase.op[i] = NULL; @@ -334,6 +333,9 @@ static int memorycmp(AVRMEM *m1, AVRMEM *m2) { typedef struct { + char descbuf[64]; + char idbuf[32]; + char family_idbuf[16]; AVRPART base; OPCODE ops[AVR_OP_MAX]; AVRMEMdeep mems[40]; @@ -341,7 +343,7 @@ typedef struct { static int avrpart_deep_copy(AVRPARTdeep *d, AVRPART *p) { AVRMEM *m; - size_t len, di; + size_t di; memset(d, 0, sizeof *d); @@ -351,20 +353,21 @@ static int avrpart_deep_copy(AVRPARTdeep *d, AVRPART *p) { d->base.config_file = NULL; d->base.lineno = 0; - // Zap all bytes beyond terminating nul of desc, id and family_id array - len = strlen(p->desc); - if(len < sizeof p->desc) - memset(d->base.desc + len, 0, sizeof p->desc - len); - - len = strlen(p->family_id); - if(len < sizeof p->family_id) - memset(d->base.family_id + len, 0, sizeof p->family_id - len); - - len = strlen(p->id); - if(len < sizeof p->id) - memset(d->base.id + len, 0, sizeof p->id - len); + // Copy over desc, id, and family_id + memset(d->descbuf, 0, sizeof d->descbuf); + if(d->descbuf) + strncpy(d->descbuf, p->desc, sizeof d->descbuf-1); + memset(d->idbuf, 0, sizeof d->idbuf); + if(d->idbuf) + strncpy(d->idbuf, p->id, sizeof d->idbuf-1); + memset(d->family_idbuf, 0, sizeof d->family_idbuf); + if(d->family_idbuf) + strncpy(d->family_idbuf, p->family_id, sizeof d->family_idbuf-1); // Zap address values + d->base.desc = NULL; + d->base.id = NULL; + d->base.family_id = NULL; d->base.mem = NULL; d->base.mem_alias = NULL; for(int i=0; i ' ' && in < 0x7f? in: '.'; + return in == 0? '.': in > ' ' && in < 0x7f? in: '_'; } static void dev_raw_dump(const char *p, int nbytes, const char *name, const char *sub, int idx) { int n = (nbytes + 31)/32; for(int i=0; idesc, "ops", 1); for(int i=0; idesc, dp.mems[i].base.desc, i+2); + dev_raw_dump((char *) (dp.mems+i), sizeof dp.mems[i], part->desc, dp.mems[i].descbuf, i+2); } @@ -680,7 +683,10 @@ void dev_output_part_defs(char *partdesc) { avr_add_mem_order(((AVRMEM_ALIAS *) ldata(lnm))->desc); } - nprinted = dev_nprinted; + if((nprinted = dev_nprinted)) { + dev_info("\n"); + nprinted = dev_nprinted; + } for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) { AVRPART *p = ldata(ln1); int flashsize, flashoffset, flashpagesize, eepromsize , eepromoffset, eeprompagesize; @@ -914,6 +920,8 @@ static void dev_pgm_raw(PROGRAMMER *pgm) { for(idx=0, ln=lfirst(dp.hvupdi_support); ln; ln=lnext(ln)) dev_raw_dump(ldata(ln), sizeof(int), id, "hvupdi_", idx++); + if(dp.desc) + dev_raw_dump(dp.desc, strlen(dp.desc)+1, id, "desc", 0); // Dump cache_string values if(dp.usbdev && *dp.usbdev) dev_raw_dump(dp.usbdev, strlen(dp.usbdev)+1, id, "usbdev", 0); @@ -925,14 +933,13 @@ static void dev_pgm_raw(PROGRAMMER *pgm) { dev_raw_dump(dp.usbproduct, strlen(dp.usbproduct)+1, id, "usbprod", 0); // Zap all bytes beyond terminating nul of desc, type and port array - if((len = strlen(dp.desc)+1) < sizeof dp.desc) - memset(dp.desc + len, 0, sizeof dp.desc - len); if((len = strlen(dp.type)+1) < sizeof dp.type) memset(dp.type + len, 0, sizeof dp.type - len); if((len = strlen(dp.port)+1) < sizeof dp.port) memset(dp.port + len, 0, sizeof dp.port - len); // Zap address values + dp.desc = NULL; dp.id = NULL; dp.parent_id = NULL; dp.initpgm = NULL; diff --git a/src/jtagmkI.c b/src/jtagmkI.c index e5d3d5d8..2e84eb5c 100644 --- a/src/jtagmkI.c +++ b/src/jtagmkI.c @@ -609,7 +609,7 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p) if (jtagmkI_reset(pgm) < 0) return -1; - strcpy(hfuse.desc, "hfuse"); + hfuse.desc = cache_string("hfuse"); if (jtagmkI_read_byte(pgm, p, &hfuse, 1, &b) < 0) return -1; if ((b & OCDEN) != 0) diff --git a/src/jtagmkII.c b/src/jtagmkII.c index 7181d186..f52f3bc3 100644 --- a/src/jtagmkII.c +++ b/src/jtagmkII.c @@ -1439,7 +1439,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p) } if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI))) { - strcpy(hfuse.desc, "hfuse"); + hfuse.desc = cache_string("hfuse"); if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0) return -1; if ((b & OCDEN) != 0) diff --git a/src/lexer.l b/src/lexer.l index 23fd2277..47c3cb25 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -45,8 +45,6 @@ DIGIT [0-9] HEXDIGIT [0-9a-fA-F] SIGN [+-] -%x incl -%x comment %option nounput /* Bump resources for classic lex. */ @@ -73,16 +71,12 @@ SIGN [+-] 0x{HEXDIGIT}+ { yylval = hexnumber(yytext); return TKN_NUMBER; } -# { /* The following captures all '#' style comments to end of line */ - BEGIN(comment); } -[^\n]*\n+ { /* eat comments */ - capture_comment_char('#'); +#[^\n]*\n+ { /* record and skip # comments */ + capture_comment_str(yytext); for(int i=0; yytext[i]; i++) { - capture_comment_char(yytext[i]); if(yytext[i] == '\n') cfg_lineno++; } - BEGIN(INITIAL); } diff --git a/src/libavrdude.h b/src/libavrdude.h index 3c2f2a57..cbbc8a79 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -203,8 +203,6 @@ typedef struct opcode { #define HV_UPDI_VARIANT_1 1 /* Dedicated UPDI pin, no HV (megaAVR0/AVR-Dx) */ #define HV_UPDI_VARIANT_2 2 /* Shared UPDI pin, HV on _RESET (AVR-Ex) */ -#define AVR_DESCLEN 64 -#define AVR_IDLEN 32 #define AVR_FAMILYIDLEN 7 #define AVR_SIBLEN 16 #define CTL_STACK_SIZE 32 @@ -215,10 +213,10 @@ typedef struct opcode { /* Any changes here, please also reflect in dev_part_strct() of developer_opts.c */ typedef struct avrpart { - char desc[AVR_DESCLEN]; /* long part name */ - char id[AVR_IDLEN]; /* short part name */ + const char * desc; /* long part name */ + const char * id; /* short part name */ const char * parent_id; /* parent id if set, for -p.../s */ - char family_id[AVR_FAMILYIDLEN+1]; /* family id in the SIB (avr8x) */ + const char * family_id; /* family id in the SIB (avr8x) */ int hvupdi_variant; /* HV pulse on UPDI pin, no pin or RESET pin */ int stk500_devcode; /* stk500 device code */ int avr910_devcode; /* avr910 device code */ @@ -286,7 +284,7 @@ typedef struct avrpart { #define AVR_MEMDESCLEN 64 typedef struct avrmem { - char desc[AVR_MEMDESCLEN]; /* memory description ("flash", "eeprom", etc) */ + const char *desc; /* memory description ("flash", "eeprom", etc) */ int paged; /* page addressed (e.g. ATmega flash) */ int size; /* total memory size in bytes */ int page_size; /* size of memory page (if page addressed) */ @@ -312,7 +310,7 @@ typedef struct avrmem { } AVRMEM; typedef struct avrmem_alias { - char desc[AVR_MEMDESCLEN]; /* alias name ("syscfg0" etc.) */ + const char *desc; /* alias name ("syscfg0" etc.) */ AVRMEM *aliased_mem; } AVRMEM_ALIAS; @@ -330,8 +328,8 @@ int avr_set_bits(OPCODE * op, unsigned char * cmd); int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr); int avr_set_addr_mem(AVRMEM *mem, int opnum, unsigned char *cmd, unsigned long addr); int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data); -int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data); -int avr_get_output_index(OPCODE * op); +int avr_get_output(const OPCODE *op, const unsigned char *res, unsigned char *data); +int avr_get_output_index(const OPCODE *op); char cmdbitchar(CMDBIT cb); char *cmdbitstr(CMDBIT cb); const char *opcodename(int opnum); @@ -340,26 +338,26 @@ char *opcode2str(OPCODE *op, int opnum, int detailed); /* Functions for AVRMEM structures */ AVRMEM * avr_new_memtype(void); AVRMEM_ALIAS * avr_new_memalias(void); -int avr_initmem(AVRPART * p); -AVRMEM * avr_dup_mem(AVRMEM * m); +int avr_initmem(const AVRPART *p); +AVRMEM * avr_dup_mem(const AVRMEM *m); void avr_free_mem(AVRMEM * m); void avr_free_memalias(AVRMEM_ALIAS * m); -AVRMEM * avr_locate_mem(AVRPART * p, const char * desc); -AVRMEM * avr_locate_mem_noalias(AVRPART * p, const char * desc); -AVRMEM_ALIAS * avr_locate_memalias(AVRPART * p, const char * desc); -AVRMEM_ALIAS * avr_find_memalias(AVRPART * p, AVRMEM * m_orig); -void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p, - int type, int verbose); +AVRMEM * avr_locate_mem(const AVRPART *p, const char *desc); +AVRMEM * avr_locate_mem_noalias(const AVRPART *p, const char *desc); +AVRMEM_ALIAS * avr_locate_memalias(const AVRPART *p, const char *desc); +AVRMEM_ALIAS * avr_find_memalias(const AVRPART *p, const AVRMEM *m_orig); +void avr_mem_display(const char *prefix, FILE *f, const AVRMEM *m, + const AVRPART *p, int verbose); /* Functions for AVRPART structures */ AVRPART * avr_new_part(void); -AVRPART * avr_dup_part(AVRPART * d); +AVRPART * avr_dup_part(const AVRPART *d); void avr_free_part(AVRPART * d); -AVRPART * locate_part(LISTID parts, const char * partdesc); -AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode); -AVRPART * locate_part_by_signature(LISTID parts, unsigned char * sig, +AVRPART * locate_part(const LISTID parts, const char *partdesc); +AVRPART * locate_part_by_avr910_devcode(const LISTID parts, int devcode); +AVRPART * locate_part_by_signature(const LISTID parts, unsigned char *sig, int sigsize); -void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose); +void avr_display(FILE *f, const AVRPART *p, const char *prefix, int verbose); typedef void (*walk_avrparts_cb)(const char *name, const char *desc, const char *cfgname, int cfglineno, @@ -653,7 +651,6 @@ extern struct serial_device usbhid_serdev; #define ON 1 #define OFF 0 -#define PGM_DESCLEN 80 #define PGM_PORTLEN PATH_MAX #define PGM_TYPELEN 32 @@ -685,7 +682,7 @@ typedef enum { /* Any changes here, please also reflect in dev_pgm_strct() of developer_opts.c */ typedef struct programmer_t { LISTID id; - char desc[PGM_DESCLEN]; + const char *desc; void (*initpgm)(struct programmer_t *pgm); const char *parent_id; // Used by developer options -c*/[sr...] struct pindef_t pin[N_PINS]; @@ -762,6 +759,7 @@ typedef struct programmer_t { int (*parseextparams) (struct programmer_t * pgm, LISTID xparams); void (*setup) (struct programmer_t * pgm); void (*teardown) (struct programmer_t * pgm); + const char *config_file; // Config file where defined int lineno; // Config file line number void *cookie; // For private use by the programmer @@ -773,8 +771,8 @@ extern "C" { #endif PROGRAMMER * pgm_new(void); -PROGRAMMER * pgm_dup(const PROGRAMMER * const src); -void pgm_free(PROGRAMMER * const p); +PROGRAMMER * pgm_dup(const PROGRAMMER *src); +void pgm_free(PROGRAMMER *p); void programmer_display(PROGRAMMER * pgm, const char * p); @@ -783,10 +781,10 @@ void programmer_display(PROGRAMMER * pgm, const char * p); #define SHOW_PPI_PINS ((1<read_sib(pgm, p, sib); avrdude_message(MSG_NOTICE, "%s: System Information Block: \"%s\"\n", progname, sib); - if (quell_progress < 2) { + if (quell_progress < 2) avrdude_message(MSG_INFO, "%s: Received FamilyID: \"%.*s\"\n", progname, AVR_FAMILYIDLEN, sib); - } + if (strncmp(p->family_id, sib, AVR_FAMILYIDLEN)) { avrdude_message(MSG_INFO, "%s: Expected FamilyID: \"%s\"\n", progname, p->family_id); if (!ovsigck) { @@ -1093,9 +1093,8 @@ int main(int argc, char * argv []) avrdude_message(MSG_INFO, "%s: conflicting -e and -n options specified, NOT erasing chip\n", progname); } else { - if (quell_progress < 2) { + if (quell_progress < 2) avrdude_message(MSG_INFO, "%s: erasing chip\n", progname); - } exitrc = avr_unlock(pgm, p); if(exitrc) goto main_exit; goto sig_again; @@ -1229,9 +1228,8 @@ int main(int argc, char * argv []) avrdude_message(MSG_INFO, "%s: conflicting -e and -n options specified, NOT erasing chip\n", progname); } else { - if (quell_progress < 2) { + if (quell_progress < 2) avrdude_message(MSG_INFO, "%s: erasing chip\n", progname); - } exitrc = avr_chip_erase(pgm, p); if(exitrc) goto main_exit; } diff --git a/src/pgm.c b/src/pgm.c index 07cbed57..518b208e 100644 --- a/src/pgm.c +++ b/src/pgm.c @@ -61,31 +61,29 @@ static void pgm_default_powerup_powerdown (struct programmer_t * pgm) } -PROGRAMMER * pgm_new(void) -{ - int i; - PROGRAMMER * pgm; +PROGRAMMER *pgm_new(void) { + PROGRAMMER *pgm = (PROGRAMMER *) cfg_malloc("pgm_new()", sizeof(*pgm)); const char *nulp = cache_string(""); - pgm = (PROGRAMMER *) cfg_malloc("pgm_new()", sizeof(*pgm)); - + // Initialise const char * and LISTID entities pgm->id = lcreat(NULL, 0); pgm->usbpid = lcreat(NULL, 0); - pgm->desc[0] = 0; - pgm->type[0] = 0; - pgm->parent_id = nulp; - pgm->config_file = nulp; - pgm->lineno = 0; - pgm->baudrate = 0; - pgm->initpgm = NULL; pgm->hvupdi_support = lcreat(NULL, 0); - + pgm->desc = nulp; + pgm->parent_id = nulp; pgm->usbdev = nulp; pgm->usbsn = nulp; pgm->usbvendor = nulp; pgm->usbproduct = nulp; + pgm->config_file = nulp; - for (i=0; iinitpgm = NULL; + pgm->lineno = 0; + pgm->baudrate = 0; + + // Clear pin array + for(int i=0; ipinno[i] = 0; pin_clear_all(&(pgm->pin[i])); } @@ -121,49 +119,70 @@ PROGRAMMER * pgm_new(void) * optional functions - these are checked to make sure they are * assigned before they are called */ + pgm->unlock = NULL; pgm->cmd = NULL; pgm->cmd_tpi = NULL; pgm->spi = NULL; pgm->paged_write = NULL; pgm->paged_load = NULL; + pgm->page_erase = NULL; pgm->write_setup = NULL; pgm->read_sig_bytes = NULL; + pgm->read_sib = NULL; + pgm->print_parms = NULL; pgm->set_vtarget = NULL; pgm->set_varef = NULL; pgm->set_fosc = NULL; + pgm->set_sck_period = NULL; + pgm->setpin = NULL; + pgm->getpin = NULL; + pgm->highpulsepin = NULL; + pgm->parseexitspecs = NULL; pgm->perform_osccal = NULL; pgm->parseextparams = NULL; pgm->setup = NULL; pgm->teardown = NULL; + // For allocating "global" memory by the programmer + pgm->cookie = NULL; + return pgm; } -void pgm_free(PROGRAMMER * const p) -{ - ldestroy_cb(p->id, free); - ldestroy_cb(p->usbpid, free); - p->id = NULL; - p->usbpid = NULL; - /* do not free p->parent_id, p->config_file, p->usbdev, p->usbsn, p->usbvendor or p-> usbproduct */ - /* p->cookie is freed by pgm_teardown */ - free(p); +void pgm_free(PROGRAMMER *p) { + if(p) { + ldestroy_cb(p->id, free); + ldestroy_cb(p->usbpid, free); + ldestroy_cb(p->hvupdi_support, free); + p->id = NULL; + p->usbpid = NULL; + p->hvupdi_support = NULL; + // Never free const char *, eg, p->desc, which are set by cache_string() + // p->cookie is freed by pgm_teardown + free(p); + } } -PROGRAMMER * pgm_dup(const PROGRAMMER * const src) -{ - PROGRAMMER * pgm; - LNODEID ln; +PROGRAMMER *pgm_dup(const PROGRAMMER *src) { + PROGRAMMER *pgm = pgm_new(); - pgm = (PROGRAMMER *) cfg_malloc("pgm_dup()", sizeof(*pgm)); - memcpy(pgm, src, sizeof(*pgm)); + if(src) { + memcpy(pgm, src, sizeof(*pgm)); + pgm->id = lcreat(NULL, 0); + pgm->usbpid = lcreat(NULL, 0); + pgm->hvupdi_support = lcreat(NULL, 0); - pgm->id = lcreat(NULL, 0); - pgm->usbpid = lcreat(NULL, 0); - for (ln = lfirst(src->usbpid); ln; ln = lnext(ln)) { - int *ip = cfg_malloc("pgm_dup()", sizeof(int)); - *ip = *(int *) ldata(ln); - ladd(pgm->usbpid, ip); + // Leave id list empty but copy usbpid and hvupdi_support over + for(LNODEID ln = lfirst(src->hvupdi_support); ln; ln = lnext(ln)) { + int *ip = cfg_malloc("pgm_dup()", sizeof(int)); + *ip = *(int *) ldata(ln); + ladd(pgm->hvupdi_support, ip); + } + for(LNODEID ln = lfirst(src->usbpid); ln; ln = lnext(ln)) { + int *ip = cfg_malloc("pgm_dup()", sizeof(int)); + *ip = *(int *) ldata(ln); + ladd(pgm->usbpid, ip); + } } return pgm; @@ -207,8 +226,7 @@ static void pgm_default_6 (struct programmer_t * pgm, const char * p) } -void programmer_display(PROGRAMMER * pgm, const char * p) -{ +void programmer_display(PROGRAMMER *pgm, const char * p) { avrdude_message(MSG_INFO, "%sProgrammer Type : %s\n", p, pgm->type); avrdude_message(MSG_INFO, "%sDescription : %s\n", p, pgm->desc); @@ -216,8 +234,7 @@ void programmer_display(PROGRAMMER * pgm, const char * p) } -void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show) -{ +void pgm_display_generic_mask(const PROGRAMMER *pgm, const char *p, unsigned int show) { if(show & (1<pin[PPI_AVR_VCC])); if(show & (1<pin[PIN_LED_VFY])); } -void pgm_display_generic(PROGRAMMER * pgm, const char * p) -{ +void pgm_display_generic(const PROGRAMMER *pgm, const char *p) { pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS); } -PROGRAMMER * locate_programmer(LISTID programmers, const char * configid) -{ - LNODEID ln1, ln2; - PROGRAMMER * p = NULL; - const char * id; - int found; +PROGRAMMER *locate_programmer(const LISTID programmers, const char *configid) { + PROGRAMMER *p = NULL; + int found = 0; - found = 0; - - for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) { + for(LNODEID ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) { p = ldata(ln1); - for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) { - id = ldata(ln2); - if (strcasecmp(configid, id) == 0) + for(LNODEID ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) + if(strcasecmp(configid, (const char *) ldata(ln2)) == 0) found = 1; - } } - if (found) - return p; - - return NULL; + return found? p: NULL; } /* @@ -296,16 +302,11 @@ void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie) /* * Compare function to sort the list of programmers */ -static int sort_programmer_compare(PROGRAMMER * p1,PROGRAMMER * p2) -{ - char* id1; - char* id2; - if(p1 == NULL || p2 == NULL) { +static int sort_programmer_compare(const PROGRAMMER *p1, const PROGRAMMER *p2) { + if(p1 == NULL || p1->id == NULL || p2 == NULL || p2->id == NULL) return 0; - } - id1 = ldata(lfirst(p1->id)); - id2 = ldata(lfirst(p2->id)); - return strncasecmp(id1,id2,AVR_IDLEN); + + return strcasecmp(ldata(lfirst(p1->id)), ldata(lfirst(p2->id))); } /* diff --git a/src/pickit2.c b/src/pickit2.c index ac3781f5..a1d32f88 100644 --- a/src/pickit2.c +++ b/src/pickit2.c @@ -193,16 +193,18 @@ static int pickit2_open(PROGRAMMER * pgm, char * port) } else { - // get the device description while we're at it - short buff[PGM_DESCLEN-1], i; - HidD_GetProductString(PDATA(pgm)->usb_handle, buff, PGM_DESCLEN-1); + // Get the device description while we're at it and overlay it on pgm->desc + short wbuf[80-1]; + char *cbuf = cfg_malloc("pickit2_open()", sizeof wbuf/sizeof*wbuf + (pgm->desc? strlen(pgm->desc): 0) + 2); + HidD_GetProductString(PDATA(pgm)->usb_handle, wbuf, sizeof wbuf/sizeof*wbuf); - // convert from wide chars, but do not overwrite trailing '\0' - memset(&(pgm->desc), 0, PGM_DESCLEN); - for (i = 0; i < (PGM_DESCLEN-1) && buff[i]; i++) - { - pgm->desc[i] = (char)buff[i]; // TODO what about little/big endian??? - } + if(pgm->desc && *pgm->desc) + strcpy(cbuf, pgm->desc); + + // Convert from wide chars and overlay over initial part of desc + for (int i = 0; i < sizeof wbuf/sizeof*wbuf && wbuf[i]; i++) + cbuf[i] = (char) wbuf[i]; // TODO what about little/big endian??? + pgm->desc = cache_string(cbuf); } #else if (usb_open_device(&(PDATA(pgm)->usb_handle), PICKIT2_VID, PICKIT2_PID) < 0) diff --git a/src/update.c b/src/update.c index 972c3847..f3dbd335 100644 --- a/src/update.c +++ b/src/update.c @@ -306,11 +306,11 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f return LIBAVRDUDE_SOFTFAIL; } - AVRMEM_ALIAS * alias_mem = avr_find_memalias(p, mem); - char alias_mem_desc[AVR_DESCLEN + 1] = ""; - if(alias_mem) { - strcat(alias_mem_desc, "/"); - strcat(alias_mem_desc, alias_mem->desc); + AVRMEM_ALIAS *alias_mem = avr_find_memalias(p, mem); + char *alias_mem_desc = cfg_malloc("do_op()", 2 + (alias_mem && alias_mem->desc? strlen(alias_mem->desc): 0)); + if(alias_mem && alias_mem->desc && *alias_mem->desc) { + *alias_mem_desc = '/'; + strcpy(alias_mem_desc+1, alias_mem->desc); } switch (upd->op) {