mittens 0.3.4 → 0.3.5

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1 -1
  5. data/lib/mittens/version.rb +1 -1
  6. data/vendor/snowball/.github/workflows/ci.yml +43 -3
  7. data/vendor/snowball/.github/workflows/coverage.yml +8 -5
  8. data/vendor/snowball/GNUmakefile +46 -16
  9. data/vendor/snowball/NEWS +437 -13
  10. data/vendor/snowball/README.rst +4 -4
  11. data/vendor/snowball/algorithms/earlymodernenglish.sbl +301 -0
  12. data/vendor/snowball/algorithms/french.sbl +1 -1
  13. data/vendor/snowball/algorithms/ukrainian.sbl +1251 -0
  14. data/vendor/snowball/compiler/analyser.c +460 -156
  15. data/vendor/snowball/compiler/driver.c +41 -36
  16. data/vendor/snowball/compiler/generator.c +24 -1
  17. data/vendor/snowball/compiler/generator_ada.c +46 -45
  18. data/vendor/snowball/compiler/generator_c.c +1094 -187
  19. data/vendor/snowball/compiler/generator_csharp.c +34 -11
  20. data/vendor/snowball/compiler/generator_dart.c +39 -11
  21. data/vendor/snowball/compiler/generator_go.c +6 -6
  22. data/vendor/snowball/compiler/generator_java.c +29 -8
  23. data/vendor/snowball/compiler/generator_js.c +65 -38
  24. data/vendor/snowball/compiler/generator_pascal.c +69 -26
  25. data/vendor/snowball/compiler/generator_php.c +33 -12
  26. data/vendor/snowball/compiler/generator_python.c +23 -4
  27. data/vendor/snowball/compiler/generator_rust.c +37 -13
  28. data/vendor/snowball/compiler/generator_zig.c +6 -6
  29. data/vendor/snowball/compiler/header.h +85 -14
  30. data/vendor/snowball/compiler/space.c +67 -38
  31. data/vendor/snowball/compiler/tokeniser.c +28 -16
  32. data/vendor/snowball/csharp/Snowball/AssemblyInfo.cs +2 -2
  33. data/vendor/snowball/csharp/Snowball/Stemmer.cs +1 -4
  34. data/vendor/snowball/cxx/generate_algorithms.pl +5 -4
  35. data/vendor/snowball/cxx/{utilities.cxx → snowball_runtime.cxx} +1 -1
  36. data/vendor/snowball/cxx/stemmer.h +4 -0
  37. data/vendor/snowball/cxx/stemwords.cxx +36 -6
  38. data/vendor/snowball/dart/lib/src/snowball.dart +2 -2
  39. data/vendor/snowball/dart/pubspec.yaml +1 -1
  40. data/vendor/snowball/doc/libstemmer_c_README +3 -0
  41. data/vendor/snowball/doc/libstemmer_php_README +1 -1
  42. data/vendor/snowball/doc/libstemmer_python_README +8 -6
  43. data/vendor/snowball/examples/stemwords.c +4 -14
  44. data/vendor/snowball/go/env.go +16 -4
  45. data/vendor/snowball/include/libstemmer.h +0 -3
  46. data/vendor/snowball/java/org/tartarus/snowball/SnowballProgram.java +4 -4
  47. data/vendor/snowball/javascript/base-stemmer.js +27 -40
  48. data/vendor/snowball/javascript/stemwords.js +34 -10
  49. data/vendor/snowball/libstemmer/libstemmer_c.in +5 -5
  50. data/vendor/snowball/libstemmer/mkmodules.pl +5 -3
  51. data/vendor/snowball/libstemmer/modules.txt +4 -2
  52. data/vendor/snowball/pascal/SnowballProgram.pas +2 -2
  53. data/vendor/snowball/php/base-stemmer.php +2 -2
  54. data/vendor/snowball/python/setup.py +5 -1
  55. data/vendor/snowball/python/snowballstemmer/basestemmer.py +1 -2
  56. data/vendor/snowball/runtime/api.c +14 -3
  57. data/vendor/snowball/runtime/api.h +13 -9
  58. data/vendor/snowball/runtime/{utilities.c → snowball_runtime.c} +115 -181
  59. data/vendor/snowball/runtime/snowball_runtime.h +35 -24
  60. data/vendor/snowball/rust/src/snowball/snowball_env.rs +1 -1
  61. data/vendor/snowball/tests/compilertest +3 -3
  62. data/vendor/snowball/tests/runtime/among.sbl +96 -2
  63. data/vendor/snowball/tests/runtime/attachinsert.sbl +4 -0
  64. data/vendor/snowball/tests/runtime/debug.out +7 -0
  65. data/vendor/snowball/tests/runtime/debug.sbl +9 -0
  66. data/vendor/snowball/tests/runtime/integertests.sbl +22 -0
  67. data/vendor/snowball/tests/runtime/marklimit.sbl +30 -0
  68. data/vendor/snowball/tests/runtime/naming.sbl +20 -0
  69. data/vendor/snowball/tests/runtime/reverse.sbl +11 -0
  70. data/vendor/snowball/tests/stemtest.c +2 -5
  71. data/vendor/snowball/tests/syntax/aeslicefrom.sbl +7 -0
  72. data/vendor/snowball/tests/syntax/canon.sbl +14 -0
  73. data/vendor/snowball/tests/syntax/canon.syntax +36 -0
  74. data/vendor/snowball/tests/syntax/inline.syntax +4 -4
  75. data/vendor/snowball/tests/syntax/localvar.sbl +38 -0
  76. data/vendor/snowball/tests/syntax/localvar.stderr +3 -0
  77. data/vendor/snowball/tests/syntax/localvar.syntax +76 -0
  78. data/vendor/snowball/tests/syntax/unused.sbl +5 -1
  79. data/vendor/snowball/tests/syntax/unused.stderr +3 -1
  80. data/vendor/snowball/zig/env.zig +24 -4
  81. metadata +14 -4
@@ -22,13 +22,13 @@ sb_stemmer_list(void)
22
22
  static stemmer_encoding_t
23
23
  sb_getenc(const char * charenc)
24
24
  {
25
- const struct stemmer_encoding * encoding;
25
+ size_t i;
26
26
  if (charenc == NULL) return ENC_UTF_8;
27
- for (encoding = encodings; encoding->name != 0; encoding++) {
28
- if (strcmp(encoding->name, charenc) == 0) break;
27
+ for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); ++i) {
28
+ if (strcmp(encodings[i].name, charenc) == 0)
29
+ return encodings[i].enc;
29
30
  }
30
- if (encoding->name == NULL) return ENC_UNKNOWN;
31
- return encoding->enc;
31
+ return ENC_UNKNOWN;
32
32
  }
33
33
 
34
34
  extern struct sb_stemmer *
@@ -121,18 +121,21 @@ EOS
121
121
  typedef enum {
122
122
  ENC_UNKNOWN=0,
123
123
  EOS
124
+ my $enc_array_len = 0;
124
125
  my $neednl = 0;
125
126
  for $enc (sort keys %encs) {
127
+ length($enc) > $enc_array_len and $enc_array_len = length($enc);
126
128
  print OUT ",\n" if $neednl;
127
129
  print OUT " ENC_${enc}";
128
130
  $neednl = 1;
129
131
  }
132
+ ++$enc_array_len; # Allow for terminating zero byte.
130
133
  print OUT <<EOS;
131
134
 
132
135
  } stemmer_encoding_t;
133
136
 
134
137
  struct stemmer_encoding {
135
- const char * name;
138
+ char name[$enc_array_len];
136
139
  stemmer_encoding_t enc;
137
140
  };
138
141
  static const struct stemmer_encoding encodings[] = {
@@ -141,7 +144,6 @@ EOS
141
144
  print OUT " {\"${enc}\", ENC_${enc}},\n";
142
145
  }
143
146
  print OUT <<EOS;
144
- {0,ENC_UNKNOWN}
145
147
  };
146
148
 
147
149
  struct stemmer_modules {
@@ -231,7 +233,7 @@ EOS
231
233
 
232
234
  $need_sep = 0;
233
235
  for $srcfile ('runtime/api.c',
234
- 'runtime/utilities.c',
236
+ 'runtime/snowball_runtime.c',
235
237
  "libstemmer/libstemmer${extn}.c") {
236
238
  print OUT " \\\n" if $need_sep;
237
239
  print OUT " $srcfile";
@@ -16,6 +16,7 @@ catalan UTF_8,ISO_8859_1 catalan,ca,cat
16
16
  czech UTF_8,ISO_8859_2 czech,cs,ces,cze
17
17
  danish UTF_8,ISO_8859_1 danish,da,dan
18
18
  dutch UTF_8,ISO_8859_1 dutch,nl,dut,nld,kraaij_pohlmann
19
+ earlymodernenglish UTF_8 earlymodernenglish
19
20
  english UTF_8,ISO_8859_1 english,en,eng
20
21
  esperanto UTF_8 esperanto,eo,epo
21
22
  estonian UTF_8 estonian,et,est
@@ -31,18 +32,19 @@ italian UTF_8,ISO_8859_1 italian,it,ita
31
32
  lithuanian UTF_8 lithuanian,lt,lit
32
33
  nepali UTF_8 nepali,ne,nep
33
34
  norwegian UTF_8,ISO_8859_1 norwegian,no,nor
35
+ persian UTF_8 persian,fa,fas,per
34
36
  polish UTF_8,ISO_8859_2 polish,pl,pol
35
- persian UTF_8 persian,fa,fas,pers
36
37
  portuguese UTF_8,ISO_8859_1 portuguese,pt,por
37
38
  romanian UTF_8 romanian,ro,rum,ron
38
39
  russian UTF_8,KOI8_R russian,ru,rus
39
40
  serbian UTF_8 serbian,sr,srp
41
+ sesotho UTF_8 sesotho,st,sot
40
42
  spanish UTF_8,ISO_8859_1 spanish,es,esl,spa
41
43
  swedish UTF_8,ISO_8859_1 swedish,sv,swe
42
44
  tamil UTF_8 tamil,ta,tam
43
45
  turkish UTF_8 turkish,tr,tur
46
+ ukrainian UTF_8 ukrainian,uk,ukr
44
47
  yiddish UTF_8 yiddish,yi,yid
45
- sesotho UTF_8 sesotho,st,sot
46
48
 
47
49
  # Also include the traditional porter algorithm for english.
48
50
  # The porter algorithm is included in the libstemmer distribution to assist
@@ -70,8 +70,8 @@ Begin
70
70
  FCursor := 0;
71
71
  FLimit := Length(Current);
72
72
  FBkLimit := 0;
73
- FBra := FCursor;
74
- FKet := FLimit;
73
+ FBra := 0;
74
+ FKet := 0;
75
75
  End;
76
76
 
77
77
  Function TSnowballProgram.InGrouping(s : array of char; min, max : Integer) : Boolean;
@@ -445,8 +445,8 @@ abstract class SnowballStemmer {
445
445
  $this->cursor = 0;
446
446
  $this->limit = strlen($word);
447
447
  $this->limit_backward = 0;
448
- $this->bra = $this->cursor;
449
- $this->ket = $this->limit;
448
+ $this->bra = 0;
449
+ $this->ket = 0;
450
450
  $this->stem();
451
451
  return $this->current;
452
452
  }
@@ -3,7 +3,7 @@
3
3
  from setuptools import setup
4
4
  import re
5
5
 
6
- SNOWBALL_VERSION = '3.1.1'
6
+ SNOWBALL_VERSION = '3.2.0'
7
7
 
8
8
  n_stemmers = 0
9
9
 
@@ -45,6 +45,10 @@ for lang in langs:
45
45
  if lang_titlecase != 'Sesotho':
46
46
  classifiers.append('Natural Language :: ' + lang_titlecase)
47
47
 
48
+ # Portuguese stemmer also works for Brazilian Portuguese.
49
+ if lang_titlecase == 'Portuguese':
50
+ classifiers.append('Natural Language :: Portuguese (Brazilian)')
51
+
48
52
  classifiers.extend([
49
53
  'Operating System :: OS Independent',
50
54
  'Programming Language :: Python',
@@ -10,8 +10,7 @@ class BaseStemmer:
10
10
  self.cursor = 0
11
11
  self.limit = len(self.current)
12
12
  self.limit_backward = 0
13
- self.bra = self.cursor
14
- self.ket = self.limit
13
+ self.bra = self.ket = 0
15
14
 
16
15
  def get_current(self):
17
16
  '''
@@ -1,14 +1,17 @@
1
1
 
2
2
  #include <stdlib.h> /* for malloc, free */
3
+ #include <string.h> /* for memset */
3
4
  #include "snowball_runtime.h"
4
5
 
5
- static const struct SN_env default_SN_env;
6
-
7
6
  extern struct SN_env * SN_new_env(int alloc_size)
8
7
  {
9
8
  struct SN_env * z = (struct SN_env *) malloc(alloc_size);
10
9
  if (z == NULL) return NULL;
11
- *z = default_SN_env;
10
+ /* This memset() will initialise z->p to all-bits-zero which (at least
11
+ * theoretically) may not be the NULL pointer representation, but that's OK
12
+ * as immediately afterwards we assign to z->p.
13
+ */
14
+ memset(z, 0, alloc_size);
12
15
  z->p = create_s();
13
16
  if (z->p == NULL) {
14
17
  SN_delete_env(z);
@@ -17,6 +20,14 @@ extern struct SN_env * SN_new_env(int alloc_size)
17
20
  return z;
18
21
  }
19
22
 
23
+ /* This is used for the stemmer-specific *_create_env() for stemmers where
24
+ * there are non non-localised variables.
25
+ */
26
+ extern struct SN_env * SN_new_env_no_vars(void)
27
+ {
28
+ return SN_new_env(sizeof(struct SN_env));
29
+ }
30
+
20
31
  extern void SN_delete_env(struct SN_env * z)
21
32
  {
22
33
  if (z == NULL) return;
@@ -1,21 +1,24 @@
1
1
  #ifndef SNOWBALL_API_H_INCLUDED
2
2
  #define SNOWBALL_API_H_INCLUDED
3
3
 
4
+ #ifdef SNOWBALL_WIDE
5
+ # ifndef __cplusplus
6
+ /* wchar_t is a built-in type in C++, but not in C. */
7
+ # include <stddef.h>
8
+ # endif
9
+ typedef wchar_t symbol;
10
+ // Use a different typename - for C++ this then means that the runtime helper
11
+ // functions that depend on sizeof(symbol) will be distinct thanks to
12
+ // overloading on SN_env and/or symbol.
13
+ # define SN_env SN_env_w
14
+ #else
4
15
  typedef unsigned char symbol;
5
-
6
- /* Or replace 'char' above with 'short' for 16 bit characters.
7
-
8
- More precisely, replace 'char' with whatever type guarantees the
9
- character width you need.
10
- */
16
+ #endif
11
17
 
12
18
  struct SN_env {
13
19
  symbol * p;
14
20
  int c; int l; int lb; int bra; int ket;
15
21
  int af;
16
- #ifdef __cplusplus
17
- SN_env() : p(), c(), l(), lb(), bra(), ket(), af() { }
18
- #endif
19
22
  };
20
23
 
21
24
  #ifdef __cplusplus
@@ -23,6 +26,7 @@ extern "C" {
23
26
  #endif
24
27
 
25
28
  extern struct SN_env * SN_new_env(int alloc_size);
29
+ extern struct SN_env * SN_new_env_no_vars(void);
26
30
  extern void SN_delete_env(struct SN_env * z);
27
31
 
28
32
  extern int SN_set_current(struct SN_env * z, int size, const symbol * s);
@@ -1,10 +1,10 @@
1
+ #include "snowball_runtime.h"
1
2
 
3
+ #include <assert.h>
2
4
  #include <stdio.h>
3
5
  #include <stdlib.h>
4
6
  #include <string.h>
5
7
 
6
- #include "snowball_runtime.h"
7
-
8
8
  #ifdef SNOWBALL_RUNTIME_THROW_EXCEPTIONS
9
9
  # include <new>
10
10
  # include <stdexcept>
@@ -29,7 +29,7 @@
29
29
  */
30
30
  typedef int sizeof_symbol_divides_head[(HEAD % sizeof(symbol) == 0) ? 1 : -1];
31
31
 
32
- #define CREATE_SIZE 1
32
+ #define CREATE_SIZE 31
33
33
 
34
34
  extern symbol * create_s(void) {
35
35
  symbol * p;
@@ -349,204 +349,138 @@ extern int eq_v_b(struct SN_env * z, const symbol * p) {
349
349
  return eq_s_b(z, SIZE(p), p);
350
350
  }
351
351
 
352
- #ifdef SNOWBALL_COVERAGE
353
- /* Declare more entries than any real Snowball program will have. */
354
- static char among_seen[4096];
352
+ #ifdef SNOWBALL_WIDE
353
+ # define GET_A(X) ((X)[1])
354
+ # define GET_B(X) ((X)[2])
355
+ # define NWAY(X) ((X) + 3)
356
+ # define SEG_RESULT(X) (X)[3]
357
+ # define SEG_DATA(X) ((X) + 4)
358
+ #else
359
+ # define GET_A(X) ((X)[1] & 0xff)
360
+ # define GET_B(X) ((X)[1] >> 8)
361
+ # define NWAY(X) ((X) + 2)
362
+ # define SEG_RESULT(X) (X)[2]
363
+ # define SEG_DATA(X) ((X) + 3)
355
364
  #endif
356
365
 
357
- extern int find_among(struct SN_env * z, const struct among * v, int v_size,
358
- int (*call_among_func)(struct SN_env*)) {
359
-
360
- int i = 0;
361
- int j = v_size;
362
-
363
- int c = z->c; int l = z->l;
364
- const symbol * q = z->p + c;
365
-
366
- const struct among * w;
367
-
368
- int common_i = 0;
369
- int common_j = 0;
370
-
371
- int first_key_inspected = 0;
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;
366
+ static int seg_matches(const symbol * p, const unsigned short * x, int len) {
367
+ int i;
368
+ x = SEG_DATA(x);
369
+ if (sizeof(symbol) == 1) {
370
+ return memcmp(p, x, len) == 0;
393
371
  }
394
- #endif
372
+ for (i = 0; i < len; ++i) {
373
+ if (p[i] != x[i]) return 0;
374
+ }
375
+ return 1;
376
+ }
377
+
378
+ extern int find_among(struct SN_env * z, const unsigned short * v) {
379
+ int c = z->c;
380
+ int l = z->l;
381
+ int o = 0;
382
+ int r = 0;
395
383
  while (1) {
396
- int k = i + ((j - i) >> 1);
397
- int diff = 0;
398
- int common = common_i < common_j ? common_i : common_j; /* smaller */
399
- w = v + k;
400
- {
401
- int i2; for (i2 = common; i2 < w->s_size; i2++) {
402
- if (c + common == l) { diff = -1; break; }
403
- diff = q[common] - w->s[i2];
404
- if (diff != 0) break;
405
- common++;
406
- }
384
+ if (o < 0) {
385
+ z->c = c;
386
+ return -o;
407
387
  }
408
- if (diff < 0) {
409
- j = k;
410
- common_j = common;
411
- } else {
412
- i = k;
413
- common_i = common;
388
+ if (v[o]) {
389
+ r = v[o];
390
+ z->c = c;
414
391
  }
415
- if (j - i <= 1) {
416
- if (i > 0) break; /* v->s has been inspected */
417
- if (j == i) break; /* only one item in v */
418
-
419
- /* - but now we need to go round once more to get
420
- v->s inspected. This looks messy, but is actually
421
- the optimal approach. */
422
-
423
- if (first_key_inspected) break;
424
- first_key_inspected = 1;
425
- }
426
- }
427
- w = v + i;
428
- while (1) {
429
- if (common_i >= w->s_size) {
430
- z->c = c + w->s_size;
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)) {
437
- z->c = c + w->s_size;
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;
392
+ if (c < l) {
393
+ symbol a = GET_A(v + o);
394
+ symbol b = GET_B(v + o);
395
+ if (b == 0) {
396
+ /* Substring segment. */
397
+ int old_c = c;
398
+ c += a;
399
+ if (c <= l && seg_matches(z->p + old_c, v + o, a)) {
400
+ o = (short)SEG_RESULT(v + o);
401
+ assert(o);
402
+ continue;
403
+ }
404
+ } else {
405
+ symbol ch = z->p[c];
406
+ if (b < a) {
407
+ /* 2-way dispatch. */
408
+ if (ch == a || ch == b) {
409
+ o = (short)NWAY(v + o)[(ch == a)];
410
+ if (o) {
411
+ ++c;
412
+ continue;
413
+ }
414
+ }
415
+ } else {
416
+ /* N-way dispatch. */
417
+ if (ch >= a && ch <= b) {
418
+ o = (short)NWAY(v + o)[ch - a];
419
+ if (o) {
420
+ ++c;
421
+ continue;
422
+ }
423
+ }
424
+ }
442
425
  }
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
426
  }
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;
452
- }
453
- w += w->substring_i;
427
+ return r;
454
428
  }
455
429
  }
456
430
 
457
431
  /* find_among_b is for backwards processing. Same comments apply */
458
-
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*)) {
461
-
462
- int i = 0;
463
- int j = v_size;
464
-
465
- int c = z->c; int lb = z->lb;
466
- const symbol * q = z->p + c - 1;
467
-
468
- const struct among * w;
469
-
470
- int common_i = 0;
471
- int common_j = 0;
472
-
473
- int first_key_inspected = 0;
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
432
+ extern int find_among_b(struct SN_env * z, const unsigned short * v) {
433
+ int c = z->c;
434
+ int lb = z->lb;
435
+ int o = 0;
436
+ int r = 0;
497
437
  while (1) {
498
- int k = i + ((j - i) >> 1);
499
- int diff = 0;
500
- int common = common_i < common_j ? common_i : common_j;
501
- w = v + k;
502
- {
503
- int i2; for (i2 = w->s_size - 1 - common; i2 >= 0; i2--) {
504
- if (c - common == lb) { diff = -1; break; }
505
- diff = q[- common] - w->s[i2];
506
- if (diff != 0) break;
507
- common++;
508
- }
438
+ if (o < 0) {
439
+ z->c = c;
440
+ return -o;
509
441
  }
510
- if (diff < 0) { j = k; common_j = common; }
511
- else { i = k; common_i = common; }
512
- if (j - i <= 1) {
513
- if (i > 0) break;
514
- if (j == i) break;
515
- if (first_key_inspected) break;
516
- first_key_inspected = 1;
442
+ if (v[o]) {
443
+ r = v[o];
444
+ z->c = c;
517
445
  }
518
- }
519
- w = v + i;
520
- while (1) {
521
- if (common_i >= w->s_size) {
522
- z->c = c - w->s_size;
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
532
- z->c = c - w->s_size;
533
- return w->result;
446
+ if (c > lb) {
447
+ symbol a = GET_A(v + o);
448
+ symbol b = GET_B(v + o);
449
+ if (b == 0) {
450
+ /* Substring segment. */
451
+ c -= a;
452
+ if (c >= lb && seg_matches(z->p + c, v + o, a)) {
453
+ o = (short)SEG_RESULT(v + o);
454
+ assert(o);
455
+ continue;
456
+ }
457
+ } else {
458
+ symbol ch = z->p[c - 1];
459
+ if (b < a) {
460
+ /* 2-way dispatch. */
461
+ if (ch == a || ch == b) {
462
+ o = (short)NWAY(v + o)[(ch == a)];
463
+ if (o) {
464
+ --c;
465
+ continue;
466
+ }
467
+ }
468
+ } else {
469
+ /* N-way dispatch. */
470
+ if (ch >= a && ch <= b) {
471
+ o = (short)NWAY(v + o)[ch - a];
472
+ if (o) {
473
+ --c;
474
+ continue;
475
+ }
476
+ }
477
+ }
534
478
  }
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
479
  }
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;
544
- }
545
- w += w->substring_i;
480
+ return r;
546
481
  }
547
482
  }
548
483
 
549
-
550
484
  /* Increase the size of the buffer pointed to by p to at least n symbols.
551
485
  * On success, returns 0. If insufficient memory, returns -1.
552
486
  */
@@ -16,6 +16,32 @@
16
16
  # define CAPACITY(p) ((int *)(p))[-2]
17
17
  #endif
18
18
 
19
+ /* We need to know the endianness to correctly encode among tables when
20
+ * we aren't using wide characters.
21
+ */
22
+ #ifndef SNOWBALL_WIDE
23
+ # if !defined SNOWBALL_BIGENDIAN && !defined SNOWBALL_LITTLEENDIAN
24
+ # ifdef __BYTE_ORDER__ /* GCC, clang */
25
+ # if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
26
+ # define SNOWBALL_BIGENDIAN
27
+ # else
28
+ # define SNOWBALL_LITTLEENDIAN
29
+ # endif
30
+ # elif defined _MSC_VER && (defined _M_AMD64 || defined _M_ARM || defined _M_ARM64 || defined _M_IX86) /* MSVC */
31
+ # define SNOWBALL_LITTLEENDIAN
32
+ # elif defined HAVE_ENDIAN_H
33
+ # include <endian.h>
34
+ # if BYTE_ORDER == BIG_ENDIAN
35
+ # define SNOWBALL_BIGENDIAN
36
+ # else
37
+ # define SNOWBALL_LITTLEENDIAN
38
+ # endif
39
+ # else
40
+ # error Platform endianness unknown - define SNOWBALL_BIGENDIAN or SNOWBALL_LITTLEENDIAN
41
+ # endif
42
+ # endif
43
+ #endif
44
+
19
45
  #ifdef SNOWBALL_RUNTIME_THROW_EXCEPTIONS
20
46
  # define SNOWBALL_ERR void
21
47
  #else
@@ -29,35 +55,22 @@ static void debug(struct SN_env * z, int n, int line) {
29
55
  int len = SIZE(z->p);
30
56
  printf("%3d (line %4d): [%d]'", n, line, len);
31
57
  for (i = 0; i <= len; i++) {
32
- if (z->lb == i) printf("{");
33
- if (z->bra == i) printf("[");
34
- if (z->c == i) printf("|");
35
- if (z->ket == i) printf("]");
36
- if (z->l == i) printf("}");
58
+ if (z->lb == i) putc('{', stdout);
59
+ if (z->bra == i) putc('[', stdout);
60
+ if (z->c == i) putc('|', stdout);
61
+ if (z->ket == i) putc(']', stdout);
62
+ if (z->l == i) putc('}', stdout);
37
63
  if (i < len) {
38
64
  int ch = z->p[i];
39
65
  if (ch == 0) ch = '#';
40
- printf("%c", ch);
66
+ putc(ch, stdout);
41
67
  }
42
68
  }
43
69
  printf("'\n");
70
+ fflush(stdout);
44
71
  }
45
72
  #endif
46
73
 
47
- struct among
48
- {
49
- /* Number of symbols in s. */
50
- int s_size;
51
- /* Search string. */
52
- const symbol * s;
53
- /* Delta of index to longest matching substring, or 0 if none. */
54
- int substring_i;
55
- /* Result of the lookup. */
56
- int result;
57
- /* Optional condition routine index, or 0 if none. */
58
- int function;
59
- };
60
-
61
74
  /* MSVC doesn't like functions declared `extern "C"` throwing exceptions. */
62
75
  #if defined __cplusplus && !defined SNOWBALL_RUNTIME_THROW_EXCEPTIONS
63
76
  extern "C" {
@@ -85,10 +98,8 @@ extern int eq_s_b(struct SN_env * z, int s_size, const symbol * s);
85
98
  extern int eq_v(struct SN_env * z, const symbol * p);
86
99
  extern int eq_v_b(struct SN_env * z, const symbol * p);
87
100
 
88
- extern int find_among(struct SN_env * z, const struct among * v, int v_size,
89
- int (*)(struct SN_env *));
90
- extern int find_among_b(struct SN_env * z, const struct among * v, int v_size,
91
- int (*)(struct SN_env *));
101
+ extern int find_among(struct SN_env * z, const unsigned short * v);
102
+ extern int find_among_b(struct SN_env * z, const unsigned short * v);
92
103
 
93
104
  extern SNOWBALL_ERR replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s);
94
105
  extern SNOWBALL_ERR slice_from_s(struct SN_env * z, int s_size, const symbol * s);
@@ -21,7 +21,7 @@ impl<'a> SnowballEnv<'a> {
21
21
  limit: len as i32,
22
22
  limit_backward: 0,
23
23
  bra: 0,
24
- ket: len as i32,
24
+ ket: 0,
25
25
  }
26
26
  }
27
27