From c2c9053b1388bfbb03c947e05be63bfe036c26bc Mon Sep 17 00:00:00 2001 From: Stefan Rueger Date: Fri, 12 Aug 2022 00:28:54 +0100 Subject: [PATCH] Show comments with -p*/s or -c*/s and reduce -p */r raw output --- src/config.c | 100 +++++++++++++- src/config.h | 21 ++- src/config_gram.y | 41 +++--- src/developer_opts.c | 239 ++++++++++++++++++++++++++------- src/developer_opts.h | 1 + src/developer_opts_private.h | 49 +++---- src/lexer.l | 252 ++++++++++++++++++----------------- src/libavrdude.h | 7 +- src/main.c | 26 ++-- 9 files changed, 505 insertions(+), 231 deletions(-) diff --git a/src/config.c b/src/config.c index ac712b17..d36e0814 100644 --- a/src/config.c +++ b/src/config.c @@ -371,10 +371,98 @@ const char *cache_string(const char *p) { return hstrings[h][k] = cfg_strdup("cache_string()", p); } -// Captures comments during parsing -void capture_comment_str(const char *p) { + +static LISTID cfg_comms; // A chain of comment lines +static LISTID cfg_prologue; // Comment lines at start of avrdude.conf +static char *lkw; // Last seen keyword +static int lkw_lineno; // Line number of that + +static LISTID cfg_strctcomms; // Passed on to config_gram.y +static LISTID cfg_pushedcomms; // Temporarily pushed main comments +static int cfg_pushed; // ... for memory sections + +COMMENT *locate_comment(const LISTID comments, const char *where, int rhs) { + if(comments) + for(LNODEID ln=lfirst(comments); ln; ln=lnext(ln)) { + COMMENT *n = ldata(ln); + if(n && rhs == n->rhs && n->kw && strcmp(where, n->kw) == 0) + return n; + } + + return NULL; } +static void addcomment(int rhs) { + if(lkw) { + COMMENT *node = cfg_malloc("addcomment()", sizeof(*node)); + node->rhs = rhs; + node->kw = cfg_strdup("addcomment()", lkw); + node->comms = cfg_comms; + cfg_comms = NULL; + if(!cfg_strctcomms) + cfg_strctcomms = lcreat(NULL, 0); + ladd(cfg_strctcomms, node); + } +} + +// Capture prologue during parsing (triggered by lexer.l) +void cfg_capture_prologue(void) { + cfg_prologue = cfg_comms; + cfg_comms = NULL; +} + +LISTID cfg_get_prologue(void) { + return cfg_prologue; +} + +// Captures comments during parsing +void capture_comment_str(const char *com, int lineno) { + if(!cfg_comms) + cfg_comms = lcreat(NULL, 0); + ladd(cfg_comms, cfg_strdup("capture_comment_str()", com)); + + // Last keyword lineno is the same as this comment's + if(lkw && lkw_lineno == lineno) + addcomment(1); // Register comms to show right of lkw = ...; +} + +// Capture assignments (keywords left of =) and associate comments to them +void capture_lvalue_kw(const char *kw, int lineno) { + if(!strcmp(kw, "memory")) { // Push part comments and start memory comments + if(!cfg_pushed) { // config_gram.y pops the part comments + cfg_pushed = 1; + cfg_pushedcomms = cfg_strctcomms; + cfg_strctcomms = NULL; + } + } + + if(!strcmp(kw, "programmer") || !strcmp(kw, "part") || !strcmp(kw, "memory")) + kw = "*"; // Show comment before programmer/part/memory + + if(lkw) + free(lkw); + lkw = cfg_strdup("capture_lvalue_kw()", kw); + lkw_lineno = lineno; + if(cfg_comms) // Accrued list of # one-line comments + addcomment(0); // Register comment to appear before lkw assignment +} + +// config_gram.y calls this once for each programmer/part/memory structure +LISTID cfg_move_comments(void) { + capture_lvalue_kw(";", -1); + + LISTID ret = cfg_strctcomms; + cfg_strctcomms = NULL; + return ret; +} + +// config_gram.y calls this after ingressing the memory structure +void cfg_pop_comms(void) { + if(cfg_pushed) { + cfg_pushed = 0; + cfg_strctcomms = cfg_pushedcomms; + } +} // Convert the next n hex digits of s to a hex number static unsigned int tohex(const unsigned char *s, unsigned int n) { @@ -558,12 +646,12 @@ char *cfg_unescape(char *d, const char *s) { return (char *) cfg_unescapeu((unsigned char *) d, (const unsigned char *) s); } -// Return an escaped string that looks like a C-style input string incl quotes, memory is malloc()ed +// Return an escaped string that looks like a C-style input string incl quotes, memory is malloc'd char *cfg_escape(const char *s) { - char *ret = (char *) cfg_malloc("cfg_escape()", 4*strlen(s)+2+3), *d = ret; + char buf[50*1024], *d = buf; *d++ = '"'; - for(; *s; s++) { + for(; *s && d-buf < sizeof buf-7; s++) { switch(*s) { case '\n': *d++ = '\\'; *d++ = 'n'; @@ -602,5 +690,5 @@ char *cfg_escape(const char *s) { *d++ = '"'; *d = 0; - return ret; + return cfg_strdup("cfg_escape()", buf); } diff --git a/src/config.h b/src/config.h index afd39b17..b8bd2031 100644 --- a/src/config.h +++ b/src/config.h @@ -30,6 +30,13 @@ #endif +typedef struct { + char *kw; // Keyword near the comments + LISTID comms; // Chained list of comments + int rhs; // Comments to print rhs of keyword line +} COMMENT; + + enum { V_NONE, V_NUM, V_NUM_REAL, V_STR }; typedef struct value_t { int type; @@ -94,7 +101,19 @@ void print_token(TOKEN *tkn); void pyytext(void); -void capture_comment_str(const char *str); +COMMENT *locate_comment(const LISTID comments, const char *where, int rhs); + +void cfg_capture_prologue(void); + +LISTID cfg_get_prologue(void); + +void capture_comment_str(const char *com, int lineno); + +void capture_lvalue_kw(const char *kw, int lineno); + +LISTID cfg_move_comments(void); + +void cfg_pop_comms(void); #ifdef __cplusplus } diff --git a/src/config_gram.y b/src/config_gram.y index 2a027c7f..2c3504f2 100644 --- a/src/config_gram.y +++ b/src/config_gram.y @@ -297,6 +297,7 @@ prog_def : lrmv_d(programmers, existing_prog); pgm_free(existing_prog); } + current_prog->comments = cfg_move_comments(); LISTADD(programmers, current_prog); // pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed // pgm_display_generic(current_prog, id); @@ -322,6 +323,7 @@ prog_decl : } current_prog = pgm_dup(pgm); current_prog->parent_id = cache_string($3->value.string); + current_prog->comments = NULL; current_prog->config_file = cache_string(cfg_infile); current_prog->lineno = cfg_lineno; free_token($3); @@ -341,32 +343,33 @@ part_def : YYABORT; } - /* - * perform some sanity checking, and compute the number of bits - * to shift a page for constructing the page address for - * page-addressed memories. - */ + // Sanity checks for memory sizes and compute/override num_pages entry for (ln=lfirst(current_part->mem); ln; ln=lnext(ln)) { m = ldata(ln); if (m->paged) { - if (m->page_size == 0) { - yyerror("must specify page_size for paged memory"); + if (m->size <= 0) { + yyerror("must specify a positive size for paged memory %s", m->desc); YYABORT; } - if (m->num_pages == 0) { - yyerror("must specify num_pages for paged memory"); + if (m->page_size <= 0) { + yyerror("must specify a positive page size for paged memory %s", m->desc); YYABORT; } - if (m->size != m->page_size * m->num_pages) { - yyerror("page size (%u) * num_pages (%u) = " - "%u does not match memory size (%u)", - m->page_size, - m->num_pages, - m->page_size * m->num_pages, - m->size); + // Code base relies on page_size being a power of 2 in some places + if (m->page_size & (m->page_size - 1)) { + yyerror("page size must be a power of 2 for paged memory %s", m->desc); YYABORT; } + // Code base relies on size being a multiple of page_size + if (m->size % m->page_size) { + yyerror("size must be a multiple of page size for paged memory %s", m->desc); + YYABORT; + } + // Warn if num_pages was specified but is inconsistent with size and page size + if (m->num_pages && m->num_pages != m->size / m->page_size) + yywarning("overriding num_page to be %d for memory %s", m->size/m->page_size, m->desc); + m->num_pages = m->size / m->page_size; } } @@ -382,6 +385,8 @@ part_def : lrmv_d(part_list, existing_part); avr_free_part(existing_part); } + + current_part->comments = cfg_move_comments(); LISTADD(part_list, current_part); current_part = NULL; } @@ -405,6 +410,7 @@ part_decl : current_part = avr_dup_part(parent_part); current_part->parent_id = cache_string($3->value.string); + current_part->comments = NULL; current_part->config_file = cache_string(cfg_infile); current_part->lineno = cfg_lineno; @@ -1291,7 +1297,9 @@ part_parm : yywarning("%s's %s %s misses a necessary address bit a%d", current_part->desc, current_mem->desc, opcodename(i), bn-1); } + current_mem->comments = cfg_move_comments(); } + cfg_pop_comms(); current_mem = NULL; } | K_MEMORY TKN_STRING TKN_EQUAL K_NULL @@ -1302,6 +1310,7 @@ part_parm : avr_free_mem(existing_mem); } free_token($2); + cfg_pop_comms(); current_mem = NULL; } | opcode TKN_EQUAL string_list { diff --git a/src/developer_opts.c b/src/developer_opts.c index 32d2c71e..e0c274b9 100644 --- a/src/developer_opts.c +++ b/src/developer_opts.c @@ -48,6 +48,7 @@ #include "avrdude.h" #include "libavrdude.h" +#include "config.h" #include "developer_opts.h" #include "developer_opts_private.h" @@ -221,8 +222,49 @@ int dev_message(int msglvl, const char *fmt, ...) { } +// Any of the strings in the list contains subs as substring? +int dev_has_subsstr_comms(const LISTID comms, const char *subs) { + if(comms) + for(LNODEID ln=lfirst(comms); ln; ln=lnext(ln)) + if(strstr((char *) ldata(ln), subs)) + return 1; + return 0; +} + +// Print a chained list of strings +void dev_print_comment(const LISTID comms) { + if(comms) + for(LNODEID ln=lfirst(comms); ln; ln=lnext(ln)) + dev_info("%s", (char *) ldata(ln)); +} + +// Conditional output of part, memory or programmer's comments field +static void dev_cout(const LISTID comms, const char *name, int rhs, int elself) { + COMMENT *cp; + + if((cp = locate_comment(comms, name, rhs))) + dev_print_comment(cp->comms); + else if(elself) + dev_info("\n"); +} + +// Print part->comments, mem->comments or pgm->comments (for debugging) +void dev_print_kw_comments(const LISTID comms) { + if(comms) + for(LNODEID ln=lfirst(comms); ln; ln=lnext(ln)) { + COMMENT *n = ldata(ln); + if(n && n->comms) { + dev_info(">>> %s %c\n", n->kw, n->rhs? '>': '<'); + dev_print_comment(n->comms); + } + } +} + +// Ideally all assignment outputs run via this function +static int dev_part_strct_entry(bool tsv, // Print as spreadsheet? + const char *col0, const char *col1, const char *col2, // Descriptors of item + const char *name, char *cont, const LISTID comms) { // Name, contents and comments -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"; @@ -239,8 +281,9 @@ static int dev_part_strct_entry(bool tsv, const char *col0, const char *col1, co dev_info("%s\t%s\n", n, c); } else { // Grammar conform int indent = col2 && strcmp(col2, "part"); - - printf("%*s%-*s = %s;\n", indent? 8: 4, "", indent? 15: 19, n, c); + dev_cout(comms, n, 0, 0); // Print comments before the line + dev_info("%*s%-*s = %s;", indent? 8: 4, "", indent? 15: 19, n, c); + dev_cout(comms, n, 1, 1); // Print comments on rhs } if(cont) @@ -267,14 +310,18 @@ static void dev_stack_out(bool tsv, AVRPART *p, const char *name, unsigned char if(tsv) dev_info(".pt\t%s\t%s\t", p->desc, name); - else + else { + dev_cout(p->comments, name, 0, 0); dev_info(" %-19s =%s", name, ns <=8? " ": ""); + } if(ns <= 0) - dev_info(tsv? "NULL\n": "NULL;\n"); + dev_info(tsv? "NULL\n": "NULL;"); else for(int i=0; i 8 && i%8 == 0? "\n ": "", stack[i], i+1 8 && i%8 == 0? "\n ": "", stack[i], i+1comments, name, 1, 1); } @@ -291,7 +338,7 @@ typedef struct { OPCODE ops[AVR_OP_MAX]; } AVRMEMdeep; -static int avrmem_deep_copy(AVRMEMdeep *d, AVRMEM *m) { +static int avrmem_deep_copy(AVRMEMdeep *d, const AVRMEM *m) { d->base = *m; // Note memory desc (name, really) is limited to 31 char here @@ -299,17 +346,16 @@ static int avrmem_deep_copy(AVRMEMdeep *d, AVRMEM *m) { strncpy(d->descbuf, m->desc, sizeof d->descbuf-1); // Zap address values + d->base.comments = NULL; d->base.buf = NULL; d->base.tags = NULL; d->base.desc = NULL; for(int i=0; ibase.op[i] = NULL; - // Copy over the SPI operations themselves - memset(d->base.op, 0, sizeof d->base.op); memset(d->ops, 0, sizeof d->ops); - for(size_t i=0; iops/sizeof *d->ops; i++) + for(size_t i=0; iop[i]) d->ops[i] = *m->op[i]; @@ -324,7 +370,7 @@ static int memorycmp(AVRMEM *m1, AVRMEM *m2) { if(!m1 || !m2) return m1? -1: 1; - + avrmem_deep_copy(&dm1, m1); avrmem_deep_copy(&dm2, m2); @@ -341,7 +387,7 @@ typedef struct { AVRMEMdeep mems[40]; } AVRPARTdeep; -static int avrpart_deep_copy(AVRPARTdeep *d, AVRPART *p) { +static int avrpart_deep_copy(AVRPARTdeep *d, const AVRPART *p) { AVRMEM *m; size_t di; @@ -349,6 +395,7 @@ static int avrpart_deep_copy(AVRPARTdeep *d, AVRPART *p) { d->base = *p; + d->base.comments = NULL; d->base.parent_id = NULL; d->base.config_file = NULL; d->base.lineno = 0; @@ -373,8 +420,7 @@ static int avrpart_deep_copy(AVRPARTdeep *d, AVRPART *p) { for(int i=0; ibase.op[i] = NULL; - // Copy over the SPI operations - memset(d->base.op, 0, sizeof d->base.op); + // Copy over all used SPI operations memset(d->ops, 0, sizeof d->ops); for(int i=0; iop[i]) @@ -403,7 +449,8 @@ static char txtchar(unsigned char 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) { +static void dev_raw_dump(const void *v, int nbytes, const char *name, const char *sub, int idx) { + const unsigned char *p = v; int n = (nbytes + 31)/32; for(int i=0; idesc, "part", 0); - dev_raw_dump((char *) &dp.ops, sizeof dp.ops, part->desc, "ops", 1); + dev_raw_dump(&dp.base, sizeof dp.base, part->desc, "part", 0); + for(int i=0; idesc, opsnm("part", i), 1); - for(int i=0; idesc, dp.mems[i].descbuf, i+2); + for(int i=0; idesc, nm, i+2); + dev_raw_dump(&dp.mems[i].base, sizeof dp.mems[i].base, part->desc, nm, i+2); + for(int j=0; jdesc, opsnm(nm, j), i+2); + } } static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) { - char *descstr = cfg_escape(p->desc); + COMMENT *cp; + if(!tsv) { - dev_info("#------------------------------------------------------------\n"); - dev_info("# %.*s\n", strlen(descstr+1)-1, descstr+1); - dev_info("#------------------------------------------------------------\n"); + const char *del = "#------------------------------------------------------------"; + cp = locate_comment(p->comments, "*", 0); + + if(!cp || !dev_has_subsstr_comms(cp->comms, del)) { + dev_info("%s\n", del); + dev_info("# %.*s\n", strlen(descstr)-2, descstr+1); // Remove double quotes + dev_info("%s\n\n", del); + } + if(cp) + dev_print_comment(cp->comms); + if(p->parent_id && *p->parent_id) - dev_info("\npart parent \"%s\"\n", p->parent_id); + dev_info("part parent \"%s\"\n", p->parent_id); else - dev_info("\npart\n"); + dev_info("part\n"); } _if_partout_str(strcmp, descstr, desc); @@ -548,7 +623,7 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) { for(int i=0; i < AVR_OP_MAX; i++) if(!base || opcodecmp(p->op[i], base->op[i], i)) - dev_part_strct_entry(tsv, ".ptop", p->desc, "part", opcodename(i), opcode2str(p->op[i], i, !tsv)); + dev_part_strct_entry(tsv, ".ptop", p->desc, "part", opcodename(i), opcode2str(p->op[i], i, !tsv), p->comments); for(size_t mi=0; mi < sizeof avr_mem_order/sizeof *avr_mem_order && avr_mem_order[mi]; mi++) { AVRMEM *m, *bm; @@ -569,7 +644,8 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) { if(!memorycmp(bm, m)) // Same memory bit for bit, no need to instantiate continue; - dev_info("\n memory \"%s\"\n", m->desc); + dev_cout(m->comments, "*", 0, 1); + dev_info(" memory \"%s\"\n", m->desc); } _if_memout_yn(paged); @@ -589,10 +665,12 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) { for(int i=0; i < AVR_OP_MAX; i++) if(!bm || opcodecmp(bm->op[i], m->op[i], i)) - dev_part_strct_entry(tsv, ".ptmmop", p->desc, m->desc, opcodename(i), opcode2str(m->op[i], i, !tsv)); + dev_part_strct_entry(tsv, ".ptmmop", p->desc, m->desc, opcodename(i), opcode2str(m->op[i], i, !tsv), m->comments); - if(!tsv) + if(!tsv) { + dev_cout(m->comments, ";", 0, 0); dev_info(" ;\n"); + } for(LNODEID lnm=lfirst(p->mem_alias); lnm; lnm=lnext(lnm)) { AVRMEM_ALIAS *ma = ldata(lnm); @@ -605,8 +683,37 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) { } } - if(!tsv) + if(!tsv) { + dev_cout(p->comments, ";", 0, 0); dev_info(";\n"); + } +} + + +void dev_output_pgm_part(int dev_opt_c, char *programmer, int dev_opt_p, char *partdesc) { + if(dev_opt_c == 2 && dev_opt_p == 2) { + char *p; + + dev_print_comment(cfg_get_prologue()); + + dev_info("default_programmer = %s;\n", p = cfg_escape(default_programmer)); free(p); + dev_info("default_parallel = %s;\n", p = cfg_escape(default_parallel)); free(p); + dev_info("default_serial = %s;\n", p = cfg_escape(default_serial)); free(p); + dev_info("default_spi = %s;\n", p = cfg_escape(default_spi)); free(p); + + dev_info("\n#\n# PROGRAMMER DEFINITIONS\n#\n\n"); + } + + if(dev_opt_c) + dev_output_pgm_defs(cfg_strdup("main()", programmer)); + + if(dev_opt_p == 2 && dev_opt_c) + dev_info("\n"); + if(dev_opt_p == 2) + dev_info("#\n# PART DEFINITIONS\n#\n"); + + if(dev_opt_p) + dev_output_part_defs(cfg_strdup("main()", partdesc)); } @@ -941,6 +1048,7 @@ static void dev_pgm_raw(PROGRAMMER *pgm) { // Zap address values dp.desc = NULL; dp.id = NULL; + dp.comments = NULL; dp.parent_id = NULL; dp.initpgm = NULL; dp.usbpid = NULL; @@ -968,29 +1076,38 @@ static const char *connstr(conntype_t conntype) { static void dev_pgm_strct(PROGRAMMER *pgm, bool tsv, PROGRAMMER *base) { char *id = ldata(lfirst(pgm->id)); LNODEID ln; + COMMENT *cp; int firstid; if(!tsv) { - dev_info("#------------------------------------------------------------\n"); - dev_info("# "); - for(firstid=1, ln=lfirst(pgm->id); ln; ln=lnext(ln)) { - if(!firstid) - dev_info("/"); - firstid = 0; - dev_info("%s", ldata(ln)); + const char *del = "#------------------------------------------------------------"; + cp = locate_comment(pgm->comments, "*", 0); + + if(!cp || !dev_has_subsstr_comms(cp->comms, del)) { + dev_info("%s\n# ", del); + for(firstid=1, ln=lfirst(pgm->id); ln; ln=lnext(ln)) { + if(!firstid) + dev_info("/"); + firstid = 0; + dev_info("%s", ldata(ln)); + } + dev_info("\n%s\n\n", del); } - dev_info("\n"); - dev_info("#------------------------------------------------------------\n"); + if(cp) + dev_print_comment(cp->comms); + if(pgm->parent_id && *pgm->parent_id) - dev_info("\nprogrammer parent \"%s\"\n", pgm->parent_id); + dev_info("programmer parent \"%s\"\n", pgm->parent_id); else - dev_info("\nprogrammer\n"); + dev_info("programmer\n"); } if(tsv) dev_info(".prog\t%s\tid\t", id); - else + else { + dev_cout(pgm->comments, "id", 0, 0); dev_info(" %-19s = ", "id"); + } for(firstid=1, ln=lfirst(pgm->id); ln; ln=lnext(ln)) { if(!firstid) dev_info(", "); @@ -999,7 +1116,12 @@ static void dev_pgm_strct(PROGRAMMER *pgm, bool tsv, PROGRAMMER *base) { dev_info("%s", str); free(str); } - dev_info(tsv? "\n": ";\n"); + if(tsv) + dev_info("\n"); + else { + dev_info(";"); + dev_cout(pgm->comments, "id", 1, 1); + } _if_pgmout_str(strcmp, cfg_escape(pgm->desc), desc); _pgmout_fmt("type", "\"%s\"", locate_programmer_type_id(pgm->initpgm)); @@ -1012,15 +1134,22 @@ static void dev_pgm_strct(PROGRAMMER *pgm, bool tsv, PROGRAMMER *base) { if(pgm->usbpid && lfirst(pgm->usbpid)) { if(tsv) dev_info(".prog\t%s\tusbpid\t", id); - else + else { + dev_cout(pgm->comments, "usbpid", 0, 0); dev_info(" %-19s = ", "usbpid"); + } for(firstid=1, ln=lfirst(pgm->usbpid); ln; ln=lnext(ln)) { if(!firstid) dev_info(", "); firstid = 0; dev_info("0x%04x", *(unsigned int *) ldata(ln)); } - dev_info(tsv? "\n": ";\n"); + if(tsv) + dev_info("\n"); + else { + dev_info(";"); + dev_cout(pgm->comments, "usbpid", 1, 1); + } } _if_pgmout_str(strcmp, cfg_escape(pgm->usbdev), usbdev); @@ -1039,20 +1168,28 @@ static void dev_pgm_strct(PROGRAMMER *pgm, bool tsv, PROGRAMMER *base) { if(pgm->hvupdi_support && lfirst(pgm->hvupdi_support)) { if(tsv) dev_info(".prog\t%s\thvupdu_support\t", id); - else + else { + dev_cout(pgm->comments, "hvupdi_support", 0, 0); dev_info(" %-19s = ", "hvupdi_support"); + } for(firstid=1, ln=lfirst(pgm->hvupdi_support); ln; ln=lnext(ln)) { if(!firstid) dev_info(", "); firstid = 0; dev_info("%d", *(unsigned int *) ldata(ln)); } - dev_info(tsv? "\n": ";\n"); + if(tsv) + dev_info("\n"); + else { + dev_info(";"); + dev_cout(pgm->comments, "hvupdi_support", 1, 1); + } } - - if(!tsv) + if(!tsv) { + dev_cout(pgm->comments, ";", 0, 0); dev_info(";\n"); + } } diff --git a/src/developer_opts.h b/src/developer_opts.h index 2079c109..bc04a9d8 100644 --- a/src/developer_opts.h +++ b/src/developer_opts.h @@ -19,6 +19,7 @@ #ifndef developer_opts_h #define developer_opts_h +void dev_output_pgm_part(int dev_opt_c, char *programmer, int dev_opt_p, char *partdesc); void dev_output_part_defs(char *partdesc); void dev_output_pgm_defs(char *programmer); diff --git a/src/developer_opts_private.h b/src/developer_opts_private.h index a5c1562e..54012838 100644 --- a/src/developer_opts_private.h +++ b/src/developer_opts_private.h @@ -52,76 +52,77 @@ static int dev_message(int msglvl, const char *fmt, ...); #define dev_notice2(...) dev_message(DEV_NOTICE2, __VA_ARGS__) #define _pgmout(fmt, component) \ - dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf(fmt, pgm->component)) + dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf(fmt, pgm->component), pgm->comments) #define _pgmout_fmt(name, fmt, what) \ - dev_part_strct_entry(tsv, ".prog", id, NULL, name, dev_sprintf(fmt, what)) + dev_part_strct_entry(tsv, ".prog", id, NULL, name, dev_sprintf(fmt, what), pgm->comments) #define _if_pgmout(cmp, fmt, component) do { \ if(!base || cmp(base->component, pgm->component)) \ - dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf(fmt, pgm->component)); \ + dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf(fmt, pgm->component), pgm->comments); \ } while(0) -// Result must be a malloc()ed string +// Result must be a malloc'd string #define _if_pgmout_str(cmp, result, component) do { \ if(!base || cmp(base->component, pgm->component)) \ - dev_part_strct_entry(tsv, ".prog", id, NULL, #component, result); \ + dev_part_strct_entry(tsv, ".prog", id, NULL, #component, result, pgm->comments); \ } while(0) + #define _partout(fmt, component) \ - dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component)) + dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component), p->comments) #define _if_partout(cmp, fmt, component) do { \ if(!base || cmp(base->component, p->component)) \ - dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component)); \ + dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component), p->comments); \ } while(0) #define _if_n_partout(cmp, n, fmt, component) do { \ if(!base || cmp(base->component, p->component, n)) \ - dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component)); \ + dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component), p->comments); \ } while(0) -// Result must be a malloc()ed string +// Result must be a malloc'd string #define _partout_str(result, component) \ - dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result) + dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments) -// Result must be a malloc()ed string +// Result must be a malloc'd string #define _if_partout_str(cmp, result, component) do { \ if(!base || cmp(base->component, p->component)) \ - dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result); \ + dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments); \ } while(0) -// Result must be a malloc()ed string +// Result must be a malloc'd string #define _if_n_partout_str(cmp, n, result, component) do { \ if(!base || cmp(base->component, p->component, n)) \ - dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result); \ + dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments); \ } while(0) #define _memout(fmt, component) \ - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component)) + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component), m->comments) #define _if_memout(cmp, fmt, component) do { \ if(!bm || cmp(bm->component, m->component)) \ - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component)); \ + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component), m->comments); \ } while(0) -// Result must be a malloc()ed string +// Result must be a malloc'd string #define _memout_str(result, component) \ - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result) + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result, m->comments) -// Result must be a malloc()ed string +// Result must be a malloc'd string #define _if_n_memout_str(cmp, n, result, component) do { \ if(!bm || cmp(bm->component, m->component, n)) \ - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result); \ + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result, m->comments); \ } while(0) #define _memout_yn(component) \ - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_memout_yn()", m->component? "yes": "no")) + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_memout_yn()", m->component? "yes": "no"), m->comments) #define _if_memout_yn(component) do { \ if(!bm || bm->component != m->component) \ - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_if_memout_yn()", m->component? "yes": "no")); \ + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_if_memout_yn()", m->component? "yes": "no"), m->comments); \ } while(0) #define _flagout(mask, name) \ @@ -132,8 +133,8 @@ static int dev_message(int msglvl, const char *fmt, ...); _partout_str(cfg_strdup("_if_flagout()", p->flags & (mask)? "yes": "no"), name); \ } while(0) -// Result must be a malloc()ed string +// Result must be a malloc'd string #define _cmderr(result, component) \ - dev_part_strct_entry(tsv, ".cmderr", p->desc, m->desc, #component, result) + dev_part_strct_entry(tsv, ".cmderr", p->desc, m->desc, #component, result, NULL) #endif diff --git a/src/lexer.l b/src/lexer.l index 47c3cb25..a69130d3 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -39,6 +39,15 @@ #define YYERRCODE 256 #endif +/* capture lvalue keywords to associate comments with that assignment */ +#define ccap() capture_lvalue_kw(yytext, cfg_lineno) + +static void adjust_cfg_lineno(const char *p) { + while(*p) + if(*p++ == '\n') + cfg_lineno++; +} + %} DIGIT [0-9] @@ -71,14 +80,19 @@ SIGN [+-] 0x{HEXDIGIT}+ { yylval = hexnumber(yytext); return TKN_NUMBER; } -#[^\n]*\n+ { /* record and skip # comments */ - capture_comment_str(yytext); - for(int i=0; yytext[i]; i++) { - if(yytext[i] == '\n') - cfg_lineno++; - } +#\n#\ PROGRAMMER\ DEFINITIONS\n#\n+ { /* Record comments so far as prologue and skip */ + cfg_capture_prologue(); + adjust_cfg_lineno(yytext); } +#\n#\ PART\ DEFINITIONS\n#\n+ { /* Ignore part definions header */ + adjust_cfg_lineno(yytext); +} + +[ \t]*#[^\n]*\n+ { /* Record and skip # comments including preceding white space */ + capture_comment_str(yytext, cfg_lineno); + adjust_cfg_lineno(yytext); +} "/*" { /* The following eats multiline C style comments, they are not captured */ int c; @@ -108,137 +122,137 @@ SIGN [+-] alias { yylval=NULL; return K_ALIAS; } -allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; } -avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; } +allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; } +avr910_devcode { yylval=NULL; ccap(); return K_AVR910_DEVCODE; } bank_size { yylval=NULL; return K_PAGE_SIZE; } banked { yylval=NULL; return K_PAGED; } -baudrate { yylval=NULL; return K_BAUDRATE; } -blocksize { yylval=NULL; return K_BLOCKSIZE; } -bs2 { yylval=NULL; return K_BS2; } -buff { yylval=NULL; return K_BUFF; } -bytedelay { yylval=NULL; return K_BYTEDELAY; } -chip_erase { yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; } -chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; } -chiperasepolltimeout { yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; } -chiperasepulsewidth { yylval=NULL; return K_CHIPERASEPULSEWIDTH; } -chiperasetime { yylval=NULL; return K_CHIPERASETIME; } -cmdexedelay { yylval=NULL; return K_CMDEXEDELAY; } -connection_type { yylval=NULL; return K_CONNTYPE; } +baudrate { yylval=NULL; ccap(); return K_BAUDRATE; } +blocksize { yylval=NULL; ccap(); return K_BLOCKSIZE; } +bs2 { yylval=NULL; ccap(); return K_BS2; } +buff { yylval=NULL; ccap(); return K_BUFF; } +bytedelay { yylval=NULL; ccap(); return K_BYTEDELAY; } +chip_erase { yylval=new_token(K_CHIP_ERASE); ccap(); return K_CHIP_ERASE; } +chip_erase_delay { yylval=NULL; ccap(); return K_CHIP_ERASE_DELAY; } +chiperasepolltimeout { yylval=NULL; ccap(); return K_CHIPERASEPOLLTIMEOUT; } +chiperasepulsewidth { yylval=NULL; ccap(); return K_CHIPERASEPULSEWIDTH; } +chiperasetime { yylval=NULL; ccap(); return K_CHIPERASETIME; } +cmdexedelay { yylval=NULL; ccap(); return K_CMDEXEDELAY; } +connection_type { yylval=NULL; ccap(); return K_CONNTYPE; } dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; } default_bitclock { yylval=NULL; return K_DEFAULT_BITCLOCK; } default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; } default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; } default_serial { yylval=NULL; return K_DEFAULT_SERIAL; } default_spi { yylval=NULL; return K_DEFAULT_SPI; } -delay { yylval=NULL; return K_DELAY; } -desc { yylval=NULL; return K_DESC; } -family_id { yylval=NULL; return K_FAMILY_ID; } -devicecode { yylval=NULL; return K_DEVICECODE; } -eecr { yylval=NULL; return K_EECR; } +delay { yylval=NULL; ccap(); return K_DELAY; } +desc { yylval=NULL; ccap(); return K_DESC; } +devicecode { yylval=NULL; ccap(); return K_DEVICECODE; } +eecr { yylval=NULL; ccap(); return K_EECR; } eeprom { yylval=NULL; return K_EEPROM; } -eeprom_instr { yylval=NULL; return K_EEPROM_INSTR; } -enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; } -errled { yylval=NULL; return K_ERRLED; } +eeprom_instr { yylval=NULL; ccap(); return K_EEPROM_INSTR; } +enablepageprogramming { yylval=NULL; ccap(); return K_ENABLEPAGEPROGRAMMING; } +errled { yylval=NULL; ccap(); return K_ERRLED; } +family_id { yylval=NULL; ccap(); return K_FAMILY_ID; } flash { yylval=NULL; return K_FLASH; } -flash_instr { yylval=NULL; return K_FLASH_INSTR; } -has_debugwire { yylval=NULL; return K_HAS_DW; } -has_jtag { yylval=NULL; return K_HAS_JTAG; } -has_pdi { yylval=NULL; return K_HAS_PDI; } -has_tpi { yylval=NULL; return K_HAS_TPI; } -has_updi { yylval=NULL; return K_HAS_UPDI; } -hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; } -hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; } -hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; } -hvspcmdexedelay { yylval=NULL; return K_HVSPCMDEXEDELAY; } -hvupdi_support { yylval=NULL; return K_HVUPDI_SUPPORT; } -hvupdi_variant { yylval=NULL; return K_HVUPDI_VARIANT; } -id { yylval=NULL; return K_ID; } -idr { yylval=NULL; return K_IDR; } +flash_instr { yylval=NULL; ccap(); return K_FLASH_INSTR; } +has_debugwire { yylval=NULL; ccap(); return K_HAS_DW; } +has_jtag { yylval=NULL; ccap(); return K_HAS_JTAG; } +has_pdi { yylval=NULL; ccap(); return K_HAS_PDI; } +has_tpi { yylval=NULL; ccap(); return K_HAS_TPI; } +has_updi { yylval=NULL; ccap(); return K_HAS_UPDI; } +hventerstabdelay { yylval=NULL; ccap(); return K_HVENTERSTABDELAY; } +hvleavestabdelay { yylval=NULL; ccap(); return K_HVLEAVESTABDELAY; } +hvsp_controlstack { yylval=NULL; ccap(); return K_HVSP_CONTROLSTACK; } +hvspcmdexedelay { yylval=NULL; ccap(); return K_HVSPCMDEXEDELAY; } +hvupdi_support { yylval=NULL; ccap(); return K_HVUPDI_SUPPORT; } +hvupdi_variant { yylval=NULL; ccap(); return K_HVUPDI_VARIANT; } +id { yylval=NULL; ccap(); return K_ID; } +idr { yylval=NULL; ccap(); return K_IDR; } io { yylval=new_token(K_IO); return K_IO; } -is_at90s1200 { yylval=NULL; return K_IS_AT90S1200; } -is_avr32 { yylval=NULL; return K_IS_AVR32; } -latchcycles { yylval=NULL; return K_LATCHCYCLES; } -load_ext_addr { yylval=new_token(K_LOAD_EXT_ADDR); return K_LOAD_EXT_ADDR; } -loadpage_hi { yylval=new_token(K_LOADPAGE_HI); return K_LOADPAGE_HI; } -loadpage_lo { yylval=new_token(K_LOADPAGE_LO); return K_LOADPAGE_LO; } -max_write_delay { yylval=NULL; return K_MAX_WRITE_DELAY; } -mcu_base { yylval=NULL; return K_MCU_BASE; } -memory { yylval=NULL; return K_MEMORY; } -min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; } -miso { yylval=NULL; return K_MISO; } -mode { yylval=NULL; return K_MODE; } -mosi { yylval=NULL; return K_MOSI; } +is_at90s1200 { yylval=NULL; ccap(); return K_IS_AT90S1200; } +is_avr32 { yylval=NULL; ccap(); return K_IS_AVR32; } +latchcycles { yylval=NULL; ccap(); return K_LATCHCYCLES; } +load_ext_addr { yylval=new_token(K_LOAD_EXT_ADDR); ccap(); return K_LOAD_EXT_ADDR; } +loadpage_hi { yylval=new_token(K_LOADPAGE_HI); ccap(); return K_LOADPAGE_HI; } +loadpage_lo { yylval=new_token(K_LOADPAGE_LO); ccap(); return K_LOADPAGE_LO; } +max_write_delay { yylval=NULL; ccap(); return K_MAX_WRITE_DELAY; } +mcu_base { yylval=NULL; ccap(); return K_MCU_BASE; } +memory { yylval=NULL; ccap(); return K_MEMORY; } +min_write_delay { yylval=NULL; ccap(); return K_MIN_WRITE_DELAY; } +miso { yylval=NULL; ccap(); return K_MISO; } +mode { yylval=NULL; ccap(); return K_MODE; } +mosi { yylval=NULL; ccap(); return K_MOSI; } no { yylval=new_token(K_NO); return K_NO; } NULL { yylval=NULL; return K_NULL; } num_banks { yylval=NULL; return K_NUM_PAGES; } -num_pages { yylval=NULL; return K_NUM_PAGES; } -nvm_base { yylval=NULL; return K_NVM_BASE; } -ocd_base { yylval=NULL; return K_OCD_BASE; } -ocdrev { yylval=NULL; return K_OCDREV; } -offset { yylval=NULL; return K_OFFSET; } -page_size { yylval=NULL; return K_PAGE_SIZE; } -paged { yylval=NULL; return K_PAGED; } -pagel { yylval=NULL; return K_PAGEL; } -parallel { yylval=NULL; return K_PARALLEL; } +num_pages { yylval=NULL; ccap(); return K_NUM_PAGES; } +nvm_base { yylval=NULL; ccap(); return K_NVM_BASE; } +ocd_base { yylval=NULL; ccap(); return K_OCD_BASE; } +ocdrev { yylval=NULL; ccap(); return K_OCDREV; } +offset { yylval=NULL; ccap(); return K_OFFSET; } +paged { yylval=NULL; ccap(); return K_PAGED; } +pagel { yylval=NULL; ccap(); return K_PAGEL; } +page_size { yylval=NULL; ccap(); return K_PAGE_SIZE; } +parallel { yylval=NULL; ccap(); return K_PARALLEL; } parent { yylval=NULL; return K_PARENT; } -part { yylval=NULL; return K_PART; } -pgm_enable { yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; } -pgmled { yylval=NULL; return K_PGMLED; } -pollindex { yylval=NULL; return K_POLLINDEX; } -pollmethod { yylval=NULL; return K_POLLMETHOD; } -pollvalue { yylval=NULL; return K_POLLVALUE; } -postdelay { yylval=NULL; return K_POSTDELAY; } -poweroffdelay { yylval=NULL; return K_POWEROFFDELAY; } -pp_controlstack { yylval=NULL; return K_PP_CONTROLSTACK; } -predelay { yylval=NULL; return K_PREDELAY; } -progmodedelay { yylval=NULL; return K_PROGMODEDELAY; } -programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; } -programfusepulsewidth { yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; } -programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; } -programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; } -programmer { yylval=NULL; return K_PROGRAMMER; } +part { yylval=NULL; ccap(); return K_PART; } +pgm_enable { yylval=new_token(K_PGM_ENABLE); ccap(); return K_PGM_ENABLE; } +pgmled { yylval=NULL; ccap(); return K_PGMLED; } +pollindex { yylval=NULL; ccap(); return K_POLLINDEX; } +pollmethod { yylval=NULL; ccap(); return K_POLLMETHOD; } +pollvalue { yylval=NULL; ccap(); return K_POLLVALUE; } +postdelay { yylval=NULL; ccap(); return K_POSTDELAY; } +poweroffdelay { yylval=NULL; ccap(); return K_POWEROFFDELAY; } +pp_controlstack { yylval=NULL; ccap(); return K_PP_CONTROLSTACK; } +predelay { yylval=NULL; ccap(); return K_PREDELAY; } +progmodedelay { yylval=NULL; ccap(); return K_PROGMODEDELAY; } +programfusepolltimeout { yylval=NULL; ccap(); return K_PROGRAMFUSEPOLLTIMEOUT; } +programfusepulsewidth { yylval=NULL; ccap(); return K_PROGRAMFUSEPULSEWIDTH; } +programlockpolltimeout { yylval=NULL; ccap(); return K_PROGRAMLOCKPOLLTIMEOUT; } +programlockpulsewidth { yylval=NULL; ccap(); return K_PROGRAMLOCKPULSEWIDTH; } +programmer { yylval=NULL; ccap(); return K_PROGRAMMER; } pseudo { yylval=new_token(K_PSEUDO); return K_PSEUDO; } -pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; } -rampz { yylval=NULL; return K_RAMPZ; } -rdyled { yylval=NULL; return K_RDYLED; } -read { yylval=new_token(K_READ); return K_READ; } -read_hi { yylval=new_token(K_READ_HI); return K_READ_HI; } -read_lo { yylval=new_token(K_READ_LO); return K_READ_LO; } -readback { yylval=NULL; return K_READBACK; } -readback_p1 { yylval=NULL; return K_READBACK_P1; } -readback_p2 { yylval=NULL; return K_READBACK_P2; } -readsize { yylval=NULL; return K_READSIZE; } -reset { yylval=new_token(K_RESET); return K_RESET; } -resetdelay { yylval=NULL; return K_RESETDELAY; } -resetdelayms { yylval=NULL; return K_RESETDELAYMS; } -resetdelayus { yylval=NULL; return K_RESETDELAYUS; } -retry_pulse { yylval=NULL; return K_RETRY_PULSE; } -sck { yylval=new_token(K_SCK); return K_SCK; } -serial { yylval=NULL; return K_SERIAL; } -signature { yylval=NULL; return K_SIGNATURE; } -size { yylval=NULL; return K_SIZE; } +pwroff_after_write { yylval=NULL; ccap(); return K_PWROFF_AFTER_WRITE; } +rampz { yylval=NULL; ccap(); return K_RAMPZ; } +rdyled { yylval=NULL; ccap(); return K_RDYLED; } +read { yylval=new_token(K_READ); ccap(); return K_READ; } +read_hi { yylval=new_token(K_READ_HI); ccap(); return K_READ_HI; } +read_lo { yylval=new_token(K_READ_LO); ccap(); return K_READ_LO; } +readback { yylval=NULL; ccap(); return K_READBACK; } +readback_p1 { yylval=NULL; ccap(); return K_READBACK_P1; } +readback_p2 { yylval=NULL; ccap(); return K_READBACK_P2; } +readsize { yylval=NULL; ccap(); return K_READSIZE; } +reset { yylval=new_token(K_RESET); ccap(); return K_RESET; } +resetdelay { yylval=NULL; ccap(); return K_RESETDELAY; } +resetdelayms { yylval=NULL; ccap(); return K_RESETDELAYMS; } +resetdelayus { yylval=NULL; ccap(); return K_RESETDELAYUS; } +retry_pulse { yylval=NULL; ccap(); return K_RETRY_PULSE; } +sck { yylval=new_token(K_SCK); ccap(); return K_SCK; } +serial { yylval=NULL; ccap(); return K_SERIAL; } +signature { yylval=NULL; ccap(); return K_SIGNATURE; } +size { yylval=NULL; ccap(); return K_SIZE; } spi { yylval=NULL; return K_SPI; } -spmcr { yylval=NULL; return K_SPMCR; } -stabdelay { yylval=NULL; return K_STABDELAY; } -stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; } -synchcycles { yylval=NULL; return K_SYNCHCYCLES; } -synchloops { yylval=NULL; return K_SYNCHLOOPS; } -timeout { yylval=NULL; return K_TIMEOUT; } -togglevtg { yylval=NULL; return K_TOGGLEVTG; } -type { yylval=NULL; return K_TYPE; } +spmcr { yylval=NULL; ccap(); return K_SPMCR; } +stabdelay { yylval=NULL; ccap(); return K_STABDELAY; } +stk500_devcode { yylval=NULL; ccap(); return K_STK500_DEVCODE; } +synchcycles { yylval=NULL; ccap(); return K_SYNCHCYCLES; } +synchloops { yylval=NULL; ccap(); return K_SYNCHLOOPS; } +timeout { yylval=NULL; ccap(); return K_TIMEOUT; } +togglevtg { yylval=NULL; ccap(); return K_TOGGLEVTG; } +type { yylval=NULL; ccap(); return K_TYPE; } usb { yylval=NULL; return K_USB; } -usbdev { yylval=NULL; return K_USBDEV; } -usbpid { yylval=NULL; return K_USBPID; } -usbproduct { yylval=NULL; return K_USBPRODUCT; } -usbsn { yylval=NULL; return K_USBSN; } -usbvendor { yylval=NULL; return K_USBVENDOR; } -usbvid { yylval=NULL; return K_USBVID; } -vcc { yylval=NULL; return K_VCC; } -vfyled { yylval=NULL; return K_VFYLED; } -write { yylval=new_token(K_WRITE); return K_WRITE; } -write_hi { yylval=new_token(K_WRITE_HI); return K_WRITE_HI; } -write_lo { yylval=new_token(K_WRITE_LO); return K_WRITE_LO; } -writepage { yylval=new_token(K_WRITEPAGE); return K_WRITEPAGE; } +usbdev { yylval=NULL; ccap(); return K_USBDEV; } +usbpid { yylval=NULL; ccap(); return K_USBPID; } +usbproduct { yylval=NULL; ccap(); return K_USBPRODUCT; } +usbsn { yylval=NULL; ccap(); return K_USBSN; } +usbvendor { yylval=NULL; ccap(); return K_USBVENDOR; } +usbvid { yylval=NULL; ccap(); return K_USBVID; } +vcc { yylval=NULL; ccap(); return K_VCC; } +vfyled { yylval=NULL; ccap(); return K_VFYLED; } +write { yylval=new_token(K_WRITE); ccap(); return K_WRITE; } +write_hi { yylval=new_token(K_WRITE_HI); ccap(); return K_WRITE_HI; } +write_lo { yylval=new_token(K_WRITE_LO); ccap(); return K_WRITE_LO; } +writepage { yylval=new_token(K_WRITEPAGE); ccap(); return K_WRITEPAGE; } yes { yylval=new_token(K_YES); return K_YES; } "," { yylval = NULL; pyytext(); return TKN_COMMA; } diff --git a/src/libavrdude.h b/src/libavrdude.h index cbbc8a79..d15677eb 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -215,7 +215,8 @@ typedef struct opcode { typedef struct avrpart { const char * desc; /* long part name */ const char * id; /* short part name */ - const char * parent_id; /* parent id if set, for -p.../s */ + LISTID comments; // Used by developer options -p*/[ASsr...] + const char * parent_id; /* Used by developer options */ 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 */ @@ -285,6 +286,7 @@ typedef struct avrpart { #define AVR_MEMDESCLEN 64 typedef struct avrmem { const char *desc; /* memory description ("flash", "eeprom", etc) */ + LISTID comments; // Used by developer options -p*/[ASsr...] 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) */ @@ -684,7 +686,8 @@ typedef struct programmer_t { LISTID id; const char *desc; void (*initpgm)(struct programmer_t *pgm); - const char *parent_id; // Used by developer options -c*/[sr...] + LISTID comments; // Used by developer options -c*/[ASsr...] + const char *parent_id; // Used by developer options struct pindef_t pin[N_PINS]; conntype_t conntype; int baudrate; diff --git a/src/main.c b/src/main.c index 2487faa7..ae9e5ea8 100644 --- a/src/main.c +++ b/src/main.c @@ -244,6 +244,14 @@ static void replace_backslashes(char *s) } } +// Return 2 if string is * or starts with */, 1 if string contains /, 0 otherwise +static int dev_opt(char *str) { + return + !str? 0: + !strcmp(str, "*") || !strncmp(str, "*/", 2)? 2: + !!strchr(str, '/'); +} + /* * main routine @@ -752,20 +760,14 @@ int main(int argc, char * argv []) bitclock = default_bitclock; } + // Developer options to print parts and/or programmer entries of avrdude.conf + int dev_opt_c = dev_opt(programmer); // -c /[sSArt] + int dev_opt_p = dev_opt(partdesc); // -p /[dsSArcow*t] - int dev_opts = 0; - // Developer option -c /[ASsrt] prints programmer description(s) and exits - if(programmer && (strcmp(programmer, "*") == 0 || strchr(programmer, '/'))) { - dev_output_pgm_defs(cfg_strdup("main()", programmer)); - dev_opts = 1; - } - // Developer option -p /[dASsrcow*t] prints part description(s) and exits - if(partdesc && (strcmp(partdesc, "*") == 0 || strchr(partdesc, '/'))) { - dev_output_part_defs(partdesc); - dev_opts = 1; - } - if(dev_opts) + if(dev_opt_c || dev_opt_p) { // See -c/h and or -p/h + dev_output_pgm_part(dev_opt_c, programmer, dev_opt_p, partdesc); exit(0); + } avrdude_message(MSG_NOTICE, "\n");