diff options
author | Max Horn | 2011-01-06 21:11:24 +0000 |
---|---|---|
committer | Max Horn | 2011-01-06 21:11:24 +0000 |
commit | 4b2f92b5e56a1fc273c8c8d2e69b747f938ea92f (patch) | |
tree | 47b453d24a6b96c85303e239d5559a62109a33ce /engines/agi/predictive.cpp | |
parent | fc130351f3cd5ca53607d109e31948dddc6db4a3 (diff) | |
download | scummvm-rg350-4b2f92b5e56a1fc273c8c8d2e69b747f938ea92f.tar.gz scummvm-rg350-4b2f92b5e56a1fc273c8c8d2e69b747f938ea92f.tar.bz2 scummvm-rg350-4b2f92b5e56a1fc273c8c8d2e69b747f938ea92f.zip |
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
Diffstat (limited to 'engines/agi/predictive.cpp')
-rw-r--r-- | engines/agi/predictive.cpp | 52 |
1 files changed, 21 insertions, 31 deletions
diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp index 3ab3f31e03..0230b9bd74 100644 --- a/engines/agi/predictive.cpp +++ b/engines/agi/predictive.cpp @@ -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, " "); - - // 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 + // If the currently entered text is too long, it cannot match anything. + if (_currentCode.size() > MAXWORDLEN) + return false; + + // 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); |