[Scummvm-cvs-logs] SF.net SVN: scummvm:[50487] scummvm/trunk/engines/sci/engine

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Tue Jun 29 12:39:14 CEST 2010


Revision: 50487
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50487&view=rev
Author:   m_kiewitz
Date:     2010-06-29 10:39:13 +0000 (Tue, 29 Jun 2010)

Log Message:
-----------
SCI: print out actual and supposed parameter types when having a kernel call signature mismatch

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/kernel.cpp
    scummvm/trunk/engines/sci/engine/kernel.h

Modified: scummvm/trunk/engines/sci/engine/kernel.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.cpp	2010-06-29 09:02:59 UTC (rev 50486)
+++ scummvm/trunk/engines/sci/engine/kernel.cpp	2010-06-29 10:39:13 UTC (rev 50487)
@@ -669,40 +669,108 @@
 	}
 }
 
+struct SignatureDebugType {
+	char typeCheck;
+	const char *text;
+};
+
+static const SignatureDebugType signatureDebugTypeList[] = {
+	{ KSIG_NULL,       "null" },
+	{ KSIG_ARITHMETIC, "value" },
+	{ KSIG_OBJECT,     "object" },
+	{ KSIG_REF,        "reference" },
+	{ KSIG_LIST,       "list" },
+	{ KSIG_NODE,       "node" },
+	{ 0,               NULL }
+};
+
+static void kernelSignatureDebugType(const char type) {
+	bool firstPrint = true;
+
+	const SignatureDebugType *list = signatureDebugTypeList;
+	while (list->typeCheck) {
+		if (type & list->typeCheck) {
+			if (!firstPrint)
+				printf(", ");
+			printf("%s", list->text);
+			firstPrint = false;
+		}
+		list++;
+	}
+}
+
+// Shows kernel call signature and current arguments for debugging purposes
+void Kernel::signatureDebug(const char *sig, int argc, const reg_t *argv) {
+	int argnr = 0;
+	while (*sig || argc) {
+		printf("parameter %d: ", argnr++);
+		if (argc) {
+			reg_t parameter = *argv;
+			printf("%04x:%04x (", PRINT_REG(parameter));
+			kernelSignatureDebugType(findRegType(parameter));
+			printf(")");
+			argv++;
+			argc--;
+		} else {
+			printf("not passed");
+		}
+		if (*sig) {
+			const char signature = *sig;
+			if ((signature & KSIG_ANY) == KSIG_ANY) {
+				printf(", may be any");
+			} else {
+				printf(", should be ");
+				kernelSignatureDebugType(signature);
+			}
+			if (signature & KSIG_ELLIPSIS)
+				printf(" (optional)");
+			sig++;
+		}
+		printf("\n");
+	}
+}
+
 bool Kernel::signatureMatch(const char *sig, int argc, const reg_t *argv) {
+	const char *checkSig = sig;
+	const reg_t *checkParam = argv;
+	int checkCount = argc;
 	// Always "match" if no signature is given
 	if (!sig)
 		return true;
 
-	while (*sig && argc) {
-		if ((*sig & KSIG_ANY) != KSIG_ANY) {
-			int type = findRegType(*argv);
+	while (*checkSig && checkCount) {
+		if ((*checkSig & KSIG_ANY) != KSIG_ANY) {
+			int type = findRegType(*checkParam);
 
 			if (!type) {
-				warning("[KERN] Could not determine type of ref %04x:%04x; failing signature check", PRINT_REG(*argv));
+				warning("[KERNEL] call signature: couldn't determine type of ref %04x:%04x", PRINT_REG(*argv));
+				signatureDebug(sig, argc, argv);
 				return false;
 			}
 
-			if (!(type & *sig)) {
-				warning("kernel_matches_signature: %d args left, is %d, should be %d", argc, type, *sig);
+			if (!(type & *checkSig)) {
+				warning("[KERNEL] call signature: %d args left, is %d, should be %d", argc, type, *sig);
+				signatureDebug(sig, argc, argv);
 				return false;
 			}
 
 		}
-		if (!(*sig & KSIG_ELLIPSIS))
-			++sig;
-		++argv;
-		--argc;
+		if (!(*checkSig & KSIG_ELLIPSIS))
+			++checkSig;
+		++checkParam;
+		--checkCount;
 	}
 
-	if (argc) {
-		warning("kernel_matches_signature: too many arguments");
+	if (checkCount) {
+		warning("[KERNEL] call signature: too many arguments");
+		signatureDebug(sig, argc, argv);
 		return false; // Too many arguments
 	}
-	if (*sig == 0 || (*sig & KSIG_ELLIPSIS))
+	if (*checkSig == 0 || (*checkSig & KSIG_ELLIPSIS))
 		return true;
 
-	warning("kernel_matches_signature: too few arguments");
+	warning("[KERNEL] call signature: too few arguments");
+	signatureDebug(sig, argc, argv);
 	return false;
 }
 

Modified: scummvm/trunk/engines/sci/engine/kernel.h
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.h	2010-06-29 09:02:59 UTC (rev 50486)
+++ scummvm/trunk/engines/sci/engine/kernel.h	2010-06-29 10:39:13 UTC (rev 50487)
@@ -169,6 +169,9 @@
 	 */
 	bool signatureMatch(const char *sig, int argc, const reg_t *argv);
 
+	// Prints out debug information in case a signature check fails
+	void signatureDebug(const char *sig, int argc, const reg_t *argv);
+
 	/**
 	 * Determines the type of the object indicated by reg.
 	 * @param reg				register to check


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