[GRASS-SVN] r72913 - in grass/trunk: include/defs lib/gis

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Jun 26 05:42:20 PDT 2018


Author: mmetz
Date: 2018-06-26 05:42:20 -0700 (Tue, 26 Jun 2018)
New Revision: 72913

Modified:
   grass/trunk/include/defs/gis.h
   grass/trunk/lib/gis/color_rules.c
   grass/trunk/lib/gis/parser_standard_options.c
Log:
libgis: +G_color_rules_description_type(), +G_list_color_rules_description_type()

Modified: grass/trunk/include/defs/gis.h
===================================================================
--- grass/trunk/include/defs/gis.h	2018-06-26 11:29:03 UTC (rev 72912)
+++ grass/trunk/include/defs/gis.h	2018-06-26 12:42:20 UTC (rev 72913)
@@ -178,7 +178,9 @@
 /* color_rules.c */
 char *G_color_rules_options(void);
 char *G_color_rules_descriptions(void);
+char *G_color_rules_description_type(void);
 void G_list_color_rules(FILE *);
+void G_list_color_rules_description_type(FILE *, char *);
 int G_find_color_rule(const char *);
 
 /* color_str.c */

Modified: grass/trunk/lib/gis/color_rules.c
===================================================================
--- grass/trunk/lib/gis/color_rules.c	2018-06-26 11:29:03 UTC (rev 72912)
+++ grass/trunk/lib/gis/color_rules.c	2018-06-26 12:42:20 UTC (rev 72913)
@@ -14,9 +14,24 @@
 #include <grass/gis.h>
 #include <grass/glocale.h>
 
-static char **scan_rules(int *);
-static int cmp(const void *, const void *);
+struct colorinfo
+{
+    char *name;
+    char *desc;
+    char *type;
+};
 
+static struct colorinfo *get_colorinfo(int *);
+static void free_colorinfo(struct colorinfo *, int);
+
+static int cmp_clrname(const void *a, const void *b)
+{
+    struct colorinfo *ca = (struct colorinfo *) a;
+    struct colorinfo *cb = (struct colorinfo *) b;
+
+    return (strcmp(ca->name, cb->name));
+}
+
 /*!
   \brief Get list of color rules for Option->options
   
@@ -24,18 +39,19 @@
 */
 char *G_color_rules_options(void)
 {
-    char *list, **rules;
+    char *list;
     const char *name;
     int size, len, nrules;
     int i, n;
+    struct colorinfo *colorinfo;
 
     list = NULL;
     size = len = 0;
 
-    rules = scan_rules(&nrules);
+    colorinfo = get_colorinfo(&nrules);
     
     for (i = 0; i < nrules; i++) {
-        name = rules[i];
+        name = colorinfo[i].name;
         n = strlen(name);
 
         if (size < len + n + 2) {
@@ -50,7 +66,7 @@
         len += n;
     }
 
-    G_free(rules);
+    free_colorinfo(colorinfo, nrules);
     
     return list;
 }
@@ -62,27 +78,21 @@
 */
 char *G_color_rules_descriptions(void)
 {
-    char path[GPATH_MAX];
-    struct Key_Value *kv;
     int result_len, result_max;
-    char *result, **rules;
+    char *result;
     const char *name, *desc;
     int i, len, nrules;
+    struct colorinfo *colorinfo;
 
     result_len = 0;
     result_max = 2000;
     result = G_malloc(result_max);
-    
-    G_snprintf(path, GPATH_MAX, "%s/etc/colors.desc", G_gisbase());
-    kv = G_read_key_value_file(path);
-    if (!kv)
-        return NULL;
 
-    rules = scan_rules(&nrules);
+    colorinfo = get_colorinfo(&nrules);
     
     for (i = 0; i < nrules; i++) {
-        name = rules[i];
-        desc = G_find_key_value(name, kv);
+        name = colorinfo[i].name;
+        desc = colorinfo[i].desc;
         
         if (!desc)
 	    desc = _("no description");
@@ -99,38 +109,62 @@
         result_len += len;
     }
 
-    G_free_key_value(kv);
-    G_free(rules);
+    free_colorinfo(colorinfo, nrules);
     
     return result;
 }
 
-char **scan_rules(int *nrules)
-{
-    char **rules;
-    char path[GPATH_MAX];
+/*!
+  \brief Get color rules description for Option->descriptions
 
-    G_snprintf(path, GPATH_MAX, "%s/etc/colors", G_gisbase());
+  The type of color rule including range is appended to the description 
 
-    rules = G_ls2(path, nrules);
+  \return allocated buffer with name, description, and type
+*/
+char *G_color_rules_description_type(void)
+{
+    int i, len, nrules;
+    struct colorinfo *colorinfo;
+    const char *name, *desc, *type;
+    int result_len, result_max;
+    char *result;
+    
+    colorinfo = get_colorinfo(&nrules);
 
-    rules = G_realloc(rules, (*nrules + 3) * sizeof (const char *));
+    result_len = 0;
+    result_max = 2000;
+    result = G_malloc(result_max);
 
-    rules[(*nrules)++] = G_store("random");
-    rules[(*nrules)++] = G_store("grey.eq");
-    rules[(*nrules)++] = G_store("grey.log");
+    for (i = 0; i < nrules; i++) {
+        name = colorinfo[i].name;
+        desc = colorinfo[i].desc;
+        type = colorinfo[i].type;
 
-    qsort(rules, *nrules, sizeof (char *), cmp);
+	if (desc) {
+	    len = strlen(name) + strlen(desc) + strlen(type) + 5;
+	    if (result_len + len >= result_max) {
+		result_max = result_len + len + 1000;
+		result = G_realloc(result, result_max);
+	    }
 
-    return rules;
-}
+	    sprintf(result + result_len, "%s;%s [%s];", name, desc, type);
+	    result_len += len;
+	}
+	else {
+	    len = strlen(name) + strlen(type) + 5;
+	    if (result_len + len >= result_max) {
+		result_max = result_len + len + 1000;
+		result = G_realloc(result, result_max);
+	    }
 
-int cmp(const void *aa, const void *bb)
-{
-    char *const *a = (char *const *) aa;
-    char *const *b = (char *const *) bb;
+	    sprintf(result + result_len, "%s; [%s];", name, type);
+	    result_len += len;
+	}
+    }
 
-    return strcmp(*a, *b);
+    free_colorinfo(colorinfo, nrules);
+    
+    return result;
 }
 
 /*!
@@ -141,15 +175,68 @@
 void G_list_color_rules(FILE *out)
 {
     int i, nrules;
-    char **rules;
+    struct colorinfo *colorinfo;
 
-    rules = scan_rules(&nrules);
+    colorinfo = get_colorinfo(&nrules);
 
     for (i = 0; i < nrules; i++)
-	fprintf(out, "%s\n", rules[i]);
+	fprintf(out, "%s\n", colorinfo[i].name);
+
+    free_colorinfo(colorinfo, nrules);
 }
 
 /*!
+  \brief Print color rules with description and type
+
+  The type of color rule including range is appended to the description. 
+  If a color rule name is given, color info is printed only for this 
+  rule.
+
+  \param name optional color rule name, or NULL
+  \param out file where to print
+*/
+void G_list_color_rules_description_type(FILE *out, char *name)
+{
+    int i, nrules;
+    struct colorinfo *colorinfo, csearch, *cfound;
+    
+    colorinfo = get_colorinfo(&nrules);
+
+    cfound = NULL;
+    if (name) {
+	csearch.name = name;
+	cfound = bsearch(&csearch, colorinfo, nrules,
+			 sizeof(struct colorinfo), cmp_clrname);
+
+	if (cfound) {
+	    if (cfound->desc) {
+		fprintf(out, "%s: %s [%s]\n", cfound->name,
+			cfound->desc, cfound->type);
+	    }
+	    else {
+		fprintf(out, "%s: [%s]\n", cfound->name,
+			cfound->type);
+	    }
+	}
+    }
+
+    if (cfound == NULL) {
+	for (i = 0; i < nrules; i++) {
+	    if (colorinfo[i].desc) {
+		fprintf(out, "%s: %s [%s]\n", colorinfo[i].name,
+			colorinfo[i].desc, colorinfo[i].type);
+	    }
+	    else {
+		fprintf(out, "%s: [%s]\n", colorinfo[i].name,
+			colorinfo[i].type);
+	    }
+	}
+    }
+
+    free_colorinfo(colorinfo, nrules);
+}
+
+/*!
   \brief Check if color rule is defined
 
   \param name color rule name
@@ -159,14 +246,172 @@
 */
 int G_find_color_rule(const char *name)
 {
-    int i, nrules;
-    char **rules;
-
-    rules = scan_rules(&nrules);
+    int result, nrules;
+    struct colorinfo *colorinfo, csearch;
     
-    for (i = 0; i < nrules; i++)
-        if (strcmp(name, rules[i]) == 0)
-            return 1;
+    colorinfo = get_colorinfo(&nrules);
 
-    return 0;
+    csearch.name = (char *)name;
+    result = (bsearch(&csearch, colorinfo, nrules,
+		      sizeof(struct colorinfo), cmp_clrname) != NULL);
+
+    free_colorinfo(colorinfo, nrules);
+
+    return result;
 }
+
+struct colorinfo *get_colorinfo(int *nrules)
+{
+    int i;
+    char path[GPATH_MAX];
+    FILE *fp;
+    struct colorinfo *colorinfo;
+    char **cnames;
+
+    /* load color rules */
+    G_snprintf(path, GPATH_MAX, "%s/etc/colors", G_gisbase());
+
+    *nrules = 0;
+    cnames = G_ls2(path, nrules);
+    (*nrules) += 3;
+    colorinfo = G_malloc(*nrules * sizeof(struct colorinfo));
+    for (i = 0; i < *nrules - 3; i++) {
+	char buf[1024];
+	double rmin, rmax;
+	int first;
+	int cisperc;
+
+	colorinfo[i].name = G_store(cnames[i]);
+	colorinfo[i].desc = NULL;
+	
+	/* open color rule file */
+	G_snprintf(path, GPATH_MAX, "%s/etc/colors/%s", G_gisbase(),
+		   colorinfo[i].name);
+	fp = fopen(path, "r");
+	if (!fp)
+	    G_fatal_error(_("Unable to open color rule"));
+	
+	/* scan all lines */
+	first = 1;
+	rmin = rmax = 0;
+	cisperc = 0;
+	while (G_getl2(buf, sizeof(buf), fp)) {
+	    char value[80], color[80];
+	    double x;
+	    char c;
+
+	    G_strip(buf);
+
+	    if (*buf == '\0')
+		continue;
+	    if (*buf == '#')
+		continue;
+
+	    if (sscanf(buf, "%s %[^\n]", value, color) != 2)
+		continue;
+
+	    if (G_strcasecmp(value, "default") == 0) {
+		continue;
+	    }
+
+	    if (G_strcasecmp(value, "nv") == 0) {
+		continue;
+	    }
+
+	    if (sscanf(value, "%lf%c", &x, &c) == 2 && c == '%') {
+		cisperc = 1;
+		break;
+	    }
+	    if (sscanf(value, "%lf", &x) == 1) {
+		if (first) {
+		    first = 0;
+		    rmin = rmax = x;
+		}
+		else {
+		    if (rmin > x)
+			rmin = x;
+		    if (rmax < x)
+			rmax = x;
+		}
+	    }
+	}
+	fclose(fp);
+
+	if (cisperc)
+	    colorinfo[i].type = G_store(_("range: map values"));
+	else {
+	    G_snprintf(buf, sizeof(buf) - 1, _("range: %g to %g"), rmin, rmax);
+	    colorinfo[i].type = G_store(buf);
+	}
+    }
+    G_free(cnames);
+
+    /* colors without rules but description */
+    colorinfo[*nrules - 3].name = G_store("random");
+    colorinfo[*nrules - 3].desc = NULL;
+    colorinfo[*nrules - 3].type = G_store(_("range: map values"));
+
+    colorinfo[*nrules - 2].name = G_store("grey.eq");
+    colorinfo[*nrules - 2].desc = NULL;
+    colorinfo[*nrules - 2].type = G_store(_("range: map values"));
+
+    colorinfo[*nrules - 1].name = G_store("grey.log");
+    colorinfo[*nrules - 1].desc = NULL;
+    colorinfo[*nrules - 1].type = G_store(_("range: map values"));
+
+    qsort(colorinfo, *nrules, sizeof(struct colorinfo), cmp_clrname);
+
+    /* load color descriptions */
+    G_snprintf(path, GPATH_MAX, "%s/etc/colors.desc", G_gisbase());
+    fp = fopen(path, "r");
+    if (!fp)
+	G_fatal_error(_("Unable to open color descriptions"));
+
+    for (;;) {
+	char buf[1024];
+	char tok_buf[1024];
+	char *cname, *cdesc;
+	int ntokens;
+	char **tokens;
+	struct colorinfo csearch, *cfound;
+
+	if (!G_getl2(buf, sizeof(buf), fp))
+	    break;
+	strcpy(tok_buf, buf);
+	tokens = G_tokenize(tok_buf, ":");
+	ntokens = G_number_of_tokens(tokens);
+	if (ntokens != 2)
+	    continue;
+
+	cname = G_chop(tokens[0]);
+	cdesc = G_chop(tokens[1]);
+	
+	csearch.name = cname;
+	cfound = bsearch(&csearch, colorinfo, *nrules,
+			 sizeof(struct colorinfo), cmp_clrname);
+
+	if (cfound) {
+	    cfound->desc = G_store(cdesc);
+	}
+	G_free_tokens(tokens);
+    }
+    fclose(fp);
+
+    return colorinfo;
+}
+
+void free_colorinfo(struct colorinfo *colorinfo, int nrules)
+{
+    int i;
+
+    for (i = 0; i < nrules; i++) {
+	if (colorinfo[i].name)
+	    G_free(colorinfo[i].name);
+	if (colorinfo[i].desc)
+	    G_free(colorinfo[i].desc);
+	if (colorinfo[i].type)
+	    G_free(colorinfo[i].type);
+    }
+    if (nrules > 0)
+	G_free(colorinfo);
+}

Modified: grass/trunk/lib/gis/parser_standard_options.c
===================================================================
--- grass/trunk/lib/gis/parser_standard_options.c	2018-06-26 11:29:03 UTC (rev 72912)
+++ grass/trunk/lib/gis/parser_standard_options.c	2018-06-26 12:42:20 UTC (rev 72913)
@@ -713,7 +713,7 @@
 	Opt->required = NO;
 	Opt->options = G_color_rules_options();
 	Opt->description = _("Name of color table");
-	Opt->descriptions = G_color_rules_descriptions();
+	Opt->descriptions = G_color_rules_description_type();
         Opt->gisprompt = "old,colortable,colortable";
 	break;
         



More information about the grass-commit mailing list