OLD | NEW |
1 #include "license.hunspell" | 1 #include "license.hunspell" |
2 #include "license.myspell" | 2 #include "license.myspell" |
3 | 3 |
4 #include <stdlib.h> | 4 #include <stdlib.h> |
5 #include <string.h> | 5 #include <string.h> |
6 #include <stdio.h> | 6 #include <stdio.h> |
7 #include <ctype.h> | 7 #include <ctype.h> |
8 | 8 |
9 #include "suggestmgr.hxx" | 9 #include "suggestmgr.hxx" |
10 #include "htypes.hxx" | 10 #include "htypes.hxx" |
11 #include "csutil.hxx" | 11 #include "csutil.hxx" |
12 | 12 |
13 const w_char W_VLINE = { '\0', '|' }; | 13 const w_char W_VLINE = { '\0', '|' }; |
14 | 14 |
| 15 #ifdef HUNSPELL_CHROME_CLIENT |
| 16 namespace { |
| 17 // A simple class which creates temporary hentry objects which are available |
| 18 // only in a scope. To conceal memory operations from SuggestMgr functions, |
| 19 // this object automatically deletes all hentry objects created through |
| 20 // CreateScopedHashEntry() calls in its destructor. So, the following snippet |
| 21 // raises a memory error. |
| 22 // |
| 23 // hentry* bad_copy = NULL; |
| 24 // { |
| 25 // ScopedHashEntryFactory factory; |
| 26 // hentry* scoped_copy = factory.CreateScopedHashEntry(0, source); |
| 27 // ... |
| 28 // bad_copy = scoped_copy; |
| 29 // } |
| 30 // if (bad_copy->word[0]) // memory for scoped_copy has been deleted! |
| 31 // |
| 32 // As listed in the above snippet, it is simple to use this class. |
| 33 // 1. Declare an instance of this ScopedHashEntryFactory, and; |
| 34 // 2. Call its CreateHashEntry() member instead of using 'new hentry' or |
| 35 // 'operator='. |
| 36 // |
| 37 class ScopedHashEntryFactory { |
| 38 public: |
| 39 ScopedHashEntryFactory(); |
| 40 ~ScopedHashEntryFactory(); |
| 41 |
| 42 // Creates a temporary copy of the given hentry struct. |
| 43 // The returned copy is available only while this object is available. |
| 44 // NOTE: this function just calls memcpy() in creating a copy of the given |
| 45 // hentry struct, i.e. it does NOT copy objects referred by pointers of the |
| 46 // given hentry struct. |
| 47 hentry* CreateScopedHashEntry(int index, const hentry* source); |
| 48 |
| 49 private: |
| 50 // A struct which encapsulates the new hentry struct introduced in hunspell |
| 51 // 1.2.8. For a pointer to an hentry struct 'h', hunspell 1.2.8 stores a word |
| 52 // (including a NUL character) into 'h->word[0]',...,'h->word[h->blen]' even |
| 53 // though arraysize(h->word[]) is 1. Also, it changed 'astr' to a pointer so |
| 54 // it can store affix flags into 'h->astr[0]',...,'h->astr[alen-1]'. To handle |
| 55 // this new hentry struct, we define a struct which combines three values: an |
| 56 // hentry struct 'hentry'; a char array 'word[kMaxWordLen]', and; an unsigned |
| 57 // short value 'astr' so a hentry struct 'h' returned from |
| 58 // CreateScopedHashEntry() satisfies the following equations: |
| 59 // hentry* h = factory.CreateScopedHashEntry(0, source); |
| 60 // h->word[0] == ((HashEntryItem*)h)->entry.word[0]. |
| 61 // h->word[1] == ((HashEntryItem*)h)->word[0]. |
| 62 // ... |
| 63 // h->word[h->blen] == ((HashEntryItem*)h)->word[h->blen-1]. |
| 64 // h->astr[0] == ((HashEntryItem*)h)->astr. |
| 65 // Our BDICT does not use affix flags longer than one for now since they are |
| 66 // discarded by convert_dict, i.e. 'h->astr' is always <= 1. Therefore, this |
| 67 // struct does not use an array for 'astr'. |
| 68 enum { |
| 69 kMaxWordLen = 128, |
| 70 }; |
| 71 struct HashEntryItem { |
| 72 hentry entry; |
| 73 char word[kMaxWordLen]; |
| 74 unsigned short astr; |
| 75 }; |
| 76 |
| 77 HashEntryItem hash_items_[MAX_ROOTS]; |
| 78 }; |
| 79 |
| 80 ScopedHashEntryFactory::ScopedHashEntryFactory() { |
| 81 memset(&hash_items_[0], 0, sizeof(hash_items_)); |
| 82 } |
| 83 |
| 84 ScopedHashEntryFactory::~ScopedHashEntryFactory() { |
| 85 } |
| 86 |
| 87 hentry* ScopedHashEntryFactory::CreateScopedHashEntry(int index, |
| 88 const hentry* source) { |
| 89 if (index >= MAX_ROOTS || source->blen >= kMaxWordLen || source->alen > 1) |
| 90 return NULL; |
| 91 |
| 92 // Retrieve a HashEntryItem struct from our spool, initialize it, and |
| 93 // returns the address of its 'hentry' member. |
| 94 size_t source_size = sizeof(hentry) + source->blen + 1; |
| 95 HashEntryItem* hash_item = &hash_items_[index]; |
| 96 memcpy(&hash_item->entry, source, source_size); |
| 97 if (source->astr) { |
| 98 hash_item->astr = *source->astr; |
| 99 hash_item->entry.astr = &hash_item->astr; |
| 100 } |
| 101 return &hash_item->entry; |
| 102 } |
| 103 |
| 104 } // namespace |
| 105 #endif |
| 106 |
15 SuggestMgr::SuggestMgr(const char * tryme, int maxn, | 107 SuggestMgr::SuggestMgr(const char * tryme, int maxn, |
16 AffixMgr * aptr) | 108 AffixMgr * aptr) |
17 { | 109 { |
18 | 110 |
19 // register affix manager and check in string of chars to | 111 // register affix manager and check in string of chars to |
20 // try when building candidate suggestions | 112 // try when building candidate suggestions |
21 pAMgr = aptr; | 113 pAMgr = aptr; |
22 | 114 |
23 csconv = NULL; | 115 csconv = NULL; |
24 | 116 |
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 | 1114 |
1023 // set character based ngram suggestion for words with non-BMP Unicode charact
ers | 1115 // set character based ngram suggestion for words with non-BMP Unicode charact
ers |
1024 if (n == -1) { | 1116 if (n == -1) { |
1025 utf8 = 0; | 1117 utf8 = 0; |
1026 n = nc; | 1118 n = nc; |
1027 nonbmp = 1; | 1119 nonbmp = 1; |
1028 } | 1120 } |
1029 | 1121 |
1030 struct hentry* hp = NULL; | 1122 struct hentry* hp = NULL; |
1031 int col = -1; | 1123 int col = -1; |
| 1124 |
| 1125 #ifdef HUNSPELL_CHROME_CLIENT |
| 1126 ScopedHashEntryFactory hash_entry_factory; |
| 1127 #endif |
| 1128 |
1032 phonetable * ph = (pAMgr) ? pAMgr->get_phonetable() : NULL; | 1129 phonetable * ph = (pAMgr) ? pAMgr->get_phonetable() : NULL; |
1033 char target[MAXSWUTF8L]; | 1130 char target[MAXSWUTF8L]; |
1034 char candidate[MAXSWUTF8L]; | 1131 char candidate[MAXSWUTF8L]; |
1035 if (ph) { | 1132 if (ph) { |
1036 strcpy(candidate, word); | 1133 strcpy(candidate, word); |
1037 mkallcap(candidate, csconv); | 1134 mkallcap(candidate, csconv); |
1038 phonet(candidate, target, n, *ph); | 1135 phonet(candidate, target, n, *ph); |
1039 } | 1136 } |
1040 | 1137 |
1041 for (i = 0; i < md; i++) { | 1138 for (i = 0; i < md; i++) { |
(...skipping 17 matching lines...) Expand all Loading... |
1059 if (ph && (sc > 2) && (abs(n - (int) hp->clen) <= 3)) { | 1156 if (ph && (sc > 2) && (abs(n - (int) hp->clen) <= 3)) { |
1060 char target2[MAXSWUTF8L]; | 1157 char target2[MAXSWUTF8L]; |
1061 strcpy(candidate, HENTRY_WORD(hp)); | 1158 strcpy(candidate, HENTRY_WORD(hp)); |
1062 mkallcap(candidate, csconv); | 1159 mkallcap(candidate, csconv); |
1063 phonet(candidate, target2, -1, *ph); | 1160 phonet(candidate, target2, -1, *ph); |
1064 scphon = 2 * ngram(3, target, target2, NGRAM_LONGER_WORSE); | 1161 scphon = 2 * ngram(3, target, target2, NGRAM_LONGER_WORSE); |
1065 } | 1162 } |
1066 | 1163 |
1067 if (sc > scores[lp]) { | 1164 if (sc > scores[lp]) { |
1068 scores[lp] = sc; | 1165 scores[lp] = sc; |
| 1166 #ifdef HUNSPELL_CHROME_CLIENT |
| 1167 roots[lp] = hash_entry_factory.CreateScopedHashEntry(lp, hp); |
| 1168 #else |
1069 roots[lp] = hp; | 1169 roots[lp] = hp; |
| 1170 #endif |
1070 lval = sc; | 1171 lval = sc; |
1071 for (j=0; j < MAX_ROOTS; j++) | 1172 for (j=0; j < MAX_ROOTS; j++) |
1072 if (scores[j] < lval) { | 1173 if (scores[j] < lval) { |
1073 lp = j; | 1174 lp = j; |
1074 lval = scores[j]; | 1175 lval = scores[j]; |
1075 } | 1176 } |
1076 } | 1177 } |
1077 | 1178 |
1078 if (scphon > scoresphon[lpphon]) { | 1179 if (scphon > scoresphon[lpphon]) { |
1079 scoresphon[lpphon] = scphon; | 1180 scoresphon[lpphon] = scphon; |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1905 len++; | 2006 len++; |
1906 i--; | 2007 i--; |
1907 j--; | 2008 j--; |
1908 } else if (result[i*(n+1) + j] == LCS_UP) { | 2009 } else if (result[i*(n+1) + j] == LCS_UP) { |
1909 i--; | 2010 i--; |
1910 } else j--; | 2011 } else j--; |
1911 } | 2012 } |
1912 free(result); | 2013 free(result); |
1913 return len; | 2014 return len; |
1914 } | 2015 } |
OLD | NEW |