GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-8cbe8fef7c
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 
17 static struct state {
18  int prev;
19  int first;
20 } state = {-1, 1};
21 
22 static struct state *st = &state;
23 static 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  */
61 void 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  */
117 void G_percent_reset(void)
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  */
158 void 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  */
192 void 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_verbose(void)
Get current verbosity level.
Definition: verbose.c:60
int G_info_format(void)
Get current message format.
Definition: gis/error.c:537
#define G_INFO_FORMAT_GUI
Definition: gis.h:386
#define G_INFO_FORMAT_PLAIN
Definition: gis.h:388
#define G_INFO_FORMAT_STANDARD
Definition: gis.h:384
#define G_INFO_FORMAT_SILENT
Definition: gis.h:387
struct state state
Definition: parser.c:103
struct state * st
Definition: parser.c:104
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
#define x