1 #include <string.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <grass/gis.h>
5 #include <grass/glocale.h>
6 #include <grass/spawn.h>
7 #include "global.h"
8 
9 static int die(void);
10 
get_stats(void)11 int get_stats(void)
12 {
13     char buf[1024];
14     int i, nl, ns;
15     FILE *fd;
16     char **tokens;
17 
18     if (stats_flag == EVERYTHING)
19 	stats_file = G_tempfile();
20 
21     if (stats_flag != REPORT_ONLY) {
22 	char tmp[50];
23 	int n_argv = 50;
24 	const char **argv = G_calloc(n_argv, sizeof(*argv));
25 	int argc = 0;
26 
27 	argv[argc++] = "r.stats";
28 	argv[argc++] = "-acr";
29 
30 	/* if (!masking) argv[argc++] = "-m"; */
31 	if (G_verbose() == G_verbose_min())
32 	    argv[argc++] = "--quiet";
33 
34 	if (no_nulls)
35 	    argv[argc++] = "-n";
36 
37 	if (no_nulls_all)
38 	    argv[argc++] = "-N";
39 
40 	if (as_int)
41 	    argv[argc++] = "-i";
42 
43 	if (cat_ranges)
44 	    argv[argc++] = "-C";
45 	else if (nsteps != 255) {
46 	    sprintf(tmp, "nsteps=%d", nsteps);
47 	    argv[argc++] = tmp;
48 	}
49 
50 	argv[argc++] = "separator=:";
51 
52 	argv[argc++] = SF_REDIRECT_FILE;
53 	argv[argc++] = SF_STDOUT;
54 	argv[argc++] = SF_MODE_OUT;
55 	argv[argc++] = stats_file;
56 
57         if (do_sort == SORT_ASC)
58             argv[argc++] = "sort=asc";
59         else if (do_sort == SORT_DESC)
60             argv[argc++] = "sort=desc";
61 
62 	for (i = 0; i < nlayers; i++) {
63 	    char *name = G_fully_qualified_name(layers[i].name, layers[i].mapset);
64 	    char *buf = G_malloc(6 + strlen(name) + 1);
65 
66 	    sprintf(buf, "input=%s", name);
67 	    G_free(name);
68 
69 	    if (argc + 1 >= n_argv) {
70 		n_argv += 50;
71 		argv = G_realloc(argv, n_argv * sizeof(*argv));
72 	    }
73 
74 	    argv[argc++] = buf;
75 	}
76 
77 	argv[argc++] = NULL;
78 
79 	if (G_vspawn_ex(argv[0], argv) != 0) {
80 	    remove(stats_file);
81 	    G_fatal_error("error running r.stats");
82 	}
83     }
84 
85     if (stats_flag == STATS_ONLY)
86 	return 0;
87 
88     fd = fopen(stats_file, "r");
89 
90     if (fd == NULL) {
91 	if (stats_flag == EVERYTHING)
92 	    unlink(stats_file);
93 	G_fatal_error(_("Unable to open result file <%s>"), stats_file);
94     }
95 
96     while (G_getl(buf, sizeof buf, fd)) {
97 	tokens = G_tokenize(buf, ":");
98 	i = 0;
99 	ns = nstats++;
100 	Gstats = (GSTATS *) G_realloc(Gstats, nstats * sizeof(GSTATS));
101 	Gstats[ns].cats = (CELL *) G_calloc(nlayers, sizeof(long));
102 	for (nl = 0; nl < nlayers; nl++) {
103 	    if (sscanf(tokens[i], "%d", &Gstats[ns].cats[nl]) != 1) {
104 		if (tokens[i][0] == '*')
105 		    Rast_set_c_null_value(&Gstats[ns].cats[nl], 1);
106 		else
107 		    die();
108 	    }
109 	    i++;
110 	}
111 	if (sscanf(tokens[i++], "%lf", &Gstats[ns].area) != 1)
112 	    die();
113 	if (sscanf(tokens[i++], "%ld", &Gstats[ns].count) != 1)
114 	    die();
115 	G_free_tokens(tokens);
116     }
117     fclose(fd);
118     if (stats_flag == EVERYTHING)
119 	unlink(stats_file);
120 
121     return 0;
122 }
123 
die(void)124 static int die(void)
125 {
126     if (stats_flag == EVERYTHING)
127 	unlink(stats_file);
128     G_fatal_error(_("Problem reading r.stats output"));
129 }
130