[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