[GRASS-SVN] r63744 - grass/trunk/lib/gis
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Dec 25 03:51:51 PST 2014
Author: glynn
Date: 2014-12-25 03:51:51 -0800 (Thu, 25 Dec 2014)
New Revision: 63744
Modified:
grass/trunk/lib/gis/parser.c
Log:
Change handling of ambiguous matches (issue #2409)
Modified: grass/trunk/lib/gis/parser.c
===================================================================
--- grass/trunk/lib/gis/parser.c 2014-12-25 11:34:18 UTC (rev 63743)
+++ grass/trunk/lib/gis/parser.c 2014-12-25 11:51:51 UTC (rev 63744)
@@ -94,6 +94,8 @@
#define KEYLENGTH 64
+#define MAX_MATCHES 50
+
/* initialize the global struct */
struct state state;
struct state *st = &state;
@@ -941,11 +943,11 @@
{
struct Option *at_opt = NULL;
struct Option *opt = NULL;
- int found;
- int prefix;
size_t key_len;
char the_key[KEYLENGTH];
char *ptr, *err;
+ struct Option *matches[MAX_MATCHES];
+ int found = 0;
err = NULL;
@@ -955,37 +957,58 @@
string++;
/* Find option with best keyword match */
- found = 0;
- prefix = 0;
key_len = strlen(the_key);
for (at_opt = &st->first_option; at_opt; at_opt = at_opt->next_opt) {
if (!at_opt->key)
continue;
if (strcmp(the_key, at_opt->key) == 0) {
- opt = at_opt;
+ matches[0] = at_opt;
found = 1;
break;
}
- if (strncmp(the_key, at_opt->key, key_len) == 0) {
- opt = at_opt;
- found++;
- prefix++;
+ if (strncmp(the_key, at_opt->key, key_len) == 0 ||
+ match_option(the_key, at_opt->key)) {
+ if (found >= MAX_MATCHES)
+ G_fatal_error("too many matches (limit %d)", MAX_MATCHES);
+ matches[found++] = at_opt;
}
- else if (match_option(the_key, at_opt->key)) {
- if (!found)
- opt = at_opt;
- found++;
- }
}
- if (found > 1 && prefix > 1) {
- G_asprintf(&err, _("%s: Sorry, <%s=> is ambiguous"), G_program_name(), the_key);
- append_error(err);
- return;
+ if (found > 1) {
+ int shortest = 0;
+ int length = strlen(matches[0]->key);
+ int prefix = 1;
+ int i;
+ for (i = 1; i < found; i++) {
+ int len = strlen(matches[i]->key);
+ if (len < length) {
+ length = len;
+ shortest = i;
+ }
+ }
+ for (i = 0; prefix && i < found; i++)
+ if (strncmp(matches[i]->key, matches[shortest]->key, length) != 0)
+ prefix = 0;
+ if (prefix) {
+ matches[0] = matches[shortest];
+ found = 1;
+ }
+ else {
+ G_asprintf(&err, _("%s: Sorry, <%s=> is ambiguous"), G_program_name(), the_key);
+ append_error(err);
+ for (i = 0; i < found; i++) {
+ G_asprintf(&err, _("Option <%s=> matches"), matches[i]->key);
+ append_error(err);
+ }
+ return;
+ }
}
+ if (found)
+ opt = matches[0];
+
/* First, check if key has been renamed in GRASS 7 */
if (found == 0) {
const char *renamed_key = NULL;
@@ -1214,7 +1237,7 @@
{
int len = strlen(ans);
int found = 0;
- int prefix = 0;
+ int matches[MAX_MATCHES];
int i;
if (!opts)
@@ -1223,26 +1246,41 @@
for (i = 0; opts[i]; i++) {
if (strcmp(ans, opts[i]) == 0)
return 0;
- if (strncmp(ans, opts[i], len) == 0) {
- *result = i;
- found++;
- prefix++;
+ if (strncmp(ans, opts[i], len) == 0 || match_option(ans, opts[i])) {
+ if (found >= MAX_MATCHES)
+ G_fatal_error("too many matches (limit %d)", MAX_MATCHES);
+ matches[found++] = i;
}
- else if (match_option(ans, opts[i])) {
- if (!found)
- *result = i;
- found++;
+ }
+
+ if (found > 1) {
+ int shortest = 0;
+ int length = strlen(opts[matches[0]]);
+ int prefix = 1;
+ int i;
+ for (i = 1; i < found; i++) {
+ int len = strlen(opts[matches[i]]);
+ if (len < length) {
+ length = len;
+ shortest = i;
+ }
}
+ for (i = 0; prefix && i < found; i++)
+ if (strncmp(opts[matches[i]], opts[matches[shortest]], length) != 0)
+ prefix = 0;
+ if (prefix) {
+ matches[0] = matches[shortest];
+ found = 1;
+ }
}
+ if (found == 1)
+ *result = matches[0];
+
switch (found) {
case 0: return OUT_OF_RANGE;
case 1: return REPLACED;
- default:
- switch (prefix) {
- case 1: return REPLACED;
- default: return AMBIGUOUS;
- }
+ default: return AMBIGUOUS;
}
}
More information about the grass-commit
mailing list