middlemac 3.1.0 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ */