[GRASS-SVN] r33643 - grass/trunk/lib/gis

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Oct 1 15:17:45 EDT 2008


Author: glynn
Date: 2008-10-01 15:17:45 -0400 (Wed, 01 Oct 2008)
New Revision: 33643

Modified:
   grass/trunk/lib/gis/parser.c
Log:
Allow "enumerated" option values to be abbreviated


Modified: grass/trunk/lib/gis/parser.c
===================================================================
--- grass/trunk/lib/gis/parser.c	2008-10-01 18:36:06 UTC (rev 33642)
+++ grass/trunk/lib/gis/parser.c	2008-10-01 19:17:45 UTC (rev 33643)
@@ -84,9 +84,11 @@
 #include <grass/spawn.h>
 
 
-#define BAD_SYNTAX  1
-#define OUT_OF_RANGE    2
-#define MISSING_VALUE   3
+#define BAD_SYNTAX    1
+#define OUT_OF_RANGE  2
+#define MISSING_VALUE 3
+#define AMBIGUOUS     4
+#define REPLACED      5
 #define KEYLENGTH 64
 
 static int interactive_ok = 1;
@@ -123,10 +125,10 @@
 static int is_option(const char *);
 static int set_option(char *);
 static int check_opts();
-static int check_an_opt(const char *, int, const char *, const char *);
-static int check_int(const char *, const char *);
-static int check_double(const char *, const char *);
-static int check_string(const char *, const char *);
+static int check_an_opt(const char *, int, const char *, const char **, char **);
+static int check_int(const char *, const char **);
+static int check_double(const char *, const char **);
+static int check_string(const char *, const char **, int *);
 static int check_required(void);
 static int split_opts(void);
 static int check_multiple_opts(void);
@@ -2206,11 +2208,11 @@
 	if (opt->options && opt->answer) {
 	    if (opt->multiple == 0)
 		error += check_an_opt(opt->key, opt->type,
-				      opt->options, opt->answer);
+				      opt->options, opt->opts, &opt->answer);
 	    else {
 		for (ans = 0; opt->answers[ans] != '\0'; ans++)
 		    error += check_an_opt(opt->key, opt->type,
-					  opt->options, opt->answers[ans]);
+					  opt->options, opt->opts, &opt->answers[ans]);
 	    }
 	}
 
@@ -2225,27 +2227,24 @@
 }
 
 static int check_an_opt(const char *key, int type, const char *options,
-			const char *answer)
+			const char **opts, char **answerp)
 {
+    const char *answer = *answerp;
     int error;
+    int found;
 
     error = 0;
 
     switch (type) {
     case TYPE_INTEGER:
-	error = check_int(answer, options);
+	error = check_int(answer, opts);
 	break;
     case TYPE_DOUBLE:
-	error = check_double(answer, options);
+	error = check_double(answer, opts);
 	break;
     case TYPE_STRING:
-	error = check_string(answer, options);
+	error = check_string(answer, opts, &found);
 	break;
-	/*
-	   case TYPE_COORDINATE:
-	   error = check_coor(answer,options) ;
-	   break ;
-	 */
     }
     switch (error) {
     case 0:
@@ -2264,135 +2263,121 @@
     case MISSING_VALUE:
 	fprintf(stderr, _("\nERROR: Missing value for parameter <%s>\n"),
 		key);
+	break;
+    case AMBIGUOUS:
+	fprintf(stderr, _("\nERROR: value <%s> ambiguous for parameter <%s>\n"),
+		answer, key);
+	fprintf(stderr, _("       valid options: %s\n"), options);
+	break;
+    case REPLACED:
+	*answerp = G_store(opts[found]);
+	error = 0;
+	break;
     }
-    return (error);
+
+    return error;
 }
 
-static int check_int(const char *ans, const char *opts)
+static int check_int(const char *ans, const char **opts)
 {
-    int d, lo, hi;
+    int d, i;
 
-    if (1 != sscanf(ans, "%d", &d))
-	return (MISSING_VALUE);
+    if (sscanf(ans, "%d", &d) != 1)
+	return MISSING_VALUE;
 
-    if (contains(opts, '-')) {
-	if (2 != sscanf(opts, "%d-%d", &lo, &hi))
-	    return (BAD_SYNTAX);
-	if (d < lo || d > hi)
-	    return (OUT_OF_RANGE);
-	else
-	    return (0);
-    }
-    else if (contains(opts, ',')) {
-	for (;;) {
-	    if (1 != sscanf(opts, "%d", &lo))
-		return (BAD_SYNTAX);
-	    if (d == lo)
-		return (0);
-	    while (*opts != '\0' && *opts != ',')
-		opts++;
-	    if (*opts == '\0')
-		return (OUT_OF_RANGE);
-	    if (*(++opts) == '\0')
-		return (OUT_OF_RANGE);
+    for (i = 0; opts[i]; i++) {
+	const char *opt = opts[i];
+	int lo, hi;
+
+	if (contains(opt, '-')) {
+	    if (sscanf(opt, "%d-%d", &lo, &hi) == 2) {
+		if (d >= lo && d <= hi)
+		    return 0;
+	    }
+	    else if (sscanf(opt, "-%d", &hi) == 1) {
+		if (d <= hi)
+		    return 0;
+	    }
+	    else if (sscanf(opt, "%d-", &lo) == 1) {
+		if (d >= lo)
+		    return 0;
+	    }
+	    else
+		return BAD_SYNTAX;
 	}
+	else {
+	    if (sscanf(opt, "%d", &lo) == 1) {
+		if (d == lo)
+		    return 0;
+	    }
+	    else
+		return BAD_SYNTAX;
+	}
     }
-    else {
-	if (1 != sscanf(opts, "%d", &lo))
-	    return (BAD_SYNTAX);
-	if (d == lo)
-	    return (0);
-	return (OUT_OF_RANGE);
-    }
+
+    return OUT_OF_RANGE;
 }
 
-/*
-   static int
-   check_coor(ans, opts)
-   char *ans ;
-   char *opts ;
-   {
-   double xd, xlo, xhi;
-   double yd, ylo, yhi;
-
-   if (1 != sscanf(ans,"%lf,%lf", &xd, &yd))
-   return(MISSING_VALUE) ;
-
-   if (contains(opts, '-'))
-   {
-   if (2 != sscanf(opts,"%lf-%lf,%lf-%lf",&xlo, &xhi, &ylo, &yhi))
-   return(BAD_SYNTAX) ;
-   if (xd < xlo || xd > xhi)
-   return(OUT_OF_RANGE) ;
-   if (yd < ylo || yd > yhi)
-   return(OUT_OF_RANGE) ;
-   return(0) ;
-   }
-   return(BAD_SYNTAX) ;
-   }
- */
-
-static int check_double(const char *ans, const char *opts)
+static int check_double(const char *ans, const char **opts)
 {
-    double d, lo, hi;
+    double d;
+    int i;
 
-    if (1 != sscanf(ans, "%lf", &d))
-	return (MISSING_VALUE);
+    if (sscanf(ans, "%lf", &d) != 1)
+	return MISSING_VALUE;
 
-    if (contains(opts, '-')) {
-	if (2 != sscanf(opts, "%lf-%lf", &lo, &hi))
-	    return (BAD_SYNTAX);
-	if (d < lo || d > hi)
-	    return (OUT_OF_RANGE);
-	else
-	    return (0);
-    }
-    else if (contains(opts, ',')) {
-	for (;;) {
-	    if (1 != sscanf(opts, "%lf", &lo))
-		return (BAD_SYNTAX);
-	    if (d == lo)
-		return (0);
-	    while (*opts != '\0' && *opts != ',')
-		opts++;
-	    if (*opts == '\0')
-		return (OUT_OF_RANGE);
-	    if (*(++opts) == '\0')
-		return (OUT_OF_RANGE);
+    for (i = 0; opts[i]; i++) {
+	const char *opt = opts[i];
+	double lo, hi;
+
+	if (contains(opt, '-')) {
+	    if (sscanf(opt, "%lf-%lf", &lo, &hi) == 2) {
+		if (d >= lo && d <= hi)
+		    return 0;
+	    }
+	    else if (sscanf(opt, "-%lf", &hi) == 1) {
+		if (d <= hi)
+		    return 0;
+	    }
+	    else if (sscanf(opt, "%lf-", &lo) == 1) {
+		if (d >= lo)
+		    return 0;
+	    }
+	    else
+		return BAD_SYNTAX;
 	}
+	else {
+	    if (sscanf(opt, "%lf", &lo) == 1) {
+		if (d == lo)
+		    return 0;
+	    }
+	    else
+		return BAD_SYNTAX;
+	}
     }
-    else {
-	if (1 != sscanf(opts, "%lf", &lo))
-	    return (BAD_SYNTAX);
-	if (d == lo)
-	    return (0);
-	return (OUT_OF_RANGE);
-    }
+
+    return OUT_OF_RANGE;
 }
 
-static int check_string(const char *ans, const char *opts)
+static int check_string(const char *ans, const char **opts, int *result)
 {
-    if (*opts == '\0')
-	return (0);
+    int len = strlen(ans);
+    int found = 0;
+    int i;
 
-    if (contains(opts, ',')) {
-	for (;;) {
-	    if ((!strncmp(ans, opts, strlen(ans)))
-		&& (*(opts + strlen(ans)) == ','
-		    || *(opts + strlen(ans)) == '\0'))
-		return (0);
-	    while (*opts != '\0' && *opts != ',')
-		opts++;
-	    if (*opts == '\0')
-		return (OUT_OF_RANGE);
-	    if (*(++opts) == '\0')
-		return (OUT_OF_RANGE);
+    for (i = 0; opts[i]; i++) {
+	if (strcmp(ans, opts[i]) == 0)
+	    return 0;
+	if (strncmp(ans, opts[i], len) == 0) {
+	    *result = i;
+	    found++;
 	}
     }
-    else {
-	if (!strcmp(ans, opts))
-	    return (0);
-	return (OUT_OF_RANGE);
+
+    switch (found) {
+    case 0: return OUT_OF_RANGE;
+    case 1: return REPLACED;
+    default: return AMBIGUOUS;
     }
 }
 



More information about the grass-commit mailing list