AGI: Rewrote predictive code matcher

The new code is simpler, avoids a potential buffer overrun
(by avoiding to to use a buffer in the first place), and
hopefully has slightly more sane matching properties.

svn-id: r55135
This commit is contained in:
Max Horn 2011-01-06 21:11:24 +00:00
parent fc130351f3
commit 4b2f92b5e5

View File

@ -555,43 +555,33 @@ void AgiEngine::loadDict() {
}
bool AgiEngine::matchWord() {
if (_currentCode.empty()) {
// If no text has been entered, then there is no match.
if (_currentCode.empty())
return false;
}
// Lookup word in the dictionary
int line = 0, cmpRes = 0, len = 0;
char target[MAXWORDLEN];
strncpy(target, _currentCode.c_str(), MAXWORDLEN);
strcat(target, " ");
// If the currently entered text is too long, it cannot match anything.
if (_currentCode.size() > MAXWORDLEN)
return false;
// do the search at most two times:
// first try to match the exact code, by matching also the space after the code
// if there is not an exact match, do it once more for the best matching prefix (drop the space)
len = _currentCode.size() + 1;
for (int i = 0; i < 2; ++i) {
// Perform a binary search.
int hi = _predictiveDictLineCount - 1;
int lo = 0;
while (lo <= hi) {
line = (lo + hi) / 2;
cmpRes = strncmp(_predictiveDictLine[line], target, len);
if (cmpRes > 0)
hi = line - 1;
else if (cmpRes < 0)
lo = line + 1;
else
break;
}
if (cmpRes == 0) // Exact match found? -> stop now
break;
len--; // Remove the trailing space
// Perform a binary search on the dictionary to find the first
// entry that has _currentCode as a prefix.
int hi = _predictiveDictLineCount - 1;
int lo = 0;
int line = 0;
while (lo < hi) {
line = (lo + hi) / 2;
int cmpVal = strncmp(_predictiveDictLine[line], _currentCode.c_str(), _currentCode.size());
if (cmpVal > 0)
hi = line - 1;
else if (cmpVal < 0)
lo = line + 1;
else
hi = line;
}
_currentWord.clear();
_wordNumber = 0;
if (!strncmp(_predictiveDictLine[line], target, len)) {
if (0 == strncmp(_predictiveDictLine[line], _currentCode.c_str(), _currentCode.size())) {
_predictiveDictActLine = _predictiveDictLine[line];
char tmp[MAXLINELEN];
strncpy(tmp, _predictiveDictActLine, MAXLINELEN);