forked from mooredan/unifuzz
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunifuzz.c
5589 lines (5299 loc) · 397 KB
/
unifuzz.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
**
** name: unifuzz.c
**
** version: (see line below)
*/
#define UNIFUZZ_VERSION Unifuzz v0.3.7 - Unicode v
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
/*
**
** authors: author of part of original code is Loic Dachary <[email protected]>
** reworked by Ioannis (ioannis.mpsounds.net)
** almost fully rewritten Jean-Christophe Deschamps <[email protected]>
**
** type: C extension for SQLite3
**
** implements: fuzzy Unicode string search
** locale-invariant Unicode support for casing and collation
** various utility functions
**
** warning: uses Windows CompareStringW() comparison function
**
** notes: this loadable extension is currently intended to be built as a
** single Win32 DLL file. This is a work in progress, bear with it.
**
** tabs: 4 spaces
**
** legalese: Don't look for a licence reference, there is none. Use this freely,
** correct its bugs (there are certainly several waiting to destroy
** your data), give it around, mail it to your representative/lover,
** as you wish. Credit DrH, Loic Dachary, Ioannis, Unicode groups
** and any other contributor.
**
** History: 0.2.4 2009/10 initial beta
** 0.2.5 2009/11/09 clearer explanations, no code change
** 0.2.6 2009/11/13 fix unaccent table for uppercase german eszet
** 0.2.7 2009/11/16 use slash '/' instead of U+2044 (fraction slash)
** in the unaccent tables for decomposing ¼ ½ ...
** into the _much_ more common 1/4 1/2 ...
** 0.2.8 2009/11/17 add the flip() function to reverse strings
** without regards to decomposed chars, graphemes.
** 0.2.9 2009/11/19 add the chrw(), ascw() and hexw() functions
** 0.3.0 2009/11/29 make auto_load feature optional to remove
** dependancy to sqlite.dll. Read notes at the end
** of file to learn more.
** 0.3.1 2009/12/01 Fix collations comparison length;
** add new NUMERICS collation function;
** document that index using collations should not
** have the UNIQUE constraint.
** 0.3.2 2009/12/02 ASCW now accept index parameter.
** 0.3.3 2009/12/05 fix NUMERICS to sort rest of string as well but
** with collation NOCASE.
** 0.3.4 2009/12/07 allow registration of some functions to return
** SQLITE_BUSY to permit loading from SQL. Requires
** having some UTF-16 functions even in only UTF-8
** is requested.
** 0.3.5 2010/03/18 Add UNACCENTED collation.
** Add strpos() and strdup() functions.
** 0.3.6 2010/05/21 Fix © --> (C) and ® --> (R).
** 0.3.7 2011/06/19 Add strfilter() and strtaboo().
** 0.3.8 2013/06/21 RMNOCASE is an alias for NOCASE; document unifuzz().
**
**
** General
** =======
**
** The goal was to provide a set of decent Unicode functions without
** too much bloat and reasonably fast. In contrast to ICU this code
** tries to work as locale-independant, which means that compromises
** had to be made. There are clearly too many rules and exceptions
** to achieve a perfect result in such a single small source file.
**
** | All functions rely on strings in normal form C. If you know or
** | suspect that your text data contains anything else must be warned
** | that the results obtained can be completely unexpected for such
** | strings. This is particularly true for indices. BTW if you don't
** | know what normal forms are, then it is probable that your data is
** | already under the C normal form.
**
** All casing and unaccentuation functions use Unicode 5.1 tries and
** should port to any system (not tested outside XP x86 yet).
**
** The fuzzy compare is also portable, with the same disclaimer.
**
** | Unfortunately and even if I tried hard other approaches, the two
** | collation functions rely on MickeySoft XP CompareStringW function,
** | which makes them non portable outside Win 32-64 world.
** | It should be possible to come up with, say, a Un*x equivalent or
** | at least end up with something very close but I can't help for
** | that anytime soon.
** |
** | If ever one of those collations is used to build indices, then they
** | \\\_MUST_/// be rebuilt if the underlying compare function changes.
** |
** | Observe that since the collations compare modified data (unaccented
** | strings for NOCASE[U] and NAMES, numeric part only for NUMERIC), it
** | is not safe to put a UNIQUE constraints on indices using these
** | collations. This is nothing new: the same remark applies to the
** | built-in NOCASE as well.
** |
** | I believe the Win function used is now reasonably stable accross
** | Win** versions and covers many aspects of Unicode v5.1, even with
** | the locale-independant parameter used here. But of course, this
** | kind of choice is likely to be useful to many and, at the same
** | time, make almost everyone unhappy. This is because many [dark]
** | corners had to be cut to avoid data and code bloat. Yet I believe
** | this offers a decent alternative between SQLite pure-ASCII offer
** | and a full blown ICU implementation.
**
** If you application demands something else, feel free to adapt the
** code (but please use different names to avoid confusion).
**
** A small set of UTF-8 and UTF-16 functions is ready for use with no
** 8 <--> 16 overhead. A preprocessor define can be used to select
** which UTF-* set of functions to include, or both.
** Also, the original unaccent tables used "short" but some codepoints
** require 32-bit. I choose to expand these tables only to hold 32-
** bit values so that all Unicode 5.1 uppercase, lowercase and title
** _simple_ conversions are enforced. No, not all: I dropped Deseret
** as I think that my friends around Salt Lake using Deseret already
** have their own tools.
**
**
** Some will call this a half-baked cake, because there may be not
** even one script/language that will be handled _perfectly_.
** Others will say it's an oven-dessicated chicken, because of too
** many cycles wasted for a non-portable, non-universal result.
**
**
** Ligatures
** =========
**
** Provision has been made to handle ligatures in the unaccent
** function. See below for the special status of 'ß'. When they have
** a defined "simple"" decomposition, then they are decomposed.
** There is little point using the output of unaccent() per se: it
** mainly makes sense used inside comparison functions (LIKE, GLOB,
** TYPOS). unaccent() can nonetheless be useful for preparing data
** before indexing by FTSx: this way searches can be successful
** independantly of diacritics, for scripts where this is a sensible
** option.
**
**
** The German ß (sharp s)
** ======================
**
** The special case of the German eszet 'ß' has been handled as
** follows:
** LOWER('ß') = 'ß'
** UPPER('ß') = 'SS'
** TITLE('ß') = 'SS'
** PROPER('ß') = 'ß' head letter (normaly never occurs)
** PROPER('ß') = 'ß' subsequent letters
** FOLD('ß') = 'ß'
** UNACCENT('ß') = 'ss'
**
** LOWER('\u1E9E') = 'ß'
** UPPER('\u1E9E') = 0x1E9E
** TITLE('\u1E9E') = 0x1E9E
** PROPER('\u1E9E') = 0x1E9E head letter
** PROPER('\u1E9E') = 'ß' subsequent letters
** FOLD('\u1E9E') = 0x1E9E
** UNACCENT('\u1E9E') = 'SS'
**
** This choice may not be the best (it may change string length)
** but it seems to be a good compromise. Notably the recently
** introduced capital sharp s (U+01E9E) is _not_ considered as the
** uppercase of 'ß', while 'ß' is the lowercase of U+01E9E.
** It sounds like most available fonts are not (yet) aware of the
** (U+01E9E) introduction. In contrast the substitution ß <--> ss
** is clearly very common.
**
**
** Unaccenting
** ===========
**
** This set of functions makes fair use of unaccent(). It should
** not be considered a linguistic aid at all, since the notions of
** script and locale are ignored. It is instead a "basic match"
** thing because when functions like fuzzy search are used, there
** must be some kind of human validation afterwards. For instance
** unaccenting sentences like "Æ e i åa å o e i åa o å" which means,
** in Trondheim dialect, "I am in the river and she is in the river
** as well" is likely to produce strict nonsense but a human operator
** can probably recognize this in "ae e i aa a o e i aa o a" if (s)he
** can read the dialect.
**
** In view of this, one should never consider that if typos(st1, st2)
** returns 0, then the strings are exactly equivalent. All it means
** is that they _look_ very close if all accents are removed from
** them.
**
** The German Umlaut letters ä, Ä, ö, Ö, ü, Ü are simply unaccented in
** resp. a, A, o, O, u, U without any 'e' appended. Doing so would
** be nonsense in non-Germanic scripts. LIKE('Köln', 'Koeln') yields
** False but LIKE('Köln', 'koln') yields True.
**
** Despite being a crude approximation, unaccent() can also be very
** useful for full text search without dependency on diacritics. You
** may want to try passing your data as lower(unaccented()) to FTS3.
** As mentionned above, this will work fine for any scripts where
** removal of diacritic signs don't completely change the meaning to
** the point of being unintelligible. Such searches will run at full
** speed with non-ICU FTS3. Beware that then the snippet() function
** may fail to locate matches!
**
**
** Casing
** ======
**
** Similarily, upper(), lower() and title() are also approximations.
** There are probably scripts where upper- and lower-case conversions
** of some codepoints are terribly wrong. Even if the tables used
** come from official Unicode specifications, there are enough cases
** of exception to invalidate every attempt to get it right in the
** general case (no script/locale selection). Anyway I believe the
** result can be useful for many users despite the limitations.
**
** fold() is _very_ similar to lower(): the two differ only for 16
** codepoints in the plane 0. Those short on memory could make a
** derivative extension omitting the fold tables and using a 16-entry
** linear table.
**
**
** Current problems
** ================
**
** | o) the collation lacks portability: one Windows call is used.
**
** o) the data table for unaccent() had problems in original source:
** data is short[] but some values were > 0xFFFF. I expanded the
** table to Unicode characters (u32) to hold those codes. As a
** consequence the current implementation is larger than the
** original version.
**
** o) For similar reason (codepoints > 0xFFFF) the Deseret alphabet
** has been excluded from the upper, lower, title, ... tables.
** Including Deseret codepoints would have doubled all tables for
** dubious benefit.
**
** o) Some details are not fixed, like handling (i.e. shutting off)
** the case-sensitive LIKE pragma.
**
**
**
** Usage
** =====
**
** Loading
** -------
**
** From C:
** ^^^^^^^
** use sqlite3_load_extension() to load on a connection basis
** and the standard sqlite3_extension_init entry point.
**
** | use sqlite3_auto_extension() to perform auto loading with
** | the standard sqlite3_extension_init entry point.
** | This requires that your application loads unifuzz.dll
** | and obtain the actual address of the entry point.
** | Be aware that the extension will only be available to
** | subsequent connections and that it will be effective
** | for _each_ of them.
**
** | use sqlite3_auto_extension() to perform auto loading with
** | the auto_load entry point. Version >= 0.3.0 don't
** | ship with this feature enabled: now needs recompile
** | with AUTOLOAD_KLUDGE defined. This causes a dependancy
** | on sqlite3.dll.
**
** From a third-party DB manager, wrappers or other SQL application:
** ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
** use "select load_extension('unifuzz.dll');"
** to load the extension for the current DB connection only.
**
** | use "select load_extension('unifuzz.dll', 'auto_load');"
** | to load as auto_loaded extension available to each
** | subsequently opened DB in the session. Versions >= 0.3.0
** | don't ship with this feature enabled and need recompile
** | with AUTOLOAD_KLUDGE defined. This causes a dependancy
** | on sqlite3.dll.
**
**
** ~~~~~~~~~~~~~~
** Function names
** ~~~~~~~~~~~~~~
** |
** | A couple of #define options let you choose to override or not
** | the native scalar functions or collation. By default, all SQLite
** | functions are overriden and the new functions carry the base name
** | with NO letter U postfixed, so the description below applies to
** | UPPER, LOWER, LIKE, GLOB, and NOCASE.
** |
** | There is no facility in the SQLite library to declare an operator
** | as available in the infix notation. Only the native names can be
** | using this feature. This means that if you choose to have this
** | extension preserve the native functions, the only way to invoke
** | the LIKEU and GLOBU functions is using the generic form for calls
** |
** | ... LIKEU(pattern, string [, escape_char]) ...
** |
** | as opposed to the infix (more common) notation.
** |
** |
** | Defining UNIFUZZ_OVERRIDE_SCALARS makes the new scalar functions
** | override corresponding native SQLite scalars functions.
** |
** | Defining UNIFUZZ_OVERRIDE_NOCASE makes the new collation override
** | the native NOCASE collation.
**
**
** Scalar functions
** ----------------
**
** UPPER(str)
** UPPERU(str)
** returns a Unicode uppercase version of str
**
** LOWER(str)
** LOWERU(str)
** returns a Unicode lowercase version of str
**
** UNACCENT(str)
** returns a Unicode unaccented version of str
**
** FOLD(str)
** returns a Unicode folded version of str
**
** str2 LIKE str1 [ESCAPE esc]
** LIKE(str1, str2 [, esc])
** LIKEU(str1, str2 [, esc])
** behaves the same as the built-in LIKE, but handles Unicode:
** same as LIKE(unaccent(fold(str1)), unaccent(fold(str2))[, esc])
**
** str2 GLOB str1
** GLOB(str1, str2)
** GLOBU(str1, str2)
** behaves the same as the built-in GLOB, but handles Unicode:
** same as GLOB(unaccent(str1), unaccent(str2))
** It is a byproduct of LIKE.
**
** TYPOS(str1, str2)
** returns the "Damerau-Levenshtein distance" between fold(str1) and
** fold(str2). This is the number of insertions, omissions, changes
** and transpositions (of adjacent letters only). Similarily to
** the overriding LIKE above, it works on Unicode strings by
** making them unaccented & lowercase.
**
** If the reference string is 'abcdef', it will return 1 (one typo) for
** 'abdef' missing c
** 'abcudef' u inserted
** 'abzef' c changed into z
** 'abdcef' c & d exchanged
**
** Only one level of "typo" is considered, e.g. the function will
** consider the following transformations to be 3 typos:
** 'abcdef' reference
** 'abdcef' c & d exchanged
** 'abdzcef' z inserted inside (c & d exchanged)
** In this case, it will return 3. Technically, it does not
** always return the minimum edit distance and doesn't satisfy
** the "triangle inequality" in all cases. It is nonetheless
** very useful to anyone having to lookup simple entry subject to
** user typo (e.g. name or city name) in a SQLite table where data
** is likely or know to use non-ASCII characters.
**
** It will also accept '_' and a trailing '%' in str2, both acting
** as in LIKE.
**
** You can use it this way:
** select * from t where typos(col, 'leivencht%') <= 2;
** select * from t where typos(name, inputname) <= 2;
** or this way:
** select typos(str1, str2)
**
** NOTE: the implementation may seem naive but is open to several
** evolutions. Due to the complexity in O(n*m) you
** should reserve its use to _short_ fields only. There
** are much better algorithms for large fields (most of
** which are terrible for small strings.) The choice made
** reflects the typical need to match names, surnames,
** street addresses, cities or such data prone to typos
** in user input. Flexibility has been choosen over mere
** performance, because fuzzy search is _slow_ anyway.
** So you better have a 380% slower algo that retrieves
** the rows you're after, than a 100% slow algo that misses
** them most of the times.
**
** LIMIT There is a limit to the character length of arguments
** that TYPOS will handle. The limit is more precisely
** on the _product_ of both length. Anything near the
** default limit will take forever, due to the O(n*m)
** algorithm.
**
** | DO NOT use TYPOS in case LIKE would do! for instance, if
** | you want rows that contain a fixed substring (without typo),
** | then use:
** | select * from t where cityname LIKE '%angel%';
** | It will match 'Los Angeles' without question. If you try:
** | select * from t where typos(cityname, 'angel%') <= 4;
** | you will be overhelmed with rows from everywhere, since up
** | to 4 typos allows for typically _many_ values (cities, here).
**
**
** FLIP(str)
** returns a flipped (reversed) version of str without regards to
** | decomposed chars or graphemes. May yield nonsense when applied
** | on strings containing decomposed characters, for scripts using
** | unbreakable multi-characters graphemes or multi-directional strings.
**
** STRPOS(str1, str2)
** STRPOS(str1, str2, nbr)
** returns the position of the <nbr>th occurence of str2 within str1.
** By default, or when nbr = 0, nbr = 1. Negative values of nbr count
** occurences from the end of str1. Returned position is 1-based
** (first character of str1 is at 1) and is 0 if str2 is not found.
**
** STRDUP(str, count)
** returns concatenation of count times the string str. count must
** be a non-negative integer. If count is zero, an empty string is
** returned; if count is negative, null is returned.
**
** STRFILTER(str1, str2)
** returns str1 with characters NOT in str2 removed.
**
** STRTABOO(str1, str2)
** returns str1 with characters IN str2 removed.
**
**
**
**
** Collation functions
** -------------------
**
** | These collations are just wrappers around a Windows call!
** | The current implementation should work consistently on all
** | Windows 32-64 versions, as long as MS doesn't change the
** | behavior of this function (which is rather unlikely).
** |
** | Any index built on one of these collations will have to be
** | rebuilt if ever the Windows function used changes!
** |
** | Observe that since the collations compare modified data
** | (unaccented strings for NOCASE[U] and NAMES, numeric part
** | only for NUMERICS), it's unsafe to put a UNIQUE constraint
** | on indices using these collations. This is nothing new: the
** | same remark applies to the built-in NOCASE as well.
**
**
** NOCASE
** NOCASEU
** RMNOCASE
** this basic function overrides the built-in function and
** handles Unicode strings using the CompareStringW Win32
** call with "locale-invariant" and IGNORECASE parameters.
** If you need locale-specific collation with the highly specific
** behavior for a locale, then you should probably use ICU instead.
** But then be aware that the locale used for indexing is a metadata
** of the table as well as the ICU and Unicode versions!
**
** UNACCENTED
** handles Unicode strings using the CompareStringW Win32
** call with "locale-independant" parameter similarly to NOCASE
** but also ignores diacritics.
**
** NAMES
** this collation uses the "word order" option explained on the
** MSDN page for CompareStringW(): hyphens and single quotes are
** ignored, as well as punctuation and symbols.
** Should be tested for validity with uncommon scripts.
** See http://msdn.microsoft.com/en-us/library/ms647476(VS.85).aspx
**
** NUMERICS
** this collation performs a numerical sort on text values similar
** to what _atoi64 would give, but converts all forms of Unicode
** decimal digits codepoints to their decimal equivalent. This
** conversion accepts leading whitespaces (all sorts of Unicode
** whitespaces are OK), one optional sign (all sorts of + and -
** are OK) then optional numeric part (all sorts of Unicode digits
** are OK) but it doesn't check for signed 64-bit integer overflow.
** Conversion stops at the first non-digit. Nulls yield zero.
** In cases where numeric prefixes yield the same value, then the
** non-numeric part of the strings, if any, are then compared
** with NOCASE collation.
**
**
** Convenience functions
** ---------------------
**
** HEXW(number)
** HEXW('number')
** Returns the hexadecimal representation of <number>.
**
**
** ASCW(string [, index])
** Returns the numeric value of the Unicode codepoint of the
** character of <string> at position <index>. First character
** is at index 1, last character at -1. Yields null for invalid
** index values. Default index is 1.
**
**
** CHRW(decimal_number)
** CHRW('decimal_number')
** CHRW(x'hexadecimal_number')
** Returns a string containing the Unicode character whose code
** point numeric value was passed as argument. Non-characters
** codepoints are rendered as U+00FFFD (invalid character).
**
**
** PRINTF(formatstr, p1, p2, ..., pn)
** This is a [dirty] wrapper around sqlite3_mprintf(). Use it in
** your SQL just like any scalar function returning a string.
**
** SELECT printf('format %lli %g %s %s', 123, 4.56, 'abc', null);
**
** will return: 'format 123 4.56 abc <NULL>'
**
** Valid format specifications include:
**
** %ll[diouxX] 64-bit integer (don't omit the ll modifier!)
** %[eEfgG] double
** %s string
** %s SQL null will print as '<NULL>'
** %q %Q %w escaping specs see sqlite3 docs
** %% percent
**
** | NEVER use %p, %c, or variations: this will crash your application.
**
** Refer to the SQlite documentation or source code for width and
** precision specifications.
**
**
** UNIFUZZ()
** Returns a string containing the Unicode tries and the unifuzz extension
** version numbers.
**
**
** Compilation
** ===========
** This code compiles fine with MinGW gcc (preferred), VC++ Express 2008 and tcc.
**
** gcc -O2 -lm -shared unifuzz.c -o unifuzz.dll
** tcc -shared unifuzz.c -ounifuzz.dll
**
**
** I hope someone will find it useful. It would be nice to have reports from users
** in various countries or using various scripts. Even if you choose to not use it
** your feedback is valuable.
**
** Please send any feedback at:
** "Jean-Christophe Deschamps" <[email protected]>
**
*/
#ifdef __cplusplus
extern "C" {
#endif
// #include "../sqlite3ext.h"
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#ifndef WIN32
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"
#endif
#ifndef NO_WINDOWS_COLLATION
#ifdef WIN32
#include <windows.h>
#endif
#endif
#ifndef SQLITE_PRIVATE
# define SQLITE_PRIVATE static
#endif
#define DLL_EXPORT __declspec(dllexport)
#define DLL_IMPORT __declspec(dllimport)
#define UNUSED_PARAMETER(x) (void)(x)
// Select preferred encoding:
//
// Choose a set of scalar functions for the preferred UTF encoding, or both.
//
// Whatever your choice is, you can still use this library with any base since
// SQLite will perform the necessary conversions for you transparently.
//
// The whole purpose of offering both UTF-8 and UTF-16 versions is to avoid these
// conversions. When, for instance, you invoke a function with a base encoded in
// UTF-16 then SQLite will select the version of this function said to be optimized
// for handling / returning UTF-16 parameters without extra conversion.
//
// Of course only one of the two set of function is required but if you happen to
// have both UTF-8 and UTF-16 bases, then you can find it more efficient to have
// both sets of functions handy.
#if !defined(UNIFUZZ_UTF8) && !defined(UNIFUZZ_UTF16) && !defined(UNIFUZZ_UTF_BOTH)
# define UNIFUZZ_UTF_BOTH
#endif
// By default, this library does overrides the native scalar functions
// UPPER, LOWER, LIKE and GLOB. The following define lets you choose to
// leave the native functions available and have the new ones suffixed by U:
// UPPERU, LOWERU, LIKEU and GLOBU.
//
// You can choose to override them by defining UNIFUZZ_OVERRIDE_SCALARS
//
// Similarily, the NOCASE collation sequence is overriden by default.
//
// You can choose to override it by defining UNIFUZZ_OVERRIDE_NOCASE
// and the new collation calls NOCASEU.
//
// You can of course choose to define those symbols at the compiler command line
// instead of having them hardcoded here.
#define UNIFUZZ_OVERRIDE_SCALARS
#define UNIFUZZ_OVERRIDE_NOCASE
/*
** Integers of known sizes. These typedefs might change for architectures
** where the sizes vary. Preprocessor macros are available so that the
** types can be conveniently redefined at compile-type. Like this:
**
** cc '-DUINTPTR_TYPE=long long int' ...
*/
#ifndef UINT32_TYPE
# ifdef HAVE_UINT32_T
# define UINT32_TYPE uint32_t
# else
# define UINT32_TYPE unsigned int
# endif
#endif
#ifndef INT32_TYPE
# ifdef HAVE_INT32_T
# define INT32_TYPE int32_t
# else
# define INT32_TYPE int
# endif
#endif
#ifndef UINT16_TYPE
# ifdef HAVE_UINT16_T
# define UINT16_TYPE uint16_t
# else
# define UINT16_TYPE unsigned short int
# endif
#endif
#ifndef INT16_TYPE
# ifdef HAVE_INT16_T
# define INT16_TYPE int16_t
# else
# define INT16_TYPE short int
# endif
#endif
#ifndef UINT8_TYPE
# ifdef HAVE_UINT8_T
# define UINT8_TYPE uint8_t
# else
# define UINT8_TYPE unsigned char
# endif
#endif
#ifndef INT8_TYPE
# ifdef HAVE_INT8_T
# define INT8_TYPE int8_t
# else
# define INT8_TYPE signed char
# endif
#endif
#ifndef LONGDOUBLE_TYPE
# define LONGDOUBLE_TYPE long double
#endif
typedef sqlite_int64 i64; /* 8-byte signed integer */
typedef sqlite_uint64 u64; /* 8-byte unsigned integer */
typedef INT32_TYPE i32; /* 4-byte signed integer */
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
typedef INT16_TYPE i16; /* 2-byte signed integer */
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
typedef INT8_TYPE i8; /* 1-byte signed integer */
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
/*
** This library sometimes has to deal with string expansion, e.g.
** apply a function to an input string which gives a longer output
** string in terms of number of Unicode characters. This is only
** discovered on the fly.
** To avoid having to realloc the output string every times this
** occurs for _one_ extra output position, the library uses a
** "chunked" allocation strategy.
**
** A "chunk" is a predefined small number of output positions which
** determines the increment by which output string grow when needed
** during some operations.
** First, the output string is allocated one extra chunk. When this
** number of extra positions have been used the string is realloc'ed
** with one more chunk, until operation ends.
**
** The output of scalar functions are used and freed quickly, so it
** shouldn't be a problem if we allocate a block of memory slightly
** larger than absolutely necessary, even on embedded systems.
**
** You can increase the size from its default value of 16 to a larger
** value if you handle strings containing more than a few characters
** subject to expansion.
**
** DO NOT set UNIFUZZ_CHUNK below 8.
**
** Most applications should use the default value of 16.
**
*/
#ifndef UNIFUZZ_CHUNK
# define UNIFUZZ_CHUNK 16
#endif
/*
** This is the maximum square size of the virtual 2D array on which
** TYPOS is allowed to work. Anything anywhere near this size is
** unreasonable and should definitely be handled otherwise.
**
** This is computed as the product of the maximum character length of
** the two arguments. Reminder: each character is one UTF-32. TYPOS
** only allocates three rows, but the algorithm complexity is directly
** proportional to the product of the length of both arguments. Don't
** forget it will run for every _row_ in the rowset. Experiment first!
*/
#ifndef UNIFUZZ_TYPOS_LIMIT
# define UNIFUZZ_TYPOS_LIMIT (1024 * 1024)
#endif
/* Generated by builder. Do not modify. Start version_defines */
#define UNICODE_VERSION_MAJOR 5
#define UNICODE_VERSION_MINOR 1
#define UNICODE_VERSION_MICRO 0
#define UNICODE_VERSION_BUILD 10
#define __UNICODE_VERSION_STRING(a,b,c,d) #a "." #b "." #c "." #d
#define _UNICODE_VERSION_STRING(a,b,c,d) __UNICODE_VERSION_STRING(a,b,c,d)
#define UNICODE_VERSION_STRING _UNICODE_VERSION_STRING(UNICODE_VERSION_MAJOR,UNICODE_VERSION_MINOR,UNICODE_VERSION_MICRO,UNICODE_VERSION_BUILD)
#define __VERSION_STRINGS(a, b) #a b
#define _VERSION_STRINGS(a, b) __VERSION_STRINGS(a, b)
#define VERSION_STRINGS _VERSION_STRINGS(UNIFUZZ_VERSION, UNICODE_VERSION_STRING)
/* Generated by builder. Do not modify. Start fold_defines */
#define FOLD_BLOCK_SHIFT 5
#define FOLD_BLOCK_MASK ((1 << FOLD_BLOCK_SHIFT) - 1)
#define FOLD_BLOCK_SIZE (1 << FOLD_BLOCK_SHIFT)
#define FOLD_BLOCK_COUNT 69
#define FOLD_INDEXES_SIZE (0x10000 >> FOLD_BLOCK_SHIFT)
/* Generated by builder. Do not modify. End fold_defines */
/* Generated by builder. Do not modify. Start fold_tables */
static const u16 fold_indexes[FOLD_INDEXES_SIZE] = {
0, 0, 1, 0, 0, 2, 3, 0, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 15, 16, 17, 18,
19, 20, 21, 22, 0, 23, 24, 25, 26, 27, 28, 29, 30, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 32,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 50, 51, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 54, 55, 0, 56, 57, 58, 59, 60,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, 63, 0, 0,
0, 0, 64, 65, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 68, 0, 0, 0, 0, 0, 0
};
static const u16 fold_data0[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data1[] = { 0x0000, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data2[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03BC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data3[] = { 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0000, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0000 };
static const u16 fold_data4[] = { 0x0101, 0x0000, 0x0103, 0x0000, 0x0105, 0x0000, 0x0107, 0x0000, 0x0109, 0x0000, 0x010B, 0x0000, 0x010D, 0x0000, 0x010F, 0x0000, 0x0111, 0x0000, 0x0113, 0x0000, 0x0115, 0x0000, 0x0117, 0x0000, 0x0119, 0x0000, 0x011B, 0x0000, 0x011D, 0x0000, 0x011F, 0x0000 };
static const u16 fold_data5[] = { 0x0121, 0x0000, 0x0123, 0x0000, 0x0125, 0x0000, 0x0127, 0x0000, 0x0129, 0x0000, 0x012B, 0x0000, 0x012D, 0x0000, 0x012F, 0x0000, 0x0000, 0x0000, 0x0133, 0x0000, 0x0135, 0x0000, 0x0137, 0x0000, 0x0000, 0x013A, 0x0000, 0x013C, 0x0000, 0x013E, 0x0000, 0x0140 };
static const u16 fold_data6[] = { 0x0000, 0x0142, 0x0000, 0x0144, 0x0000, 0x0146, 0x0000, 0x0148, 0x0000, 0x0000, 0x014B, 0x0000, 0x014D, 0x0000, 0x014F, 0x0000, 0x0151, 0x0000, 0x0153, 0x0000, 0x0155, 0x0000, 0x0157, 0x0000, 0x0159, 0x0000, 0x015B, 0x0000, 0x015D, 0x0000, 0x015F, 0x0000 };
static const u16 fold_data7[] = { 0x0161, 0x0000, 0x0163, 0x0000, 0x0165, 0x0000, 0x0167, 0x0000, 0x0169, 0x0000, 0x016B, 0x0000, 0x016D, 0x0000, 0x016F, 0x0000, 0x0171, 0x0000, 0x0173, 0x0000, 0x0175, 0x0000, 0x0177, 0x0000, 0x00FF, 0x017A, 0x0000, 0x017C, 0x0000, 0x017E, 0x0000, 0x0073 };
static const u16 fold_data8[] = { 0x0000, 0x0253, 0x0183, 0x0000, 0x0185, 0x0000, 0x0254, 0x0188, 0x0000, 0x0256, 0x0257, 0x018C, 0x0000, 0x0000, 0x01DD, 0x0259, 0x025B, 0x0192, 0x0000, 0x0260, 0x0263, 0x0000, 0x0269, 0x0268, 0x0199, 0x0000, 0x0000, 0x0000, 0x026F, 0x0272, 0x0000, 0x0275 };
static const u16 fold_data9[] = { 0x01A1, 0x0000, 0x01A3, 0x0000, 0x01A5, 0x0000, 0x0280, 0x01A8, 0x0000, 0x0283, 0x0000, 0x0000, 0x01AD, 0x0000, 0x0288, 0x01B0, 0x0000, 0x028A, 0x028B, 0x01B4, 0x0000, 0x01B6, 0x0000, 0x0292, 0x01B9, 0x0000, 0x0000, 0x0000, 0x01BD, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data10[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x01C6, 0x01C6, 0x0000, 0x01C9, 0x01C9, 0x0000, 0x01CC, 0x01CC, 0x0000, 0x01CE, 0x0000, 0x01D0, 0x0000, 0x01D2, 0x0000, 0x01D4, 0x0000, 0x01D6, 0x0000, 0x01D8, 0x0000, 0x01DA, 0x0000, 0x01DC, 0x0000, 0x0000, 0x01DF, 0x0000 };
static const u16 fold_data11[] = { 0x01E1, 0x0000, 0x01E3, 0x0000, 0x01E5, 0x0000, 0x01E7, 0x0000, 0x01E9, 0x0000, 0x01EB, 0x0000, 0x01ED, 0x0000, 0x01EF, 0x0000, 0x0000, 0x01F3, 0x01F3, 0x0000, 0x01F5, 0x0000, 0x0195, 0x01BF, 0x01F9, 0x0000, 0x01FB, 0x0000, 0x01FD, 0x0000, 0x01FF, 0x0000 };
static const u16 fold_data12[] = { 0x0201, 0x0000, 0x0203, 0x0000, 0x0205, 0x0000, 0x0207, 0x0000, 0x0209, 0x0000, 0x020B, 0x0000, 0x020D, 0x0000, 0x020F, 0x0000, 0x0211, 0x0000, 0x0213, 0x0000, 0x0215, 0x0000, 0x0217, 0x0000, 0x0219, 0x0000, 0x021B, 0x0000, 0x021D, 0x0000, 0x021F, 0x0000 };
static const u16 fold_data13[] = { 0x019E, 0x0000, 0x0223, 0x0000, 0x0225, 0x0000, 0x0227, 0x0000, 0x0229, 0x0000, 0x022B, 0x0000, 0x022D, 0x0000, 0x022F, 0x0000, 0x0231, 0x0000, 0x0233, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2C65, 0x023C, 0x0000, 0x019A, 0x2C66, 0x0000 };
static const u16 fold_data14[] = { 0x0000, 0x0242, 0x0000, 0x0180, 0x0289, 0x028C, 0x0247, 0x0000, 0x0249, 0x0000, 0x024B, 0x0000, 0x024D, 0x0000, 0x024F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data15[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03B9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data16[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0371, 0x0000, 0x0373, 0x0000, 0x0000, 0x0000, 0x0377, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data17[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03AC, 0x0000, 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE, 0x0000, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF };
static const u16 fold_data18[] = { 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data19[] = { 0x0000, 0x0000, 0x03C3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03D7, 0x03B2, 0x03B8, 0x0000, 0x0000, 0x0000, 0x03C6, 0x03C0, 0x0000, 0x03D9, 0x0000, 0x03DB, 0x0000, 0x03DD, 0x0000, 0x03DF, 0x0000 };
static const u16 fold_data20[] = { 0x03E1, 0x0000, 0x03E3, 0x0000, 0x03E5, 0x0000, 0x03E7, 0x0000, 0x03E9, 0x0000, 0x03EB, 0x0000, 0x03ED, 0x0000, 0x03EF, 0x0000, 0x03BA, 0x03C1, 0x0000, 0x0000, 0x03B8, 0x03B5, 0x0000, 0x03F8, 0x0000, 0x03F2, 0x03FB, 0x0000, 0x0000, 0x037B, 0x037C, 0x037D };
static const u16 fold_data21[] = { 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045D, 0x045E, 0x045F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F };
static const u16 fold_data22[] = { 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data23[] = { 0x0461, 0x0000, 0x0463, 0x0000, 0x0465, 0x0000, 0x0467, 0x0000, 0x0469, 0x0000, 0x046B, 0x0000, 0x046D, 0x0000, 0x046F, 0x0000, 0x0471, 0x0000, 0x0473, 0x0000, 0x0475, 0x0000, 0x0477, 0x0000, 0x0479, 0x0000, 0x047B, 0x0000, 0x047D, 0x0000, 0x047F, 0x0000 };
static const u16 fold_data24[] = { 0x0481, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x048B, 0x0000, 0x048D, 0x0000, 0x048F, 0x0000, 0x0491, 0x0000, 0x0493, 0x0000, 0x0495, 0x0000, 0x0497, 0x0000, 0x0499, 0x0000, 0x049B, 0x0000, 0x049D, 0x0000, 0x049F, 0x0000 };
static const u16 fold_data25[] = { 0x04A1, 0x0000, 0x04A3, 0x0000, 0x04A5, 0x0000, 0x04A7, 0x0000, 0x04A9, 0x0000, 0x04AB, 0x0000, 0x04AD, 0x0000, 0x04AF, 0x0000, 0x04B1, 0x0000, 0x04B3, 0x0000, 0x04B5, 0x0000, 0x04B7, 0x0000, 0x04B9, 0x0000, 0x04BB, 0x0000, 0x04BD, 0x0000, 0x04BF, 0x0000 };
static const u16 fold_data26[] = { 0x04CF, 0x04C2, 0x0000, 0x04C4, 0x0000, 0x04C6, 0x0000, 0x04C8, 0x0000, 0x04CA, 0x0000, 0x04CC, 0x0000, 0x04CE, 0x0000, 0x0000, 0x04D1, 0x0000, 0x04D3, 0x0000, 0x04D5, 0x0000, 0x04D7, 0x0000, 0x04D9, 0x0000, 0x04DB, 0x0000, 0x04DD, 0x0000, 0x04DF, 0x0000 };
static const u16 fold_data27[] = { 0x04E1, 0x0000, 0x04E3, 0x0000, 0x04E5, 0x0000, 0x04E7, 0x0000, 0x04E9, 0x0000, 0x04EB, 0x0000, 0x04ED, 0x0000, 0x04EF, 0x0000, 0x04F1, 0x0000, 0x04F3, 0x0000, 0x04F5, 0x0000, 0x04F7, 0x0000, 0x04F9, 0x0000, 0x04FB, 0x0000, 0x04FD, 0x0000, 0x04FF, 0x0000 };
static const u16 fold_data28[] = { 0x0501, 0x0000, 0x0503, 0x0000, 0x0505, 0x0000, 0x0507, 0x0000, 0x0509, 0x0000, 0x050B, 0x0000, 0x050D, 0x0000, 0x050F, 0x0000, 0x0511, 0x0000, 0x0513, 0x0000, 0x0515, 0x0000, 0x0517, 0x0000, 0x0519, 0x0000, 0x051B, 0x0000, 0x051D, 0x0000, 0x051F, 0x0000 };
static const u16 fold_data29[] = { 0x0521, 0x0000, 0x0523, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568, 0x0569, 0x056A, 0x056B, 0x056C, 0x056D, 0x056E, 0x056F };
static const u16 fold_data30[] = { 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057A, 0x057B, 0x057C, 0x057D, 0x057E, 0x057F, 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data31[] = { 0x2D00, 0x2D01, 0x2D02, 0x2D03, 0x2D04, 0x2D05, 0x2D06, 0x2D07, 0x2D08, 0x2D09, 0x2D0A, 0x2D0B, 0x2D0C, 0x2D0D, 0x2D0E, 0x2D0F, 0x2D10, 0x2D11, 0x2D12, 0x2D13, 0x2D14, 0x2D15, 0x2D16, 0x2D17, 0x2D18, 0x2D19, 0x2D1A, 0x2D1B, 0x2D1C, 0x2D1D, 0x2D1E, 0x2D1F };
static const u16 fold_data32[] = { 0x2D20, 0x2D21, 0x2D22, 0x2D23, 0x2D24, 0x2D25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data33[] = { 0x1E01, 0x0000, 0x1E03, 0x0000, 0x1E05, 0x0000, 0x1E07, 0x0000, 0x1E09, 0x0000, 0x1E0B, 0x0000, 0x1E0D, 0x0000, 0x1E0F, 0x0000, 0x1E11, 0x0000, 0x1E13, 0x0000, 0x1E15, 0x0000, 0x1E17, 0x0000, 0x1E19, 0x0000, 0x1E1B, 0x0000, 0x1E1D, 0x0000, 0x1E1F, 0x0000 };
static const u16 fold_data34[] = { 0x1E21, 0x0000, 0x1E23, 0x0000, 0x1E25, 0x0000, 0x1E27, 0x0000, 0x1E29, 0x0000, 0x1E2B, 0x0000, 0x1E2D, 0x0000, 0x1E2F, 0x0000, 0x1E31, 0x0000, 0x1E33, 0x0000, 0x1E35, 0x0000, 0x1E37, 0x0000, 0x1E39, 0x0000, 0x1E3B, 0x0000, 0x1E3D, 0x0000, 0x1E3F, 0x0000 };
static const u16 fold_data35[] = { 0x1E41, 0x0000, 0x1E43, 0x0000, 0x1E45, 0x0000, 0x1E47, 0x0000, 0x1E49, 0x0000, 0x1E4B, 0x0000, 0x1E4D, 0x0000, 0x1E4F, 0x0000, 0x1E51, 0x0000, 0x1E53, 0x0000, 0x1E55, 0x0000, 0x1E57, 0x0000, 0x1E59, 0x0000, 0x1E5B, 0x0000, 0x1E5D, 0x0000, 0x1E5F, 0x0000 };
static const u16 fold_data36[] = { 0x1E61, 0x0000, 0x1E63, 0x0000, 0x1E65, 0x0000, 0x1E67, 0x0000, 0x1E69, 0x0000, 0x1E6B, 0x0000, 0x1E6D, 0x0000, 0x1E6F, 0x0000, 0x1E71, 0x0000, 0x1E73, 0x0000, 0x1E75, 0x0000, 0x1E77, 0x0000, 0x1E79, 0x0000, 0x1E7B, 0x0000, 0x1E7D, 0x0000, 0x1E7F, 0x0000 };
static const u16 fold_data37[] = { 0x1E81, 0x0000, 0x1E83, 0x0000, 0x1E85, 0x0000, 0x1E87, 0x0000, 0x1E89, 0x0000, 0x1E8B, 0x0000, 0x1E8D, 0x0000, 0x1E8F, 0x0000, 0x1E91, 0x0000, 0x1E93, 0x0000, 0x1E95, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E61, 0x0000, 0x0000, 0x00DF, 0x0000 };
static const u16 fold_data38[] = { 0x1EA1, 0x0000, 0x1EA3, 0x0000, 0x1EA5, 0x0000, 0x1EA7, 0x0000, 0x1EA9, 0x0000, 0x1EAB, 0x0000, 0x1EAD, 0x0000, 0x1EAF, 0x0000, 0x1EB1, 0x0000, 0x1EB3, 0x0000, 0x1EB5, 0x0000, 0x1EB7, 0x0000, 0x1EB9, 0x0000, 0x1EBB, 0x0000, 0x1EBD, 0x0000, 0x1EBF, 0x0000 };
static const u16 fold_data39[] = { 0x1EC1, 0x0000, 0x1EC3, 0x0000, 0x1EC5, 0x0000, 0x1EC7, 0x0000, 0x1EC9, 0x0000, 0x1ECB, 0x0000, 0x1ECD, 0x0000, 0x1ECF, 0x0000, 0x1ED1, 0x0000, 0x1ED3, 0x0000, 0x1ED5, 0x0000, 0x1ED7, 0x0000, 0x1ED9, 0x0000, 0x1EDB, 0x0000, 0x1EDD, 0x0000, 0x1EDF, 0x0000 };
static const u16 fold_data40[] = { 0x1EE1, 0x0000, 0x1EE3, 0x0000, 0x1EE5, 0x0000, 0x1EE7, 0x0000, 0x1EE9, 0x0000, 0x1EEB, 0x0000, 0x1EED, 0x0000, 0x1EEF, 0x0000, 0x1EF1, 0x0000, 0x1EF3, 0x0000, 0x1EF5, 0x0000, 0x1EF7, 0x0000, 0x1EF9, 0x0000, 0x1EFB, 0x0000, 0x1EFD, 0x0000, 0x1EFF, 0x0000 };
static const u16 fold_data41[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000 };
static const u16 fold_data42[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37 };
static const u16 fold_data43[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57 };
static const u16 fold_data44[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data45[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97 };
static const u16 fold_data46[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x0000, 0x03B9, 0x0000 };
static const u16 fold_data47[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data48[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data49[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03C9, 0x0000, 0x0000, 0x0000, 0x006B, 0x00E5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x214E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data50[] = { 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data51[] = { 0x0000, 0x0000, 0x0000, 0x2184, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data52[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x24D0, 0x24D1, 0x24D2, 0x24D3, 0x24D4, 0x24D5, 0x24D6, 0x24D7, 0x24D8, 0x24D9 };
static const u16 fold_data53[] = { 0x24DA, 0x24DB, 0x24DC, 0x24DD, 0x24DE, 0x24DF, 0x24E0, 0x24E1, 0x24E2, 0x24E3, 0x24E4, 0x24E5, 0x24E6, 0x24E7, 0x24E8, 0x24E9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data54[] = { 0x2C30, 0x2C31, 0x2C32, 0x2C33, 0x2C34, 0x2C35, 0x2C36, 0x2C37, 0x2C38, 0x2C39, 0x2C3A, 0x2C3B, 0x2C3C, 0x2C3D, 0x2C3E, 0x2C3F, 0x2C40, 0x2C41, 0x2C42, 0x2C43, 0x2C44, 0x2C45, 0x2C46, 0x2C47, 0x2C48, 0x2C49, 0x2C4A, 0x2C4B, 0x2C4C, 0x2C4D, 0x2C4E, 0x2C4F };
static const u16 fold_data55[] = { 0x2C50, 0x2C51, 0x2C52, 0x2C53, 0x2C54, 0x2C55, 0x2C56, 0x2C57, 0x2C58, 0x2C59, 0x2C5A, 0x2C5B, 0x2C5C, 0x2C5D, 0x2C5E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data56[] = { 0x2C61, 0x0000, 0x026B, 0x1D7D, 0x027D, 0x0000, 0x0000, 0x2C68, 0x0000, 0x2C6A, 0x0000, 0x2C6C, 0x0000, 0x0251, 0x0271, 0x0250, 0x0000, 0x0000, 0x2C73, 0x0000, 0x0000, 0x2C76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data57[] = { 0x2C81, 0x0000, 0x2C83, 0x0000, 0x2C85, 0x0000, 0x2C87, 0x0000, 0x2C89, 0x0000, 0x2C8B, 0x0000, 0x2C8D, 0x0000, 0x2C8F, 0x0000, 0x2C91, 0x0000, 0x2C93, 0x0000, 0x2C95, 0x0000, 0x2C97, 0x0000, 0x2C99, 0x0000, 0x2C9B, 0x0000, 0x2C9D, 0x0000, 0x2C9F, 0x0000 };
static const u16 fold_data58[] = { 0x2CA1, 0x0000, 0x2CA3, 0x0000, 0x2CA5, 0x0000, 0x2CA7, 0x0000, 0x2CA9, 0x0000, 0x2CAB, 0x0000, 0x2CAD, 0x0000, 0x2CAF, 0x0000, 0x2CB1, 0x0000, 0x2CB3, 0x0000, 0x2CB5, 0x0000, 0x2CB7, 0x0000, 0x2CB9, 0x0000, 0x2CBB, 0x0000, 0x2CBD, 0x0000, 0x2CBF, 0x0000 };
static const u16 fold_data59[] = { 0x2CC1, 0x0000, 0x2CC3, 0x0000, 0x2CC5, 0x0000, 0x2CC7, 0x0000, 0x2CC9, 0x0000, 0x2CCB, 0x0000, 0x2CCD, 0x0000, 0x2CCF, 0x0000, 0x2CD1, 0x0000, 0x2CD3, 0x0000, 0x2CD5, 0x0000, 0x2CD7, 0x0000, 0x2CD9, 0x0000, 0x2CDB, 0x0000, 0x2CDD, 0x0000, 0x2CDF, 0x0000 };
static const u16 fold_data60[] = { 0x2CE1, 0x0000, 0x2CE3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data61[] = { 0xA641, 0x0000, 0xA643, 0x0000, 0xA645, 0x0000, 0xA647, 0x0000, 0xA649, 0x0000, 0xA64B, 0x0000, 0xA64D, 0x0000, 0xA64F, 0x0000, 0xA651, 0x0000, 0xA653, 0x0000, 0xA655, 0x0000, 0xA657, 0x0000, 0xA659, 0x0000, 0xA65B, 0x0000, 0xA65D, 0x0000, 0xA65F, 0x0000 };
static const u16 fold_data62[] = { 0x0000, 0x0000, 0xA663, 0x0000, 0xA665, 0x0000, 0xA667, 0x0000, 0xA669, 0x0000, 0xA66B, 0x0000, 0xA66D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data63[] = { 0xA681, 0x0000, 0xA683, 0x0000, 0xA685, 0x0000, 0xA687, 0x0000, 0xA689, 0x0000, 0xA68B, 0x0000, 0xA68D, 0x0000, 0xA68F, 0x0000, 0xA691, 0x0000, 0xA693, 0x0000, 0xA695, 0x0000, 0xA697, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data64[] = { 0x0000, 0x0000, 0xA723, 0x0000, 0xA725, 0x0000, 0xA727, 0x0000, 0xA729, 0x0000, 0xA72B, 0x0000, 0xA72D, 0x0000, 0xA72F, 0x0000, 0x0000, 0x0000, 0xA733, 0x0000, 0xA735, 0x0000, 0xA737, 0x0000, 0xA739, 0x0000, 0xA73B, 0x0000, 0xA73D, 0x0000, 0xA73F, 0x0000 };
static const u16 fold_data65[] = { 0xA741, 0x0000, 0xA743, 0x0000, 0xA745, 0x0000, 0xA747, 0x0000, 0xA749, 0x0000, 0xA74B, 0x0000, 0xA74D, 0x0000, 0xA74F, 0x0000, 0xA751, 0x0000, 0xA753, 0x0000, 0xA755, 0x0000, 0xA757, 0x0000, 0xA759, 0x0000, 0xA75B, 0x0000, 0xA75D, 0x0000, 0xA75F, 0x0000 };
static const u16 fold_data66[] = { 0xA761, 0x0000, 0xA763, 0x0000, 0xA765, 0x0000, 0xA767, 0x0000, 0xA769, 0x0000, 0xA76B, 0x0000, 0xA76D, 0x0000, 0xA76F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xA77A, 0x0000, 0xA77C, 0x0000, 0x1D79, 0xA77F, 0x0000 };
static const u16 fold_data67[] = { 0xA781, 0x0000, 0xA783, 0x0000, 0xA785, 0x0000, 0xA787, 0x0000, 0x0000, 0x0000, 0x0000, 0xA78C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 fold_data68[] = { 0x0000, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
static const u16 *fold_data_table[FOLD_BLOCK_COUNT] = {
fold_data0,fold_data1,fold_data2,fold_data3,fold_data4,fold_data5,fold_data6,fold_data7,fold_data8,fold_data9,
fold_data10,fold_data11,fold_data12,fold_data13,fold_data14,fold_data15,fold_data16,fold_data17,fold_data18,fold_data19,
fold_data20,fold_data21,fold_data22,fold_data23,fold_data24,fold_data25,fold_data26,fold_data27,fold_data28,fold_data29,
fold_data30,fold_data31,fold_data32,fold_data33,fold_data34,fold_data35,fold_data36,fold_data37,fold_data38,fold_data39,
fold_data40,fold_data41,fold_data42,fold_data43,fold_data44,fold_data45,fold_data46,fold_data47,fold_data48,fold_data49,
fold_data50,fold_data51,fold_data52,fold_data53,fold_data54,fold_data55,fold_data56,fold_data57,fold_data58,fold_data59,
fold_data60,fold_data61,fold_data62,fold_data63,fold_data64,fold_data65,fold_data66,fold_data67,fold_data68
};
/* Generated by builder. Do not modify. End fold_tables */
SQLITE_PRIVATE u32 unifuzz_fold(
u32 c