mittens 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/Gemfile +2 -1
  4. data/README.md +2 -2
  5. data/Rakefile +12 -5
  6. data/ext/mittens/extconf.rb +3 -1
  7. data/lib/mittens/version.rb +1 -1
  8. data/vendor/snowball/.github/workflows/ci.yml +144 -17
  9. data/vendor/snowball/.github/workflows/coverage.yml +117 -0
  10. data/vendor/snowball/.github/workflows/runtime-tests.yml +26 -0
  11. data/vendor/snowball/.gitignore +33 -7
  12. data/vendor/snowball/CONTRIBUTING.rst +7 -0
  13. data/vendor/snowball/COPYING +1 -1
  14. data/vendor/snowball/GNUmakefile +736 -298
  15. data/vendor/snowball/NEWS +1394 -7
  16. data/vendor/snowball/README.rst +8 -8
  17. data/vendor/snowball/ada/generate/generate.adb +5 -5
  18. data/vendor/snowball/ada/src/stemmer.adb +177 -188
  19. data/vendor/snowball/ada/src/stemmer.ads +86 -89
  20. data/vendor/snowball/ada/src/stemwords.adb +21 -5
  21. data/vendor/snowball/algorithms/czech.sbl +255 -0
  22. data/vendor/snowball/algorithms/danish.sbl +22 -10
  23. data/vendor/snowball/algorithms/english.sbl +7 -4
  24. data/vendor/snowball/algorithms/esperanto.sbl +6 -7
  25. data/vendor/snowball/algorithms/estonian.sbl +9 -4
  26. data/vendor/snowball/algorithms/finnish.sbl +33 -21
  27. data/vendor/snowball/algorithms/german.sbl +5 -0
  28. data/vendor/snowball/algorithms/indonesian.sbl +115 -96
  29. data/vendor/snowball/algorithms/italian.sbl +26 -1
  30. data/vendor/snowball/algorithms/lithuanian.sbl +13 -13
  31. data/vendor/snowball/algorithms/norwegian.sbl +17 -6
  32. data/vendor/snowball/algorithms/persian.sbl +387 -0
  33. data/vendor/snowball/algorithms/polish.sbl +177 -0
  34. data/vendor/snowball/algorithms/sesotho.sbl +115 -0
  35. data/vendor/snowball/algorithms/turkish.sbl +4 -4
  36. data/vendor/snowball/compiler/analyser.c +2002 -711
  37. data/vendor/snowball/compiler/driver.c +460 -298
  38. data/vendor/snowball/compiler/generator.c +439 -1965
  39. data/vendor/snowball/compiler/generator_ada.c +605 -430
  40. data/vendor/snowball/compiler/generator_c.c +2227 -0
  41. data/vendor/snowball/compiler/generator_csharp.c +365 -274
  42. data/vendor/snowball/compiler/generator_dart.c +1476 -0
  43. data/vendor/snowball/compiler/generator_go.c +348 -270
  44. data/vendor/snowball/compiler/generator_java.c +330 -233
  45. data/vendor/snowball/compiler/generator_js.c +534 -385
  46. data/vendor/snowball/compiler/generator_pascal.c +361 -320
  47. data/vendor/snowball/compiler/generator_php.c +1445 -0
  48. data/vendor/snowball/compiler/generator_python.c +399 -299
  49. data/vendor/snowball/compiler/generator_rust.c +370 -261
  50. data/vendor/snowball/compiler/generator_zig.c +1474 -0
  51. data/vendor/snowball/compiler/header.h +153 -86
  52. data/vendor/snowball/compiler/space.c +121 -63
  53. data/vendor/snowball/compiler/tokeniser.c +286 -182
  54. data/vendor/snowball/compiler/tokens.h +71 -0
  55. data/vendor/snowball/csharp/Snowball/Among.cs +14 -26
  56. data/vendor/snowball/csharp/Snowball/AssemblyInfo.cs +3 -3
  57. data/vendor/snowball/csharp/Snowball/Stemmer.cs +41 -45
  58. data/vendor/snowball/csharp/Stemwords/Program.cs +20 -14
  59. data/vendor/snowball/cxx/.gitignore +4 -0
  60. data/vendor/snowball/cxx/generate_algorithms.pl +87 -0
  61. data/vendor/snowball/cxx/stemmer.h +12 -0
  62. data/vendor/snowball/cxx/stemwords.cxx +176 -0
  63. data/vendor/snowball/cxx/utilities.cxx +2 -0
  64. data/vendor/snowball/dart/.gitignore +4 -0
  65. data/vendor/snowball/dart/analysis_options.yaml +1 -0
  66. data/vendor/snowball/dart/example/test_app.dart +65 -0
  67. data/vendor/snowball/dart/generate_algorithms.pl +21 -0
  68. data/vendor/snowball/dart/lib/snowball.dart +18 -0
  69. data/vendor/snowball/dart/lib/src/snowball.dart +339 -0
  70. data/vendor/snowball/dart/pubspec.yaml +17 -0
  71. data/vendor/snowball/doc/libstemmer_dart_README +37 -0
  72. data/vendor/snowball/doc/libstemmer_js_README +2 -2
  73. data/vendor/snowball/doc/libstemmer_php_README +38 -0
  74. data/vendor/snowball/doc/libstemmer_python_README +3 -3
  75. data/vendor/snowball/examples/stemwords.c +18 -3
  76. data/vendor/snowball/go/README.md +12 -4
  77. data/vendor/snowball/go/env.go +12 -14
  78. data/vendor/snowball/go/stemwords/main.go +2 -1
  79. data/vendor/snowball/java/org/tartarus/snowball/CharArraySequence.java +36 -0
  80. data/vendor/snowball/java/org/tartarus/snowball/SnowballProgram.java +17 -34
  81. data/vendor/snowball/java/org/tartarus/snowball/SnowballStemmer.java +0 -2
  82. data/vendor/snowball/javascript/base-stemmer.js +219 -252
  83. data/vendor/snowball/javascript/stemwords.js +86 -58
  84. data/vendor/snowball/libstemmer/mkmodules.pl +1 -1
  85. data/vendor/snowball/libstemmer/modules.txt +4 -0
  86. data/vendor/snowball/pascal/SnowballProgram.pas +18 -31
  87. data/vendor/snowball/php/base-stemmer.php +453 -0
  88. data/vendor/snowball/php/stemwords.php +25 -0
  89. data/vendor/snowball/python/create_init.py +16 -21
  90. data/vendor/snowball/python/pyproject.toml +3 -0
  91. data/vendor/snowball/python/setup.py +5 -7
  92. data/vendor/snowball/python/snowballstemmer/among.py +1 -2
  93. data/vendor/snowball/python/snowballstemmer/basestemmer.py +24 -33
  94. data/vendor/snowball/python/stemwords.py +72 -63
  95. data/vendor/snowball/runtime/api.c +11 -42
  96. data/vendor/snowball/runtime/api.h +11 -9
  97. data/vendor/snowball/runtime/snowball_runtime.h +110 -0
  98. data/vendor/snowball/runtime/utilities.c +282 -106
  99. data/vendor/snowball/rust/src/main.rs +2 -2
  100. data/vendor/snowball/rust/src/snowball/snowball_env.rs +7 -9
  101. data/vendor/snowball/tests/compilertest +62 -0
  102. data/vendor/snowball/tests/errors/ae-errors.sbl +53 -0
  103. data/vendor/snowball/tests/errors/ae-errors.stderr +8 -0
  104. data/vendor/snowball/tests/errors/bad-dollar.sbl +14 -0
  105. data/vendor/snowball/tests/errors/bad-dollar.stderr +4 -0
  106. data/vendor/snowball/tests/errors/bad-grouping-definition.sbl +9 -0
  107. data/vendor/snowball/tests/errors/bad-grouping-definition.stderr +6 -0
  108. data/vendor/snowball/tests/errors/missing-bra.sbl +6 -0
  109. data/vendor/snowball/tests/errors/missing-bra.stderr +3 -0
  110. data/vendor/snowball/tests/errors/missing-command.sbl +9 -0
  111. data/vendor/snowball/tests/errors/missing-command.stderr +1 -0
  112. data/vendor/snowball/tests/errors/missing-ket-backwardmode.sbl +3 -0
  113. data/vendor/snowball/tests/errors/missing-ket-backwardmode.stderr +1 -0
  114. data/vendor/snowball/tests/errors/missing-ket.sbl +7 -0
  115. data/vendor/snowball/tests/errors/missing-ket.stderr +6 -0
  116. data/vendor/snowball/tests/errors/notdefined.sbl +4 -0
  117. data/vendor/snowball/tests/errors/notdefined.stderr +2 -0
  118. data/vendor/snowball/tests/errors/string-omitted.sbl +5 -0
  119. data/vendor/snowball/tests/errors/string-omitted.stderr +1 -0
  120. data/vendor/snowball/tests/errors/undeclared.sbl +20 -0
  121. data/vendor/snowball/tests/errors/undeclared.stderr +9 -0
  122. data/vendor/snowball/tests/errors/unexpected-token.sbl +24 -0
  123. data/vendor/snowball/tests/errors/unexpected-token.stderr +17 -0
  124. data/vendor/snowball/tests/errors/wrongdirection.sbl +14 -0
  125. data/vendor/snowball/tests/errors/wrongdirection.stderr +1 -0
  126. data/vendor/snowball/tests/runtime/among.sbl +19 -0
  127. data/vendor/snowball/tests/runtime/arithmeticexpr.sbl +86 -0
  128. data/vendor/snowball/tests/runtime/attachinsert.sbl +47 -0
  129. data/vendor/snowball/tests/runtime/booleans.sbl +19 -0
  130. data/vendor/snowball/tests/runtime/externals.sbl +22 -0
  131. data/vendor/snowball/tests/runtime/hop.sbl +12 -0
  132. data/vendor/snowball/tests/runtime/integertests.sbl +60 -0
  133. data/vendor/snowball/tests/runtime/intlimits.sbl +25 -0
  134. data/vendor/snowball/tests/runtime/naming.sbl +20 -0
  135. data/vendor/snowball/tests/runtime/not.sbl +30 -0
  136. data/vendor/snowball/tests/runtime/or.sbl +17 -0
  137. data/vendor/snowball/tests/runtime/repeat.sbl +16 -0
  138. data/vendor/snowball/tests/runtime/setlimit.sbl +24 -0
  139. data/vendor/snowball/tests/runtime/sizelen.sbl +56 -0
  140. data/vendor/snowball/tests/runtime/slice.sbl +27 -0
  141. data/vendor/snowball/tests/runtime/stringdollar.sbl +39 -0
  142. data/vendor/snowball/tests/runtime/strings.sbl +66 -0
  143. data/vendor/snowball/tests/runtime/test.sbl +19 -0
  144. data/vendor/snowball/tests/stemtest.c +41 -1
  145. data/vendor/snowball/tests/syntax/canon.sbl +32 -0
  146. data/vendor/snowball/tests/syntax/canon.stderr +0 -0
  147. data/vendor/snowball/tests/syntax/canon.syntax +57 -0
  148. data/vendor/snowball/tests/syntax/emptyprogram.sbl +2 -0
  149. data/vendor/snowball/tests/syntax/emptyprogram.syntax +0 -0
  150. data/vendor/snowball/tests/syntax/groupings.sbl +11 -0
  151. data/vendor/snowball/tests/syntax/inline.sbl +144 -0
  152. data/vendor/snowball/tests/syntax/inline.stderr +0 -0
  153. data/vendor/snowball/tests/syntax/inline.syntax +121 -0
  154. data/vendor/snowball/tests/syntax/legacy.sbl +17 -0
  155. data/vendor/snowball/tests/syntax/legacy.stderr +5 -0
  156. data/vendor/snowball/tests/syntax/legacy.syntax +19 -0
  157. data/vendor/snowball/tests/syntax/loops.sbl +14 -0
  158. data/vendor/snowball/tests/syntax/loops.stderr +9 -0
  159. data/vendor/snowball/tests/syntax/loops.syntax +29 -0
  160. data/vendor/snowball/tests/syntax/noops.sbl +76 -0
  161. data/vendor/snowball/tests/syntax/noops.stderr +27 -0
  162. data/vendor/snowball/tests/syntax/noops.syntax +135 -0
  163. data/vendor/snowball/tests/syntax/simplifyae.sbl +21 -0
  164. data/vendor/snowball/tests/syntax/simplifyae.stderr +0 -0
  165. data/vendor/snowball/tests/syntax/simplifyae.syntax +39 -0
  166. data/vendor/snowball/tests/syntax/unused.sbl +18 -0
  167. data/vendor/snowball/tests/syntax/unused.stderr +7 -0
  168. data/vendor/snowball/tests/syntax/unused.syntax +3 -0
  169. data/vendor/snowball/zig/env.zig +599 -0
  170. data/vendor/snowball/zig/generate_algorithms.pl +19 -0
  171. data/vendor/snowball/zig/stemwords.zig +123 -0
  172. metadata +102 -4
  173. data/vendor/snowball/compiler/syswords.h +0 -86
  174. data/vendor/snowball/runtime/header.h +0 -62
@@ -3,14 +3,39 @@
3
3
  #include <stdlib.h>
4
4
  #include <string.h>
5
5
 
6
- #include "header.h"
6
+ #include "snowball_runtime.h"
7
+
8
+ #ifdef SNOWBALL_RUNTIME_THROW_EXCEPTIONS
9
+ # include <new>
10
+ # include <stdexcept>
11
+ # define SNOWBALL_RETURN_OK return
12
+ # define SNOWBALL_RETURN_OR_THROW(R, E) throw E
13
+ # define SNOWBALL_PROPAGATE_ERR(F) F
14
+ #else
15
+ # define SNOWBALL_RETURN_OK return 0
16
+ # define SNOWBALL_RETURN_OR_THROW(R, E) return R
17
+ # define SNOWBALL_PROPAGATE_ERR(F) do { \
18
+ int snowball_err = F; \
19
+ if (snowball_err < 0) return snowball_err; \
20
+ } while (0)
21
+ #endif
22
+
23
+ #define HEAD (2 * sizeof(int))
24
+
25
+ /* Note that sizeof(symbol) should divide HEAD without remainder, otherwise
26
+ * there is an alignment problem.
27
+ *
28
+ * We support C90 here so use a typedef trick instead of static_assert.
29
+ */
30
+ typedef int sizeof_symbol_divides_head[(HEAD % sizeof(symbol) == 0) ? 1 : -1];
7
31
 
8
32
  #define CREATE_SIZE 1
9
33
 
10
34
  extern symbol * create_s(void) {
11
35
  symbol * p;
12
36
  void * mem = malloc(HEAD + (CREATE_SIZE + 1) * sizeof(symbol));
13
- if (mem == NULL) return NULL;
37
+ if (mem == NULL)
38
+ SNOWBALL_RETURN_OR_THROW(NULL, std::bad_alloc());
14
39
  p = (symbol *) (HEAD + (char *) mem);
15
40
  CAPACITY(p) = CREATE_SIZE;
16
41
  SET_SIZE(p, 0);
@@ -24,14 +49,15 @@ extern void lose_s(symbol * p) {
24
49
 
25
50
  /*
26
51
  new_p = skip_utf8(p, c, l, n); skips n characters forwards from p + c.
27
- new_p is the new position, or -1 on failure.
52
+ new_p is the new position, or -1 on failure (if c would be > l).
53
+
54
+ Caller ensures n >= 0.
28
55
 
29
56
  -- used to implement hop and next in the utf8 case.
30
57
  */
31
58
 
32
59
  extern int skip_utf8(const symbol * p, int c, int limit, int n) {
33
60
  int b;
34
- if (n < 0) return -1;
35
61
  for (; n > 0; n--) {
36
62
  if (c >= limit) return -1;
37
63
  b = p[c++];
@@ -49,14 +75,15 @@ extern int skip_utf8(const symbol * p, int c, int limit, int n) {
49
75
 
50
76
  /*
51
77
  new_p = skip_b_utf8(p, c, lb, n); skips n characters backwards from p + c - 1
52
- new_p is the new position, or -1 on failure.
78
+ new_p is the new position, or -1 on failure (if c would be < lb).
79
+
80
+ Caller ensures n >= 0.
53
81
 
54
82
  -- used to implement hop and next in the utf8 case.
55
83
  */
56
84
 
57
85
  extern int skip_b_utf8(const symbol * p, int c, int limit, int n) {
58
86
  int b;
59
- if (n < 0) return -1;
60
87
  for (; n > 0; n--) {
61
88
  if (c <= limit) return -1;
62
89
  b = p[--c];
@@ -119,13 +146,79 @@ static int get_b_utf8(const symbol * p, int c, int lb, int * slot) {
119
146
  return 4;
120
147
  }
121
148
 
149
+ #ifdef SNOWBALL_COVERAGE
150
+ /* The grouping number gets stored in a byte, clamped to 255. */
151
+ static char grouping_seen[255];
152
+
153
+ static void report_coverage(const unsigned char * s, int min, int max, int ch, const unsigned char * p, int w) {
154
+ int i = 0;
155
+ int j;
156
+ int outof = 0;
157
+ const unsigned char * loc = s + (max - min + 8) / 8;
158
+ int grouping_number = *loc++;
159
+ /* Adjust ch be an offset from min if it's past the end of the range. If
160
+ * we already subtracted min then this will condition will be false. Only
161
+ * needed for the "out" case but the condition can never be true for the
162
+ * "in" case.
163
+ */
164
+ if (ch > max) ch -= min;
165
+ /* Find the index of this character in the grouping. */
166
+ for (j = 0; j != max - min; ++j) {
167
+ if (s[j >> 3] & (0X1 << (j & 0X7))) {
168
+ ++outof;
169
+ if (j < ch) ++i;
170
+ }
171
+ }
172
+ if (grouping_number < (int)sizeof(grouping_seen) &&
173
+ grouping_seen[grouping_number] == 0) {
174
+ /* Report every entry once, then unused cases will appear (and we can
175
+ * decrement each count when generating the coverage report).
176
+ */
177
+ int k = 0;
178
+ for (j = 0; j != max - min; ++j) {
179
+ if (s[j >> 3] & (0X1 << (j & 0X7))) {
180
+ fprintf(stderr, "%s index %d of %d '", loc, k, outof + 1);
181
+ int codepoint = j + min;
182
+ if (codepoint < 0x80) {
183
+ putc(codepoint, stderr);
184
+ } else if (codepoint < 0x800) {
185
+ putc((codepoint >> 6) | 0xC0, stderr);
186
+ putc((codepoint & 0x3F) | 0x80, stderr);
187
+ } else {
188
+ putc((codepoint >> 12) | 0xE0, stderr);
189
+ putc(((codepoint >> 6) & 0x3F) | 0x80, stderr);
190
+ putc((codepoint & 0x3F) | 0x80, stderr);
191
+ }
192
+ fprintf(stderr, "'\n");
193
+ ++k;
194
+ }
195
+ }
196
+ grouping_seen[grouping_number] = 1;
197
+ }
198
+ fprintf(stderr, "%s index %d of %d '%.*s'\n", loc, i, outof + 1, w, p);
199
+ }
200
+
201
+ static void report_coverage_nomatch(const unsigned char * s, int min, int max) {
202
+ const unsigned char * loc = s + (max - min + 8) / 8;
203
+ ++loc;
204
+ fprintf(stderr, "%s no match\n", loc);
205
+ }
206
+ #endif
207
+
122
208
  extern int in_grouping_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat) {
123
209
  do {
124
210
  int ch;
125
211
  int w = get_utf8(z->p, z->c, z->l, & ch);
126
212
  if (!w) return -1;
127
- if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
213
+ if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) {
214
+ #ifdef SNOWBALL_COVERAGE
215
+ report_coverage_nomatch(s, min, max);
216
+ #endif
128
217
  return w;
218
+ }
219
+ #ifdef SNOWBALL_COVERAGE
220
+ report_coverage(s, min, max, ch, z->p + z->c, w);
221
+ #endif
129
222
  z->c += w;
130
223
  } while (repeat);
131
224
  return 0;
@@ -136,8 +229,15 @@ extern int in_grouping_b_U(struct SN_env * z, const unsigned char * s, int min,
136
229
  int ch;
137
230
  int w = get_b_utf8(z->p, z->c, z->lb, & ch);
138
231
  if (!w) return -1;
139
- if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
232
+ if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) {
233
+ #ifdef SNOWBALL_COVERAGE
234
+ report_coverage_nomatch(s, min, max);
235
+ #endif
140
236
  return w;
237
+ }
238
+ #ifdef SNOWBALL_COVERAGE
239
+ report_coverage(s, min, max, ch, z->p + z->c - w, w);
240
+ #endif
141
241
  z->c -= w;
142
242
  } while (repeat);
143
243
  return 0;
@@ -148,8 +248,15 @@ extern int out_grouping_U(struct SN_env * z, const unsigned char * s, int min, i
148
248
  int ch;
149
249
  int w = get_utf8(z->p, z->c, z->l, & ch);
150
250
  if (!w) return -1;
151
- if (!(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0))
251
+ if (!(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)) {
252
+ #ifdef SNOWBALL_COVERAGE
253
+ report_coverage(s, min, max, ch, z->p + z->c, w);
254
+ #endif
152
255
  return w;
256
+ }
257
+ #ifdef SNOWBALL_COVERAGE
258
+ report_coverage_nomatch(s, min, max);
259
+ #endif
153
260
  z->c += w;
154
261
  } while (repeat);
155
262
  return 0;
@@ -160,8 +267,15 @@ extern int out_grouping_b_U(struct SN_env * z, const unsigned char * s, int min,
160
267
  int ch;
161
268
  int w = get_b_utf8(z->p, z->c, z->lb, & ch);
162
269
  if (!w) return -1;
163
- if (!(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0))
270
+ if (!(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)) {
271
+ #ifdef SNOWBALL_COVERAGE
272
+ report_coverage(s, min, max, ch, z->p + z->c - w, w);
273
+ #endif
164
274
  return w;
275
+ }
276
+ #ifdef SNOWBALL_COVERAGE
277
+ report_coverage_nomatch(s, min, max);
278
+ #endif
165
279
  z->c -= w;
166
280
  } while (repeat);
167
281
  return 0;
@@ -235,7 +349,13 @@ extern int eq_v_b(struct SN_env * z, const symbol * p) {
235
349
  return eq_s_b(z, SIZE(p), p);
236
350
  }
237
351
 
238
- extern int find_among(struct SN_env * z, const struct among * v, int v_size) {
352
+ #ifdef SNOWBALL_COVERAGE
353
+ /* Declare more entries than any real Snowball program will have. */
354
+ static char among_seen[4096];
355
+ #endif
356
+
357
+ extern int find_among(struct SN_env * z, const struct among * v, int v_size,
358
+ int (*call_among_func)(struct SN_env*)) {
239
359
 
240
360
  int i = 0;
241
361
  int j = v_size;
@@ -250,6 +370,28 @@ extern int find_among(struct SN_env * z, const struct among * v, int v_size) {
250
370
 
251
371
  int first_key_inspected = 0;
252
372
 
373
+ #ifdef SNOWBALL_COVERAGE
374
+ int among_number = v[v_size].s_size;
375
+ if (among_number < (int)sizeof(among_seen) &&
376
+ among_seen[among_number] == 0) {
377
+ /* Report every entry once, then unused cases will appear (and we can
378
+ * decrement each count when generating the coverage report).
379
+ */
380
+ int k;
381
+ for (k = 0; k < v_size; ++k) {
382
+ w = v + k;
383
+ fprintf(stderr, "%s: among %d : %d of %d string '%.*s'\n", w[v_size].s, among_number, w[v_size].result, v_size, w->s_size, w->s);
384
+ }
385
+ /* If the among matches the empty string without a gating function then
386
+ * the "no match" case is impossible and so not useful to include in a
387
+ * coverage report.
388
+ */
389
+ if (v[v_size * 2].s_size != -1) {
390
+ fprintf(stderr, "%s: among %d no match\n", v[v_size * 2].s, among_number);
391
+ }
392
+ among_seen[among_number] = 1;
393
+ }
394
+ #endif
253
395
  while (1) {
254
396
  int k = i + ((j - i) >> 1);
255
397
  int diff = 0;
@@ -286,21 +428,36 @@ extern int find_among(struct SN_env * z, const struct among * v, int v_size) {
286
428
  while (1) {
287
429
  if (common_i >= w->s_size) {
288
430
  z->c = c + w->s_size;
289
- if (w->function == NULL) return w->result;
290
- {
291
- int res = w->function(z);
431
+ #ifdef SNOWBALL_COVERAGE
432
+ fprintf(stderr, "%s: among %d : %d of %d string '%.*s'\n", w[v_size].s, among_number, w[v_size].result, v_size, w->s_size, w->s);
433
+ #endif
434
+ if (!w->function) return w->result;
435
+ z->af = w->function;
436
+ if (call_among_func(z)) {
292
437
  z->c = c + w->s_size;
293
- if (res) return w->result;
438
+ #ifdef SNOWBALL_COVERAGE
439
+ fprintf(stderr, "%s: among %d : %d of %d func-t '%.*s'\n", w[v_size].s, among_number, w[v_size].result, v_size, w->s_size, w->s);
440
+ #endif
441
+ return w->result;
294
442
  }
443
+ #ifdef SNOWBALL_COVERAGE
444
+ fprintf(stderr, "%s: among %d : %d of %d func-f '%.*s'\n", w[v_size].s, among_number, w[v_size].result, v_size, w->s_size, w->s);
445
+ #endif
446
+ }
447
+ if (!w->substring_i) {
448
+ #ifdef SNOWBALL_COVERAGE
449
+ fprintf(stderr, "%s: among %d no match\n", v[v_size * 2].s, among_number);
450
+ #endif
451
+ return 0;
295
452
  }
296
- if (!w->substring_i) return 0;
297
453
  w += w->substring_i;
298
454
  }
299
455
  }
300
456
 
301
457
  /* find_among_b is for backwards processing. Same comments apply */
302
458
 
303
- extern int find_among_b(struct SN_env * z, const struct among * v, int v_size) {
459
+ extern int find_among_b(struct SN_env * z, const struct among * v, int v_size,
460
+ int (*call_among_func)(struct SN_env*)) {
304
461
 
305
462
  int i = 0;
306
463
  int j = v_size;
@@ -315,6 +472,28 @@ extern int find_among_b(struct SN_env * z, const struct among * v, int v_size) {
315
472
 
316
473
  int first_key_inspected = 0;
317
474
 
475
+ #ifdef SNOWBALL_COVERAGE
476
+ int among_number = v[v_size].s_size;
477
+ if (among_number < (int)sizeof(among_seen) &&
478
+ among_seen[among_number] == 0) {
479
+ /* Report every entry once, then unused cases will appear (and we can
480
+ * decrement each count when generating the coverage report).
481
+ */
482
+ int k;
483
+ for (k = 0; k < v_size; ++k) {
484
+ w = v + k;
485
+ fprintf(stderr, "%s: among %d : %d of %d string '%.*s'\n", w[v_size].s, among_number, w[v_size].result, v_size, w->s_size, w->s);
486
+ }
487
+ /* If the among matches the empty string without a gating function then
488
+ * the "no match" case is impossible and so not useful to include in a
489
+ * coverage report.
490
+ */
491
+ if (v[v_size * 2].s_size != -1) {
492
+ fprintf(stderr, "%s: among %d no match\n", v[v_size * 2].s, among_number);
493
+ }
494
+ among_seen[among_number] = 1;
495
+ }
496
+ #endif
318
497
  while (1) {
319
498
  int k = i + ((j - i) >> 1);
320
499
  int diff = 0;
@@ -341,55 +520,59 @@ extern int find_among_b(struct SN_env * z, const struct among * v, int v_size) {
341
520
  while (1) {
342
521
  if (common_i >= w->s_size) {
343
522
  z->c = c - w->s_size;
344
- if (w->function == NULL) return w->result;
345
- {
346
- int res = w->function(z);
523
+ #ifdef SNOWBALL_COVERAGE
524
+ fprintf(stderr, "%s: among %d : %d of %d string '%.*s'\n", w[v_size].s, among_number, w[v_size].result, v_size, w->s_size, w->s);
525
+ #endif
526
+ if (!w->function) return w->result;
527
+ z->af = w->function;
528
+ if (call_among_func(z)) {
529
+ #ifdef SNOWBALL_COVERAGE
530
+ fprintf(stderr, "%s: among %d : %d of %d func-t '%.*s'\n", w[v_size].s, among_number, w[v_size].result, v_size, w->s_size, w->s);
531
+ #endif
347
532
  z->c = c - w->s_size;
348
- if (res) return w->result;
533
+ return w->result;
349
534
  }
535
+ #ifdef SNOWBALL_COVERAGE
536
+ fprintf(stderr, "%s: among %d : %d of %d func-f '%.*s'\n", w[v_size].s, among_number, w[v_size].result, v_size, w->s_size, w->s);
537
+ #endif
538
+ }
539
+ if (!w->substring_i) {
540
+ #ifdef SNOWBALL_COVERAGE
541
+ fprintf(stderr, "%s: among %d no match\n", v[v_size * 2].s, among_number);
542
+ #endif
543
+ return 0;
350
544
  }
351
- if (!w->substring_i) return 0;
352
545
  w += w->substring_i;
353
546
  }
354
547
  }
355
548
 
356
549
 
357
550
  /* Increase the size of the buffer pointed to by p to at least n symbols.
358
- * If insufficient memory, returns NULL and frees the old buffer.
551
+ * On success, returns 0. If insufficient memory, returns -1.
359
552
  */
360
- static symbol * increase_size(symbol * p, int n) {
361
- symbol * q;
553
+ static int increase_size(symbol ** p, int n) {
362
554
  int new_size = n + 20;
363
- void * mem = realloc((char *) p - HEAD,
555
+ void * mem = realloc((char *) *p - HEAD,
364
556
  HEAD + (new_size + 1) * sizeof(symbol));
365
- if (mem == NULL) {
366
- lose_s(p);
367
- return NULL;
368
- }
557
+ symbol * q;
558
+ if (mem == NULL) return -1;
369
559
  q = (symbol *) (HEAD + (char *)mem);
370
560
  CAPACITY(q) = new_size;
371
- return q;
561
+ *p = q;
562
+ return 0;
372
563
  }
373
564
 
374
565
  /* to replace symbols between c_bra and c_ket in z->p by the
375
566
  s_size symbols at s.
376
567
  Returns 0 on success, -1 on error.
377
- Also, frees z->p (and sets it to NULL) on error.
378
568
  */
379
- extern int replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s, int * adjptr)
569
+ extern SNOWBALL_ERR replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s)
380
570
  {
381
- int adjustment;
382
- int len;
383
- if (z->p == NULL) {
384
- z->p = create_s();
385
- if (z->p == NULL) return -1;
386
- }
387
- adjustment = s_size - (c_ket - c_bra);
388
- len = SIZE(z->p);
571
+ int adjustment = s_size - (c_ket - c_bra);
389
572
  if (adjustment != 0) {
573
+ int len = SIZE(z->p);
390
574
  if (adjustment + len > CAPACITY(z->p)) {
391
- z->p = increase_size(z->p, adjustment + len);
392
- if (z->p == NULL) return -1;
575
+ SNOWBALL_PROPAGATE_ERR(increase_size(&z->p, adjustment + len));
393
576
  }
394
577
  memmove(z->p + c_ket + adjustment,
395
578
  z->p + c_ket,
@@ -402,82 +585,97 @@ extern int replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const
402
585
  z->c = c_bra;
403
586
  }
404
587
  if (s_size) memmove(z->p + c_bra, s, s_size * sizeof(symbol));
405
- if (adjptr != NULL)
406
- *adjptr = adjustment;
407
- return 0;
588
+ SNOWBALL_RETURN_OK;
408
589
  }
409
590
 
410
- static int slice_check(struct SN_env * z) {
591
+ # define REPLACE_S(Z, B, K, SIZE, S) \
592
+ SNOWBALL_PROPAGATE_ERR(replace_s(Z, B, K, SIZE, S))
593
+
594
+ static SNOWBALL_ERR slice_check(struct SN_env * z) {
411
595
 
412
596
  if (z->bra < 0 ||
413
597
  z->bra > z->ket ||
414
598
  z->ket > z->l ||
415
- z->p == NULL ||
416
599
  z->l > SIZE(z->p)) /* this line could be removed */
417
600
  {
418
601
  #if 0
419
602
  fprintf(stderr, "faulty slice operation:\n");
420
603
  debug(z, -1, 0);
421
604
  #endif
422
- return -1;
605
+ SNOWBALL_RETURN_OR_THROW(-1, std::logic_error("Snowball slice invalid"));
423
606
  }
424
- return 0;
607
+ SNOWBALL_RETURN_OK;
425
608
  }
426
609
 
427
- extern int slice_from_s(struct SN_env * z, int s_size, const symbol * s) {
428
- if (slice_check(z)) return -1;
429
- return replace_s(z, z->bra, z->ket, s_size, s, NULL);
610
+ # define SLICE_CHECK(Z) SNOWBALL_PROPAGATE_ERR(slice_check(Z))
611
+
612
+ extern SNOWBALL_ERR slice_from_s(struct SN_env * z, int s_size, const symbol * s) {
613
+ SLICE_CHECK(z);
614
+ REPLACE_S(z, z->bra, z->ket, s_size, s);
615
+ z->ket = z->bra + s_size;
616
+ SNOWBALL_RETURN_OK;
430
617
  }
431
618
 
432
- extern int slice_from_v(struct SN_env * z, const symbol * p) {
619
+ extern SNOWBALL_ERR slice_from_v(struct SN_env * z, const symbol * p) {
433
620
  return slice_from_s(z, SIZE(p), p);
434
621
  }
435
622
 
436
- extern int slice_del(struct SN_env * z) {
437
- return slice_from_s(z, 0, NULL);
623
+ extern SNOWBALL_ERR slice_del(struct SN_env * z) {
624
+ SLICE_CHECK(z);
625
+ {
626
+ int slice_size = z->ket - z->bra;
627
+ if (slice_size != 0) {
628
+ int len = SIZE(z->p);
629
+ memmove(z->p + z->bra,
630
+ z->p + z->ket,
631
+ (len - z->ket) * sizeof(symbol));
632
+ SET_SIZE(z->p, len - slice_size);
633
+ z->l -= slice_size;
634
+ if (z->c >= z->ket)
635
+ z->c -= slice_size;
636
+ else if (z->c > z->bra)
637
+ z->c = z->bra;
638
+ z->ket = z->bra;
639
+ }
640
+ }
641
+ SNOWBALL_RETURN_OK;
438
642
  }
439
643
 
440
- extern int insert_s(struct SN_env * z, int bra, int ket, int s_size, const symbol * s) {
441
- int adjustment;
442
- if (replace_s(z, bra, ket, s_size, s, &adjustment))
443
- return -1;
444
- if (bra <= z->bra) z->bra += adjustment;
445
- if (bra <= z->ket) z->ket += adjustment;
446
- return 0;
644
+ extern SNOWBALL_ERR insert_s(struct SN_env * z, int bra, int ket, int s_size, const symbol * s) {
645
+ REPLACE_S(z, bra, ket, s_size, s);
646
+ if (bra <= z->ket) {
647
+ int adjustment = s_size - (ket - bra);
648
+ z->ket += adjustment;
649
+ if (bra <= z->bra) z->bra += adjustment;
650
+ }
651
+ SNOWBALL_RETURN_OK;
447
652
  }
448
653
 
449
- extern int insert_v(struct SN_env * z, int bra, int ket, const symbol * p) {
654
+ extern SNOWBALL_ERR insert_v(struct SN_env * z, int bra, int ket, const symbol * p) {
450
655
  return insert_s(z, bra, ket, SIZE(p), p);
451
656
  }
452
657
 
453
- extern symbol * slice_to(struct SN_env * z, symbol * p) {
454
- if (slice_check(z)) {
455
- lose_s(p);
456
- return NULL;
457
- }
658
+ extern SNOWBALL_ERR slice_to(struct SN_env * z, symbol ** p) {
659
+ SLICE_CHECK(z);
458
660
  {
459
661
  int len = z->ket - z->bra;
460
- if (CAPACITY(p) < len) {
461
- p = increase_size(p, len);
462
- if (p == NULL)
463
- return NULL;
662
+ if (CAPACITY(*p) < len) {
663
+ SNOWBALL_PROPAGATE_ERR(increase_size(p, len));
464
664
  }
465
- memmove(p, z->p + z->bra, len * sizeof(symbol));
466
- SET_SIZE(p, len);
665
+ memmove(*p, z->p + z->bra, len * sizeof(symbol));
666
+ SET_SIZE(*p, len);
467
667
  }
468
- return p;
668
+ SNOWBALL_RETURN_OK;
469
669
  }
470
670
 
471
- extern symbol * assign_to(struct SN_env * z, symbol * p) {
671
+ extern SNOWBALL_ERR assign_to(struct SN_env * z, symbol ** p) {
472
672
  int len = z->l;
473
- if (CAPACITY(p) < len) {
474
- p = increase_size(p, len);
475
- if (p == NULL)
476
- return NULL;
673
+ if (CAPACITY(*p) < len) {
674
+ SNOWBALL_PROPAGATE_ERR(increase_size(p, len));
477
675
  }
478
- memmove(p, z->p, len * sizeof(symbol));
479
- SET_SIZE(p, len);
480
- return p;
676
+ memmove(*p, z->p, len * sizeof(symbol));
677
+ SET_SIZE(*p, len);
678
+ SNOWBALL_RETURN_OK;
481
679
  }
482
680
 
483
681
  extern int len_utf8(const symbol * p) {
@@ -489,25 +687,3 @@ extern int len_utf8(const symbol * p) {
489
687
  }
490
688
  return len;
491
689
  }
492
-
493
- #if 0
494
- extern void debug(struct SN_env * z, int number, int line_count) {
495
- int i;
496
- int limit = SIZE(z->p);
497
- /*if (number >= 0) printf("%3d (line %4d): '", number, line_count);*/
498
- if (number >= 0) printf("%3d (line %4d): [%d]'", number, line_count,limit);
499
- for (i = 0; i <= limit; i++) {
500
- if (z->lb == i) printf("{");
501
- if (z->bra == i) printf("[");
502
- if (z->c == i) printf("|");
503
- if (z->ket == i) printf("]");
504
- if (z->l == i) printf("}");
505
- if (i < limit)
506
- { int ch = z->p[i];
507
- if (ch == 0) ch = '#';
508
- printf("%c", ch);
509
- }
510
- }
511
- printf("'\n");
512
- }
513
- #endif
@@ -85,9 +85,9 @@ impl Stemmer {
85
85
  pub fn create(lang: String) -> Self {
86
86
  // Have a look at ../build.rs
87
87
  // There we generate a file that is rust code for a closure that returns a stemmer.
88
- // We match against all the algorithms in src/snowball/algoritms/ folder.
88
+ // We match against all the algorithms in src/snowball/algorithms/ folder.
89
89
  // Alas, this cannot be included as a match statement or function because of Rust's
90
- // hygenic macros.
90
+ // hygienic macros.
91
91
  let match_language = include!(concat!(env!("OUT_DIR"), "/lang_matches.rs"));
92
92
  match_language(lang)
93
93
  }
@@ -93,10 +93,10 @@ impl<'a> SnowballEnv<'a> {
93
93
  }
94
94
 
95
95
  /// Replace string between `bra` and `ket` with s
96
- pub fn slice_from(&mut self, s: &str) -> bool {
96
+ pub fn slice_from(&mut self, s: &str) {
97
97
  let (bra, ket) = (self.bra, self.ket);
98
98
  self.replace_s(bra, ket, s);
99
- true
99
+ self.ket = bra + s.len() as i32;
100
100
  }
101
101
 
102
102
  /// Move cursor to next character
@@ -331,7 +331,7 @@ impl<'a> SnowballEnv<'a> {
331
331
 
332
332
 
333
333
  /// Helper function that removes the string slice between `bra` and `ket`
334
- pub fn slice_del(&mut self) -> bool {
334
+ pub fn slice_del(&mut self) {
335
335
  self.slice_from("")
336
336
  }
337
337
 
@@ -407,9 +407,8 @@ impl<'a> SnowballEnv<'a> {
407
407
  if common_i >= w.0.len() as i32{
408
408
  self.cursor = c + w.0.len() as i32;
409
409
  if let Some(ref method) = w.3 {
410
- let res = method(self, context);
411
- self.cursor = c + w.0.len() as i32;
412
- if res {
410
+ if method(self, context) {
411
+ self.cursor = c + w.0.len() as i32;
413
412
  return w.2;
414
413
  }
415
414
  } else {
@@ -481,9 +480,8 @@ impl<'a> SnowballEnv<'a> {
481
480
  if common_i >= w.0.len() as i32 {
482
481
  self.cursor = c - w.0.len() as i32;
483
482
  if let Some(ref method) = w.3 {
484
- let res = method(self, context);
485
- self.cursor = c - w.0.len() as i32;
486
- if res {
483
+ if method(self, context) {
484
+ self.cursor = c - w.0.len() as i32;
487
485
  return w.2;
488
486
  }
489
487
  } else {
@@ -0,0 +1,62 @@
1
+ #!/bin/sh
2
+ set -e
3
+ SNOWBALL='../snowball -o tmp'
4
+ r=0
5
+
6
+ # Tests for expected compiler errors.
7
+ set x errors/*.sbl
8
+ shift
9
+ echo "1..$#"
10
+ for t ; do
11
+ b=`echo "$t"|sed 's/\.sbl$//'`
12
+ f=
13
+ # Run with -syntax to avoid generating files if we get none of the expected
14
+ # errors.
15
+ if $SNOWBALL -syntax "$t" 2> tmp.stderr > tmp.syntax ; then
16
+ f="snowball compiler did not fail"
17
+ else
18
+ if ! diff "$b.stderr" tmp.stderr ; then
19
+ f="stderr output not as expected"
20
+ fi
21
+ fi
22
+ if [ -z "$f" ] ; then
23
+ echo "ok - $b"
24
+ else
25
+ echo "not ok - $b: $f"
26
+ r=1
27
+ fi
28
+ done
29
+
30
+ # Tests which check --syntax output.
31
+ set x syntax/*.sbl
32
+ shift
33
+ echo "1..$#"
34
+ for t ; do
35
+ b=`echo "$t"|sed 's/\.sbl$//'`
36
+ f=
37
+ if $SNOWBALL -syntax "$t" 2> tmp.stderr > tmp.syntax ; then
38
+ if [ -f "$b.stderr" ] ; then
39
+ if ! diff "$b.stderr" tmp.stderr ; then
40
+ f="stderr output not as expected"
41
+ fi
42
+ fi
43
+ if [ -z "$f" ] && [ -f "$b.syntax" ] ; then
44
+ if ! diff "$b.syntax" tmp.syntax ; then
45
+ f="syntax tree not as expected"
46
+ else
47
+ rm tmp.syntax
48
+ fi
49
+ fi
50
+ else
51
+ f="snowball compiler failed"
52
+ fi
53
+ if [ -z "$f" ] ; then
54
+ echo "ok - $b"
55
+ rm -f tmp.stderr tmp.syntax
56
+ else
57
+ echo "not ok - $b: $f"
58
+ r=1
59
+ fi
60
+ done
61
+
62
+ exit $r