percent.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * \file gis/percent.c
  3. *
  4. * \brief GIS Library - percentage progress functions.
  5. *
  6. * (C) 2001-2009 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. #include <stdio.h>
  14. #include <grass/gis.h>
  15. static struct state {
  16. int prev;
  17. int first;
  18. } state = {-1, 1};
  19. static struct state *st = &state;
  20. static int (*ext_percent) (int);
  21. /**
  22. * \brief Print percent complete messages.
  23. *
  24. * This routine prints a percentage complete message to stderr. The
  25. * percentage complete is <i>(<b>n</b>/<b>d</b>)*100</i>, and these are
  26. * printed only for each <b>s</b> percentage. This is perhaps best
  27. * explained by example:
  28. \code
  29. #include <stdio.h>
  30. #include <grass/gis.h>
  31. int row;
  32. int nrows;
  33. nrows = 1352; // 1352 is not a special value - example only
  34. G_message(_("Percent complete..."));
  35. for (row = 0; row < nrows; row++)
  36. {
  37. G_percent(row, nrows, 10);
  38. do_calculation(row);
  39. }
  40. G_percent(1, 1, 1);
  41. \endcode
  42. *
  43. * This example code will print completion messages at 10% increments;
  44. * i.e., 0%, 10%, 20%, 30%, etc., up to 100%. Each message does not appear
  45. * on a new line, but rather erases the previous message.
  46. *
  47. * Note that to prevent the illusion of the module stalling, the G_percent()
  48. * call is placed before the time consuming part of the for loop, and an
  49. * additional call is generally needed after the loop to "finish it off"
  50. * at 100%.
  51. *
  52. * \param n current element
  53. * \param d total number of elements
  54. * \param s increment size
  55. *
  56. * \return always returns 0
  57. */
  58. void G_percent(long n, long d, int s)
  59. {
  60. int x, format;
  61. format = G_info_format();
  62. x = (d <= 0 || s <= 0)
  63. ? 100 : (int)(100 * n / d);
  64. /* be verbose only 1> */
  65. if (format == G_INFO_FORMAT_SILENT || G_verbose() < 1)
  66. return;
  67. if (n <= 0 || n >= d || x > st->prev + s) {
  68. st->prev = x;
  69. if (ext_percent) {
  70. ext_percent(x);
  71. }
  72. else {
  73. if (format == G_INFO_FORMAT_STANDARD) {
  74. fprintf(stderr, "%4d%%\b\b\b\b\b", x);
  75. }
  76. else {
  77. if (format == G_INFO_FORMAT_PLAIN) {
  78. if (x == 100)
  79. fprintf(stderr, "%d\n", x);
  80. else
  81. fprintf(stderr, "%d..", x);
  82. }
  83. else { /* GUI */
  84. if (st->first) {
  85. fprintf(stderr, "\n");
  86. }
  87. fprintf(stderr, "GRASS_INFO_PERCENT: %d\n", x);
  88. fflush(stderr);
  89. st->first = 0;
  90. }
  91. }
  92. }
  93. }
  94. if (x >= 100) {
  95. if (ext_percent) {
  96. ext_percent(100);
  97. }
  98. else if (format == G_INFO_FORMAT_STANDARD) {
  99. fprintf(stderr, "\n");
  100. }
  101. st->prev = -1;
  102. st->first = 1;
  103. }
  104. }
  105. /**
  106. * \brief Reset G_percent() to 0%; do not add newline.
  107. *
  108. * \return always returns 0
  109. */
  110. void G_percent_reset(void)
  111. {
  112. st->prev = -1;
  113. st->first = 1;
  114. }
  115. /**
  116. * \brief Establishes percent_routine as the routine that will handle
  117. * the printing of percentage progress messages.
  118. *
  119. * \param percent_routine routine will be called like this: percent_routine(x)
  120. */
  121. void G_set_percent_routine(int (*percent_routine) (int))
  122. {
  123. ext_percent = percent_routine;
  124. }
  125. /**
  126. * \brief After this call subsequent percentage progress messages will
  127. * be handled in the default method.
  128. *
  129. * Percentage progress messages are printed directly to stderr.
  130. */
  131. void G_unset_percent_routine(void)
  132. {
  133. ext_percent = NULL;
  134. }