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