File: command.h

package info (click to toggle)
residualvm 0.3.1%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: bullseye
  • size: 31,292 kB
  • sloc: cpp: 227,029; sh: 7,256; xml: 1,731; perl: 1,067; java: 861; asm: 738; python: 691; ansic: 272; makefile: 139; objc: 81; sed: 22; php: 1
file content (180 lines) | stat: -rw-r--r-- 5,178 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* ResidualVM - A 3D game interpreter
 *
 * ResidualVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the AUTHORS
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef STARK_TOOLS_COMMAND_H
#define STARK_TOOLS_COMMAND_H

#include "common/array.h"
#include "common/hashmap.h"

#include "engines/stark/hash-ptr.h"
#include "engines/stark/resources/command.h"

namespace Stark {
namespace Tools {

class Block;
class DefinitionRegistry;

/**
 * A base script command for disassembly use
 *
 * As opposed to the Command class in the Resources namespace, this class
 * is not meant to be executed. It is meant to be used for script disassembly,
 * to store analysis results.
 */
class Command {
public:
	enum ControlFlowType {
		kFlowNormal,
		kFlowBranch,
		kFlowEnd
	};
	typedef Common::Array<Resources::Command::Argument> ArgumentArray;

	Command(Command *command);
	Command(Resources::Command *resource);

	/**
	 * Print a call to this command to the debug output
	 */
	void printCall() const;

	/** This command's resource tree index */
	uint16 getIndex() const;
	Resources::Command::SubType getSubType() const;
	bool hasSubtypeDescription() const;

	/** List the command's arguments ignoring the control flow related ones */
	ArgumentArray getEffectiveArguments() const;

protected:
	struct SubTypeDesc {
		Resources::Command::SubType subType;
		const char *name;
		ControlFlowType controlFlowType;
	};

	/** Get a description for a command subtype from an internal database */
	static const SubTypeDesc *searchSubTypeDesc(Resources::Command::SubType subType);

	/** List the arguments values as a coma separated string */
	Common::String describeArguments(DefinitionRegistry *definitions) const;

	uint16 _index;
	Resources::Command::SubType _subType;
	const SubTypeDesc *_subTypeDesc;
	ArgumentArray _arguments;
};

/**
 * A script command with control flow information
 *
 * This class is a node in the disassembly command control flow graph.
 * It is referenced by the blocks in the block control flow graph.
 */
class CFGCommand : public Command {
public:
	CFGCommand(Resources::Command *resource);

	/** Is this command an entry point for the whole script? */
	bool isEntryPoint() const;

	/** Can this command influence the control flow? */
	bool isBranch() const;

	/** Is this command a jump target? */
	bool isBranchTarget() const;

	/**
	 * Commands are linked together in the command graph with these relationships:
	 * - follower: The natural follower of the command. Used when the command is not a branch, nor an end point.
	 * - true branch: The next command when the command's condition evaluates to true.
	 * - false branch: The next command when the command's condition evaluates to false.
	 * - predecessors: A list of commands whose execution can lead to this command.
	 */
	CFGCommand *getFollower() const;
	CFGCommand *getTrueBranch() const;
	CFGCommand *getFalseBranch() const;

	/**
	 * Commands are aggregated into blocks
	 */
	Block *getBlock() const;
	void setBlock(Block *block);

	/**
	 * Add the command to the command graph
	 *
	 * This sets the graph edges concerning this command.
	 */
	void linkBranches(const Common::Array<CFGCommand *> &commands);

protected:
	/** Set the link indices from the argument values */
	void initBranches();

	/** Gets the command with the specifed index */
	static CFGCommand *findCommandWithIndex(const Common::Array<CFGCommand *> &commands, int32 index);

	int32 _followerIndex;
	int32 _trueBranchIndex;
	int32 _falseBranchIndex;

	CFGCommand *_follower;
	CFGCommand *_trueBranch;
	CFGCommand *_falseBranch;
	Common::Array<CFGCommand *> _predecessors;

	Block *_block;
};

/**
 * Storage for aliases between world resources and names
 */
class DefinitionRegistry {
public:
	/**
	 * Add a definition from a reference
	 *
	 * The name is computed from the object's name
	 */
	void registerReference(const ResourceReference &reference);

	/** Get a previously registered definition from a reference */
	Common::String getFromReference(const ResourceReference &reference) const;

	/** Print all the registered definitions */
	void printAll() const;

private:
	typedef Common::HashMap<Resources::Object *, Common::String> DefinitionMap;

	Common::String stringToCamelCase(const Common::String &input);

	DefinitionMap _definitions;
};

} // End of namespace Tools
} // End of namespace Stark

#endif // STARK_TOOLS_COMMAND_H