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
|