mittens 0.3.1 → 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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile +1 -0
  4. data/README.md +2 -2
  5. data/Rakefile +10 -3
  6. data/lib/mittens/version.rb +1 -1
  7. data/vendor/snowball/.github/workflows/ci.yml +144 -17
  8. data/vendor/snowball/.github/workflows/coverage.yml +117 -0
  9. data/vendor/snowball/.github/workflows/runtime-tests.yml +26 -0
  10. data/vendor/snowball/.gitignore +33 -7
  11. data/vendor/snowball/CONTRIBUTING.rst +7 -0
  12. data/vendor/snowball/COPYING +1 -1
  13. data/vendor/snowball/GNUmakefile +736 -298
  14. data/vendor/snowball/NEWS +1394 -7
  15. data/vendor/snowball/README.rst +8 -8
  16. data/vendor/snowball/ada/generate/generate.adb +5 -5
  17. data/vendor/snowball/ada/src/stemmer.adb +177 -188
  18. data/vendor/snowball/ada/src/stemmer.ads +86 -89
  19. data/vendor/snowball/ada/src/stemwords.adb +21 -5
  20. data/vendor/snowball/algorithms/czech.sbl +255 -0
  21. data/vendor/snowball/algorithms/danish.sbl +22 -10
  22. data/vendor/snowball/algorithms/english.sbl +7 -4
  23. data/vendor/snowball/algorithms/esperanto.sbl +6 -7
  24. data/vendor/snowball/algorithms/estonian.sbl +9 -4
  25. data/vendor/snowball/algorithms/finnish.sbl +33 -21
  26. data/vendor/snowball/algorithms/german.sbl +5 -0
  27. data/vendor/snowball/algorithms/indonesian.sbl +115 -96
  28. data/vendor/snowball/algorithms/italian.sbl +26 -1
  29. data/vendor/snowball/algorithms/lithuanian.sbl +13 -13
  30. data/vendor/snowball/algorithms/norwegian.sbl +17 -6
  31. data/vendor/snowball/algorithms/persian.sbl +387 -0
  32. data/vendor/snowball/algorithms/polish.sbl +177 -0
  33. data/vendor/snowball/algorithms/sesotho.sbl +115 -0
  34. data/vendor/snowball/algorithms/turkish.sbl +4 -4
  35. data/vendor/snowball/compiler/analyser.c +2002 -711
  36. data/vendor/snowball/compiler/driver.c +460 -298
  37. data/vendor/snowball/compiler/generator.c +439 -1965
  38. data/vendor/snowball/compiler/generator_ada.c +605 -430
  39. data/vendor/snowball/compiler/generator_c.c +2227 -0
  40. data/vendor/snowball/compiler/generator_csharp.c +365 -274
  41. data/vendor/snowball/compiler/generator_dart.c +1476 -0
  42. data/vendor/snowball/compiler/generator_go.c +348 -270
  43. data/vendor/snowball/compiler/generator_java.c +330 -233
  44. data/vendor/snowball/compiler/generator_js.c +534 -385
  45. data/vendor/snowball/compiler/generator_pascal.c +361 -320
  46. data/vendor/snowball/compiler/generator_php.c +1445 -0
  47. data/vendor/snowball/compiler/generator_python.c +399 -299
  48. data/vendor/snowball/compiler/generator_rust.c +370 -261
  49. data/vendor/snowball/compiler/generator_zig.c +1474 -0
  50. data/vendor/snowball/compiler/header.h +153 -86
  51. data/vendor/snowball/compiler/space.c +121 -63
  52. data/vendor/snowball/compiler/tokeniser.c +286 -182
  53. data/vendor/snowball/compiler/tokens.h +71 -0
  54. data/vendor/snowball/csharp/Snowball/Among.cs +14 -26
  55. data/vendor/snowball/csharp/Snowball/AssemblyInfo.cs +3 -3
  56. data/vendor/snowball/csharp/Snowball/Stemmer.cs +41 -45
  57. data/vendor/snowball/csharp/Stemwords/Program.cs +20 -14
  58. data/vendor/snowball/cxx/.gitignore +4 -0
  59. data/vendor/snowball/cxx/generate_algorithms.pl +87 -0
  60. data/vendor/snowball/cxx/stemmer.h +12 -0
  61. data/vendor/snowball/cxx/stemwords.cxx +176 -0
  62. data/vendor/snowball/cxx/utilities.cxx +2 -0
  63. data/vendor/snowball/dart/.gitignore +4 -0
  64. data/vendor/snowball/dart/analysis_options.yaml +1 -0
  65. data/vendor/snowball/dart/example/test_app.dart +65 -0
  66. data/vendor/snowball/dart/generate_algorithms.pl +21 -0
  67. data/vendor/snowball/dart/lib/snowball.dart +18 -0
  68. data/vendor/snowball/dart/lib/src/snowball.dart +339 -0
  69. data/vendor/snowball/dart/pubspec.yaml +17 -0
  70. data/vendor/snowball/doc/libstemmer_dart_README +37 -0
  71. data/vendor/snowball/doc/libstemmer_js_README +2 -2
  72. data/vendor/snowball/doc/libstemmer_php_README +38 -0
  73. data/vendor/snowball/doc/libstemmer_python_README +3 -3
  74. data/vendor/snowball/examples/stemwords.c +18 -3
  75. data/vendor/snowball/go/README.md +12 -4
  76. data/vendor/snowball/go/env.go +12 -14
  77. data/vendor/snowball/go/stemwords/main.go +2 -1
  78. data/vendor/snowball/java/org/tartarus/snowball/CharArraySequence.java +36 -0
  79. data/vendor/snowball/java/org/tartarus/snowball/SnowballProgram.java +17 -34
  80. data/vendor/snowball/java/org/tartarus/snowball/SnowballStemmer.java +0 -2
  81. data/vendor/snowball/javascript/base-stemmer.js +219 -252
  82. data/vendor/snowball/javascript/stemwords.js +86 -58
  83. data/vendor/snowball/libstemmer/mkmodules.pl +1 -1
  84. data/vendor/snowball/libstemmer/modules.txt +4 -0
  85. data/vendor/snowball/pascal/SnowballProgram.pas +18 -31
  86. data/vendor/snowball/php/base-stemmer.php +453 -0
  87. data/vendor/snowball/php/stemwords.php +25 -0
  88. data/vendor/snowball/python/create_init.py +16 -21
  89. data/vendor/snowball/python/pyproject.toml +3 -0
  90. data/vendor/snowball/python/setup.py +5 -7
  91. data/vendor/snowball/python/snowballstemmer/among.py +1 -2
  92. data/vendor/snowball/python/snowballstemmer/basestemmer.py +24 -33
  93. data/vendor/snowball/python/stemwords.py +72 -63
  94. data/vendor/snowball/runtime/api.c +11 -42
  95. data/vendor/snowball/runtime/api.h +11 -9
  96. data/vendor/snowball/runtime/snowball_runtime.h +110 -0
  97. data/vendor/snowball/runtime/utilities.c +282 -106
  98. data/vendor/snowball/rust/src/main.rs +2 -2
  99. data/vendor/snowball/rust/src/snowball/snowball_env.rs +7 -9
  100. data/vendor/snowball/tests/compilertest +62 -0
  101. data/vendor/snowball/tests/errors/ae-errors.sbl +53 -0
  102. data/vendor/snowball/tests/errors/ae-errors.stderr +8 -0
  103. data/vendor/snowball/tests/errors/bad-dollar.sbl +14 -0
  104. data/vendor/snowball/tests/errors/bad-dollar.stderr +4 -0
  105. data/vendor/snowball/tests/errors/bad-grouping-definition.sbl +9 -0
  106. data/vendor/snowball/tests/errors/bad-grouping-definition.stderr +6 -0
  107. data/vendor/snowball/tests/errors/missing-bra.sbl +6 -0
  108. data/vendor/snowball/tests/errors/missing-bra.stderr +3 -0
  109. data/vendor/snowball/tests/errors/missing-command.sbl +9 -0
  110. data/vendor/snowball/tests/errors/missing-command.stderr +1 -0
  111. data/vendor/snowball/tests/errors/missing-ket-backwardmode.sbl +3 -0
  112. data/vendor/snowball/tests/errors/missing-ket-backwardmode.stderr +1 -0
  113. data/vendor/snowball/tests/errors/missing-ket.sbl +7 -0
  114. data/vendor/snowball/tests/errors/missing-ket.stderr +6 -0
  115. data/vendor/snowball/tests/errors/notdefined.sbl +4 -0
  116. data/vendor/snowball/tests/errors/notdefined.stderr +2 -0
  117. data/vendor/snowball/tests/errors/string-omitted.sbl +5 -0
  118. data/vendor/snowball/tests/errors/string-omitted.stderr +1 -0
  119. data/vendor/snowball/tests/errors/undeclared.sbl +20 -0
  120. data/vendor/snowball/tests/errors/undeclared.stderr +9 -0
  121. data/vendor/snowball/tests/errors/unexpected-token.sbl +24 -0
  122. data/vendor/snowball/tests/errors/unexpected-token.stderr +17 -0
  123. data/vendor/snowball/tests/errors/wrongdirection.sbl +14 -0
  124. data/vendor/snowball/tests/errors/wrongdirection.stderr +1 -0
  125. data/vendor/snowball/tests/runtime/among.sbl +19 -0
  126. data/vendor/snowball/tests/runtime/arithmeticexpr.sbl +86 -0
  127. data/vendor/snowball/tests/runtime/attachinsert.sbl +47 -0
  128. data/vendor/snowball/tests/runtime/booleans.sbl +19 -0
  129. data/vendor/snowball/tests/runtime/externals.sbl +22 -0
  130. data/vendor/snowball/tests/runtime/hop.sbl +12 -0
  131. data/vendor/snowball/tests/runtime/integertests.sbl +60 -0
  132. data/vendor/snowball/tests/runtime/intlimits.sbl +25 -0
  133. data/vendor/snowball/tests/runtime/naming.sbl +20 -0
  134. data/vendor/snowball/tests/runtime/not.sbl +30 -0
  135. data/vendor/snowball/tests/runtime/or.sbl +17 -0
  136. data/vendor/snowball/tests/runtime/repeat.sbl +16 -0
  137. data/vendor/snowball/tests/runtime/setlimit.sbl +24 -0
  138. data/vendor/snowball/tests/runtime/sizelen.sbl +56 -0
  139. data/vendor/snowball/tests/runtime/slice.sbl +27 -0
  140. data/vendor/snowball/tests/runtime/stringdollar.sbl +39 -0
  141. data/vendor/snowball/tests/runtime/strings.sbl +66 -0
  142. data/vendor/snowball/tests/runtime/test.sbl +19 -0
  143. data/vendor/snowball/tests/stemtest.c +41 -1
  144. data/vendor/snowball/tests/syntax/canon.sbl +32 -0
  145. data/vendor/snowball/tests/syntax/canon.stderr +0 -0
  146. data/vendor/snowball/tests/syntax/canon.syntax +57 -0
  147. data/vendor/snowball/tests/syntax/emptyprogram.sbl +2 -0
  148. data/vendor/snowball/tests/syntax/emptyprogram.syntax +0 -0
  149. data/vendor/snowball/tests/syntax/groupings.sbl +11 -0
  150. data/vendor/snowball/tests/syntax/inline.sbl +144 -0
  151. data/vendor/snowball/tests/syntax/inline.stderr +0 -0
  152. data/vendor/snowball/tests/syntax/inline.syntax +121 -0
  153. data/vendor/snowball/tests/syntax/legacy.sbl +17 -0
  154. data/vendor/snowball/tests/syntax/legacy.stderr +5 -0
  155. data/vendor/snowball/tests/syntax/legacy.syntax +19 -0
  156. data/vendor/snowball/tests/syntax/loops.sbl +14 -0
  157. data/vendor/snowball/tests/syntax/loops.stderr +9 -0
  158. data/vendor/snowball/tests/syntax/loops.syntax +29 -0
  159. data/vendor/snowball/tests/syntax/noops.sbl +76 -0
  160. data/vendor/snowball/tests/syntax/noops.stderr +27 -0
  161. data/vendor/snowball/tests/syntax/noops.syntax +135 -0
  162. data/vendor/snowball/tests/syntax/simplifyae.sbl +21 -0
  163. data/vendor/snowball/tests/syntax/simplifyae.stderr +0 -0
  164. data/vendor/snowball/tests/syntax/simplifyae.syntax +39 -0
  165. data/vendor/snowball/tests/syntax/unused.sbl +18 -0
  166. data/vendor/snowball/tests/syntax/unused.stderr +7 -0
  167. data/vendor/snowball/tests/syntax/unused.syntax +3 -0
  168. data/vendor/snowball/zig/env.zig +599 -0
  169. data/vendor/snowball/zig/generate_algorithms.pl +19 -0
  170. data/vendor/snowball/zig/stemwords.zig +123 -0
  171. metadata +102 -4
  172. data/vendor/snowball/compiler/syswords.h +0 -86
  173. data/vendor/snowball/runtime/header.h +0 -62
@@ -9,6 +9,8 @@
9
9
  #define DEFAULT_JAVA_AMONG_CLASS "org.tartarus.snowball.Among"
10
10
  #define DEFAULT_JAVA_STRING_CLASS "java.lang.StringBuilder"
11
11
 
12
+ #define DEFAULT_DART_BASE_CLASS "SnowballProgram"
13
+
12
14
  #define DEFAULT_GO_PACKAGE "snowball"
13
15
  #define DEFAULT_GO_SNOWBALL_RUNTIME "github.com/snowballstem/snowball/go"
14
16
 
@@ -20,7 +22,10 @@
20
22
  #define DEFAULT_CS_AMONG_CLASS "Among"
21
23
  #define DEFAULT_CS_STRING_CLASS "StringBuilder"
22
24
 
23
- #define DEFAULT_JS_BASE_CLASS "BaseStemmer"
25
+ #define DEFAULT_CPLUSPLUS_NAMESPACE "Snowball"
26
+ #define DEFAULT_CPLUSPLUS_BASE_CLASS "Stemmer"
27
+
28
+ #define DEFAULT_JS_BASE_CLASS "B"
24
29
 
25
30
  #define DEFAULT_PYTHON_BASE_CLASS "BaseStemmer"
26
31
 
@@ -33,33 +38,21 @@ static void print_arglist(int exit_code) {
33
38
  fprintf(f, "Usage: snowball SOURCE_FILE... [OPTIONS]\n\n"
34
39
  "Supported options:\n"
35
40
  " -o, -output OUTPUT_BASE\n"
36
- " -s, -syntax\n"
37
- " -comments\n"
38
- #ifndef DISABLE_JAVA
39
- " -j, -java\n"
40
- #endif
41
- #ifndef DISABLE_CSHARP
42
- " -cs, -csharp\n"
43
- #endif
44
- " -c++\n"
45
- #ifndef DISABLE_PASCAL
46
- " -pascal\n"
47
- #endif
48
- #ifndef DISABLE_PYTHON
49
- " -py, -python\n"
50
- #endif
51
- #ifndef DISABLE_JS
41
+ " -s, -syntax show syntax tree and stop\n"
42
+ " -comments generate comments\n"
43
+ " -coverage generate coverage report\n"
44
+ " -ada generate Ada\n"
45
+ " -c++ generate C++\n"
46
+ " -cs, -csharp generate C#\n"
47
+ " -dart generate Dart\n"
48
+ " -go generate Go\n"
49
+ " -j, -java generate Java\n"
52
50
  " -js generate Javascript\n"
53
- #endif
54
- #ifndef DISABLE_RUST
55
- " -rust\n"
56
- #endif
57
- #ifndef DISABLE_GO
58
- " -go\n"
59
- #endif
60
- #ifndef DISABLE_ADA
61
- " -ada\n"
62
- #endif
51
+ " -pascal generate Pascal\n"
52
+ " -php generate PHP\n"
53
+ " -py, -python generate Python\n"
54
+ " -rust generate Rust\n"
55
+ " -zig generate Zig\n"
63
56
  " -w, -widechars\n"
64
57
  " -u, -utf8\n"
65
58
  " -n, -name CLASS_NAME\n"
@@ -67,16 +60,13 @@ static void print_arglist(int exit_code) {
67
60
  " -vp, -vprefix VARIABLE_PREFIX\n"
68
61
  " -i, -include DIRECTORY\n"
69
62
  " -r, -runtime DIRECTORY\n"
63
+ " -cheader header name to include from C/C++ file\n"
64
+ " -hheader header name to include from C/C++ header\n"
70
65
  " -p, -parentclassname CLASS_NAME fully qualified parent class name\n"
71
- #if !defined(DISABLE_JAVA) || !defined(DISABLE_CSHARP)
72
66
  " -P, -Package PACKAGE_NAME package name for stemmers\n"
73
67
  " -S, -Stringclass STRING_CLASS StringBuffer-compatible class\n"
74
68
  " -a, -amongclass AMONG_CLASS fully qualified name of the Among class\n"
75
- #endif
76
- #ifndef DISABLE_GO
77
- " -gop, -gopackage PACKAGE_NAME Go package name for stemmers\n"
78
69
  " -gor, -goruntime PACKAGE_NAME Go snowball runtime package\n"
79
- #endif
80
70
  " --help display this help and exit\n"
81
71
  " --version output version information and exit\n"
82
72
  );
@@ -101,7 +91,8 @@ static FILE * get_output(byte * s) {
101
91
  return output;
102
92
  }
103
93
 
104
- static int read_options(struct options * o, int argc, char * argv[]) {
94
+ static struct options * read_options(int * argc_ptr, char * argv[]) {
95
+ int argc = *argc_ptr;
105
96
  int i = 1;
106
97
  int new_argc = 1;
107
98
  /* Note down the last option used to specify an explicit encoding so
@@ -109,31 +100,18 @@ static int read_options(struct options * o, int argc, char * argv[]) {
109
100
  */
110
101
  const char * encoding_opt = NULL;
111
102
 
112
- /* set defaults: */
113
-
114
- o->output_file = NULL;
115
- o->syntax_tree = false;
116
- o->comments = false;
117
- o->js_esm = false;
118
- o->externals_prefix = NULL;
119
- o->variables_prefix = NULL;
120
- o->runtime_path = NULL;
121
- o->parent_class_name = NULL;
122
- o->string_class = NULL;
123
- o->among_class = NULL;
124
- o->package = NULL;
125
- o->go_snowball_runtime = DEFAULT_GO_SNOWBALL_RUNTIME;
126
- o->name = NULL;
127
- o->make_lang = LANG_C;
128
- o->includes = NULL;
129
- o->includes_end = NULL;
103
+ NEW(options, o);
104
+ *o = (struct options){0};
105
+
106
+ // Set defaults which differ from empty initialisation.
107
+ o->target_lang = LANG_C;
130
108
  o->encoding = ENC_SINGLEBYTE;
131
109
 
132
110
  /* read options: */
133
111
 
134
112
  while (i < argc) {
135
113
  char * s = argv[i++];
136
- if (s[0] != '-') {
114
+ if (s[0] != '-' || s[1] == '\0') {
137
115
  /* Non-option argument - shuffle down. */
138
116
  argv[new_argc++] = s;
139
117
  continue;
@@ -141,77 +119,67 @@ static int read_options(struct options * o, int argc, char * argv[]) {
141
119
 
142
120
  {
143
121
  if (eq(s, "-o") || eq(s, "-output")) {
144
- check_lim(i, argc);
145
- o->output_file = argv[i++];
122
+ check_lim(i, argc);
123
+ if (strcmp(argv[i], "-") == 0) {
124
+ fprintf(stderr, "output to stdout not supported\n");
125
+ exit(1);
126
+ }
127
+ o->output_file = create_s_from_sz(argv[i++]);
146
128
  continue;
147
129
  }
148
130
  if (eq(s, "-n") || eq(s, "-name")) {
149
- char * new_name;
150
- size_t len;
151
-
152
131
  check_lim(i, argc);
153
- /* Take a copy of the argument here, because
154
- * later we will free o->name */
155
- len = strlen(argv[i]);
156
- new_name = MALLOC(len + 1);
157
- memcpy(new_name, argv[i++], len);
158
- new_name[len] = '\0';
159
- o->name = new_name;
132
+ o->name = create_s_from_sz(argv[i++]);
160
133
  continue;
161
134
  }
162
- #ifndef DISABLE_JS
163
135
  if (eq(s, "-js")) {
164
- o->make_lang = LANG_JAVASCRIPT;
165
- o->js_esm = false;
136
+ o->target_lang = LANG_JAVASCRIPT;
137
+ continue;
138
+ }
139
+ if (eq(s, "-php")) {
140
+ o->target_lang = LANG_PHP;
166
141
  continue;
167
142
  }
168
- #endif
169
- #ifndef DISABLE_RUST
170
143
  if (eq(s, "-rust")) {
171
- o->make_lang = LANG_RUST;
144
+ o->target_lang = LANG_RUST;
145
+ continue;
146
+ }
147
+ if (eq(s, "-zig")) {
148
+ o->target_lang = LANG_ZIG;
172
149
  continue;
173
150
  }
174
- #endif
175
- #ifndef DISABLE_GO
176
151
  if (eq(s, "-go")) {
177
- o->make_lang = LANG_GO;
152
+ o->target_lang = LANG_GO;
178
153
  continue;
179
154
  }
180
- #endif
181
- #ifndef DISABLE_JAVA
182
155
  if (eq(s, "-j") || eq(s, "-java")) {
183
- o->make_lang = LANG_JAVA;
156
+ o->target_lang = LANG_JAVA;
157
+ continue;
158
+ }
159
+ if (eq(s, "-dart")) {
160
+ o->target_lang = LANG_DART;
184
161
  continue;
185
162
  }
186
- #endif
187
- #ifndef DISABLE_CSHARP
188
163
  if (eq(s, "-cs") || eq(s, "-csharp")) {
189
- o->make_lang = LANG_CSHARP;
164
+ o->target_lang = LANG_CSHARP;
190
165
  continue;
191
166
  }
192
- #endif
193
167
  if (eq(s, "-c++")) {
194
- o->make_lang = LANG_CPLUSPLUS;
168
+ o->target_lang = LANG_CPLUSPLUS;
195
169
  continue;
196
170
  }
197
- #ifndef DISABLE_PASCAL
198
171
  if (eq(s, "-pascal")) {
199
- o->make_lang = LANG_PASCAL;
172
+ o->target_lang = LANG_PASCAL;
200
173
  continue;
201
174
  }
202
- #endif
203
- #ifndef DISABLE_PYTHON
204
175
  if (eq(s, "-py") || eq(s, "-python")) {
205
- o->make_lang = LANG_PYTHON;
176
+ o->target_lang = LANG_PYTHON;
206
177
  continue;
207
178
  }
208
- #endif
209
- #ifndef DISABLE_ADA
210
179
  if (eq(s, "-ada")) {
211
- o->make_lang = LANG_ADA;
180
+ o->target_lang = LANG_ADA;
212
181
  continue;
213
182
  }
214
- #endif
215
183
  if (eq(s, "-w") || eq(s, "-widechars")) {
216
184
  encoding_opt = s;
217
185
  o->encoding = ENC_WIDECHARS;
@@ -225,6 +193,10 @@ static int read_options(struct options * o, int argc, char * argv[]) {
225
193
  o->comments = true;
226
194
  continue;
227
195
  }
196
+ if (eq(s, "-coverage")) {
197
+ o->coverage = true;
198
+ continue;
199
+ }
228
200
  if (eq(s, "-ep") || eq(s, "-eprefix")) {
229
201
  check_lim(i, argc);
230
202
  o->externals_prefix = argv[i++];
@@ -235,14 +207,25 @@ static int read_options(struct options * o, int argc, char * argv[]) {
235
207
  o->variables_prefix = argv[i++];
236
208
  continue;
237
209
  }
210
+ if (eq(s, "-cheader")) {
211
+ check_lim(i, argc);
212
+ o->cheader = argv[i++];
213
+ continue;
214
+ }
215
+ if (eq(s, "-hheader")) {
216
+ check_lim(i, argc);
217
+ o->hheader = argv[i++];
218
+ continue;
219
+ }
238
220
  if (eq(s, "-i") || eq(s, "-include")) {
239
221
  check_lim(i, argc);
240
222
 
241
223
  {
242
224
  NEW(include, p);
225
+ *p = (struct include){0};
243
226
  byte * include_dir = add_sz_to_s(NULL, argv[i++]);
244
227
  include_dir = add_char_to_s(include_dir, '/');
245
- p->next = NULL; p->s = include_dir;
228
+ p->s = include_dir;
246
229
 
247
230
  if (o->includes == NULL) {
248
231
  o->includes = p;
@@ -268,7 +251,6 @@ static int read_options(struct options * o, int argc, char * argv[]) {
268
251
  o->parent_class_name = argv[i++];
269
252
  continue;
270
253
  }
271
- #if !defined(DISABLE_JAVA) || !defined(DISABLE_CSHARP)
272
254
  if (eq(s, "-P") || eq(s, "-Package")) {
273
255
  check_lim(i, argc);
274
256
  o->package = argv[i++];
@@ -284,19 +266,11 @@ static int read_options(struct options * o, int argc, char * argv[]) {
284
266
  o->among_class = argv[i++];
285
267
  continue;
286
268
  }
287
- #endif
288
- #ifndef DISABLE_GO
289
- if (eq(s, "-gop") || eq(s, "-gopackage")) {
290
- check_lim(i, argc);
291
- o->package = argv[i++];
292
- continue;
293
- }
294
269
  if (eq(s, "-gor") || eq(s, "-goruntime")) {
295
270
  check_lim(i, argc);
296
271
  o->go_snowball_runtime = argv[i++];
297
272
  continue;
298
273
  }
299
- #endif
300
274
  if (eq(s, "--help")) {
301
275
  print_arglist(0);
302
276
  }
@@ -317,10 +291,16 @@ static int read_options(struct options * o, int argc, char * argv[]) {
317
291
  argv[new_argc] = NULL;
318
292
 
319
293
  /* Set language-dependent defaults. */
320
- switch (o->make_lang) {
294
+ switch (o->target_lang) {
321
295
  case LANG_C:
296
+ encoding_opt = NULL;
297
+ break;
322
298
  case LANG_CPLUSPLUS:
323
299
  encoding_opt = NULL;
300
+ if (!o->parent_class_name)
301
+ o->parent_class_name = DEFAULT_CPLUSPLUS_BASE_CLASS;
302
+ if (!o->package)
303
+ o->package = DEFAULT_CPLUSPLUS_NAMESPACE;
324
304
  break;
325
305
  case LANG_CSHARP:
326
306
  o->encoding = ENC_WIDECHARS;
@@ -337,6 +317,8 @@ static int read_options(struct options * o, int argc, char * argv[]) {
337
317
  o->encoding = ENC_UTF8;
338
318
  if (!o->package)
339
319
  o->package = DEFAULT_GO_PACKAGE;
320
+ if (!o->go_snowball_runtime)
321
+ o->go_snowball_runtime = DEFAULT_GO_SNOWBALL_RUNTIME;
340
322
  break;
341
323
  case LANG_ADA:
342
324
  o->encoding = ENC_UTF8;
@@ -354,11 +336,19 @@ static int read_options(struct options * o, int argc, char * argv[]) {
354
336
  if (!o->package)
355
337
  o->package = DEFAULT_JAVA_PACKAGE;
356
338
  break;
339
+ case LANG_DART:
340
+ o->encoding = ENC_WIDECHARS;
341
+ if (!o->parent_class_name)
342
+ o->parent_class_name = DEFAULT_DART_BASE_CLASS;
343
+ break;
357
344
  case LANG_JAVASCRIPT:
358
345
  o->encoding = ENC_WIDECHARS;
359
346
  if (!o->parent_class_name)
360
347
  o->parent_class_name = DEFAULT_JS_BASE_CLASS;
361
348
  break;
349
+ case LANG_PHP:
350
+ o->encoding = ENC_UTF8;
351
+ break;
362
352
  case LANG_PYTHON:
363
353
  o->encoding = ENC_WIDECHARS;
364
354
  if (!o->parent_class_name)
@@ -367,6 +357,9 @@ static int read_options(struct options * o, int argc, char * argv[]) {
367
357
  case LANG_RUST:
368
358
  o->encoding = ENC_UTF8;
369
359
  break;
360
+ case LANG_ZIG:
361
+ o->encoding = ENC_UTF8;
362
+ break;
370
363
  default:
371
364
  break;
372
365
  }
@@ -376,247 +369,416 @@ static int read_options(struct options * o, int argc, char * argv[]) {
376
369
  encoding_opt);
377
370
  }
378
371
 
379
- if (o->make_lang != LANG_C && o->make_lang != LANG_CPLUSPLUS) {
372
+ if (o->target_lang != LANG_C && o->target_lang != LANG_CPLUSPLUS) {
380
373
  if (o->runtime_path) {
381
374
  fprintf(stderr, "warning: -r/-runtime only meaningful for C and C++\n");
382
375
  }
383
- if (o->externals_prefix) {
384
- fprintf(stderr, "warning: -ep/-eprefix only meaningful for C and C++\n");
376
+ if (o->variables_prefix) {
377
+ fprintf(stderr, "warning: -vp/-vprefix only meaningful for C and C++\n");
378
+ }
379
+ if (o->coverage) {
380
+ fprintf(stderr, "warning: -coverage only currently supported for C and C++\n");
385
381
  }
386
382
  }
387
- if (!o->externals_prefix) o->externals_prefix = "";
388
383
 
389
- if (!o->name && o->output_file) {
390
- /* Default class name to basename of output_file - this is the standard
391
- * convention for at least Java and C#.
392
- */
393
- const char * slash = strrchr(o->output_file, '/');
394
- size_t len;
395
- const char * leaf = (slash == NULL) ? o->output_file : slash + 1;
384
+ // Split any extension off o->output_file and set o->output_leaf to just
385
+ // its leafname (which e.g. is used to generate `#include "english.h"` in
386
+ // path/to/english.c).
387
+ if (!o->output_file) {
388
+ // Default output uses the basename from the first Snowball source.
389
+ // E.g. algorithms/english.sbl -> english
390
+ const char * first_source = argv[1];
391
+ const char * slash = strrchr(first_source, '/');
392
+ const char * leaf = (slash == NULL) ? first_source : slash + 1;
396
393
 
397
394
  slash = strrchr(leaf, '\\');
398
395
  if (slash != NULL) leaf = slash + 1;
399
396
 
400
- {
401
- const char * dot = strchr(leaf, '.');
402
- len = (dot == NULL) ? strlen(leaf) : (size_t)(dot - leaf);
397
+ const char * dot = strrchr(leaf, '.');
398
+ if (dot) {
399
+ o->output_file = create_s_from_data(leaf, dot - leaf);
400
+ } else {
401
+ o->output_file = create_s_from_sz(leaf);
403
402
  }
403
+ o->output_leaf = copy_s(o->output_file);
404
+ } else {
405
+ // Remove any extension from o->output_file so `-o path/to/english.c`
406
+ // works.
407
+ o->output_file[SIZE(o->output_file)] = '\0';
408
+ const char * output_file = (const char *)o->output_file;
409
+ const char * slash = strrchr(output_file, '/');
410
+ const char * leaf = (slash == NULL) ? output_file : slash + 1;
404
411
 
405
- {
406
- char * new_name = MALLOC(len + 1);
407
- switch (o->make_lang) {
408
- case LANG_CSHARP:
409
- case LANG_PASCAL:
410
- /* Upper case initial letter. */
411
- memcpy(new_name, leaf, len);
412
- new_name[0] = toupper(new_name[0]);
413
- break;
414
- case LANG_JAVASCRIPT:
415
- case LANG_PYTHON: {
416
- /* Upper case initial letter and change each
417
- * underscore+letter or hyphen+letter to an upper case
418
- * letter.
419
- */
420
- size_t new_len = 0;
421
- int uc_next = true;
422
- for (size_t j = 0; j != len; ++j) {
423
- unsigned char ch = leaf[j];
424
- if (ch == '_' || ch == '-') {
425
- uc_next = true;
412
+ slash = strrchr(leaf, '\\');
413
+ if (slash != NULL) leaf = slash + 1;
414
+
415
+ const char * dot = strrchr(leaf, '.');
416
+ if (dot) {
417
+ o->extension = create_s_from_sz(dot);
418
+ SET_SIZE(o->output_file, dot - output_file);
419
+ o->output_leaf = create_s_from_data(leaf, dot - leaf);
420
+ } else {
421
+ o->output_leaf = create_s_from_sz(leaf);
422
+ }
423
+ }
424
+
425
+ if (!o->name) {
426
+ o->name = copy_s(o->output_leaf);
427
+ const byte * dot = memchr(o->name, '.', SIZE(o->name));
428
+ if (dot) {
429
+ // Trim off any extension (we only remove the last of multiple
430
+ // extensions above).
431
+ SET_SIZE(o->name, dot - o->name);
432
+ }
433
+ switch (o->target_lang) {
434
+ case LANG_CSHARP:
435
+ case LANG_PASCAL:
436
+ /* Upper case initial letter. */
437
+ o->name[0] = toupper(o->name[0]);
438
+ break;
439
+ case LANG_CPLUSPLUS:
440
+ case LANG_PHP:
441
+ case LANG_PYTHON: {
442
+ /* Upper case initial letter and change each
443
+ * underscore+letter or hyphen+letter to an upper case
444
+ * letter.
445
+ */
446
+ size_t len = SIZE(o->name);
447
+ size_t new_len = 0;
448
+ bool uc_next = true;
449
+ for (size_t j = 0; j != len; ++j) {
450
+ byte ch = o->name[j];
451
+ if (ch == '_' || ch == '-') {
452
+ uc_next = true;
453
+ } else {
454
+ if (uc_next) {
455
+ o->name[new_len] = toupper(ch);
456
+ uc_next = false;
426
457
  } else {
427
- if (uc_next) {
428
- new_name[new_len] = toupper(ch);
429
- uc_next = false;
430
- } else {
431
- new_name[new_len] = ch;
432
- }
433
- ++new_len;
458
+ o->name[new_len] = ch;
434
459
  }
460
+ ++new_len;
435
461
  }
436
- len = new_len;
437
- break;
438
462
  }
439
- default:
440
- /* Just copy. */
441
- memcpy(new_name, leaf, len);
442
- break;
463
+ SET_SIZE(o->name, new_len);
464
+ break;
443
465
  }
444
- new_name[len] = '\0';
445
- o->name = new_name;
466
+ default:
467
+ /* Just use as-is, e.g. that's the Java convention. */
468
+ break;
446
469
  }
447
470
  }
448
471
 
449
- return new_argc;
472
+ *argc_ptr = new_argc;
473
+ return o;
450
474
  }
451
475
 
452
476
  extern int main(int argc, char * argv[]) {
453
- int i;
454
- NEW(options, o);
455
- argc = read_options(o, argc, argv);
456
- {
457
- char * file = argv[1];
458
- byte * u = get_input(file);
477
+ struct options * o = read_options(&argc, argv);
478
+ char * file = argv[1];
479
+ byte * u = get_input(file);
480
+ if (u == NULL) {
481
+ fprintf(stderr, "Can't open input %s\n", file);
482
+ exit(1);
483
+ }
484
+
485
+ struct tokeniser * t = create_tokeniser(u, file);
486
+ struct analyser * a = create_analyser(t);
487
+ struct input ** next_input_ptr = &(t->next);
488
+ unsigned localise_mask = 0;
489
+ a->encoding = t->encoding = o->encoding;
490
+ t->includes = o->includes;
491
+ /* If multiple source files are specified, set up the others to be
492
+ * read after the first in order, using the same mechanism as
493
+ * 'get' uses. */
494
+ for (int i = 2; i != argc; ++i) {
495
+ NEW(input, q);
496
+ *q = (struct input){0};
497
+ file = argv[i];
498
+ u = get_input(file);
459
499
  if (u == NULL) {
460
500
  fprintf(stderr, "Can't open input %s\n", file);
461
501
  exit(1);
462
502
  }
463
- {
464
- struct tokeniser * t = create_tokeniser(u, file);
465
- struct analyser * a = create_analyser(t);
466
- struct input ** next_input_ptr = &(t->next);
467
- a->encoding = t->encoding = o->encoding;
468
- t->includes = o->includes;
469
- /* If multiple source files are specified, set up the others to be
470
- * read after the first in order, using the same mechanism as
471
- * 'get' uses. */
472
- for (i = 2; i != argc; ++i) {
473
- NEW(input, q);
474
- file = argv[i];
475
- u = get_input(file);
476
- if (u == NULL) {
477
- fprintf(stderr, "Can't open input %s\n", file);
478
- exit(1);
503
+ q->p = u;
504
+ q->file = file;
505
+ q->line_number = 1;
506
+ *next_input_ptr = q;
507
+ next_input_ptr = &(q->next);
508
+ }
509
+ *next_input_ptr = NULL;
510
+
511
+ /* Whether it's helpful to try to localise string variables varies
512
+ * greatly between target languages. One reason for this is likely
513
+ * to be that strings are immutable in some languages (e.g. Dart,
514
+ * Javascript, Python) so each string operation creates a new
515
+ * string anyway.
516
+ *
517
+ * We've attempted to benchmark most languages to decide.
518
+ *
519
+ * One potential gotcha here is for garbage collected languages,
520
+ * where our benchmark might not trigger GC and in that case our
521
+ * timing is missing the cost of that, which any long running
522
+ * indexing process will eventually incur.
523
+ *
524
+ * We've mostly used the following artificial benchmark which
525
+ * exercises a local string variable to test this:
526
+ *
527
+ * strings ( s )
528
+ * routines ( r )
529
+ * externals ( stem )
530
+ * define r as (-> s s)
531
+ * define stem as ( next [tolimit] loop 100000000 do r )
532
+ *
533
+ * Replace e.g. english.sbl with this and build the stemwords
534
+ * equivalent for the target language, then:
535
+ *
536
+ * $ echo nonalphabetisations|time ./stemwords
537
+ *
538
+ * The appropriate number of iterations to use varies, and is
539
+ * annotated below.
540
+ */
541
+ switch (o->target_lang) {
542
+ case LANG_ADA:
543
+ // 1000000000: local 13.7s vs global 5.2s
544
+ case LANG_C:
545
+ // We lack a way to generate lose_s(v) on every `return`
546
+ // from the function, but manually adjusting the generated
547
+ // code to do this gives:
548
+ //
549
+ // 1000000000: local 44.9s vs global 6.3s
550
+ case LANG_CPLUSPLUS:
551
+ // String variables are handled the same as LANG_C.
552
+ case LANG_CSHARP:
553
+ // 100000000: local 18.8s vs global 12.4s
554
+ case LANG_JAVA:
555
+ // 1000000000: local 10.1s vs global 7.1s
556
+ case LANG_RUST:
557
+ // 1000000000: localising was slightly slower.
558
+ case LANG_ZIG:
559
+ // 10000000: localising strings was slightly slower.
560
+ localise_mask = (1 << t_boolean) | (1 << t_integer);
561
+ break;
562
+ case LANG_DART:
563
+ // Not timed, but strings are immutable so seems likely
564
+ // to be helpful to localise.
565
+ case LANG_GO:
566
+ // 1000000000: localising was about 10% faster.
567
+ case LANG_JAVASCRIPT:
568
+ // 10000000: Slightly faster.
569
+ case LANG_PASCAL:
570
+ // Slightly faster.
571
+ case LANG_PHP:
572
+ // Slightly faster.
573
+ case LANG_PYTHON:
574
+ // 10000000: local 7.6s vs global 7.9s. Microbenchmarking
575
+ // with timeit aligns with this.
576
+ localise_mask = (1 << t_boolean) | (1 << t_integer) | (1 << t_string);
577
+ break;
578
+ }
579
+ read_program(a, localise_mask);
580
+ if (t->error_count > 0) exit(1);
581
+ if (o->syntax_tree) print_program(a);
582
+ if (!o->syntax_tree) {
583
+ struct generator * g = create_generator(a, o);
584
+ switch (o->target_lang) {
585
+ case LANG_C:
586
+ case LANG_CPLUSPLUS: {
587
+ byte * s = copy_s(o->output_file);
588
+ s = add_literal_to_s(s, ".h");
589
+ o->output_h = get_output(s);
590
+ SET_SIZE(s, SIZE(o->output_file));
591
+ if (o->extension &&
592
+ !(SIZE(o->extension) == 2 && memcmp(o->extension, ".h", 2) == 0)) {
593
+ s = add_s_to_s(s, o->extension);
594
+ } else if (o->target_lang == LANG_CPLUSPLUS) {
595
+ s = add_literal_to_s(s, ".cc");
596
+ } else {
597
+ s = add_literal_to_s(s, ".c");
479
598
  }
480
- q->p = u;
481
- q->c = 0;
482
- q->file = file;
483
- q->file_owned = 0;
484
- q->line_number = 1;
485
- *next_input_ptr = q;
486
- next_input_ptr = &(q->next);
487
- }
488
- *next_input_ptr = NULL;
489
- read_program(a);
490
- if (t->error_count > 0) exit(1);
491
- if (o->syntax_tree) print_program(a);
492
- if (!o->syntax_tree) {
493
- struct generator * g;
494
-
495
- const char * output_base = o->output_file;
496
- if (!output_base) {
497
- fprintf(stderr, "Please include the -o option\n");
498
- print_arglist(1);
599
+ o->output_src = get_output(s);
600
+ lose_s(s);
601
+
602
+ generate_program_c(g);
603
+ fclose(o->output_src);
604
+ fclose(o->output_h);
605
+ break;
606
+ }
607
+ #ifndef TARGET_C_ONLY
608
+ case LANG_ADA: {
609
+ byte * s = copy_s(o->output_file);
610
+ s = add_literal_to_s(s, ".ads");
611
+ o->output_h = get_output(s);
612
+ SET_SIZE(s, SIZE(o->output_file));
613
+ if (o->extension &&
614
+ !(SIZE(o->extension) == 4 && memcmp(o->extension, ".ads", 2) == 0)) {
615
+ s = add_s_to_s(s, o->extension);
616
+ s = add_s_to_s(s, o->extension);
617
+ } else {
618
+ s = add_literal_to_s(s, ".adb");
499
619
  }
500
- g = create_generator(a, o);
501
- if (o->make_lang == LANG_C || o->make_lang == LANG_CPLUSPLUS) {
502
- byte * s = add_sz_to_s(NULL, output_base);
503
- s = add_literal_to_s(s, ".h");
504
- o->output_h = get_output(s);
505
- s[SIZE(s) - 1] = 'c';
506
- if (o->make_lang == LANG_CPLUSPLUS) {
507
- s = add_char_to_s(s, 'c');
508
- }
509
- o->output_src = get_output(s);
510
- lose_s(s);
620
+ o->output_src = get_output(s);
621
+ lose_s(s);
511
622
 
512
- generate_program_c(g);
513
- fclose(o->output_src);
514
- fclose(o->output_h);
623
+ generate_program_ada(g);
624
+ fclose(o->output_src);
625
+ fclose(o->output_h);
626
+ break;
627
+ }
628
+ case LANG_CSHARP: {
629
+ byte * s = copy_s(o->output_file);
630
+ if (o->extension) {
631
+ s = add_s_to_s(s, o->extension);
632
+ } else {
633
+ s = add_literal_to_s(s, ".cs");
634
+ }
635
+ o->output_src = get_output(s);
636
+ lose_s(s);
637
+ generate_program_csharp(g);
638
+ fclose(o->output_src);
639
+ break;
640
+ }
641
+ case LANG_DART: {
642
+ byte * s = copy_s(o->output_file);
643
+ if (o->extension) {
644
+ s = add_s_to_s(s, o->extension);
645
+ } else {
646
+ s = add_literal_to_s(s, ".dart");
647
+ }
648
+ o->output_src = get_output(s);
649
+ lose_s(s);
650
+ generate_program_dart(g);
651
+ fclose(o->output_src);
652
+ break;
653
+ }
654
+ case LANG_GO: {
655
+ byte * s = copy_s(o->output_file);
656
+ if (o->extension) {
657
+ s = add_s_to_s(s, o->extension);
658
+ } else {
659
+ s = add_literal_to_s(s, ".go");
515
660
  }
516
- #ifndef DISABLE_JAVA
517
- if (o->make_lang == LANG_JAVA) {
518
- byte * s = add_sz_to_s(NULL, output_base);
661
+ o->output_src = get_output(s);
662
+ lose_s(s);
663
+ generate_program_go(g);
664
+ fclose(o->output_src);
665
+ break;
666
+ }
667
+ case LANG_JAVA: {
668
+ byte * s = copy_s(o->output_file);
669
+ if (o->extension) {
670
+ s = add_s_to_s(s, o->extension);
671
+ } else {
519
672
  s = add_literal_to_s(s, ".java");
520
- o->output_src = get_output(s);
521
- lose_s(s);
522
- generate_program_java(g);
523
- fclose(o->output_src);
524
673
  }
525
- #endif
526
- #ifndef DISABLE_PASCAL
527
- if (o->make_lang == LANG_PASCAL) {
528
- byte * s = add_sz_to_s(NULL, output_base);
529
- s = add_literal_to_s(s, ".pas");
530
- o->output_src = get_output(s);
531
- lose_s(s);
532
- generate_program_pascal(g);
533
- fclose(o->output_src);
674
+ o->output_src = get_output(s);
675
+ lose_s(s);
676
+ generate_program_java(g);
677
+ fclose(o->output_src);
678
+ break;
679
+ }
680
+ case LANG_JAVASCRIPT: {
681
+ byte * s = copy_s(o->output_file);
682
+ if (o->extension) {
683
+ s = add_s_to_s(s, o->extension);
684
+ } else {
685
+ s = add_literal_to_s(s, ".js");
534
686
  }
535
- #endif
536
- #ifndef DISABLE_PYTHON
537
- if (o->make_lang == LANG_PYTHON) {
538
- byte * s = add_sz_to_s(NULL, output_base);
539
- s = add_literal_to_s(s, ".py");
540
- o->output_src = get_output(s);
541
- lose_s(s);
542
- generate_program_python(g);
543
- fclose(o->output_src);
687
+ o->output_src = get_output(s);
688
+ lose_s(s);
689
+ generate_program_js(g);
690
+ fclose(o->output_src);
691
+ break;
692
+ }
693
+ case LANG_PASCAL: {
694
+ byte * s = copy_s(o->output_file);
695
+ if (o->extension) {
696
+ s = add_s_to_s(s, o->extension);
697
+ } else {
698
+ s = add_literal_to_s(s, ".pas");
544
699
  }
545
- #endif
546
- #ifndef DISABLE_JS
547
- if (o->make_lang == LANG_JAVASCRIPT) {
548
- byte * s = add_sz_to_s(NULL, output_base);
549
- if (o->js_esm) {
550
- s = add_literal_to_s(s, ".mjs");
551
- } else {
552
- s = add_literal_to_s(s, ".js");
553
- }
554
- o->output_src = get_output(s);
555
- lose_s(s);
556
- generate_program_js(g);
557
- fclose(o->output_src);
700
+ o->output_src = get_output(s);
701
+ lose_s(s);
702
+ generate_program_pascal(g);
703
+ fclose(o->output_src);
704
+ break;
705
+ }
706
+ case LANG_PHP: {
707
+ byte * s = copy_s(o->output_file);
708
+ if (o->extension) {
709
+ s = add_s_to_s(s, o->extension);
710
+ } else {
711
+ s = add_literal_to_s(s, ".php");
558
712
  }
559
- #endif
560
- #ifndef DISABLE_CSHARP
561
- if (o->make_lang == LANG_CSHARP) {
562
- byte * s = add_sz_to_s(NULL, output_base);
563
- s = add_literal_to_s(s, ".cs");
564
- o->output_src = get_output(s);
565
- lose_s(s);
566
- generate_program_csharp(g);
567
- fclose(o->output_src);
713
+ o->output_src = get_output(s);
714
+ lose_s(s);
715
+ generate_program_php(g);
716
+ fclose(o->output_src);
717
+ break;
718
+ }
719
+ case LANG_PYTHON: {
720
+ byte * s = copy_s(o->output_file);
721
+ if (o->extension) {
722
+ s = add_s_to_s(s, o->extension);
723
+ } else {
724
+ s = add_literal_to_s(s, ".py");
568
725
  }
569
- #endif
570
- #ifndef DISABLE_RUST
571
- if (o->make_lang == LANG_RUST) {
572
- byte * s = add_sz_to_s(NULL, output_base);
726
+ o->output_src = get_output(s);
727
+ lose_s(s);
728
+ generate_program_python(g);
729
+ fclose(o->output_src);
730
+ break;
731
+ }
732
+ case LANG_RUST: {
733
+ byte * s = copy_s(o->output_file);
734
+ if (o->extension) {
735
+ s = add_s_to_s(s, o->extension);
736
+ } else {
573
737
  s = add_literal_to_s(s, ".rs");
574
- o->output_src = get_output(s);
575
- lose_s(s);
576
- generate_program_rust(g);
577
- fclose(o->output_src);
578
738
  }
579
- #endif
580
- #ifndef DISABLE_GO
581
- if (o->make_lang == LANG_GO) {
582
- byte * s = add_sz_to_s(NULL, output_base);
583
- s = add_literal_to_s(s, ".go");
584
- o->output_src = get_output(s);
585
- lose_s(s);
586
- generate_program_go(g);
587
- fclose(o->output_src);
588
- }
589
- #endif
590
- #ifndef DISABLE_ADA
591
- if (o->make_lang == LANG_ADA) {
592
- byte * s = add_sz_to_s(NULL, output_base);
593
- s = add_literal_to_s(s, ".ads");
594
- o->output_h = get_output(s);
595
- s[SIZE(s) - 1] = 'b';
596
- o->output_src = get_output(s);
597
- lose_s(s);
598
-
599
- generate_program_ada(g);
600
- fclose(o->output_src);
601
- fclose(o->output_h);
739
+ o->output_src = get_output(s);
740
+ lose_s(s);
741
+ generate_program_rust(g);
742
+ fclose(o->output_src);
743
+ break;
744
+ }
745
+ case LANG_ZIG: {
746
+ byte * s = copy_s(o->output_file);
747
+ if (o->extension) {
748
+ s = add_s_to_s(s, o->extension);
749
+ } else {
750
+ s = add_literal_to_s(s, ".zig");
602
751
  }
603
- #endif
604
- close_generator(g);
752
+ o->output_src = get_output(s);
753
+ lose_s(s);
754
+ generate_program_zig(g);
755
+ fclose(o->output_src);
756
+ break;
605
757
  }
606
- close_tokeniser(t);
607
- close_analyser(a);
758
+ #else
759
+ default:
760
+ fprintf(stderr, "Support for requested target language not enabled\n");
761
+ exit(1);
762
+ #endif
608
763
  }
609
- lose_s(u);
764
+ close_generator(g);
610
765
  }
611
- { struct include * p = o->includes;
612
- while (p) {
613
- struct include * q = p->next;
614
- lose_s(p->s);
615
- FREE(p);
616
- p = q;
617
- }
766
+ close_tokeniser(t);
767
+ close_analyser(a);
768
+ lose_s(u);
769
+
770
+ struct include * p = o->includes;
771
+ while (p) {
772
+ struct include * q = p->next;
773
+ lose_s(p->s);
774
+ FREE(p);
775
+ p = q;
618
776
  }
619
- FREE(o->name);
777
+
778
+ lose_s(o->extension);
779
+ lose_s(o->name);
780
+ lose_s(o->output_file);
781
+ lose_s(o->output_leaf);
620
782
  FREE(o);
621
783
  if (space_count) fprintf(stderr, "%d blocks unfreed\n", space_count);
622
784
  return 0;