From 1f1cbb6af4bb096eab8f29e977b62cf2e4c4ccb3 Mon Sep 17 00:00:00 2001 From: Stefan Rueger Date: Tue, 18 Apr 2023 02:05:42 +0100 Subject: [PATCH] Match variants part ids for -p and print variants on -vp? --- src/avrpart.c | 39 +++++++++++++++++++++++++++++++++++++-- src/developer_opts.c | 2 +- src/libavrdude.h | 3 +++ src/main.c | 4 +++- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/avrpart.c b/src/avrpart.c index fe08e04f..78b8928e 100644 --- a/src/avrpart.c +++ b/src/avrpart.c @@ -654,8 +654,7 @@ AVRPART *locate_part(const LISTID parts, const char *partdesc) { for (LNODEID ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) { p = ldata(ln1); - if ((strcasecmp(partdesc, p->id) == 0) || - (strcasecmp(partdesc, p->desc) == 0)) + if(part_eq(p, partdesc, strcase_eq)) found = 1; } @@ -899,6 +898,42 @@ char *opcode2str(const OPCODE *op, int opnum, int detailed) { } +int strcase_eq(const char *str1, const char *str2) { + return strcasecmp(str1, str2) == 0; +} + +// Returns 1 if the part pointed to by p matches the string or pattern s under the function cmp(s, ...) +int part_eq(AVRPART *p, const char *s, int (*cmp)(const char *, const char *)) { + // Matching id or desc? OK + if(cmp(s, p->id) || cmp(s, p->desc)) + return 1; + + // Check against all variants, either up to colon or up to dash + size_t desclen = strlen(p->desc), variantlen, dashlen; + char query[1024]; + for(LNODEID ln = lfirst(p->variants); ln; ln = lnext(ln)) { + const char *q = (const char *) ldata(ln), *qdash = strchr(q, '-'), *qcolon = strchr(q, ':'); + variantlen = qcolon? (size_t) (qcolon-q): strlen(q); + dashlen = qdash? (size_t) (qdash-q): variantlen; + if(variantlen < sizeof query) { // Sanity: should not expect such long strings + // Variant names should be unique order numbers, but don't check (again) if it's the same as p->desc + if(variantlen != desclen || memcmp(q, p->desc, desclen)) { + memcpy(query, q, variantlen); query[variantlen] = 0; + if(cmp(s, query)) + return 1; + // The name before dash should normally be p->desc and the dash is meant to come before the colon + if(dashlen > desclen && dashlen < variantlen) { + query[dashlen] = 0; + if(cmp(s, query)) + return 1; + } + } + } + } + return 0; +} + + /* * Match STRING against the partname pattern PATTERN, returning 1 if it * matches, 0 if not. NOTE: part_match() is a modified old copy of !fnmatch() diff --git a/src/developer_opts.c b/src/developer_opts.c index 13ef7970..fca09a1d 100644 --- a/src/developer_opts.c +++ b/src/developer_opts.c @@ -974,7 +974,7 @@ void dev_output_part_defs(char *partdesc) { nprinted = dev_nprinted; } - if(!part_match(partdesc, p->desc) && !part_match(partdesc, p->id)) + if(!part_eq(p, partdesc, part_match)) continue; if(astrc || strct || cmpst) diff --git a/src/libavrdude.h b/src/libavrdude.h index b72764a7..5753b1cc 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -403,7 +403,10 @@ typedef void (*walk_avrparts_cb)(const char *name, const char *desc, void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie); void sort_avrparts(LISTID avrparts); +int strcase_eq(const char *str1, const char *str2); int part_match(const char *pattern, const char *string); +// cmp can be, eg, strcase_eq or part_match +int part_eq(AVRPART *p, const char *string, int (*cmp)(const char *, const char *)); int compare_memory_masked(AVRMEM * m, uint8_t buf1, uint8_t buf2); diff --git a/src/main.c b/src/main.c index 2e321ba4..a4e85a9a 100644 --- a/src/main.c +++ b/src/main.c @@ -405,7 +405,6 @@ static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) { } } - for(ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) { p = ldata(ln1); // List part if pm or prog_modes uninitialised or if they are compatible otherwise @@ -419,6 +418,9 @@ static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) { if(pm != ~0) fprintf(f, " via %s", via_prog_modes(pm & p->prog_modes)); fprintf(f, "\n"); + if(verbose) + for(LNODEID ln = lfirst(p->variants); ln; ln = lnext(ln)) + fprintf(f, "%s%s- %s\n", prefix, prefix, (char *) ldata(ln)); } } }