aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMax Horn2011-01-06 21:11:24 +0000
committerMax Horn2011-01-06 21:11:24 +0000
commit4b2f92b5e56a1fc273c8c8d2e69b747f938ea92f (patch)
tree47b453d24a6b96c85303e239d5559a62109a33ce /engines
parentfc130351f3cd5ca53607d109e31948dddc6db4a3 (diff)
downloadscummvm-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')
-rw-r--r--engines/agi/predictive.cpp52
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);