@delali/narsil-react-native 0.3.1-next.155 → 0.3.1-next.156
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.
- package/NOTICE +144 -0
- package/NarsilReactNative.podspec +2 -2
- package/android/CMakeLists.txt +1 -1
- package/cpp/HybridNarsilCoreAnalysis.cpp +277 -0
- package/cpp/HybridNarsilCoreImpl.hpp +43 -0
- package/cpp/HybridNarsilCoreKeyword.cpp +253 -0
- package/cpp/HybridNarsilCoreMath.cpp +47 -0
- package/cpp/core/include/narsil_analysis.h +86 -0
- package/cpp/core/include/narsil_core.h +1 -1
- package/cpp/core/include/narsil_keyword.h +110 -0
- package/cpp/core/include/narsil_math.h +36 -0
- package/cpp/core/src/analysis/analyse.c +281 -0
- package/cpp/core/src/analysis/analyser.h +49 -0
- package/cpp/core/src/analysis/languages.c +79 -0
- package/cpp/core/src/analysis/languages.h +42 -0
- package/cpp/core/src/analysis/normalise.c +242 -0
- package/cpp/core/src/analysis/normalise.h +28 -0
- package/cpp/core/src/analysis/split.c +183 -0
- package/cpp/core/src/analysis/split.h +27 -0
- package/cpp/core/src/analysis/stop_words.c +82 -0
- package/cpp/core/src/analysis/stop_words.h +19 -0
- package/cpp/core/src/analysis/term_cache.c +88 -0
- package/cpp/core/src/analysis/term_cache.h +36 -0
- package/cpp/core/src/analysis/text.c +161 -0
- package/cpp/core/src/analysis/text.h +45 -0
- package/cpp/core/src/analysis/transform.c +103 -0
- package/cpp/core/src/analysis/unicode.c +252 -0
- package/cpp/core/src/analysis/unicode.h +54 -0
- package/cpp/core/src/internal.h +4 -0
- package/cpp/core/src/keyword/pass.h +117 -0
- package/cpp/core/src/keyword/prune.c +324 -0
- package/cpp/core/src/keyword/request.c +179 -0
- package/cpp/core/src/keyword/rows.c +83 -0
- package/cpp/core/src/keyword/rows.h +18 -0
- package/cpp/core/src/keyword/score.c +257 -0
- package/cpp/core/src/keyword/score.h +17 -0
- package/cpp/core/src/keyword/scratch.c +226 -0
- package/cpp/core/src/keyword/scratch.h +55 -0
- package/cpp/core/src/keyword/select.c +155 -0
- package/cpp/core/src/keyword/select.h +17 -0
- package/cpp/core/src/languages/bulgarian_stemmer.c +114 -0
- package/cpp/core/src/languages/data/albanian.c +54 -0
- package/cpp/core/src/languages/data/amharic.c +93 -0
- package/cpp/core/src/languages/data/arabic.c +146 -0
- package/cpp/core/src/languages/data/armenian.c +46 -0
- package/cpp/core/src/languages/data/azerbaijani.c +68 -0
- package/cpp/core/src/languages/data/bambara.c +48 -0
- package/cpp/core/src/languages/data/basque.c +62 -0
- package/cpp/core/src/languages/data/belarusian.c +56 -0
- package/cpp/core/src/languages/data/bengali.c +63 -0
- package/cpp/core/src/languages/data/bosnian.c +73 -0
- package/cpp/core/src/languages/data/breton.c +52 -0
- package/cpp/core/src/languages/data/bulgarian.c +144 -0
- package/cpp/core/src/languages/data/burmese.c +48 -0
- package/cpp/core/src/languages/data/catalan.c +84 -0
- package/cpp/core/src/languages/data/chinese.c +70 -0
- package/cpp/core/src/languages/data/croatian.c +72 -0
- package/cpp/core/src/languages/data/czech.c +72 -0
- package/cpp/core/src/languages/data/dagbani.c +88 -0
- package/cpp/core/src/languages/data/danish.c +56 -0
- package/cpp/core/src/languages/data/declarations.h +114 -0
- package/cpp/core/src/languages/data/dutch.c +58 -0
- package/cpp/core/src/languages/data/english.c +172 -0
- package/cpp/core/src/languages/data/esperanto.c +71 -0
- package/cpp/core/src/languages/data/estonian.c +417 -0
- package/cpp/core/src/languages/data/ewe.c +89 -0
- package/cpp/core/src/languages/data/faroese.c +54 -0
- package/cpp/core/src/languages/data/fijian.c +44 -0
- package/cpp/core/src/languages/data/finnish.c +100 -0
- package/cpp/core/src/languages/data/french.c +74 -0
- package/cpp/core/src/languages/data/ga.c +83 -0
- package/cpp/core/src/languages/data/galician.c +70 -0
- package/cpp/core/src/languages/data/georgian.c +57 -0
- package/cpp/core/src/languages/data/german.c +96 -0
- package/cpp/core/src/languages/data/greek.c +202 -0
- package/cpp/core/src/languages/data/guarani.c +110 -0
- package/cpp/core/src/languages/data/gujarati.c +90 -0
- package/cpp/core/src/languages/data/haitian-creole.c +54 -0
- package/cpp/core/src/languages/data/hausa.c +85 -0
- package/cpp/core/src/languages/data/hawaiian.c +50 -0
- package/cpp/core/src/languages/data/hebrew.c +85 -0
- package/cpp/core/src/languages/data/hindi.c +91 -0
- package/cpp/core/src/languages/data/hungarian.c +98 -0
- package/cpp/core/src/languages/data/icelandic.c +73 -0
- package/cpp/core/src/languages/data/igbo.c +90 -0
- package/cpp/core/src/languages/data/indonesian.c +296 -0
- package/cpp/core/src/languages/data/irish.c +60 -0
- package/cpp/core/src/languages/data/italian.c +107 -0
- package/cpp/core/src/languages/data/japanese.c +52 -0
- package/cpp/core/src/languages/data/kannada.c +60 -0
- package/cpp/core/src/languages/data/kazakh.c +57 -0
- package/cpp/core/src/languages/data/khmer.c +71 -0
- package/cpp/core/src/languages/data/kinyarwanda.c +54 -0
- package/cpp/core/src/languages/data/kirundi.c +53 -0
- package/cpp/core/src/languages/data/korean.c +74 -0
- package/cpp/core/src/languages/data/kurmanji.c +43 -0
- package/cpp/core/src/languages/data/kyrgyz.c +65 -0
- package/cpp/core/src/languages/data/lao.c +46 -0
- package/cpp/core/src/languages/data/latin.c +46 -0
- package/cpp/core/src/languages/data/latvian.c +75 -0
- package/cpp/core/src/languages/data/lingala.c +88 -0
- package/cpp/core/src/languages/data/lithuanian.c +65 -0
- package/cpp/core/src/languages/data/luxembourgish.c +80 -0
- package/cpp/core/src/languages/data/macedonian.c +286 -0
- package/cpp/core/src/languages/data/malagasy.c +51 -0
- package/cpp/core/src/languages/data/malay.c +184 -0
- package/cpp/core/src/languages/data/malayalam.c +64 -0
- package/cpp/core/src/languages/data/maltese.c +102 -0
- package/cpp/core/src/languages/data/maori.c +52 -0
- package/cpp/core/src/languages/data/marathi.c +62 -0
- package/cpp/core/src/languages/data/nepali.c +72 -0
- package/cpp/core/src/languages/data/norwegian.c +74 -0
- package/cpp/core/src/languages/data/oromo.c +51 -0
- package/cpp/core/src/languages/data/persian.c +150 -0
- package/cpp/core/src/languages/data/polish.c +111 -0
- package/cpp/core/src/languages/data/portuguese.c +91 -0
- package/cpp/core/src/languages/data/punjabi.c +80 -0
- package/cpp/core/src/languages/data/registry.c +116 -0
- package/cpp/core/src/languages/data/romanian.c +93 -0
- package/cpp/core/src/languages/data/russian.c +76 -0
- package/cpp/core/src/languages/data/samoan.c +47 -0
- package/cpp/core/src/languages/data/sanskrit.c +53 -0
- package/cpp/core/src/languages/data/scottish-gaelic.c +119 -0
- package/cpp/core/src/languages/data/serbian.c +84 -0
- package/cpp/core/src/languages/data/shona.c +55 -0
- package/cpp/core/src/languages/data/sinhala.c +78 -0
- package/cpp/core/src/languages/data/slovak.c +135 -0
- package/cpp/core/src/languages/data/slovenian.c +139 -0
- package/cpp/core/src/languages/data/sorani.c +55 -0
- package/cpp/core/src/languages/data/spanish.c +84 -0
- package/cpp/core/src/languages/data/swahili.c +59 -0
- package/cpp/core/src/languages/data/swedish.c +60 -0
- package/cpp/core/src/languages/data/tagalog.c +75 -0
- package/cpp/core/src/languages/data/tamil.c +69 -0
- package/cpp/core/src/languages/data/tatar.c +548 -0
- package/cpp/core/src/languages/data/telugu.c +54 -0
- package/cpp/core/src/languages/data/thai.c +46 -0
- package/cpp/core/src/languages/data/tibetan.c +55 -0
- package/cpp/core/src/languages/data/tigrinya.c +73 -0
- package/cpp/core/src/languages/data/tongan.c +47 -0
- package/cpp/core/src/languages/data/turkish.c +100 -0
- package/cpp/core/src/languages/data/twi.c +88 -0
- package/cpp/core/src/languages/data/ukrainian.c +99 -0
- package/cpp/core/src/languages/data/urdu.c +174 -0
- package/cpp/core/src/languages/data/vietnamese.c +88 -0
- package/cpp/core/src/languages/data/welsh.c +143 -0
- package/cpp/core/src/languages/data/wolof.c +51 -0
- package/cpp/core/src/languages/data/xhosa.c +56 -0
- package/cpp/core/src/languages/data/yoruba.c +93 -0
- package/cpp/core/src/languages/data/zulu.c +58 -0
- package/cpp/core/src/languages/marks.c +64 -0
- package/cpp/core/src/languages/rules.c +63 -0
- package/cpp/core/src/languages/rules.h +68 -0
- package/cpp/core/src/languages/sanskrit_stemmer.c +50 -0
- package/cpp/core/src/languages/scripts.c +143 -0
- package/cpp/core/src/languages/slovenian_stemmer.c +46 -0
- package/cpp/core/src/languages/snowball/api.c +52 -0
- package/cpp/core/src/languages/snowball/api.h +43 -0
- package/cpp/core/src/languages/snowball/arabic_stemmer.c +1506 -0
- package/cpp/core/src/languages/snowball/arabic_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/armenian_stemmer.c +523 -0
- package/cpp/core/src/languages/snowball/armenian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/basque_stemmer.c +1089 -0
- package/cpp/core/src/languages/snowball/basque_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/catalan_stemmer.c +1380 -0
- package/cpp/core/src/languages/snowball/catalan_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/czech_stemmer.c +582 -0
- package/cpp/core/src/languages/snowball/czech_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/danish_stemmer.c +352 -0
- package/cpp/core/src/languages/snowball/danish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/dutch_stemmer.c +1657 -0
- package/cpp/core/src/languages/snowball/dutch_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/english_stemmer.c +1019 -0
- package/cpp/core/src/languages/snowball/english_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/esperanto_stemmer.c +716 -0
- package/cpp/core/src/languages/snowball/esperanto_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/estonian_stemmer.c +1361 -0
- package/cpp/core/src/languages/snowball/estonian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/finnish_stemmer.c +800 -0
- package/cpp/core/src/languages/snowball/finnish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/french_stemmer.c +1217 -0
- package/cpp/core/src/languages/snowball/french_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/german_stemmer.c +567 -0
- package/cpp/core/src/languages/snowball/german_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/greek_stemmer.c +3450 -0
- package/cpp/core/src/languages/snowball/greek_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/hindi_stemmer.c +325 -0
- package/cpp/core/src/languages/snowball/hindi_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/hungarian_stemmer.c +742 -0
- package/cpp/core/src/languages/snowball/hungarian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/indonesian_stemmer.c +443 -0
- package/cpp/core/src/languages/snowball/indonesian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/irish_stemmer.c +428 -0
- package/cpp/core/src/languages/snowball/irish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/italian_stemmer.c +983 -0
- package/cpp/core/src/languages/snowball/italian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/lithuanian_stemmer.c +794 -0
- package/cpp/core/src/languages/snowball/lithuanian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/nepali_stemmer.c +361 -0
- package/cpp/core/src/languages/snowball/nepali_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/norwegian_stemmer.c +332 -0
- package/cpp/core/src/languages/snowball/norwegian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/persian_stemmer.c +538 -0
- package/cpp/core/src/languages/snowball/persian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/polish_stemmer.c +501 -0
- package/cpp/core/src/languages/snowball/polish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/portuguese_stemmer.c +866 -0
- package/cpp/core/src/languages/snowball/portuguese_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/romanian_stemmer.c +940 -0
- package/cpp/core/src/languages/snowball/romanian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/russian_stemmer.c +598 -0
- package/cpp/core/src/languages/snowball/russian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/serbian_stemmer.c +6765 -0
- package/cpp/core/src/languages/snowball/serbian_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/snowball_runtime.h +122 -0
- package/cpp/core/src/languages/snowball/spanish_stemmer.c +955 -0
- package/cpp/core/src/languages/snowball/spanish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/swedish_stemmer.c +364 -0
- package/cpp/core/src/languages/snowball/swedish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/tamil_stemmer.c +1305 -0
- package/cpp/core/src/languages/snowball/tamil_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/turkish_stemmer.c +1700 -0
- package/cpp/core/src/languages/snowball/turkish_stemmer.h +24 -0
- package/cpp/core/src/languages/snowball/utilities.c +716 -0
- package/cpp/core/src/languages/substitutions.c +131 -0
- package/cpp/core/src/languages/swahili_stemmer.c +85 -0
- package/cpp/core/src/languages/ukrainian_stemmer.c +168 -0
- package/cpp/core/src/locks.c +2 -15
- package/cpp/core/src/math/apply.c +44 -0
- package/cpp/core/src/math/fdlibm.h +16 -0
- package/cpp/core/src/math/inverse.c +242 -0
- package/cpp/core/src/math/log.c +90 -0
- package/cpp/core/src/math/reduce.c +325 -0
- package/cpp/core/src/math/trig.c +188 -0
- package/cpp/core/src/math/words.h +45 -0
- package/cpp/core/src/thread_yield.h +18 -0
- package/cpp/core/src/unicode/decompositions.c +310 -0
- package/cpp/core/src/unicode/lowercase.c +172 -0
- package/cpp/core/src/unicode/properties.c +214 -0
- package/cpp/core/src/workspace.c +5 -1
- package/lib/engine/analysis.d.ts +3 -0
- package/lib/engine/analysis.js +76 -0
- package/lib/engine/core.js +5 -0
- package/lib/engine/keyword.d.ts +3 -0
- package/lib/engine/keyword.js +25 -0
- package/lib/specs/core.nitro.d.ts +1 -0
- package/nitrogen/generated/shared/c++/HybridNarsilCoreSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridNarsilCoreSpec.hpp +1 -0
- package/package.json +4 -3
- package/src/engine/analysis.ts +87 -0
- package/src/engine/core.ts +6 -0
- package/src/engine/keyword.ts +26 -0
- package/src/specs/core.nitro.ts +1 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#ifndef NARSIL_ANALYSIS_TERM_CACHE_H
|
|
2
|
+
#define NARSIL_ANALYSIS_TERM_CACHE_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
#define NARSIL_TERM_CACHE_UNITS 24U
|
|
8
|
+
|
|
9
|
+
typedef struct {
|
|
10
|
+
uint32_t tag;
|
|
11
|
+
uint16_t key_length;
|
|
12
|
+
uint16_t value_length;
|
|
13
|
+
uint16_t key[NARSIL_TERM_CACHE_UNITS];
|
|
14
|
+
uint16_t value[NARSIL_TERM_CACHE_UNITS];
|
|
15
|
+
} narsil_term_slot;
|
|
16
|
+
|
|
17
|
+
typedef struct {
|
|
18
|
+
narsil_term_slot *slots;
|
|
19
|
+
uint8_t *next_victim;
|
|
20
|
+
int unavailable;
|
|
21
|
+
} narsil_term_cache;
|
|
22
|
+
|
|
23
|
+
typedef struct {
|
|
24
|
+
uint32_t language_index;
|
|
25
|
+
uint32_t flags;
|
|
26
|
+
const uint16_t *units;
|
|
27
|
+
size_t length;
|
|
28
|
+
} narsil_term_key;
|
|
29
|
+
|
|
30
|
+
narsil_term_slot *narsil_term_cache_find(narsil_term_cache *cache, const narsil_term_key *key,
|
|
31
|
+
narsil_term_slot **victim);
|
|
32
|
+
int narsil_term_cache_store(narsil_term_slot *slot, const narsil_term_key *key, const uint16_t *value, size_t length);
|
|
33
|
+
uint32_t narsil_term_cache_index(const narsil_term_cache *cache, const narsil_term_slot *slot);
|
|
34
|
+
void narsil_term_cache_release(narsil_term_cache *cache);
|
|
35
|
+
|
|
36
|
+
#endif
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#include "text.h"
|
|
2
|
+
|
|
3
|
+
#include "../../include/narsil_core.h"
|
|
4
|
+
|
|
5
|
+
#include <stddef.h>
|
|
6
|
+
#include <stdint.h>
|
|
7
|
+
#include <stdlib.h>
|
|
8
|
+
#include <string.h>
|
|
9
|
+
|
|
10
|
+
#define MIN_CAPACITY 16U
|
|
11
|
+
|
|
12
|
+
typedef struct {
|
|
13
|
+
size_t current;
|
|
14
|
+
size_t needed;
|
|
15
|
+
size_t element_size;
|
|
16
|
+
} growth;
|
|
17
|
+
|
|
18
|
+
static size_t grown_capacity(growth request) {
|
|
19
|
+
size_t limit = SIZE_MAX / request.element_size;
|
|
20
|
+
size_t capacity = request.current < MIN_CAPACITY ? MIN_CAPACITY : request.current;
|
|
21
|
+
while (capacity < request.needed) {
|
|
22
|
+
if (capacity > limit / 2) { return request.needed <= limit ? request.needed : 0; }
|
|
23
|
+
capacity *= 2;
|
|
24
|
+
}
|
|
25
|
+
return capacity;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
int narsil_text_reserve(narsil_text *text, size_t capacity) {
|
|
29
|
+
if (capacity <= text->capacity) { return NARSIL_OK; }
|
|
30
|
+
growth request = {text->capacity, capacity, sizeof(uint16_t)};
|
|
31
|
+
size_t grown = grown_capacity(request);
|
|
32
|
+
if (grown == 0) { return NARSIL_OUT_OF_MEMORY; }
|
|
33
|
+
uint16_t *units = realloc(text->units, grown * sizeof(uint16_t));
|
|
34
|
+
if (units == NULL) { return NARSIL_OUT_OF_MEMORY; }
|
|
35
|
+
text->units = units;
|
|
36
|
+
text->capacity = grown;
|
|
37
|
+
return NARSIL_OK;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
int narsil_text_assign(narsil_text *text, const uint16_t *units, size_t length) {
|
|
41
|
+
text->length = 0;
|
|
42
|
+
return narsil_text_append(text, units, length);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
int narsil_text_append(narsil_text *text, const uint16_t *units, size_t length) {
|
|
46
|
+
if (length == 0) { return NARSIL_OK; }
|
|
47
|
+
if (length > SIZE_MAX - text->length) { return NARSIL_OUT_OF_MEMORY; }
|
|
48
|
+
int status = narsil_text_reserve(text, text->length + length);
|
|
49
|
+
if (status != NARSIL_OK) { return status; }
|
|
50
|
+
memmove(text->units + text->length, units, length * sizeof(uint16_t));
|
|
51
|
+
text->length += length;
|
|
52
|
+
return NARSIL_OK;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
int narsil_text_push(narsil_text *text, uint16_t unit) {
|
|
56
|
+
if (text->length == text->capacity) {
|
|
57
|
+
int status = narsil_text_reserve(text, text->length + 1);
|
|
58
|
+
if (status != NARSIL_OK) { return status; }
|
|
59
|
+
}
|
|
60
|
+
text->units[text->length++] = unit;
|
|
61
|
+
return NARSIL_OK;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
int narsil_text_push_code_point(narsil_text *text, uint32_t code_point) {
|
|
65
|
+
if (code_point < NARSIL_SUPPLEMENTARY_FIRST) { return narsil_text_push(text, (uint16_t)code_point); }
|
|
66
|
+
uint32_t offset = code_point - NARSIL_SUPPLEMENTARY_FIRST;
|
|
67
|
+
int status =
|
|
68
|
+
narsil_text_push(text, (uint16_t)(NARSIL_HIGH_SURROGATE_FIRST + (offset >> NARSIL_SURROGATE_PAYLOAD_BITS)));
|
|
69
|
+
if (status != NARSIL_OK) { return status; }
|
|
70
|
+
return narsil_text_push(text, (uint16_t)(NARSIL_LOW_SURROGATE_FIRST + (offset & NARSIL_SURROGATE_PAYLOAD_MASK)));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
void narsil_text_release(narsil_text *text) {
|
|
74
|
+
free(text->units);
|
|
75
|
+
text->units = NULL;
|
|
76
|
+
text->length = 0;
|
|
77
|
+
text->capacity = 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
int narsil_code_points_reserve(narsil_code_points *points, size_t capacity) {
|
|
81
|
+
if (capacity <= points->capacity) { return NARSIL_OK; }
|
|
82
|
+
growth request = {points->capacity, capacity, sizeof(uint32_t)};
|
|
83
|
+
size_t grown = grown_capacity(request);
|
|
84
|
+
if (grown == 0) { return NARSIL_OUT_OF_MEMORY; }
|
|
85
|
+
uint32_t *values = realloc(points->values, grown * sizeof(uint32_t));
|
|
86
|
+
if (values == NULL) { return NARSIL_OUT_OF_MEMORY; }
|
|
87
|
+
points->values = values;
|
|
88
|
+
points->capacity = grown;
|
|
89
|
+
return NARSIL_OK;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
int narsil_code_points_push(narsil_code_points *points, uint32_t code_point) {
|
|
93
|
+
if (points->length == points->capacity) {
|
|
94
|
+
int status = narsil_code_points_reserve(points, points->length + 1);
|
|
95
|
+
if (status != NARSIL_OK) { return status; }
|
|
96
|
+
}
|
|
97
|
+
points->values[points->length++] = code_point;
|
|
98
|
+
return NARSIL_OK;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
void narsil_code_points_release(narsil_code_points *points) {
|
|
102
|
+
free(points->values);
|
|
103
|
+
points->values = NULL;
|
|
104
|
+
points->length = 0;
|
|
105
|
+
points->capacity = 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static int is_high_surrogate(uint32_t unit) {
|
|
109
|
+
return unit >= NARSIL_HIGH_SURROGATE_FIRST && unit < NARSIL_LOW_SURROGATE_FIRST;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static int is_low_surrogate(uint32_t unit) { return unit >= NARSIL_LOW_SURROGATE_FIRST && unit < NARSIL_SURROGATE_END; }
|
|
113
|
+
|
|
114
|
+
static uint32_t combine_surrogates(uint32_t high, uint32_t low) {
|
|
115
|
+
return NARSIL_SUPPLEMENTARY_FIRST + ((high - NARSIL_HIGH_SURROGATE_FIRST) << NARSIL_SURROGATE_PAYLOAD_BITS) +
|
|
116
|
+
(low - NARSIL_LOW_SURROGATE_FIRST);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
uint32_t narsil_decode_next(const uint16_t *units, size_t length, size_t *index) {
|
|
120
|
+
uint32_t unit = units[*index];
|
|
121
|
+
*index += 1;
|
|
122
|
+
if (is_high_surrogate(unit) && *index < length && is_low_surrogate(units[*index])) {
|
|
123
|
+
uint32_t low = units[*index];
|
|
124
|
+
*index += 1;
|
|
125
|
+
return combine_surrogates(unit, low);
|
|
126
|
+
}
|
|
127
|
+
return unit;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
uint32_t narsil_decode_previous(const uint16_t *units, size_t *index) {
|
|
131
|
+
*index -= 1;
|
|
132
|
+
uint32_t unit = units[*index];
|
|
133
|
+
if (is_low_surrogate(unit) && *index > 0 && is_high_surrogate(units[*index - 1])) {
|
|
134
|
+
*index -= 1;
|
|
135
|
+
return combine_surrogates(units[*index], unit);
|
|
136
|
+
}
|
|
137
|
+
return unit;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
int narsil_units_are_ascii(const uint16_t *units, size_t length) {
|
|
141
|
+
for (size_t i = 0; i < length; i++) {
|
|
142
|
+
if (units[i] >= NARSIL_ASCII_END) { return 0; }
|
|
143
|
+
}
|
|
144
|
+
return 1;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
int narsil_units_equal(const uint16_t *left, size_t left_length, const uint16_t *right, size_t right_length) {
|
|
148
|
+
return left_length == right_length && (left_length == 0 || memcmp(left, right, left_length * sizeof(uint16_t)) == 0);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
void narsil_replace_unpaired_surrogates(uint16_t *units, size_t length) {
|
|
152
|
+
for (size_t i = 0; i < length; i++) {
|
|
153
|
+
uint32_t unit = units[i];
|
|
154
|
+
if (unit < NARSIL_HIGH_SURROGATE_FIRST || unit >= NARSIL_SURROGATE_END) { continue; }
|
|
155
|
+
if (is_high_surrogate(unit) && i + 1 < length && is_low_surrogate(units[i + 1])) {
|
|
156
|
+
i++;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
units[i] = (uint16_t)NARSIL_REPLACEMENT_CHARACTER;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#ifndef NARSIL_ANALYSIS_TEXT_H
|
|
2
|
+
#define NARSIL_ANALYSIS_TEXT_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
#define NARSIL_HIGH_SURROGATE_FIRST 0xD800U
|
|
8
|
+
#define NARSIL_LOW_SURROGATE_FIRST 0xDC00U
|
|
9
|
+
#define NARSIL_SURROGATE_END 0xE000U
|
|
10
|
+
#define NARSIL_SUPPLEMENTARY_FIRST 0x10000U
|
|
11
|
+
#define NARSIL_SURROGATE_PAYLOAD_BITS 10U
|
|
12
|
+
#define NARSIL_SURROGATE_PAYLOAD_MASK 0x3FFU
|
|
13
|
+
#define NARSIL_ASCII_END 0x80U
|
|
14
|
+
#define NARSIL_REPLACEMENT_CHARACTER 0xFFFDU
|
|
15
|
+
|
|
16
|
+
typedef struct {
|
|
17
|
+
uint16_t *units;
|
|
18
|
+
size_t length;
|
|
19
|
+
size_t capacity;
|
|
20
|
+
} narsil_text;
|
|
21
|
+
|
|
22
|
+
typedef struct {
|
|
23
|
+
uint32_t *values;
|
|
24
|
+
size_t length;
|
|
25
|
+
size_t capacity;
|
|
26
|
+
} narsil_code_points;
|
|
27
|
+
|
|
28
|
+
int narsil_text_reserve(narsil_text *text, size_t capacity);
|
|
29
|
+
int narsil_text_assign(narsil_text *text, const uint16_t *units, size_t length);
|
|
30
|
+
int narsil_text_append(narsil_text *text, const uint16_t *units, size_t length);
|
|
31
|
+
int narsil_text_push(narsil_text *text, uint16_t unit);
|
|
32
|
+
int narsil_text_push_code_point(narsil_text *text, uint32_t code_point);
|
|
33
|
+
void narsil_text_release(narsil_text *text);
|
|
34
|
+
|
|
35
|
+
int narsil_code_points_reserve(narsil_code_points *points, size_t capacity);
|
|
36
|
+
int narsil_code_points_push(narsil_code_points *points, uint32_t code_point);
|
|
37
|
+
void narsil_code_points_release(narsil_code_points *points);
|
|
38
|
+
|
|
39
|
+
uint32_t narsil_decode_next(const uint16_t *units, size_t length, size_t *index);
|
|
40
|
+
uint32_t narsil_decode_previous(const uint16_t *units, size_t *index);
|
|
41
|
+
int narsil_units_are_ascii(const uint16_t *units, size_t length);
|
|
42
|
+
int narsil_units_equal(const uint16_t *left, size_t left_length, const uint16_t *right, size_t right_length);
|
|
43
|
+
void narsil_replace_unpaired_surrogates(uint16_t *units, size_t length);
|
|
44
|
+
|
|
45
|
+
#endif
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#include "../../include/narsil_analysis.h"
|
|
2
|
+
#include "../../include/narsil_core.h"
|
|
3
|
+
#include "../languages/snowball/api.h"
|
|
4
|
+
#include "analyser.h"
|
|
5
|
+
#include "languages.h"
|
|
6
|
+
#include "normalise.h"
|
|
7
|
+
#include "term_cache.h"
|
|
8
|
+
#include "text.h"
|
|
9
|
+
|
|
10
|
+
#include <limits.h>
|
|
11
|
+
#include <stddef.h>
|
|
12
|
+
#include <stdint.h>
|
|
13
|
+
|
|
14
|
+
static narsil_text *buffer_apart_from(narsil_analyser *analyser, narsil_unit_view current) {
|
|
15
|
+
if (current.units != NULL && current.units == analyser->step_a.units) { return &analyser->step_b; }
|
|
16
|
+
return &analyser->step_a;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static narsil_unit_view view_of(const narsil_text *text) {
|
|
20
|
+
narsil_unit_view view = {text->units, text->length};
|
|
21
|
+
return view;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static int rewrite(narsil_analyser *analyser, narsil_token_rewrite step, narsil_unit_view *current) {
|
|
25
|
+
narsil_text *target = buffer_apart_from(analyser, *current);
|
|
26
|
+
int status = step(current->units, current->length, target, &analyser->scratch);
|
|
27
|
+
if (status == NARSIL_OK) { *current = view_of(target); }
|
|
28
|
+
return status;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static int strip_diacritics(narsil_analyser *analyser, narsil_unit_view *current) {
|
|
32
|
+
narsil_text *target = buffer_apart_from(analyser, *current);
|
|
33
|
+
int status = narsil_strip_diacritics(current->units, current->length, target, &analyser->scratch.points);
|
|
34
|
+
if (status == NARSIL_OK) { *current = view_of(target); }
|
|
35
|
+
return status;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static int stem_with_snowball(narsil_analyser *analyser, const narsil_language *language, uint32_t language_index,
|
|
39
|
+
narsil_unit_view *current) {
|
|
40
|
+
if (current->length > INT_MAX) { return NARSIL_INVALID_ARGUMENT; }
|
|
41
|
+
struct SN_env *env = analyser->snowball[language_index];
|
|
42
|
+
if (env == NULL) {
|
|
43
|
+
env = language->create_snowball();
|
|
44
|
+
if (env == NULL) { return NARSIL_OUT_OF_MEMORY; }
|
|
45
|
+
analyser->snowball[language_index] = env;
|
|
46
|
+
}
|
|
47
|
+
if (SN_set_current(env, (int)current->length, current->units) < 0) { return NARSIL_OUT_OF_MEMORY; }
|
|
48
|
+
if (language->snowball_stem(env) < 0 || env->l < 0) { return NARSIL_OUT_OF_MEMORY; }
|
|
49
|
+
current->units = env->p;
|
|
50
|
+
current->length = (size_t)env->l;
|
|
51
|
+
return NARSIL_OK;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static int transform_uncached(narsil_analyser *analyser, const narsil_language *language, uint32_t language_index,
|
|
55
|
+
narsil_unit_view candidate, uint32_t flags, narsil_unit_view *result) {
|
|
56
|
+
narsil_unit_view current = candidate;
|
|
57
|
+
int status = NARSIL_OK;
|
|
58
|
+
if (language->normalise != NULL) { status = rewrite(analyser, language->normalise, ¤t); }
|
|
59
|
+
if (status == NARSIL_OK && (flags & NARSIL_ANALYSE_REMOVE_DIACRITICS) != 0) {
|
|
60
|
+
status = strip_diacritics(analyser, ¤t);
|
|
61
|
+
}
|
|
62
|
+
if (status == NARSIL_OK && (flags & NARSIL_ANALYSE_STEM) != 0) {
|
|
63
|
+
if (language->stem_by_rules != NULL) {
|
|
64
|
+
status = rewrite(analyser, language->stem_by_rules, ¤t);
|
|
65
|
+
} else if (language->snowball_stem != NULL) {
|
|
66
|
+
status = stem_with_snowball(analyser, language, language_index, ¤t);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (status == NARSIL_OK) { *result = current; }
|
|
70
|
+
return status;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
int narsil_transform_token(narsil_analyser *analyser, const narsil_language *language, uint32_t language_index,
|
|
74
|
+
narsil_unit_view candidate, uint32_t flags, narsil_unit_view *result, uint32_t *term_slot) {
|
|
75
|
+
*term_slot = NARSIL_NO_TERM_SLOT;
|
|
76
|
+
narsil_term_key key = {language_index, flags & NARSIL_TRANSFORM_FLAGS, candidate.units, candidate.length};
|
|
77
|
+
narsil_term_slot *victim = NULL;
|
|
78
|
+
narsil_term_slot *held = narsil_term_cache_find(&analyser->terms, &key, &victim);
|
|
79
|
+
if (held != NULL) {
|
|
80
|
+
result->units = held->value;
|
|
81
|
+
result->length = held->value_length;
|
|
82
|
+
*term_slot = narsil_term_cache_index(&analyser->terms, held);
|
|
83
|
+
return NARSIL_OK;
|
|
84
|
+
}
|
|
85
|
+
int status = transform_uncached(analyser, language, language_index, candidate, key.flags, result);
|
|
86
|
+
if (status == NARSIL_OK && victim != NULL && narsil_term_cache_store(victim, &key, result->units, result->length)) {
|
|
87
|
+
*term_slot = narsil_term_cache_index(&analyser->terms, victim);
|
|
88
|
+
}
|
|
89
|
+
return status;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
int narsil_surface_of(narsil_analyser *analyser, const narsil_language *language, narsil_unit_view candidate,
|
|
93
|
+
narsil_unit_view *result) {
|
|
94
|
+
narsil_unit_view current = candidate;
|
|
95
|
+
if (language->normalise != NULL) {
|
|
96
|
+
int status = language->normalise(current.units, current.length, &analyser->surface_step, &analyser->scratch);
|
|
97
|
+
if (status != NARSIL_OK) { return status; }
|
|
98
|
+
current = view_of(&analyser->surface_step);
|
|
99
|
+
}
|
|
100
|
+
int status = narsil_strip_diacritics(current.units, current.length, &analyser->surface, &analyser->scratch.points);
|
|
101
|
+
if (status == NARSIL_OK) { *result = view_of(&analyser->surface); }
|
|
102
|
+
return status;
|
|
103
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#include "unicode.h"
|
|
2
|
+
|
|
3
|
+
#include "../../include/narsil_core.h"
|
|
4
|
+
#include "../thread_yield.h"
|
|
5
|
+
|
|
6
|
+
#include <stdatomic.h>
|
|
7
|
+
#include <stddef.h>
|
|
8
|
+
#include <stdint.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
|
|
11
|
+
#define BMP_SIZE 0x10000U
|
|
12
|
+
#define RUN_INDEX_MASK ((1U << NARSIL_UNICODE_RUN_INDEX_BITS) - 1U)
|
|
13
|
+
#define DECOMPOSITION_STRIDE 3U
|
|
14
|
+
#define SPECIAL_LOWERCASE_STRIDE 3U
|
|
15
|
+
#define LOWERCASE_STRIDE 2U
|
|
16
|
+
#define COMPOSITION_SECOND_BITS 21U
|
|
17
|
+
|
|
18
|
+
#define HANGUL_SYLLABLE_FIRST 0xAC00U
|
|
19
|
+
#define HANGUL_LEADING_FIRST 0x1100U
|
|
20
|
+
#define HANGUL_VOWEL_FIRST 0x1161U
|
|
21
|
+
#define HANGUL_TRAILING_BEFORE_FIRST 0x11A7U
|
|
22
|
+
#define HANGUL_LEADING_COUNT 19U
|
|
23
|
+
#define HANGUL_VOWEL_COUNT 21U
|
|
24
|
+
#define HANGUL_TRAILING_COUNT 28U
|
|
25
|
+
#define HANGUL_SYLLABLES_PER_LEADING (HANGUL_VOWEL_COUNT * HANGUL_TRAILING_COUNT)
|
|
26
|
+
#define HANGUL_SYLLABLE_COUNT (HANGUL_LEADING_COUNT * HANGUL_SYLLABLES_PER_LEADING)
|
|
27
|
+
|
|
28
|
+
enum { PREPARE_IDLE = 0, PREPARE_BUILDING = 1, PREPARE_READY = 2 };
|
|
29
|
+
|
|
30
|
+
typedef struct {
|
|
31
|
+
uint64_t key;
|
|
32
|
+
uint32_t composite;
|
|
33
|
+
} composition_entry;
|
|
34
|
+
|
|
35
|
+
static atomic_int prepare_state = PREPARE_IDLE;
|
|
36
|
+
static uint8_t bmp_value_index[BMP_SIZE];
|
|
37
|
+
static uint32_t *supplementary_starts;
|
|
38
|
+
static const uint32_t *supplementary_runs;
|
|
39
|
+
static uint32_t supplementary_run_count;
|
|
40
|
+
static composition_entry *compositions;
|
|
41
|
+
static uint32_t composition_count;
|
|
42
|
+
|
|
43
|
+
static uint64_t composition_key(uint32_t first, uint32_t second) {
|
|
44
|
+
return ((uint64_t)first << COMPOSITION_SECOND_BITS) | second;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static int compare_compositions(const void *lhs, const void *rhs) {
|
|
48
|
+
const composition_entry *left = lhs;
|
|
49
|
+
const composition_entry *right = rhs;
|
|
50
|
+
return (left->key > right->key) - (left->key < right->key);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static int build_property_index(void) {
|
|
54
|
+
uint32_t start = 0;
|
|
55
|
+
uint32_t first_supplementary = narsil_unicode_property_runs_length;
|
|
56
|
+
for (uint32_t run = 0; run < narsil_unicode_property_runs_length; run++) {
|
|
57
|
+
uint32_t length = narsil_unicode_property_runs[run] >> NARSIL_UNICODE_RUN_INDEX_BITS;
|
|
58
|
+
uint32_t end = start + length;
|
|
59
|
+
for (uint32_t code_point = start; code_point < end && code_point < BMP_SIZE; code_point++) {
|
|
60
|
+
bmp_value_index[code_point] = (uint8_t)(narsil_unicode_property_runs[run] & RUN_INDEX_MASK);
|
|
61
|
+
}
|
|
62
|
+
if (end > BMP_SIZE && first_supplementary == narsil_unicode_property_runs_length) { first_supplementary = run; }
|
|
63
|
+
start = end;
|
|
64
|
+
}
|
|
65
|
+
supplementary_run_count = narsil_unicode_property_runs_length - first_supplementary;
|
|
66
|
+
if (supplementary_run_count == 0) { return NARSIL_OK; }
|
|
67
|
+
supplementary_starts = malloc((size_t)supplementary_run_count * sizeof(uint32_t));
|
|
68
|
+
if (supplementary_starts == NULL) { return NARSIL_OUT_OF_MEMORY; }
|
|
69
|
+
supplementary_runs = &narsil_unicode_property_runs[first_supplementary];
|
|
70
|
+
start = 0;
|
|
71
|
+
for (uint32_t run = 0; run < narsil_unicode_property_runs_length; run++) {
|
|
72
|
+
if (run >= first_supplementary) { supplementary_starts[run - first_supplementary] = start; }
|
|
73
|
+
start += narsil_unicode_property_runs[run] >> NARSIL_UNICODE_RUN_INDEX_BITS;
|
|
74
|
+
}
|
|
75
|
+
return NARSIL_OK;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static int build_compositions(void) {
|
|
79
|
+
uint32_t entries = narsil_unicode_decompositions_length / DECOMPOSITION_STRIDE;
|
|
80
|
+
composition_count = 0;
|
|
81
|
+
if (entries == 0) { return NARSIL_OK; }
|
|
82
|
+
compositions = malloc((size_t)entries * sizeof(composition_entry));
|
|
83
|
+
if (compositions == NULL) { return NARSIL_OUT_OF_MEMORY; }
|
|
84
|
+
for (uint32_t entry = 0; entry < entries; entry++) {
|
|
85
|
+
const uint32_t *row = &narsil_unicode_decompositions[(size_t)entry * DECOMPOSITION_STRIDE];
|
|
86
|
+
if (row[2] == 0 || (narsil_unicode_properties(row[0]) & NARSIL_UNICODE_COMPOSITION_EXCLUDED) != 0) { continue; }
|
|
87
|
+
compositions[composition_count].key = composition_key(row[1], row[2]);
|
|
88
|
+
compositions[composition_count].composite = row[0];
|
|
89
|
+
composition_count++;
|
|
90
|
+
}
|
|
91
|
+
qsort(compositions, composition_count, sizeof(composition_entry), compare_compositions);
|
|
92
|
+
return NARSIL_OK;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static void release_tables(void) {
|
|
96
|
+
free(supplementary_starts);
|
|
97
|
+
supplementary_starts = NULL;
|
|
98
|
+
free(compositions);
|
|
99
|
+
compositions = NULL;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
int narsil_unicode_prepare(void) {
|
|
103
|
+
for (;;) {
|
|
104
|
+
int state = atomic_load_explicit(&prepare_state, memory_order_acquire);
|
|
105
|
+
if (state == PREPARE_READY) { return NARSIL_OK; }
|
|
106
|
+
if (state == PREPARE_IDLE && atomic_compare_exchange_strong_explicit(&prepare_state, &state, PREPARE_BUILDING,
|
|
107
|
+
memory_order_acq_rel, memory_order_acquire)) {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
if (state == PREPARE_BUILDING) { narsil_yield_thread(); }
|
|
111
|
+
}
|
|
112
|
+
int status = build_property_index();
|
|
113
|
+
if (status == NARSIL_OK) { status = build_compositions(); }
|
|
114
|
+
if (status == NARSIL_OK) {
|
|
115
|
+
atomic_store_explicit(&prepare_state, PREPARE_READY, memory_order_release);
|
|
116
|
+
return NARSIL_OK;
|
|
117
|
+
}
|
|
118
|
+
release_tables();
|
|
119
|
+
atomic_store_explicit(&prepare_state, PREPARE_IDLE, memory_order_release);
|
|
120
|
+
return status;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
uint32_t narsil_unicode_properties(uint32_t code_point) {
|
|
124
|
+
if (code_point < BMP_SIZE) { return narsil_unicode_property_values[bmp_value_index[code_point]]; }
|
|
125
|
+
if (code_point > NARSIL_UNICODE_MAX_CODE_POINT || supplementary_run_count == 0) { return 0; }
|
|
126
|
+
uint32_t low = 0;
|
|
127
|
+
uint32_t high = supplementary_run_count;
|
|
128
|
+
while (high - low > 1) {
|
|
129
|
+
uint32_t middle = low + ((high - low) / 2);
|
|
130
|
+
if (supplementary_starts[middle] <= code_point) {
|
|
131
|
+
low = middle;
|
|
132
|
+
} else {
|
|
133
|
+
high = middle;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return narsil_unicode_property_values[supplementary_runs[low] & RUN_INDEX_MASK];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
uint32_t narsil_unicode_combining_class(uint32_t code_point) {
|
|
140
|
+
return narsil_unicode_properties(code_point) & NARSIL_UNICODE_COMBINING_CLASS_MASK;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
uint32_t narsil_unicode_script(uint32_t code_point) {
|
|
144
|
+
return (narsil_unicode_properties(code_point) >> NARSIL_UNICODE_SCRIPT_SHIFT) & NARSIL_UNICODE_SCRIPT_MASK;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
typedef struct {
|
|
148
|
+
const uint32_t *rows;
|
|
149
|
+
uint32_t length;
|
|
150
|
+
uint32_t stride;
|
|
151
|
+
} row_table;
|
|
152
|
+
|
|
153
|
+
static const uint32_t *find_row(row_table table, uint32_t code_point) {
|
|
154
|
+
size_t low = 0;
|
|
155
|
+
size_t high = table.length / table.stride;
|
|
156
|
+
while (low < high) {
|
|
157
|
+
size_t middle = low + ((high - low) / 2);
|
|
158
|
+
const uint32_t *row = &table.rows[middle * table.stride];
|
|
159
|
+
if (row[0] == code_point) { return row; }
|
|
160
|
+
if (row[0] < code_point) {
|
|
161
|
+
low = middle + 1;
|
|
162
|
+
} else {
|
|
163
|
+
high = middle;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return NULL;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
uint32_t narsil_unicode_lowercase_of(uint32_t code_point, uint32_t *second) {
|
|
170
|
+
*second = 0;
|
|
171
|
+
if ((narsil_unicode_properties(code_point) & NARSIL_UNICODE_LOWERCASE_MAPPING) == 0) { return code_point; }
|
|
172
|
+
row_table special_table = {narsil_unicode_special_lowercase, narsil_unicode_special_lowercase_length,
|
|
173
|
+
SPECIAL_LOWERCASE_STRIDE};
|
|
174
|
+
const uint32_t *special = find_row(special_table, code_point);
|
|
175
|
+
if (special != NULL) {
|
|
176
|
+
*second = special[2];
|
|
177
|
+
return special[1];
|
|
178
|
+
}
|
|
179
|
+
row_table pair_table = {narsil_unicode_lowercase, narsil_unicode_lowercase_length, LOWERCASE_STRIDE};
|
|
180
|
+
const uint32_t *pair = find_row(pair_table, code_point);
|
|
181
|
+
return pair == NULL ? code_point : pair[1];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
static const uint32_t *decomposition_of(uint32_t code_point) {
|
|
185
|
+
if ((narsil_unicode_properties(code_point) & NARSIL_UNICODE_DECOMPOSES) == 0) { return NULL; }
|
|
186
|
+
row_table table = {narsil_unicode_decompositions, narsil_unicode_decompositions_length, DECOMPOSITION_STRIDE};
|
|
187
|
+
return find_row(table, code_point);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
static uint32_t decompose_fully(uint32_t code_point, uint32_t *out) {
|
|
191
|
+
uint32_t pending[NARSIL_UNICODE_MAX_DECOMPOSITION];
|
|
192
|
+
uint32_t pending_count = 1;
|
|
193
|
+
uint32_t written = 0;
|
|
194
|
+
pending[0] = code_point;
|
|
195
|
+
while (pending_count > 0 && written < NARSIL_UNICODE_MAX_DECOMPOSITION) {
|
|
196
|
+
uint32_t current = pending[--pending_count];
|
|
197
|
+
const uint32_t *row = decomposition_of(current);
|
|
198
|
+
if (row == NULL || pending_count + 2 > NARSIL_UNICODE_MAX_DECOMPOSITION) {
|
|
199
|
+
out[written++] = current;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (row[2] != 0) { pending[pending_count++] = row[2]; }
|
|
203
|
+
pending[pending_count++] = row[1];
|
|
204
|
+
}
|
|
205
|
+
return written;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
uint32_t narsil_unicode_decompose(uint32_t code_point, uint32_t *out) {
|
|
209
|
+
if (code_point >= HANGUL_SYLLABLE_FIRST && code_point < HANGUL_SYLLABLE_FIRST + HANGUL_SYLLABLE_COUNT) {
|
|
210
|
+
uint32_t index = code_point - HANGUL_SYLLABLE_FIRST;
|
|
211
|
+
uint32_t trailing = index % HANGUL_TRAILING_COUNT;
|
|
212
|
+
out[0] = HANGUL_LEADING_FIRST + (index / HANGUL_SYLLABLES_PER_LEADING);
|
|
213
|
+
out[1] = HANGUL_VOWEL_FIRST + ((index % HANGUL_SYLLABLES_PER_LEADING) / HANGUL_TRAILING_COUNT);
|
|
214
|
+
if (trailing == 0) { return 2; }
|
|
215
|
+
out[2] = HANGUL_TRAILING_BEFORE_FIRST + trailing;
|
|
216
|
+
return 3;
|
|
217
|
+
}
|
|
218
|
+
return decompose_fully(code_point, out);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
static uint32_t compose_hangul(uint32_t first, uint32_t second) {
|
|
222
|
+
if (first >= HANGUL_LEADING_FIRST && first < HANGUL_LEADING_FIRST + HANGUL_LEADING_COUNT &&
|
|
223
|
+
second >= HANGUL_VOWEL_FIRST && second < HANGUL_VOWEL_FIRST + HANGUL_VOWEL_COUNT) {
|
|
224
|
+
return HANGUL_SYLLABLE_FIRST + ((first - HANGUL_LEADING_FIRST) * HANGUL_SYLLABLES_PER_LEADING) +
|
|
225
|
+
((second - HANGUL_VOWEL_FIRST) * HANGUL_TRAILING_COUNT);
|
|
226
|
+
}
|
|
227
|
+
if (first >= HANGUL_SYLLABLE_FIRST && first < HANGUL_SYLLABLE_FIRST + HANGUL_SYLLABLE_COUNT &&
|
|
228
|
+
(first - HANGUL_SYLLABLE_FIRST) % HANGUL_TRAILING_COUNT == 0 && second > HANGUL_TRAILING_BEFORE_FIRST &&
|
|
229
|
+
second < HANGUL_TRAILING_BEFORE_FIRST + HANGUL_TRAILING_COUNT) {
|
|
230
|
+
return first + (second - HANGUL_TRAILING_BEFORE_FIRST);
|
|
231
|
+
}
|
|
232
|
+
return NARSIL_UNICODE_NO_COMPOSITE;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
uint32_t narsil_unicode_compose(uint32_t first, uint32_t second) {
|
|
236
|
+
uint32_t hangul = compose_hangul(first, second);
|
|
237
|
+
if (hangul != NARSIL_UNICODE_NO_COMPOSITE) { return hangul; }
|
|
238
|
+
if ((narsil_unicode_properties(second) & NARSIL_UNICODE_COMPOSES_SECOND) == 0) { return NARSIL_UNICODE_NO_COMPOSITE; }
|
|
239
|
+
uint64_t key = composition_key(first, second);
|
|
240
|
+
uint32_t low = 0;
|
|
241
|
+
uint32_t high = composition_count;
|
|
242
|
+
while (low < high) {
|
|
243
|
+
uint32_t middle = low + ((high - low) / 2);
|
|
244
|
+
if (compositions[middle].key == key) { return compositions[middle].composite; }
|
|
245
|
+
if (compositions[middle].key < key) {
|
|
246
|
+
low = middle + 1;
|
|
247
|
+
} else {
|
|
248
|
+
high = middle;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return NARSIL_UNICODE_NO_COMPOSITE;
|
|
252
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#ifndef NARSIL_ANALYSIS_UNICODE_H
|
|
2
|
+
#define NARSIL_ANALYSIS_UNICODE_H
|
|
3
|
+
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
|
|
6
|
+
#define NARSIL_UNICODE_COMBINING_CLASS_MASK 0xFFU
|
|
7
|
+
#define NARSIL_UNICODE_LETTER (1U << 8)
|
|
8
|
+
#define NARSIL_UNICODE_MARK (1U << 9)
|
|
9
|
+
#define NARSIL_UNICODE_NUMBER (1U << 10)
|
|
10
|
+
#define NARSIL_UNICODE_FORMAT (1U << 11)
|
|
11
|
+
#define NARSIL_UNICODE_CASED (1U << 12)
|
|
12
|
+
#define NARSIL_UNICODE_CASE_IGNORABLE (1U << 13)
|
|
13
|
+
#define NARSIL_UNICODE_LOWERCASE_MAPPING (1U << 14)
|
|
14
|
+
#define NARSIL_UNICODE_DECOMPOSES (1U << 15)
|
|
15
|
+
#define NARSIL_UNICODE_COMPOSES_SECOND (1U << 16)
|
|
16
|
+
#define NARSIL_UNICODE_COMPOSITION_EXCLUDED (1U << 17)
|
|
17
|
+
#define NARSIL_UNICODE_SCRIPT_SHIFT 20
|
|
18
|
+
#define NARSIL_UNICODE_SCRIPT_MASK 0xFU
|
|
19
|
+
|
|
20
|
+
#define NARSIL_UNICODE_SCRIPT_OTHER 0
|
|
21
|
+
#define NARSIL_UNICODE_SCRIPT_HAN 1
|
|
22
|
+
#define NARSIL_UNICODE_SCRIPT_HIRAGANA 2
|
|
23
|
+
#define NARSIL_UNICODE_SCRIPT_KATAKANA 3
|
|
24
|
+
#define NARSIL_UNICODE_SCRIPT_HANGUL 4
|
|
25
|
+
#define NARSIL_UNICODE_SCRIPT_THAI 5
|
|
26
|
+
#define NARSIL_UNICODE_SCRIPT_LAO 6
|
|
27
|
+
#define NARSIL_UNICODE_SCRIPT_KHMER 7
|
|
28
|
+
#define NARSIL_UNICODE_SCRIPT_MYANMAR 8
|
|
29
|
+
|
|
30
|
+
#define NARSIL_UNICODE_RUN_INDEX_BITS 8
|
|
31
|
+
#define NARSIL_UNICODE_MAX_CODE_POINT 0x10FFFFU
|
|
32
|
+
#define NARSIL_UNICODE_MAX_DECOMPOSITION 4
|
|
33
|
+
#define NARSIL_UNICODE_NO_COMPOSITE 0U
|
|
34
|
+
|
|
35
|
+
extern const uint32_t narsil_unicode_property_values[];
|
|
36
|
+
extern const uint32_t narsil_unicode_property_values_length;
|
|
37
|
+
extern const uint32_t narsil_unicode_property_runs[];
|
|
38
|
+
extern const uint32_t narsil_unicode_property_runs_length;
|
|
39
|
+
extern const uint32_t narsil_unicode_lowercase[];
|
|
40
|
+
extern const uint32_t narsil_unicode_lowercase_length;
|
|
41
|
+
extern const uint32_t narsil_unicode_special_lowercase[];
|
|
42
|
+
extern const uint32_t narsil_unicode_special_lowercase_length;
|
|
43
|
+
extern const uint32_t narsil_unicode_decompositions[];
|
|
44
|
+
extern const uint32_t narsil_unicode_decompositions_length;
|
|
45
|
+
|
|
46
|
+
int narsil_unicode_prepare(void);
|
|
47
|
+
uint32_t narsil_unicode_properties(uint32_t code_point);
|
|
48
|
+
uint32_t narsil_unicode_combining_class(uint32_t code_point);
|
|
49
|
+
uint32_t narsil_unicode_script(uint32_t code_point);
|
|
50
|
+
uint32_t narsil_unicode_lowercase_of(uint32_t code_point, uint32_t *second);
|
|
51
|
+
uint32_t narsil_unicode_decompose(uint32_t code_point, uint32_t *out);
|
|
52
|
+
uint32_t narsil_unicode_compose(uint32_t first, uint32_t second);
|
|
53
|
+
|
|
54
|
+
#endif
|
package/cpp/core/src/internal.h
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#ifndef NARSIL_CORE_INTERNAL_H
|
|
2
2
|
#define NARSIL_CORE_INTERNAL_H
|
|
3
3
|
|
|
4
|
+
#include "keyword/scratch.h"
|
|
5
|
+
|
|
4
6
|
#include "../include/narsil_core.h"
|
|
5
7
|
|
|
6
8
|
#include <stdatomic.h>
|
|
@@ -162,6 +164,7 @@ struct narsil_workspace {
|
|
|
162
164
|
int32_t repaired[MAX_NEIGHBOURS_PER_LIST];
|
|
163
165
|
double kept_distances[MAX_NEIGHBOURS_PER_LIST];
|
|
164
166
|
uint8_t replacement_tried[MAX_NEIGHBOURS_PER_LIST];
|
|
167
|
+
keyword_scratch keyword;
|
|
165
168
|
};
|
|
166
169
|
|
|
167
170
|
typedef struct {
|
|
@@ -187,6 +190,7 @@ static inline int is_tombstoned(const walk_context *context, int32_t ordinal) {
|
|
|
187
190
|
}
|
|
188
191
|
|
|
189
192
|
uint32_t grown_capacity(uint32_t first, uint32_t needed);
|
|
193
|
+
keyword_scratch *workspace_keyword_scratch(narsil_workspace *workspace);
|
|
190
194
|
|
|
191
195
|
narsil_status heap_reserve(distance_heap *heap, uint32_t capacity);
|
|
192
196
|
void heap_release(distance_heap *heap);
|