middlemac 3.1.0 → 3.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 577f3591f5f815b959d9a272ea275cbaa18b19996c4234312fcb177aa3b56df0
4
- data.tar.gz: 4c6765e7f1d9a70043301616d7245deb167c1e87de787b8cd3e830298a112efe
3
+ metadata.gz: 9cc65eec33bce51ed9f9895d28f87491bf7f3ec0165928e4ac61e82f7fb0994f
4
+ data.tar.gz: a092b0da52ba6da22fb0487984488a6fb4b16648a3db8ae61913d0d98e959a8b
5
5
  SHA512:
6
- metadata.gz: 780edeb0005d4a5ce14210306b63b297518ba471c0904510260722de7155f1e0ec54141ab3cc310c1592b3da217377efec6bd71f5e9aa2610bf115769d7e2076
7
- data.tar.gz: 8d1856e6b75850ca86e7bab12cb702e93f5af2536384798e1a5d656800c46813b5efee6c1d53f2506ba9c93da380ec6a36870eae389b64fd9c5975f9cbc8a741
6
+ metadata.gz: 4640aba23a4ae0e588ea1f75805e211fd6c9060767baea5864158951ddc900b1b21377b5369397a55e7e379c0803afe1ae7d96792b0cf2061c466b0aa44c6b62
7
+ data.tar.gz: eb53d93c3ea28dc7894efae7191bc0d104b2ca8cb7a06251338fd25869efe799c9c6d5c5eb1a09e51cc572d8dd87fb1792cbf1addc5123b57f08862b34ce856a
data/.gitignore CHANGED
@@ -22,3 +22,9 @@ build/*
22
22
 
23
23
  # Aruba
24
24
  /tmp/
25
+
26
+ # Native Extension Build
27
+ /lib/trie
28
+
29
+ # Fixture build folder when testing.
30
+ /fixtures/middlemac_app/New_Project_(pro).help
data/CHANGELOG.md CHANGED
@@ -1,6 +1,23 @@
1
1
  middlemac change log
2
2
  ====================
3
3
 
4
+ - Version 3.1.1 / 2021-April-12
5
+
6
+ - Compatibility Updates
7
+ - Version bump.
8
+ - Vendor the source of the fast_trie gem, because it's no longer maintained, and I
9
+ don't want to create another unmaintained Ruby gem. Updates to fast_trie are needed
10
+ because Clang now has added diagnostics including default C99 which causes the
11
+ original fast_trie to no longer build. I've also silenced warnings.
12
+ - Make the landing page use target magic images instead of the static image it uses.
13
+ This means you should have `target1-icon_256x256` and `target2-icon_256x256` in
14
+ your images, or to use the same icon for all targets, `all-icon_256x256`.
15
+ - Enforce a newer minimum Middleman version, because it has removed support for
16
+ automatic alt attributes, and we've done the same. This keeps us in sync.
17
+ - Enforce Ruby versions. Right now Ruby 2.6.0 approaching 3.0 is supported. Once
18
+ Middleman has a numbered release supporting Ruby 3.0, I'll take a look at supporting
19
+ it.
20
+
4
21
  - Version 3.1.0 / 2019-October-11
5
22
 
6
23
  - Version 3.1.0
@@ -58,4 +75,3 @@ middlemac change log
58
75
  - README, getting started.
59
76
  - Overhaul of helpers and sitemap manipulators complete.
60
77
  - BRETHREN checkpoint
61
- - Continued refactoring resources.
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ require "rake/extensiontask"
1
2
  require 'bundler/gem_tasks'
2
3
  require 'cucumber/rake/task'
3
4
  require 'yard'
@@ -5,23 +6,33 @@ require 'git'
5
6
  require File.expand_path('../lib/middlemac/version.rb', __FILE__)
6
7
 
7
8
 
9
+ ###############################################################################
10
+ # ExtensionTask.new
11
+ # Compile the native extensions.
12
+ ###############################################################################
13
+ Rake::ExtensionTask.new("trie") do |ext|
14
+ ext.ext_dir = 'ext/trie'
15
+ ext.lib_dir = 'lib/trie'
16
+ end
17
+
18
+
8
19
  ###############################################################################
9
20
  # :default
10
21
  # Define the default task.
11
22
  ###############################################################################
12
- task :default => :test
23
+ task :default => [:compile, :test]
13
24
 
14
25
 
15
26
  ###############################################################################
16
27
  # :test
17
28
  # Perform Cucumber testing.
18
29
  ###############################################################################
19
- Cucumber::Rake::Task.new(:test, 'Features that must pass') do |task|
20
- task.cucumber_opts = '--require features --color --tags "not @wip" --strict --format pretty'
30
+ Cucumber::Rake::Task.new(:test, 'Features that must pass; do "rake compile" first!') do |task|
31
+ task.cucumber_opts = '--publish-quiet --require features --color --tags "not @wip" --strict --format pretty 2>/dev/null'
21
32
  end
22
33
 
23
- Cucumber::Rake::Task.new(:testq, 'Features that must pass') do |task|
24
- task.cucumber_opts = '--require features --color --tags "not @wip" --strict --format pretty 2>/dev/null'
34
+ Cucumber::Rake::Task.new(:testnoisy, 'Features that must pass; do "rake compile" first!') do |task|
35
+ task.cucumber_opts = '--publish-quiet --require features --color --tags "not @wip" --strict --format pretty'
25
36
  end
26
37
 
27
38
 
@@ -20,12 +20,12 @@
20
20
  %a{:name => current_page.data.anchor || current_page.page_name}
21
21
 
22
22
  - if landing
23
- = image_tag "icon_256x256"
23
+ = image_tag "all-icon_256x256"
24
24
  %h1 #{product_name} #{product_version}
25
25
  %h2
26
26
  %a{:href => "#{product_uri}" } #{product_uri}
27
27
  - else
28
- = image_tag current_page.data.topicIcon || "icon_256x256", :figure_class => 'topicIcon'
28
+ = image_tag current_page.data.topicIcon || "all-icon_256x256", :figure_class => 'topicIcon'
29
29
  %h1 #{current_page.data.title}
30
30
 
31
31
  = yield
@@ -17,14 +17,14 @@ source 'https://rubygems.org'
17
17
  #######################################
18
18
  # Middlemac, natch.
19
19
  #######################################
20
- gem 'middlemac', '~> 3.1.0'
20
+ gem 'middlemac', '~> 3.1.1'
21
21
  gem 'middleman-targets', '~> 1.0.12'
22
22
 
23
23
 
24
24
  #######################################
25
25
  # Core gems
26
26
  #######################################
27
- gem 'middleman', '~> 4.2.0'
27
+ gem 'middleman', '~> 4.3.7'
28
28
  gem 'middleman-core'
29
29
  gem 'middleman-cli'
30
30
  gem 'middleman-livereload' # Live-reloading plugin
@@ -94,9 +94,9 @@ config[:targets] = {
94
94
  :HPDBookIconPath => 'SharedGlobalArt/free-icon_32x32@2x.png',
95
95
  :CFBundleName => 'Middlemac',
96
96
  :ProductName => 'Middlemac',
97
- :ProductVersion => version_app || '3.1.0',
97
+ :ProductVersion => version_app || '3.1.1',
98
98
  :ProductURI => 'http://www.balthisar.com/developer',
99
- :ProductCopyright => '© 2019 Jim Derry. All rights reserved.',
99
+ :ProductCopyright => '© 2021 Jim Derry. All rights reserved.',
100
100
  :features =>
101
101
  {
102
102
  :feature_advertise_pro => true,
@@ -112,9 +112,9 @@ config[:targets] = {
112
112
  :HPDBookIconPath => 'SharedGlobalArt/pro-icon_32x32@2x.png',
113
113
  :CFBundleName => 'Middlemac',
114
114
  :ProductName => 'Middlemac Pro',
115
- :ProductVersion => version_app || '3.1.0',
115
+ :ProductVersion => version_app || '3.1.1',
116
116
  :ProductURI => 'http://www.balthisar.com/developer',
117
- :ProductCopyright => '© 2019 Jim Derry. All rights reserved.',
117
+ :ProductCopyright => '© 2021 Jim Derry. All rights reserved.',
118
118
  :features =>
119
119
  {
120
120
  :feature_advertise_pro => false,
@@ -227,11 +227,12 @@ set :strip_index_file, false
227
227
 
228
228
  #===============================================================
229
229
  # Default to HTML5 Layout.
230
+ # Specify layouts from most specific to least specific.
230
231
  #===============================================================
231
232
  Haml::TempleEngine.disable_option_validator!
232
233
  set :haml, :format => :html5
233
- page 'Resources/*.lproj/*.html', :layout => :'layout-apple-modern'
234
234
  page 'Resources/*.lproj/asides/*.html', :layout => :'layout-apple-modern-aside'
235
+ page 'Resources/*.lproj/*.html', :layout => :'layout-apple-modern'
235
236
 
236
237
 
237
238
  #===============================================================
data/ext/trie/darray.c ADDED
@@ -0,0 +1,673 @@
1
+ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
+ /*
3
+ * darray.c - Double-array trie structure
4
+ * Created: 2006-08-13
5
+ * Author: Theppitak Karoonboonyanan <thep@linux.thai.net>
6
+ */
7
+
8
+ #include <string.h>
9
+ #include <stdlib.h>
10
+ #include <stdio.h>
11
+
12
+ #include "trie-private.h"
13
+ #include "darray.h"
14
+ #include "fileutils.h"
15
+
16
+ /*----------------------------------*
17
+ * INTERNAL TYPES DECLARATIONS *
18
+ *----------------------------------*/
19
+
20
+ typedef struct _Symbols Symbols;
21
+
22
+ struct _Symbols {
23
+ short num_symbols;
24
+ TrieChar symbols[256];
25
+ };
26
+
27
+ static Symbols * symbols_new ();
28
+ static void symbols_free (Symbols *syms);
29
+ static void symbols_add (Symbols *syms, TrieChar c);
30
+
31
+ #define symbols_num(s) ((s)->num_symbols)
32
+ #define symbols_get(s,i) ((s)->symbols[i])
33
+ #define symbols_add_fast(s,c) ((s)->symbols[(s)->num_symbols++] = c)
34
+
35
+ /*-----------------------------------*
36
+ * PRIVATE METHODS DECLARATIONS *
37
+ *-----------------------------------*/
38
+
39
+ #define da_get_free_list(d) (1)
40
+
41
+ static Bool da_check_free_cell (DArray *d,
42
+ TrieIndex s);
43
+
44
+ static Bool da_has_children (DArray *d,
45
+ TrieIndex s);
46
+
47
+ static Symbols * da_output_symbols (const DArray *d,
48
+ TrieIndex s);
49
+
50
+ static TrieChar * da_get_state_key (const DArray *d,
51
+ TrieIndex state);
52
+
53
+ static TrieIndex da_find_free_base (DArray *d,
54
+ const Symbols *symbols);
55
+
56
+ static Bool da_fit_symbols (DArray *d,
57
+ TrieIndex base,
58
+ const Symbols *symbols);
59
+
60
+ static void da_relocate_base (DArray *d,
61
+ TrieIndex s,
62
+ TrieIndex new_base);
63
+
64
+ static Bool da_extend_pool (DArray *d,
65
+ TrieIndex to_index);
66
+
67
+ static void da_alloc_cell (DArray *d,
68
+ TrieIndex cell);
69
+
70
+ static void da_free_cell (DArray *d,
71
+ TrieIndex cell);
72
+
73
+ static Bool da_enumerate_recursive (const DArray *d,
74
+ TrieIndex state,
75
+ DAEnumFunc enum_func,
76
+ void *user_data);
77
+
78
+ /* ==================== BEGIN IMPLEMENTATION PART ==================== */
79
+
80
+ /*------------------------------------*
81
+ * INTERNAL TYPES IMPLEMENTATIONS *
82
+ *------------------------------------*/
83
+
84
+ static Symbols *
85
+ symbols_new ()
86
+ {
87
+ Symbols *syms;
88
+
89
+ syms = (Symbols *) malloc (sizeof (Symbols));
90
+
91
+ if (!syms)
92
+ return NULL;
93
+
94
+ syms->num_symbols = 0;
95
+
96
+ return syms;
97
+ }
98
+
99
+ static void
100
+ symbols_free (Symbols *syms)
101
+ {
102
+ free (syms);
103
+ }
104
+
105
+ static void
106
+ symbols_add (Symbols *syms, TrieChar c)
107
+ {
108
+ short lower, upper;
109
+
110
+ lower = 0;
111
+ upper = syms->num_symbols;
112
+ while (lower < upper) {
113
+ short middle;
114
+
115
+ middle = (lower + upper)/2;
116
+ if (c > syms->symbols[middle])
117
+ lower = middle + 1;
118
+ else if (c < syms->symbols[middle])
119
+ upper = middle;
120
+ else
121
+ return;
122
+ }
123
+ if (lower < syms->num_symbols) {
124
+ memmove (syms->symbols + lower + 1, syms->symbols + lower,
125
+ syms->num_symbols - lower);
126
+ }
127
+ syms->symbols[lower] = c;
128
+ syms->num_symbols++;
129
+ }
130
+
131
+ /*------------------------------*
132
+ * PRIVATE DATA DEFINITONS *
133
+ *------------------------------*/
134
+
135
+ typedef struct {
136
+ TrieIndex base;
137
+ TrieIndex check;
138
+ } DACell;
139
+
140
+ struct _DArray {
141
+ TrieIndex num_cells;
142
+ DACell *cells;
143
+ };
144
+
145
+ /*-----------------------------*
146
+ * METHODS IMPLEMENTAIONS *
147
+ *-----------------------------*/
148
+
149
+ #define DA_SIGNATURE 0xDAFCDAFC
150
+
151
+ /* DA Header:
152
+ * - Cell 0: SIGNATURE, number of cells
153
+ * - Cell 1: free circular-list pointers
154
+ * - Cell 2: root node
155
+ * - Cell 3: DA pool begin
156
+ */
157
+ #define DA_POOL_BEGIN 3
158
+
159
+ DArray *
160
+ da_new ()
161
+ {
162
+ DArray *d;
163
+
164
+ d = (DArray *) malloc (sizeof (DArray));
165
+ if (!d)
166
+ return NULL;
167
+
168
+ d->num_cells = DA_POOL_BEGIN;
169
+ d->cells = (DACell *) malloc (d->num_cells * sizeof (DACell));
170
+ if (!d->cells)
171
+ goto exit_da_created;
172
+ d->cells[0].base = DA_SIGNATURE;
173
+ d->cells[0].check = d->num_cells;
174
+ d->cells[1].base = -1;
175
+ d->cells[1].check = -1;
176
+ d->cells[2].base = DA_POOL_BEGIN;
177
+ d->cells[2].check = 0;
178
+
179
+ return d;
180
+
181
+ exit_da_created:
182
+ free (d);
183
+ return NULL;
184
+ }
185
+
186
+ DArray *
187
+ da_read (FILE *file)
188
+ {
189
+ long save_pos;
190
+ DArray *d = NULL;
191
+ TrieIndex n;
192
+
193
+ /* check signature */
194
+ save_pos = ftell (file);
195
+ if (!file_read_int32 (file, &n) || DA_SIGNATURE != (uint32) n) {
196
+ fseek (file, save_pos, SEEK_SET);
197
+ return NULL;
198
+ }
199
+
200
+ d = (DArray *) malloc (sizeof (DArray));
201
+ if (!d)
202
+ return NULL;
203
+
204
+ /* read number of cells */
205
+ file_read_int32 (file, &d->num_cells);
206
+ d->cells = (DACell *) malloc (d->num_cells * sizeof (DACell));
207
+ if (!d->cells)
208
+ goto exit_da_created;
209
+ d->cells[0].base = DA_SIGNATURE;
210
+ d->cells[0].check= d->num_cells;
211
+ for (n = 1; n < d->num_cells; n++) {
212
+ file_read_int32 (file, &d->cells[n].base);
213
+ file_read_int32 (file, &d->cells[n].check);
214
+ }
215
+
216
+ return d;
217
+
218
+ exit_da_created:
219
+ free (d);
220
+ return NULL;
221
+ }
222
+
223
+ void
224
+ da_free (DArray *d)
225
+ {
226
+ free (d->cells);
227
+ free (d);
228
+ }
229
+
230
+ int
231
+ da_write (const DArray *d, FILE *file)
232
+ {
233
+ TrieIndex i;
234
+
235
+ for (i = 0; i < d->num_cells; i++) {
236
+ if (!file_write_int32 (file, d->cells[i].base) ||
237
+ !file_write_int32 (file, d->cells[i].check))
238
+ {
239
+ return -1;
240
+ }
241
+ }
242
+
243
+ return 0;
244
+ }
245
+
246
+
247
+ TrieIndex
248
+ da_get_root (const DArray *d)
249
+ {
250
+ /* can be calculated value for multi-index trie */
251
+ return 2;
252
+ }
253
+
254
+
255
+ TrieIndex
256
+ da_get_base (const DArray *d, TrieIndex s)
257
+ {
258
+ return (0 <= s && s < d->num_cells) ? d->cells[s].base : TRIE_INDEX_ERROR;
259
+ }
260
+
261
+ TrieIndex
262
+ da_get_check (const DArray *d, TrieIndex s)
263
+ {
264
+ return (0 <= s && s < d->num_cells) ? d->cells[s].check : TRIE_INDEX_ERROR;
265
+ }
266
+
267
+
268
+ void
269
+ da_set_base (DArray *d, TrieIndex s, TrieIndex val)
270
+ {
271
+ if (0 <= s && s < d->num_cells) {
272
+ d->cells[s].base = val;
273
+ }
274
+ }
275
+
276
+ void
277
+ da_set_check (DArray *d, TrieIndex s, TrieIndex val)
278
+ {
279
+ if (0 <= s && s < d->num_cells) {
280
+ d->cells[s].check = val;
281
+ }
282
+ }
283
+
284
+ Bool
285
+ da_walk (const DArray *d, TrieIndex *s, TrieChar c)
286
+ {
287
+ TrieIndex next;
288
+
289
+ next = da_get_base (d, *s) + c;
290
+ if (da_get_check (d, next) == *s) {
291
+ *s = next;
292
+ return TRUE;
293
+ }
294
+ return FALSE;
295
+ }
296
+
297
+ TrieIndex
298
+ da_insert_branch (DArray *d, TrieIndex s, TrieChar c)
299
+ {
300
+ TrieIndex base, next;
301
+
302
+ base = da_get_base (d, s);
303
+
304
+ if (base > 0) {
305
+ next = base + c;
306
+
307
+ /* if already there, do not actually insert */
308
+ if (da_get_check (d, next) == s)
309
+ return next;
310
+
311
+ /* if (base + c) > TRIE_INDEX_MAX which means 'next' is overflow,
312
+ * or cell [next] is not free, relocate to a free slot
313
+ */
314
+ if (base > TRIE_INDEX_MAX - c || !da_check_free_cell (d, next)) {
315
+ Symbols *symbols;
316
+ TrieIndex new_base;
317
+
318
+ /* relocate BASE[s] */
319
+ symbols = da_output_symbols (d, s);
320
+ symbols_add (symbols, c);
321
+ new_base = da_find_free_base (d, symbols);
322
+ symbols_free (symbols);
323
+
324
+ if (TRIE_INDEX_ERROR == new_base)
325
+ return TRIE_INDEX_ERROR;
326
+
327
+ da_relocate_base (d, s, new_base);
328
+ next = new_base + c;
329
+ }
330
+ } else {
331
+ Symbols *symbols;
332
+ TrieIndex new_base;
333
+
334
+ symbols = symbols_new ();
335
+ symbols_add (symbols, c);
336
+ new_base = da_find_free_base (d, symbols);
337
+ symbols_free (symbols);
338
+
339
+ if (TRIE_INDEX_ERROR == new_base)
340
+ return TRIE_INDEX_ERROR;
341
+
342
+ da_set_base (d, s, new_base);
343
+ next = new_base + c;
344
+ }
345
+ da_alloc_cell (d, next);
346
+ da_set_check (d, next, s);
347
+
348
+ return next;
349
+ }
350
+
351
+ static Bool
352
+ da_check_free_cell (DArray *d,
353
+ TrieIndex s)
354
+ {
355
+ return da_extend_pool (d, s) && da_get_check (d, s) < 0;
356
+ }
357
+
358
+ static Bool
359
+ da_has_children (DArray *d,
360
+ TrieIndex s)
361
+ {
362
+ TrieIndex base;
363
+ TrieIndex c, max_c;
364
+
365
+ base = da_get_base (d, s);
366
+ if (TRIE_INDEX_ERROR == base || base < 0)
367
+ return FALSE;
368
+
369
+ max_c = MIN_VAL (TRIE_CHAR_MAX, TRIE_INDEX_MAX - base);
370
+ for (c = 0; c < max_c; c++) {
371
+ if (da_get_check (d, base + c) == s)
372
+ return TRUE;
373
+ }
374
+
375
+ return FALSE;
376
+ }
377
+
378
+ static Symbols *
379
+ da_output_symbols (const DArray *d,
380
+ TrieIndex s)
381
+ {
382
+ Symbols *syms;
383
+ TrieIndex base;
384
+ TrieIndex c, max_c;
385
+
386
+ syms = symbols_new ();
387
+
388
+ base = da_get_base (d, s);
389
+ max_c = MIN_VAL (TRIE_CHAR_MAX, TRIE_INDEX_MAX - base);
390
+ for (c = 0; c < max_c; c++) {
391
+ if (da_get_check (d, base + c) == s)
392
+ symbols_add_fast (syms, (TrieChar) c);
393
+ }
394
+
395
+ return syms;
396
+ }
397
+
398
+ static TrieChar *
399
+ da_get_state_key (const DArray *d,
400
+ TrieIndex state)
401
+ {
402
+ TrieChar *key;
403
+ int key_size, key_length;
404
+ int i;
405
+
406
+ key_size = 20;
407
+ key_length = 0;
408
+ key = (TrieChar *) malloc (key_size);
409
+
410
+ /* trace back to root */
411
+ while (da_get_root (d) != state) {
412
+ TrieIndex parent;
413
+
414
+ if (key_length + 1 >= key_size) {
415
+ key_size += 20;
416
+ key = (TrieChar *) realloc (key, key_size);
417
+ }
418
+ parent = da_get_check (d, state);
419
+ key[key_length++] = (TrieChar) (state - da_get_base (d, parent));
420
+ state = parent;
421
+ }
422
+ key[key_length] = '\0';
423
+
424
+ /* reverse the string */
425
+ for (i = 0; i < --key_length; i++) {
426
+ TrieChar temp;
427
+
428
+ temp = key[i];
429
+ key[i] = key[key_length];
430
+ key[key_length] = temp;
431
+ }
432
+
433
+ return key;
434
+ }
435
+
436
+ static TrieIndex
437
+ da_find_free_base (DArray *d,
438
+ const Symbols *symbols)
439
+ {
440
+ TrieChar first_sym;
441
+ TrieIndex s;
442
+
443
+ /* find first free cell that is beyond the first symbol */
444
+ first_sym = symbols_get (symbols, 0);
445
+ s = -da_get_check (d, da_get_free_list (d));
446
+ while (s != da_get_free_list (d)
447
+ && s < (TrieIndex) first_sym + DA_POOL_BEGIN)
448
+ {
449
+ s = -da_get_check (d, s);
450
+ }
451
+ if (s == da_get_free_list (d)) {
452
+ for (s = first_sym + DA_POOL_BEGIN; ; ++s) {
453
+ if (!da_extend_pool (d, s))
454
+ return TRIE_INDEX_ERROR;
455
+ if (da_get_check (d, s) < 0)
456
+ break;
457
+ }
458
+ }
459
+
460
+ /* search for next free cell that fits the symbols set */
461
+ while (!da_fit_symbols (d, s - first_sym, symbols)) {
462
+ /* extend pool before getting exhausted */
463
+ if (-da_get_check (d, s) == da_get_free_list (d)) {
464
+ if (!da_extend_pool (d, d->num_cells))
465
+ return TRIE_INDEX_ERROR;
466
+ }
467
+
468
+ s = -da_get_check (d, s);
469
+ }
470
+
471
+ return s - first_sym;
472
+ }
473
+
474
+ static Bool
475
+ da_fit_symbols (DArray *d,
476
+ TrieIndex base,
477
+ const Symbols *symbols)
478
+ {
479
+ int i;
480
+
481
+ for (i = 0; i < symbols_num (symbols); i++) {
482
+ TrieChar sym = symbols_get (symbols, i);
483
+
484
+ /* if (base + sym) > TRIE_INDEX_MAX which means it's overflow,
485
+ * or cell [base + sym] is not free, the symbol is not fit.
486
+ */
487
+ if (base > TRIE_INDEX_MAX - sym || !da_check_free_cell (d, base + sym))
488
+ return FALSE;
489
+ }
490
+ return TRUE;
491
+ }
492
+
493
+ static void
494
+ da_relocate_base (DArray *d,
495
+ TrieIndex s,
496
+ TrieIndex new_base)
497
+ {
498
+ TrieIndex old_base;
499
+ Symbols *symbols;
500
+ int i;
501
+
502
+ old_base = da_get_base (d, s);
503
+ symbols = da_output_symbols (d, s);
504
+
505
+ for (i = 0; i < symbols_num (symbols); i++) {
506
+ TrieIndex old_next, new_next, old_next_base;
507
+
508
+ old_next = old_base + symbols_get (symbols, i);
509
+ new_next = new_base + symbols_get (symbols, i);
510
+ old_next_base = da_get_base (d, old_next);
511
+
512
+ /* allocate new next node and copy BASE value */
513
+ da_alloc_cell (d, new_next);
514
+ da_set_check (d, new_next, s);
515
+ da_set_base (d, new_next, old_next_base);
516
+
517
+ /* old_next node is now moved to new_next
518
+ * so, all cells belonging to old_next
519
+ * must be given to new_next
520
+ */
521
+ /* preventing the case of TAIL pointer */
522
+ if (old_next_base > 0) {
523
+ TrieIndex c, max_c;
524
+
525
+ max_c = MIN_VAL (TRIE_CHAR_MAX, TRIE_INDEX_MAX - old_next_base);
526
+ for (c = 0; c < max_c; c++) {
527
+ if (da_get_check (d, old_next_base + c) == old_next)
528
+ da_set_check (d, old_next_base + c, new_next);
529
+ }
530
+ }
531
+
532
+ /* free old_next node */
533
+ da_free_cell (d, old_next);
534
+ }
535
+
536
+ symbols_free (symbols);
537
+
538
+ /* finally, make BASE[s] point to new_base */
539
+ da_set_base (d, s, new_base);
540
+ }
541
+
542
+ static Bool
543
+ da_extend_pool (DArray *d,
544
+ TrieIndex to_index)
545
+ {
546
+ TrieIndex new_begin;
547
+ TrieIndex i;
548
+ TrieIndex free_tail;
549
+
550
+ if (to_index <= 0 || TRIE_INDEX_MAX <= to_index)
551
+ return FALSE;
552
+
553
+ if (to_index < d->num_cells)
554
+ return TRUE;
555
+
556
+ d->cells = (DACell *) realloc (d->cells, (to_index + 1) * sizeof (DACell));
557
+ new_begin = d->num_cells;
558
+ d->num_cells = to_index + 1;
559
+
560
+ /* initialize new free list */
561
+ for (i = new_begin; i < to_index; i++) {
562
+ da_set_check (d, i, -(i + 1));
563
+ da_set_base (d, i + 1, -i);
564
+ }
565
+
566
+ /* merge the new circular list to the old */
567
+ free_tail = -da_get_base (d, da_get_free_list (d));
568
+ da_set_check (d, free_tail, -new_begin);
569
+ da_set_base (d, new_begin, -free_tail);
570
+ da_set_check (d, to_index, -da_get_free_list (d));
571
+ da_set_base (d, da_get_free_list (d), -to_index);
572
+
573
+ /* update header cell */
574
+ d->cells[0].check = d->num_cells;
575
+
576
+ return TRUE;
577
+ }
578
+
579
+ void
580
+ da_prune (DArray *d, TrieIndex s)
581
+ {
582
+ da_prune_upto (d, da_get_root (d), s);
583
+ }
584
+
585
+ void
586
+ da_prune_upto (DArray *d, TrieIndex p, TrieIndex s)
587
+ {
588
+ while (p != s && !da_has_children (d, s)) {
589
+ TrieIndex parent;
590
+
591
+ parent = da_get_check (d, s);
592
+ da_free_cell (d, s);
593
+ s = parent;
594
+ }
595
+ }
596
+
597
+ static void
598
+ da_alloc_cell (DArray *d,
599
+ TrieIndex cell)
600
+ {
601
+ TrieIndex prev, next;
602
+
603
+ prev = -da_get_base (d, cell);
604
+ next = -da_get_check (d, cell);
605
+
606
+ /* remove the cell from free list */
607
+ da_set_check (d, prev, -next);
608
+ da_set_base (d, next, -prev);
609
+ }
610
+
611
+ static void
612
+ da_free_cell (DArray *d,
613
+ TrieIndex cell)
614
+ {
615
+ TrieIndex i, prev;
616
+
617
+ /* find insertion point */
618
+ i = -da_get_check (d, da_get_free_list (d));
619
+ while (i != da_get_free_list (d) && i < cell)
620
+ i = -da_get_check (d, i);
621
+
622
+ prev = -da_get_base (d, i);
623
+
624
+ /* insert cell before i */
625
+ da_set_check (d, cell, -i);
626
+ da_set_base (d, cell, -prev);
627
+ da_set_check (d, prev, -cell);
628
+ da_set_base (d, i, -cell);
629
+ }
630
+
631
+ Bool
632
+ da_enumerate (const DArray *d, DAEnumFunc enum_func, void *user_data)
633
+ {
634
+ return da_enumerate_recursive (d, da_get_root (d), enum_func, user_data);
635
+ }
636
+
637
+ static Bool
638
+ da_enumerate_recursive (const DArray *d,
639
+ TrieIndex state,
640
+ DAEnumFunc enum_func,
641
+ void *user_data)
642
+ {
643
+ Bool ret;
644
+ TrieIndex base;
645
+
646
+ base = da_get_base (d, state);
647
+
648
+ if (base < 0) {
649
+ TrieChar *key;
650
+
651
+ key = da_get_state_key (d, state);
652
+ ret = (*enum_func) (key, state, user_data);
653
+ free (key);
654
+ } else {
655
+ Symbols *symbols;
656
+ int i;
657
+
658
+ ret = TRUE;
659
+ symbols = da_output_symbols (d, state);
660
+ for (i = 0; ret && i < symbols_num (symbols); i++) {
661
+ ret = da_enumerate_recursive (d, base + symbols_get (symbols, i),
662
+ enum_func, user_data);
663
+ }
664
+
665
+ symbols_free (symbols);
666
+ }
667
+
668
+ return ret;
669
+ }
670
+
671
+ /*
672
+ vi:ts=4:ai:expandtab
673
+ */