GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
percent.c
Go to the documentation of this file.
1/*!
2 \file lib/gis/percent.c
3
4 \brief GIS Library - percentage progress functions.
5
6 (C) 2001-2009, 2011 by the GRASS Development Team
7
8 This program is free software under the GNU General Public License
9 (>=v2). Read the file COPYING that comes with GRASS for details.
10
11 \author GRASS GIS Development Team
12 */
13
14#include <stdio.h>
15#include <grass/gis.h>
16
17static struct state {
18 int prev;
19 int first;
20} state = {-1, 1};
21
22static struct state *st = &state;
23static int (*ext_percent)(int);
24
25/*!
26 \brief Print percent complete messages.
27
28 This routine prints a percentage complete message to stderr. The
29 percentage complete is <i>(<b>n</b>/<b>d</b>)*100</i>, and these are
30 printed only for each <b>s</b> percentage. This is perhaps best
31 explained by example:
32 \code
33 #include <stdio.h>
34 #include <grass/gis.h>
35 int row;
36 int nrows;
37 nrows = 1352; // 1352 is not a special value - example only
38
39 G_message(_("Percent complete..."));
40 for (row = 0; row < nrows; row++)
41 {
42 G_percent(row, nrows, 10);
43 do_calculation(row);
44 }
45 G_percent(1, 1, 1);
46 \endcode
47
48 This example code will print completion messages at 10% increments;
49 i.e., 0%, 10%, 20%, 30%, etc., up to 100%. Each message does not appear
50 on a new line, but rather erases the previous message.
51
52 Note that to prevent the illusion of the module stalling, the G_percent()
53 call is placed before the time consuming part of the for loop, and an
54 additional call is generally needed after the loop to "finish it off"
55 at 100%.
56
57 \param n current element
58 \param d total number of elements
59 \param s increment size
60 */
61void G_percent(long n, long d, int s)
62{
63 int x, format;
64
65 format = G_info_format();
66
67 x = (d <= 0 || s <= 0) ? 100 : (int)(100 * n / d);
68
69 /* be verbose only 1> */
70 if (format == G_INFO_FORMAT_SILENT || G_verbose() < 1)
71 return;
72
73 if (n <= 0 || n >= d || x > st->prev + s) {
74 st->prev = x;
75
76 if (ext_percent) {
77 ext_percent(x);
78 }
79 else {
80 if (format == G_INFO_FORMAT_STANDARD) {
81 fprintf(stderr, "%4d%%\b\b\b\b\b", x);
82 }
83 else {
84 if (format == G_INFO_FORMAT_PLAIN) {
85 if (x == 100)
86 fprintf(stderr, "%d\n", x);
87 else
88 fprintf(stderr, "%d..", x);
89 }
90 else { /* GUI */
91 if (st->first) {
92 fprintf(stderr, "\n");
93 }
94 fprintf(stderr, "GRASS_INFO_PERCENT: %d\n", x);
95 fflush(stderr);
96 st->first = 0;
97 }
98 }
99 }
100 }
101
102 if (x >= 100) {
103 if (ext_percent) {
104 ext_percent(100);
105 }
106 else if (format == G_INFO_FORMAT_STANDARD) {
107 fprintf(stderr, "\n");
108 }
109 st->prev = -1;
110 st->first = 1;
111 }
112}
113
114/*!
115 \brief Reset G_percent() to 0%; do not add newline.
116 */
118{
119 st->prev = -1;
120 st->first = 1;
121}
122
123/*!
124 \brief Print progress info messages
125
126 Use G_percent() when number of elements is defined.
127
128 This routine prints a progress info message to stderr. The value
129 <b>n</b> is printed only for each <b>s</b>. This is perhaps best
130 explained by example:
131 \code
132 #include <grass/vector.h>
133
134 int line;
135
136 G_message(_("Reading features..."));
137 line = 0;
138 while(TRUE)
139 {
140 if (Vect_read_next_line(Map, Points, Cats) < 0)
141 break;
142 line++;
143 G_progress(line, 1e3);
144 }
145 G_progress(1, 1);
146 \endcode
147
148 This example code will print progress in messages at 1000
149 increments; i.e., 1000, 2000, 3000, 4000, etc., up to number of
150 features for given vector map. Each message does not appear on a new
151 line, but rather erases the previous message.
152
153 \param n current element
154 \param s increment size
155
156 \return always returns 0
157 */
158void G_progress(long n, int s)
159{
160 int format;
161
162 format = G_info_format();
163
164 /* be verbose only 1> */
165 if (format == G_INFO_FORMAT_SILENT || G_verbose() < 1)
166 return;
167
168 if (n == s && n == 1) {
169 if (format == G_INFO_FORMAT_PLAIN)
170 fprintf(stderr, "\n");
171 else if (format != G_INFO_FORMAT_GUI)
172 fprintf(stderr, "\r");
173 return;
174 }
175
176 if (n % s == 0) {
177 if (format == G_INFO_FORMAT_PLAIN)
178 fprintf(stderr, "%ld..", n);
179 else if (format == G_INFO_FORMAT_GUI)
180 fprintf(stderr, "GRASS_INFO_PROGRESS: %ld\n", n);
181 else
182 fprintf(stderr, "%10ld\b\b\b\b\b\b\b\b\b\b", n);
183 }
184}
185
186/*!
187 \brief Establishes percent_routine as the routine that will handle
188 the printing of percentage progress messages.
189
190 \param percent_routine routine will be called like this: percent_routine(x)
191 */
192void G_set_percent_routine(int (*percent_routine)(int))
193{
194 ext_percent = percent_routine;
195}
196
197/*!
198 \brief After this call subsequent percentage progress messages will
199 be handled in the default method.
200
201 Percentage progress messages are printed directly to stderr.
202 */
204{
205 ext_percent = NULL;
206}
#define NULL
Definition ccmath.h:32
int G_info_format(void)
Get current message format.
Definition gis/error.c:537
void G_percent_reset(void)
Reset G_percent() to 0%; do not add newline.
Definition percent.c:117
void G_unset_percent_routine(void)
After this call subsequent percentage progress messages will be handled in the default method.
Definition percent.c:203
void G_percent(long n, long d, int s)
Print percent complete messages.
Definition percent.c:61
void G_set_percent_routine(int(*percent_routine)(int))
Establishes percent_routine as the routine that will handle the printing of percentage progress messa...
Definition percent.c:192
void G_progress(long n, int s)
Print progress info messages.
Definition percent.c:158
int G_verbose(void)
Get current verbosity level.
Definition verbose.c:60
#define x