main.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /****************************************************************************
  2. *
  3. * MODULE: r.mapcalc
  4. * AUTHOR(S): Michael Shapiro, CERL (original contributor)
  5. * rewritten 2002: Glynn Clements <glynn gclements.plus.com>
  6. * PURPOSE:
  7. * COPYRIGHT: (C) 1999-2007 by the GRASS Development Team
  8. *
  9. * This program is free software under the GNU General Public
  10. * License (>=v2). Read the file COPYING that comes with GRASS
  11. * for details.
  12. *
  13. *****************************************************************************/
  14. #include <unistd.h>
  15. #include <signal.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <grass/glocale.h>
  20. #include "mapcalc.h"
  21. /****************************************************************************/
  22. int overflow_occurred;
  23. int overwrite_flag;
  24. volatile int floating_point_exception;
  25. volatile int floating_point_exception_occurred;
  26. long seed_value;
  27. long seeded;
  28. /****************************************************************************/
  29. static expr_list *result;
  30. /****************************************************************************/
  31. static RETSIGTYPE handle_fpe(int n)
  32. {
  33. floating_point_exception = 1;
  34. floating_point_exception_occurred = 1;
  35. }
  36. static void pre_exec(void)
  37. {
  38. #ifndef __MINGW32__
  39. #ifdef SIGFPE
  40. struct sigaction act;
  41. act.sa_handler = &handle_fpe;
  42. act.sa_flags = 0;
  43. sigemptyset(&act.sa_mask);
  44. sigaction(SIGFPE, &act, NULL);
  45. #endif
  46. #endif
  47. floating_point_exception_occurred = 0;
  48. overflow_occurred = 0;
  49. }
  50. static void post_exec(void)
  51. {
  52. #ifndef __MINGW32__
  53. #ifdef SIGFPE
  54. struct sigaction act;
  55. act.sa_handler = SIG_DFL;
  56. act.sa_flags = 0;
  57. sigemptyset(&act.sa_mask);
  58. sigaction(SIGFPE, &act, NULL);
  59. #endif
  60. #endif
  61. }
  62. /****************************************************************************/
  63. static expr_list *parse_file(const char *filename)
  64. {
  65. expr_list *res;
  66. FILE *fp;
  67. if (strcmp(filename, "-") == 0)
  68. return parse_stream(stdin);
  69. fp = fopen(filename, "r");
  70. if (!fp)
  71. G_fatal_error(_("Unable to open input file <%s>"), filename);
  72. res = parse_stream(fp);
  73. fclose(fp);
  74. return res;
  75. }
  76. /****************************************************************************/
  77. int main(int argc, char **argv)
  78. {
  79. struct GModule *module;
  80. struct Option *expr, *file, *seed;
  81. struct Flag *random;
  82. int all_ok;
  83. G_gisinit(argv[0]);
  84. module = G_define_module();
  85. G_add_keyword(_("raster"));
  86. G_add_keyword(_("algebra"));
  87. module->description = _("Raster map calculator.");
  88. module->overwrite = 1;
  89. expr = G_define_option();
  90. expr->key = "expression";
  91. expr->type = TYPE_STRING;
  92. expr->required = NO;
  93. expr->description = _("Expression to evaluate");
  94. expr->guisection = _("Expression");
  95. file = G_define_standard_option(G_OPT_F_INPUT);
  96. file->key = "file";
  97. file->required = NO;
  98. file->description = _("File containing expression(s) to evaluate");
  99. file->guisection = _("Expression");
  100. seed = G_define_option();
  101. seed->key = "seed";
  102. seed->type = TYPE_INTEGER;
  103. seed->required = NO;
  104. seed->description = _("Seed for rand() function");
  105. random = G_define_flag();
  106. random->key = 's';
  107. random->description = _("Generate random seed (result is non-deterministic)");
  108. if (argc == 1)
  109. {
  110. char **p = G_malloc(3 * sizeof(char *));
  111. p[0] = argv[0];
  112. p[1] = G_store("file=-");
  113. p[2] = NULL;
  114. argv = p;
  115. argc = 2;
  116. }
  117. if (G_parser(argc, argv))
  118. exit(EXIT_FAILURE);
  119. overwrite_flag = module->overwrite;
  120. if (expr->answer && file->answer)
  121. G_fatal_error(_("file= and expression= are mutually exclusive"));
  122. if (seed->answer && random->answer)
  123. G_fatal_error(_("%s= and -%c are mutually exclusive"),
  124. seed->key, random->key);
  125. if (expr->answer)
  126. result = parse_string(expr->answer);
  127. else if (file->answer)
  128. result = parse_file(file->answer);
  129. else
  130. result = parse_stream(stdin);
  131. if (!result)
  132. G_fatal_error(_("parse error"));
  133. if (seed->answer) {
  134. seed_value = atol(seed->answer);
  135. G_srand48(seed_value);
  136. seeded = 1;
  137. G_debug(3, "Read random seed from seed=: %ld", seed_value);
  138. }
  139. if (random->answer) {
  140. seed_value = G_srand48_auto();
  141. seeded = 1;
  142. G_debug(3, "Generated random seed (-s): %ld", seed_value);
  143. }
  144. pre_exec();
  145. execute(result);
  146. post_exec();
  147. all_ok = 1;
  148. if (floating_point_exception_occurred) {
  149. G_warning(_("Floating point error(s) occurred in the calculation"));
  150. all_ok = 0;
  151. }
  152. if (overflow_occurred) {
  153. G_warning(_("Overflow occurred in the calculation"));
  154. all_ok = 0;
  155. }
  156. return all_ok ? EXIT_SUCCESS : EXIT_FAILURE;
  157. }
  158. /****************************************************************************/