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