[Scummvm-cvs-logs] SF.net SVN: scummvm:[49097] scummvm/trunk/engines/sci/console.cpp

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Wed May 19 15:32:27 CEST 2010


Revision: 49097
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49097&view=rev
Author:   m_kiewitz
Date:     2010-05-19 13:32:27 +0000 (Wed, 19 May 2010)

Log Message:
-----------
SCI: changing debugger commands to not require "?"-prefix for objects anymore. It's now also possible to use 0x prefix for hexadecimal values e.g. "vo 0x13", "vo 13h", "vo theSound", "vo 12f:34f" is now possible

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2010-05-19 12:34:10 UTC (rev 49096)
+++ scummvm/trunk/engines/sci/console.cpp	2010-05-19 13:32:27 UTC (rev 49097)
@@ -2769,74 +2769,144 @@
 
 		// Finally, after the colon comes the offset
 		offsetStr = colon + 1;
-	} else if (*str == '?') {	// Object by name: "?OBJ" or "?OBJ.INDEX" or "?OBJ.INDEX+OFFSET" or "?OBJ.INDEX-OFFSET"
-		// The (optional) index can be used to distinguish multiple object with the same name.
-		int index = -1;
 
-		// Skip over the leading question mark '?'
-		str++;
+	} else {
+		// Now we either got an object name, or segment:offset or plain value
+		//  segment:offset is recognized by the ":"
+		//  plain value may be "123" or "123h" or "fffh" or "0xfff"
+		//  object name is assumed if nothing else matches or a "?" is used as prefix as override
+		//  object name may contain "+", "-" and "." for relative calculations, those chars are used nowhere else
 
-		// Look for an offset. It starts with + or -
-		relativeOffset = true;
-		offsetStr = strchr(str, '+');
-		if (!offsetStr)	// No + found, look for -
-			offsetStr = strchr(str, '-');
+		// First we cycle through the string counting special chars
+		const char *strLoop = str;
+		int charsCount = strlen(str);
+		int charsCountObject = 0;
+		int charsCountSegmentOffset = 0;
+		int charsCountLetter = 0;
+		int charsCountNumber = 0;
+		bool charsForceHex = false;
+		bool charsForceObject = false;
 
-		// Strip away the offset and the leading '?'
-		Common::String str_objname;
-		if (offsetStr)
-			str_objname = Common::String(str, offsetStr);
-		else
-			str_objname = str;
+		while (*strLoop) {
+			switch (*strLoop) {
+			case '+':
+			case '-':
+			case '.':
+				charsCountObject++;
+				break;
+			case '?':
+				if (strLoop == str) {
+					charsForceObject = true;
+					str++; // skip over prefix
+				}
+				break;
+			case ':':
+				charsCountSegmentOffset++;
+				break;
+			case 'h':
+				if (*(strLoop + 1) == 0)
+					charsForceHex = true;
+				else
+					charsCountObject++;
+				break;
+			case '0':
+				if (*(strLoop + 1) == 'x') {
+					str += 2; // skip "0x"
+					strLoop++; // skip "x"
+					charsForceHex = true;
+				}
+				charsCountNumber++;
+				break;
+			default:
+				if ((*strLoop >= '0') && (*strLoop <= '9'))
+					charsCountNumber++;
+				if ((*strLoop >= 'a') && (*strLoop <= 'f'))
+					charsCountLetter++;
+				if ((*strLoop >= 'A') && (*strLoop <= 'F'))
+					charsCountLetter++;
+				if ((*strLoop >= 'i') && (*strLoop <= 'z'))
+					charsCountObject++;
+				if ((*strLoop >= 'I') && (*strLoop <= 'Z'))
+					charsCountObject++;
+			}
+			strLoop++;
+		}
 
+		if ((charsCountObject) && (charsCountSegmentOffset))
+			return 1; // input doesn't make sense
 
-		// Scan for a period, after which (if present) we'll find an index
-		const char *tmp = Common::find(str_objname.begin(), str_objname.end(), '.');
-		if (tmp != str_objname.end()) {
-			index = strtol(tmp + 1, &endptr, 16);
-			if (*endptr)
-				return -1;
-			// Chop of the index
-			str_objname = Common::String(str_objname.c_str(), tmp);
-		}
+		if (!charsForceObject) {
+			// input may be values/segment:offset
 
-		// Now all values are available; iterate over all objects.
+			if (charsCountSegmentOffset) {
+				// ':' found, so must be segment:offset
+				const char *colon = strchr(str, ':');
 
-		*dest = s->_segMan->findObjectByName(str_objname, index);
-		if (dest->isNull())
-			return 1;
+				offsetStr = colon + 1;
 
-	} else {	// Finally, check for "SEGMENT:OFFSET" or just "OFFSET"
-		const char *colon = strchr(str, ':');
+				Common::String segmentStr(str, colon);
+				dest->segment = strtol(segmentStr.c_str(), &endptr, 16);
+				if (*endptr)
+					return 1;
+			} else {
+				int val = 0;
+				dest->segment = 0;
 
-		if (!colon) {
-			// No segment specified
-			if (mayBeValue) {
-				// We assume that this is not an offset, but a straight (decimal) value
-				int val;
-				int length = strlen(str);
-				const char *lastchar = str + length - (length ? 1 : 0);
-				if (*lastchar != 'h') {
+				if (charsCountNumber == charsCount) {
+					// Only numbers in input, assume decimal value
 					val = strtol(str, &endptr, 10);
 					if (*endptr)
-						return 1;
+						return 1; // strtol failed?
+					dest->offset = val;
+					return 0;
 				} else {
-					val = strtol(str, &endptr, 16);
-					if (endptr != lastchar)
-						return 1;
+					// We also got letters, check if there were only hexadecimal letters and '0x' at the start or 'h' at the end
+					if ((charsForceHex) && (!charsCountObject)) {
+						val = strtol(str, &endptr, 16);
+						if ((*endptr != 'h') && (*endptr != 0))
+							return 1;
+						dest->offset = val;
+						return 0;
+					} else {
+						// Something else was in input, assume object name
+						charsForceObject = true;
+					}
 				}
-				dest->offset = val;
-			} else {
-				// We require an address, so interpret it as an offset (hexadecimal)
-				offsetStr = str;
 			}
-			dest->segment = 0;
-		} else {
-			offsetStr = colon + 1;
+		}
 
-			Common::String segmentStr(str, colon);
-			dest->segment = strtol(segmentStr.c_str(), &endptr, 16);
-			if (*endptr)
+		if (charsForceObject) {
+			// We assume now that input is object name
+			// Object by name: "?OBJ" or "?OBJ.INDEX" or "?OBJ.INDEX+OFFSET" or "?OBJ.INDEX-OFFSET"
+			// The (optional) index can be used to distinguish multiple object with the same name.
+			int index = -1;
+
+			// Look for an offset. It starts with + or -
+			relativeOffset = true;
+			offsetStr = strchr(str, '+');
+			if (!offsetStr)	// No + found, look for -
+				offsetStr = strchr(str, '-');
+
+			// Strip away the offset and the leading '?'
+			Common::String str_objname;
+			if (offsetStr)
+				str_objname = Common::String(str, offsetStr);
+			else
+				str_objname = str;
+
+			// Scan for a period, after which (if present) we'll find an index
+			const char *tmp = Common::find(str_objname.begin(), str_objname.end(), '.');
+			if (tmp != str_objname.end()) {
+				index = strtol(tmp + 1, &endptr, 16);
+				if (*endptr)
+					return -1;
+				// Chop of the index
+				str_objname = Common::String(str_objname.c_str(), tmp);
+			}
+
+			// Now all values are available; iterate over all objects.
+			*dest = s->_segMan->findObjectByName(str_objname, index);
+			if (dest->isNull())
 				return 1;
 		}
 	}


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