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