Fix partial matches for locate_mem() and do_cmd()

This commit is contained in:
Stefan Rueger 2023-01-01 23:29:06 +00:00
parent b6d50ef0a9
commit 17e2feff26
No known key found for this signature in database
GPG Key ID: B0B4F1FD86B1EC55
2 changed files with 25 additions and 27 deletions

View File

@ -420,51 +420,51 @@ void avr_free_memalias(AVRMEM_ALIAS *m) {
AVRMEM_ALIAS *avr_locate_memalias(const AVRPART *p, const char *desc) { AVRMEM_ALIAS *avr_locate_memalias(const AVRPART *p, const char *desc) {
AVRMEM_ALIAS * m, * match; AVRMEM_ALIAS * m, * match;
LNODEID ln; LNODEID ln;
int matches, exact; int matches;
int l; size_t l;
if(!p || !desc || !p->mem_alias) if(!p || !desc || !p->mem_alias)
return NULL; return NULL;
l = strlen(desc); l = strlen(desc);
matches = exact = 0; matches = 0;
match = NULL; match = NULL;
for (ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) { for (ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) {
m = ldata(ln); m = ldata(ln);
if (strncmp(m->desc, desc, l) == 0) { // Partial initial match if(l && strncmp(m->desc, desc, l) == 0) { // Partial initial match
match = m; match = m;
matches++; matches++;
if(m->desc[l] == 0) // Exact match between arg and memory if(m->desc[l] == 0) // Exact match; return straight away
exact++; return m;
} }
} }
return exact == 1 || matches == 1? match: NULL; return matches == 1? match: NULL;
} }
AVRMEM *avr_locate_mem_noalias(const AVRPART *p, const char *desc) { AVRMEM *avr_locate_mem_noalias(const AVRPART *p, const char *desc) {
AVRMEM * m, * match; AVRMEM * m, * match;
LNODEID ln; LNODEID ln;
int matches, exact; int matches;
int l; size_t l;
if(!p || !desc || !p->mem) if(!p || !desc || !p->mem)
return NULL; return NULL;
l = strlen(desc); l = strlen(desc);
matches = exact = 0; matches = 0;
match = NULL; match = NULL;
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) { for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
m = ldata(ln); m = ldata(ln);
if (strncmp(m->desc, desc, l) == 0) { // Partial initial match if(l && strncmp(m->desc, desc, l) == 0) { // Partial initial match
match = m; match = m;
matches++; matches++;
if(m->desc[l] == 0) // Exact match between arg and memory if(m->desc[l] == 0) // Exact match; return straight away
exact++; return m;
} }
} }
return exact == 1 || matches == 1? match: NULL; return matches == 1? match: NULL;
} }

View File

@ -1235,30 +1235,28 @@ static int tokenize(char *s, char ***argv) {
static int do_cmd(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) { static int do_cmd(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
int i; int i;
int hold; int hold, matches;
int len; size_t len;
len = strlen(argv[0]); len = strlen(argv[0]);
hold = -1; matches = 0;
for (i=0; i<NCMDS; i++) { for (i=0; i<NCMDS; i++) {
if(!*(void (**)(void)) ((char *) pgm + cmd[i].fnoff)) if(!*(void (**)(void)) ((char *) pgm + cmd[i].fnoff))
continue; continue;
if (len && strcasecmp(argv[0], cmd[i].name) == 0) if(len && strncasecmp(argv[0], cmd[i].name, len)==0) { // Partial initial match
return cmd[i].func(pgm, p, argc, argv);
if (len && strncasecmp(argv[0], cmd[i].name, len)==0) {
if (hold != -1) {
pmsg_error("(cmd) command %s is ambiguous\n", argv[0]);
return -1;
}
hold = i; hold = i;
matches++;
if(cmd[i].name[len] == 0) { // Exact match
matches = 1;
break;
}
} }
} }
if (hold != -1) if(matches == 1)
return cmd[hold].func(pgm, p, argc, argv); return cmd[hold].func(pgm, p, argc, argv);
pmsg_error("(cmd) invalid command %s\n", argv[0]); pmsg_error("(cmd) command %s is %s\n", argv[0], matches > 1? "ambiguous": "invalid");
return -1; return -1;
} }