[Scummvm-cvs-logs] SF.net SVN: scummvm: [24925] tools/trunk

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Tue Dec 26 00:05:09 CET 2006


Revision: 24925
          http://scummvm.svn.sourceforge.net/scummvm/?rev=24925&view=rev
Author:   fingolfin
Date:     2006-12-25 15:05:07 -0800 (Mon, 25 Dec 2006)

Log Message:
-----------
cleanup

Modified Paths:
--------------
    tools/trunk/descumm-common.cpp
    tools/trunk/descumm-tool.cpp
    tools/trunk/descumm.cpp
    tools/trunk/descumm.h
    tools/trunk/descumm6.cpp

Modified: tools/trunk/descumm-common.cpp
===================================================================
--- tools/trunk/descumm-common.cpp	2006-12-25 17:21:54 UTC (rev 24924)
+++ tools/trunk/descumm-common.cpp	2006-12-25 23:05:07 UTC (rev 24925)
@@ -24,12 +24,8 @@
 #include "descumm.h"
 
 
-#define BLOCK_STACK_SIZE	256
+BlockStack g_blockStack;
 
-
-BlockStack *block_stack;
-int num_block_stack;
-
 bool pendingElse, haveElse;
 int pendingElseTo;
 int pendingElseOffs;
@@ -101,163 +97,107 @@
 
 ///////////////////////////////////////////////////////////////////////////
 
-#define INDENT_SIZE 2
+void outputLine(const char *buf, int curoffs, int opcode, int indent) {
 
-static char indentbuf[127 * INDENT_SIZE + 1];
-
-// Generate a string with white spaces for the given indention level.
-// For each level, INDENT_SIZE spaces are inserted.
-char *getIndentString(int level)
-{
-	if (level >= 127)
-		level = 127;
-	if (level < 0)
-		level = 0;
-
-	level *= INDENT_SIZE;
-
-	memset(indentbuf, ' ', level);
-	indentbuf[level] = 0;
-	return indentbuf;
-}
-
-void outputLine(const char *buf, int curoffs, int opcode, int indent)
-{
-	char *s;
-
 	if (buf[0]) {
-		if (indent == -1)
-			indent = num_block_stack;
-		if (curoffs == -1)
-			curoffs = get_curoffs();
+		assert(curoffs >= 0);
+		assert(indent >= 0);
 
-		s = getIndentString(indent);
-
-		if (dontShowOpcode) {
-			if (dontShowOffsets)
-				printf("%s%s\n", s, buf);
-			else
-				printf("[%.4X] %s%s\n", curoffs, s, buf);
-		} else {
-			char buf2[4];
+		// Show the offset
+		if (!dontShowOffsets) {
+			printf("[%.4X] ", curoffs);
+		}
+		
+		// Show the opcode value
+		if (!dontShowOpcode) {
 			if (opcode != -1)
-				sprintf(buf2, "%.2X", opcode);
+				printf("(%.2X) ", opcode);
 			else
-				strcpy(buf2, "**");
-			if (dontShowOffsets)
-				printf("(%s) %s%s\n", buf2, s, buf);
-			else
-				printf("[%.4X] (%s) %s%s\n", curoffs, buf2, s, buf);
+				printf("(**) ");
 		}
-	}
-}
 
-///////////////////////////////////////////////////////////////////////////
+		// Indent the line as requested ...
+		for (int i = 0; i < indent; ++i)
+			printf("  ");
 
-bool indentBlock(unsigned int cur)
-{
-	BlockStack *p;
-
-	if (!num_block_stack)
-		return false;
-
-	p = &block_stack[num_block_stack - 1];
-	if (cur < p->to)
-		return false;
-
-	num_block_stack--;
-	return true;
-}
-
-
-BlockStack *pushBlockStackItem()
-{
-	if (!block_stack)
-		block_stack = (BlockStack *) malloc(BLOCK_STACK_SIZE * sizeof(BlockStack));
-
-	if (num_block_stack >= BLOCK_STACK_SIZE) {
-		error("block_stack full");
+		// ... and finally print the actual code
+		puts(buf);
 	}
-	return &block_stack[num_block_stack++];
 }
 
+///////////////////////////////////////////////////////////////////////////
+
 // Returns 0 or 1 depending if it's ok to add a block
 bool maybeAddIf(uint cur, uint to)
 {
+	Block p;
 	int i;
-	BlockStack *p;
 	
 	if (((to | cur) >> 24) || (to <= cur))
 		return false; // Invalid jump
 	
-	for (i = 0, p = block_stack; i < num_block_stack; i++, p++) {
-		if (to > p->to)
+	for (i = 0; i < g_blockStack.size(); ++i) {
+		if (to > g_blockStack[i].to)
 			return false;
 	}
 	
-	p = pushBlockStackItem();
-
 	// Try to determine if this is a while loop. For this, first check if we 
 	// jump right behind a regular jump, then whether that jump is targeting us.
 	if (scriptVersion == 8) {
-		p->isWhile = (*(byte*)(org_pos+to-5) == g_jump_opcode);
+		p.isWhile = (*(byte*)(org_pos+to-5) == g_jump_opcode);
 		i = (int32)READ_LE_UINT32(org_pos+to-4);
 	} else {
-		p->isWhile = (*(byte*)(org_pos+to-3) == g_jump_opcode);
+		p.isWhile = (*(byte*)(org_pos+to-3) == g_jump_opcode);
 		i = (int16)READ_LE_UINT16(org_pos+to-2);
 	}
 	
-	p->isWhile = p->isWhile && (offs_of_line == (int)to + i);
-	p->from = cur;
-	p->to = to;
+	p.isWhile = p.isWhile && (offs_of_line == (int)to + i);
+	p.from = cur;
+	p.to = to;
+	
+	g_blockStack.push(p);
+	
 	return true;
 }
 
 // Returns 0 or 1 depending if it's ok to add an else
-bool maybeAddElse(uint cur, uint to)
-{
+bool maybeAddElse(uint cur, uint to) {
 	int i;
-	BlockStack *p;
 
 	if (((to | cur) >> 16) || (to <= cur))
 		return false;								/* Invalid jump */
 
-	if (!num_block_stack)
+	if (g_blockStack.empty())
 		return false;								/* There are no previous blocks, so an else is not ok */
 
-	p = &block_stack[num_block_stack - 1];
-	if (cur != p->to)
+	if (cur != g_blockStack.top().to)
 		return false;								/* We have no prevoius if that is exiting right at the end of this goto */
 
 	// Don't jump out of previous blocks. In addition, don't jump "onto"
 	// the end of a while loop, as that would lead to incorrect output.
 	// This test is stronger than the one in maybeAddIf.
-	for (i = 0, p = block_stack; i < num_block_stack - 1; i++, p++) {
-		if (to > p->to || (to == p->to && p->isWhile))
+	for (i = 0; i < g_blockStack.size() - 1; ++i) {
+		if (to > g_blockStack[i].to || (to == g_blockStack[i].to && g_blockStack[i].isWhile))
 			return false;
 	}
 
-	num_block_stack--;
+	Block tmp = g_blockStack.pop();
 	if (maybeAddIf(cur, to))
 		return true;								/* We can add an else */
-	num_block_stack++;
+	g_blockStack.push(tmp);
 	return false;									/* An else is not OK here :( */
 }
 
-bool maybeAddElseIf(uint cur, uint elseto, uint to)
-{
+bool maybeAddElseIf(uint cur, uint elseto, uint to) {
 	uint k;
-	BlockStack *p;
 
 	if (((to | cur | elseto) >> 16) || (elseto < to) || (to <= cur))
 		return false;								/* Invalid jump */
 
-	if (!num_block_stack)
+	if (g_blockStack.empty())
 		return false;								/* There are no previous blocks, so an ifelse is not ok */
 
-	p = &block_stack[num_block_stack - 1];
-
-	if (p->isWhile)
+	if (g_blockStack.top().isWhile)
 		return false;
 
 	if (scriptVersion == 8)
@@ -280,27 +220,23 @@
 		if (k != elseto)
 			return false;							/* Not an ifelse */
 	}
-	p->from = cur;
-	p->to = to;
+	g_blockStack.top().from = cur;
+	g_blockStack.top().to = to;
 
 	return true;
 }
 
-bool maybeAddBreak(uint cur, uint to)
-{
-	BlockStack *p;
-
+bool maybeAddBreak(uint cur, uint to) {
 	if (((to | cur) >> 16) || (to <= cur))
 		return false;								/* Invalid jump */
 
-	if (!num_block_stack)
+	if (g_blockStack.empty())
 		return false;								/* There are no previous blocks, so a break is not ok */
 
 	/* Find the first parent block that is a while and if we're jumping to the end of that, we use a break */
-	for (int i = num_block_stack - 1; i >= 0; i--) {
-		p = &block_stack[i];
-		if (p->isWhile) {
-			if (to == p->to)
+	for (int i = g_blockStack.size() - 1; i >= 0; --i) {
+		if (g_blockStack[i].isWhile) {
+			if (to == g_blockStack[i].to)
 				return true;
 			else
 				return false;
@@ -310,8 +246,7 @@
 	return false;
 }
 
-void writePendingElse()
-{
+void writePendingElse() {
 	if (pendingElse) {
 		char buf[32];
 		sprintf(buf, alwaysShowOffs ? "} else /*%.4X*/ {" : "} else {", pendingElseTo);

Modified: tools/trunk/descumm-tool.cpp
===================================================================
--- tools/trunk/descumm-tool.cpp	2006-12-25 17:21:54 UTC (rev 24924)
+++ tools/trunk/descumm-tool.cpp	2006-12-25 23:05:07 UTC (rev 24925)
@@ -130,20 +130,10 @@
 	return minOffset;
 }
 
-int main(int argc, char *argv[])
-{
-	FILE *in;
-	byte *mem, *memorg;
-	int len;
-	char *filename, *buf;
+char *parseCommandLine(int argc, char *argv[]) {
+	char *filename = NULL;
 	int i;
 	char *s;
-
-	scriptVersion = 0xff;
-	heVersion = 0;
-	
-	// Parse the arguments
-	filename = NULL;
 	for (i = 1; i < argc; i++) {
 		s = argv[i];
 
@@ -253,7 +243,21 @@
 			filename = s;
 		}
 	}
+	
+	return filename;
+}
 
+int main(int argc, char *argv[]) {
+	FILE *in;
+	byte *mem, *memorg;
+	int len;
+	char *filename;
+
+	scriptVersion = 0xff;
+	heVersion = 0;
+	
+	// Parse the arguments
+	filename = parseCommandLine(argc, argv);
 	if (!filename || scriptVersion == 0xff)
 		ShowHelpAndExit();
 
@@ -263,19 +267,17 @@
 		return 1;
 	}
 
+	// Read the file into memory
 	memorg = mem = (byte *)malloc(MAX_FILE_SIZE);
 	len = fread(mem, 1, MAX_FILE_SIZE, in);
 	fclose(in);
 	size_of_code = len;
 
-	buf = (char *)malloc(8192);
-
 	offs_of_line = 0;
 
 	if (GF_UNBLOCKED) {
 		if (size_of_code < 4) {
-			printf("File too small to be a script\n");
-			return 1;
+			error("File too small to be a script");
 		}
 		// Hack to detect verb script: first 4 bytes should be file length
 		if (READ_LE_UINT32(mem) == size_of_code) {
@@ -288,13 +290,12 @@
 		}
 	} else if (scriptVersion >= 5) {
 		if (size_of_code < (scriptVersion == 5 ? 8 : 9)) {
-			printf("File too small to be a script\n");
-			return 1;
+			error("File too small to be a script");
 		}
 	
 		switch (READ_BE_UINT32(mem)) {
 		case 'LSC2':
-			if (size_of_code < 13) {
+			if (size_of_code <= 12) {
 				printf("File too small to be a local script\n");
 			}
 			printf("Script# %d\n", READ_LE_UINT32(mem+8));
@@ -302,19 +303,19 @@
 			break;											/* Local script */
 		case 'LSCR':
 			if (scriptVersion == 8) {
-				if (size_of_code < 13) {
+				if (size_of_code <= 12) {
 					printf("File too small to be a local script\n");
 				}
 				printf("Script# %d\n", READ_LE_UINT32(mem+8));
 				mem += 12;
 			} else if (scriptVersion == 7) {
-				if (size_of_code < 11) {
+				if (size_of_code <= 10) {
 					printf("File too small to be a local script\n");
 				}
 				printf("Script# %d\n", READ_LE_UINT16(mem+8));
 				mem += 10;
 			} else {
-				if (size_of_code < 10) {
+				if (size_of_code <= 9) {
 					printf("File too small to be a local script\n");
  				}
 				printf("Script# %d\n", (byte)mem[8]);
@@ -338,13 +339,11 @@
 				offs_of_line = skipVerbHeader_V567(mem);
 			break;											/* Verb */
 		default:
-			printf("Unknown script type!\n");
-			return 1;
+			error("Unknown script type");
 		}
 	} else {
 		if (size_of_code < 6) {
-			printf("File too small to be a script\n");
-			return 1;
+			error("File too small to be a script");
 		}
 		switch (READ_BE_UINT16(mem + 4)) {
 		case 'LS':
@@ -364,8 +363,7 @@
 			offs_of_line = skipVerbHeader_V34(mem);
 			break;			/* Verb */
 		default:
-			printf("Unknown script type!\n");
-			return 1;
+			error("Unknown script type");
 		}
 	}
 
@@ -375,45 +373,47 @@
 
 	while (cur_pos < mem + len) {
 		byte opcode = *cur_pos;
-		int j = num_block_stack;
-		buf[0] = 0;
+		int j = g_blockStack.size();
+		char outputLineBuffer[8192] = "";
+
 		switch (scriptVersion) {
 		case 0:
-			next_line_V0(buf);
+			next_line_V0(outputLineBuffer);
 			break;
 		case 1:
 		case 2:
-			next_line_V12(buf);
+			next_line_V12(outputLineBuffer);
 			break;
 		case 3:
 		case 4:
 		case 5:
-			next_line_V345(buf);
+			next_line_V345(outputLineBuffer);
 			break;
 		case 6:
 			if (heVersion)
-				next_line_HE_V72(buf);
+				next_line_HE_V72(outputLineBuffer);
 			else
-				next_line_V67(buf);
+				next_line_V67(outputLineBuffer);
 			break;
 		case 7:
-			next_line_V67(buf);
+			next_line_V67(outputLineBuffer);
 			break;
 		case 8:
-			next_line_V8(buf);
+			next_line_V8(outputLineBuffer);
 			break;
 		}
-		if (buf[0]) {
+		if (outputLineBuffer[0]) {
 			writePendingElse();
 			if (haveElse) {
 				haveElse = false;
 				j--;
 			}
-			outputLine(buf, offs_of_line, opcode, j);
+			outputLine(outputLineBuffer, offs_of_line, opcode, j);
 			offs_of_line = get_curoffs();
 		}
-		while (indentBlock(get_curoffs())) {
-			outputLine("}", offs_of_line, -1, -1);
+		while (!g_blockStack.empty() && get_curoffs() >= (int)g_blockStack.top().to) {
+			g_blockStack.pop();
+			outputLine("}", offs_of_line, -1, g_blockStack.size());
 			offs_of_line = get_curoffs();
 		}
 		fflush(stdout);
@@ -427,9 +427,9 @@
 		if (num_stack > 0) {
 			printf("Stack contents:\n");
 			while (num_stack) {
-				buf[0] = 0;
-				se_astext(pop(), buf);
-				printf("%s\n", buf);
+				outputLineBuffer[0] = 0;
+				se_astext(pop(), outputLineBuffer);
+				printf("%s\n", outputLineBuffer);
 			}
 		}
 	}

Modified: tools/trunk/descumm.cpp
===================================================================
--- tools/trunk/descumm.cpp	2006-12-25 17:21:54 UTC (rev 24924)
+++ tools/trunk/descumm.cpp	2006-12-25 23:05:07 UTC (rev 24925)
@@ -1563,12 +1563,12 @@
 		pendingElseTo = to;
 		pendingElseOffs = cur;
 		pendingElseOpcode = g_jump_opcode;
-		pendingElseIndent = num_block_stack;
+		pendingElseIndent = g_blockStack.size();
 		buf[0] = 0;
 	} else {
-		if (num_block_stack && !dontOutputWhile) {
-			BlockStack *p = &block_stack[num_block_stack - 1];
-			if (p->isWhile && cur == (int)p->to)
+		if (!g_blockStack.empty() && !dontOutputWhile) {
+			Block p = g_blockStack.top();
+			if (p.isWhile && cur == (int)p.to)
 				return;		// A 'while' ends here.
 		}
 		sprintf(buf, "goto %.4X;", to);
@@ -1593,7 +1593,7 @@
 	}
 
 	if (!dontOutputIfs && maybeAddIf(cur, to)) {
-		if (!dontOutputWhile && block_stack[num_block_stack - 1].isWhile) {
+		if (!dontOutputWhile && g_blockStack.top().isWhile) {
 			buf = strecpy(buf, "while (");
 		} else
 			buf = strecpy(buf, "if (");

Modified: tools/trunk/descumm.h
===================================================================
--- tools/trunk/descumm.h	2006-12-25 17:21:54 UTC (rev 24924)
+++ tools/trunk/descumm.h	2006-12-25 23:05:07 UTC (rev 24925)
@@ -35,18 +35,67 @@
 
 typedef unsigned int uint;
 
+/**
+ * Extremly simple fixed size stack class.
+ */
+template <class T, int MAX_SIZE = 10>
+class FixedStack {
+protected:
+	T	_stack[MAX_SIZE];
+	int	_size;
+public:
+	FixedStack<T, MAX_SIZE>() : _size(0) {}
+
+	bool empty() const {
+		return _size <= 0;
+	}
+	void clear() {
+		_size = 0;
+	}
+	void push(const T& x) {
+		assert(_size < MAX_SIZE);
+		_stack[_size++] = x;
+	}
+	const T& top() const {
+		assert(_size > 0);
+		return _stack[_size - 1];
+	}
+	T& top() {
+		assert(_size > 0);
+		return _stack[_size - 1];
+	}
+	T pop() {
+		T tmp = top();
+		--_size;
+		return tmp;
+	}
+	int size() const {
+		return _size;
+	}
+	T& operator [](int i) {
+		assert(0 <= i && i < MAX_SIZE);
+		return _stack[i];
+	}
+	const T& operator [](int i) const {
+		assert(0 <= i && i < MAX_SIZE);
+		return _stack[i];
+	}
+};
+
 //
 // The block stack records jump instructions
 //
-struct BlockStack {
+struct Block {
 	uint from;	// From which offset...
 	uint to;		// ...to which offset
 	bool isWhile;			// Set to true if we think this jump is part of a while loop
 };
 
-extern BlockStack *block_stack;
-extern int num_block_stack;
+typedef FixedStack<Block, 256> BlockStack;
 
+extern BlockStack g_blockStack;
+
+
 //
 // Jump decoding auxillaries (used by the code which tries to translate jumps
 // back into if / else / while / etc. constructs).
@@ -102,7 +151,6 @@
 //
 
 extern void outputLine(const char *buf, int curoffs, int opcode, int indent);
-extern bool indentBlock(unsigned int cur);
 
 extern char *strecpy(char *buf, const char *src);
 extern int get_curoffs();

Modified: tools/trunk/descumm6.cpp
===================================================================
--- tools/trunk/descumm6.cpp	2006-12-25 17:21:54 UTC (rev 24924)
+++ tools/trunk/descumm6.cpp	2006-12-25 23:05:07 UTC (rev 24925)
@@ -1331,11 +1331,11 @@
 		pendingElseTo = to;
 		pendingElseOffs = cur;
 		pendingElseOpcode = g_jump_opcode;
-		pendingElseIndent = num_block_stack;
+		pendingElseIndent = g_blockStack.size();
 	} else {
-		if (num_block_stack && !dontOutputWhile) {
-			BlockStack *p = &block_stack[num_block_stack - 1];
-			if (p->isWhile && cur == (int)p->to)
+		if (!g_blockStack.empty() && !dontOutputWhile) {
+			Block p = g_blockStack.top();
+			if (p.isWhile && cur == (int)p.to)
 				return;		// A 'while' ends here.
 			if (!dontOutputBreaks && maybeAddBreak(cur, to)) {
 				sprintf(output, "break");
@@ -1365,7 +1365,7 @@
 	}
 
 	if (!dontOutputIfs && maybeAddIf(cur, to)) {
-		if (!dontOutputWhile && block_stack[num_block_stack - 1].isWhile)
+		if (!dontOutputWhile && g_blockStack.top().isWhile)
 			e = strecpy(e, negate ? "until (" : "while (");
 		else
 			e = strecpy(e, negate ? "unless (" : "if (");


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