mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 14:51:40 +00:00
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:
parent
fc130351f3
commit
4b2f92b5e5
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user