parse.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #include <string.h>
  2. #include <grass/gis.h>
  3. #include <grass/raster.h>
  4. #include <grass/glocale.h>
  5. #include "rule.h"
  6. static int scan_value(CELL *);
  7. static const char *cur;
  8. static int state;
  9. int default_rule = 0;
  10. int default_to_itself = 0;
  11. char *default_label;
  12. CELL DEFAULT;
  13. int parse(const char *line, RULE ** rules, RULE ** tail, struct Categories *cats)
  14. {
  15. const char *label;
  16. const char *save;
  17. CELL v;
  18. CELL lo[100], hi[100], new = (CELL) 0;
  19. int count;
  20. int i, last_null = 0;
  21. cur = line;
  22. state = 0;
  23. count = 0;
  24. label = "";
  25. while (*cur == ' ' || *cur == '\t' || *cur == '\n')
  26. cur++;
  27. while (*cur) {
  28. while (*cur == ' ' || *cur == '\t' || *cur == '\n')
  29. cur++;
  30. if (!*cur)
  31. break;
  32. switch (state) {
  33. case 0:
  34. save = cur;
  35. if (!strncmp(cur, "help", 4)) { /* help text */
  36. fprintf(stdout, _("Enter a rule in one of these formats:\n"));
  37. fprintf(stdout, "1 3 5 = 1 %s\n", _("poor quality"));
  38. fprintf(stdout, "1 thru 10 = 1\n");
  39. fprintf(stdout, "20 thru 50 = 2 %s\n", _("medium quality"));
  40. fprintf(stdout, "* = NULL\n");
  41. state = 0;
  42. cur += 4;
  43. continue;
  44. }
  45. if (*cur == '*') { /* default rule */
  46. default_rule = 1;
  47. state = 1;
  48. cur++;
  49. continue;
  50. }
  51. if (!scan_value(&v))
  52. return -1;
  53. if (Rast_is_c_null_value(&v)) {
  54. G_warning(_("Can't have null on the left-hand side of the rule"));
  55. return -1;
  56. }
  57. state = 1;
  58. cur = save;
  59. continue;
  60. case 1:
  61. if (*cur == '=') {
  62. cur++;
  63. state = 4;
  64. continue;
  65. }
  66. if (default_rule)
  67. return -1;
  68. if (!scan_value(&v))
  69. return -1;
  70. if (Rast_is_c_null_value(&v))
  71. last_null = 1;
  72. else
  73. last_null = 0;
  74. lo[count] = hi[count] = v;
  75. count++;
  76. state = 2;
  77. continue;
  78. case 2:
  79. state = 1;
  80. if (strncmp(cur, "thru", 4) != 0)
  81. continue;
  82. if (last_null) {
  83. G_warning(_("Can't have null on the right-hand side of the rule"));
  84. return -1;
  85. }
  86. cur += 4;
  87. if (*cur != ' ' && *cur != '\t')
  88. return -1;
  89. state = 3;
  90. continue;
  91. case 3:
  92. if (!scan_value(&v))
  93. return -1;
  94. if (Rast_is_c_null_value(&v)) {
  95. G_warning(_("Can't have null on the right-hand side of the rule"));
  96. return -1;
  97. }
  98. if (lo[count - 1] > v) {
  99. hi[count - 1] = lo[count - 1];
  100. lo[count - 1] = v;
  101. }
  102. else
  103. hi[count - 1] = v;
  104. state = 1;
  105. continue;
  106. case 4:
  107. if (*cur == '*' && default_rule) {
  108. cur++;
  109. new = 0;
  110. default_to_itself = 1;
  111. state = 5;
  112. continue;
  113. }
  114. if (!scan_value(&v))
  115. return -1;
  116. new = v;
  117. state = 5;
  118. continue;
  119. case 5:
  120. label = cur;
  121. cur = ""; /* force break from while */
  122. }
  123. }
  124. if (state > 0 && state < 5)
  125. return -1;
  126. if (default_rule) {
  127. DEFAULT = new;
  128. default_label = G_store((*label ? label : ""));
  129. return 1;
  130. }
  131. for (i = 0; i < count; i++) {
  132. add_rule(tail, lo[i], hi[i], new);
  133. if (*rules == NULL)
  134. *rules = *tail;
  135. if (*label)
  136. Rast_set_c_cat(&new, &new, label, cats);
  137. }
  138. return count;
  139. }
  140. static int scan_value(CELL * v)
  141. {
  142. int i, sign, dec;
  143. double fv, fd;
  144. if (strncmp(cur, "null", 4) == 0 || strncmp(cur, "NULL", 4) == 0) {
  145. cur += 4;
  146. Rast_set_c_null_value(v, 1);
  147. }
  148. else {
  149. sign = 1;
  150. if (*cur == '-') {
  151. sign = -1;
  152. cur++;
  153. }
  154. /*
  155. if (*cur < '0' || *cur > '9')
  156. return 0;
  157. *v = *cur++ - '0' ;
  158. */
  159. dec = 0;
  160. fv = 0.0;
  161. while ((*cur >= '0' && *cur <= '9') || *cur == '.') {
  162. if (*cur == '.') {
  163. if (!dec)
  164. dec++;
  165. cur++;
  166. continue;
  167. }
  168. if (!dec)
  169. fv = fv * 10 + *cur++ - '0';
  170. else {
  171. fd = 1.0;
  172. for (i = 0; i < dec; i++)
  173. fd *= 0.1;
  174. dec++;
  175. fv += (*cur++ - '0') * fd;
  176. }
  177. }
  178. if (dec)
  179. fv += 0.5;
  180. *v = sign * (CELL) fv;
  181. if (dec && state)
  182. fprintf(stdout, _("%f rounded up to %d\n"), sign * fv, *v);
  183. }
  184. switch (*cur) {
  185. case 0:
  186. case ' ':
  187. case '\t':
  188. case '\n':
  189. case '=':
  190. return 1;
  191. default:
  192. return 0;
  193. }
  194. }