[Scummvm-cvs-logs] SF.net SVN: scummvm:[55135] scummvm/trunk/engines/agi/predictive.cpp

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Thu Jan 6 22:11:26 CET 2011


Revision: 55135
          http://scummvm.svn.sourceforge.net/scummvm/?rev=55135&view=rev
Author:   fingolfin
Date:     2011-01-06 21:11:24 +0000 (Thu, 06 Jan 2011)

Log Message:
-----------
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.

Modified Paths:
--------------
    scummvm/trunk/engines/agi/predictive.cpp

Modified: scummvm/trunk/engines/agi/predictive.cpp
===================================================================
--- scummvm/trunk/engines/agi/predictive.cpp	2011-01-06 14:30:34 UTC (rev 55134)
+++ scummvm/trunk/engines/agi/predictive.cpp	2011-01-06 21:11:24 UTC (rev 55135)
@@ -555,43 +555,33 @@
 }
 
 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);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list