DEVTOOLS: Adapt create_project for new configure.engine files.

I could not try any generated project files since I do not have access to
the IDEs.
This commit is contained in:
Johannes Schickel 2013-11-07 12:58:34 +01:00 committed by D G Turner
parent ef85456859
commit 6e29e1abee
2 changed files with 152 additions and 58 deletions

View file

@ -81,22 +81,6 @@ std::string unifyPath(const std::string &path);
* @param exe Name of the executable.
*/
void displayHelp(const char *exe);
/**
* Structure for describing an FSNode. This is a very minimalistic
* description, which includes everything we need.
* It only contains the name of the node and whether it is a directory
* or not.
*/
struct FSNode {
FSNode() : name(), isDirectory(false) {}
FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {}
std::string name; ///< Name of the file system node
bool isDirectory; ///< Whether it is a directory or not
};
typedef std::list<FSNode> FileList;
} // End of anonymous namespace
enum ProjectType {
@ -128,7 +112,7 @@ int main(int argc, char *argv[]) {
setup.filePrefix = setup.srcDir;
setup.outputDir = '.';
setup.engines = parseConfigure(setup.srcDir);
setup.engines = parseEngines(setup.srcDir);
if (setup.engines.empty()) {
std::cout << "WARNING: No engines found in configure file or configure file missing in \"" << setup.srcDir << "\"\n";
@ -672,47 +656,51 @@ void displayHelp(const char *exe) {
}
/**
* Try to parse a given line and create an engine definition
* out of the result.
* Parse the configure.engine file of a given engine directory and return a
* list of all defined engines.
*
* This may take *any* input line, when the line is not used
* to define an engine the result of the function will be "false".
*
* Note that the contents of "engine" are undefined, when this
* function returns "false".
*
* @param line Text input line.
* @param engine Reference to an object, where the engine information
* is to be stored in.
* @return "true", when parsing succeeded, "false" otherwise.
* @param engineDir The directory of the engine.
* @return The list of all defined engines.
*/
bool parseEngine(const std::string &line, EngineDesc &engine);
EngineDescList parseEngineConfigure(const std::string &engineDir);
/**
* Compares two FSNode entries in a strict-weak fashion based on the name.
*
* @param left The first operand.
* @param right The second operand.
* @return "true" when the name of the left operand is strictly smaller than
* the name of the second operand. "false" otherwise.
*/
bool compareFSNode(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right);
} // End of anonymous namespace
EngineDescList parseConfigure(const std::string &srcDir) {
std::string configureFile = srcDir + "/engines/configure.engines";
EngineDescList parseEngines(const std::string &srcDir) {
using CreateProjectTool::FileList;
using CreateProjectTool::listDirectory;
std::ifstream configure(configureFile.c_str());
if (!configure)
return EngineDescList();
EngineDescList engineList;
std::string line;
EngineDescList engines;
FileList engineFiles = listDirectory(srcDir + "/engines/");
for (;;) {
std::getline(configure, line);
if (configure.eof())
break;
// Sort file list alphabetically this allows for a nicer order in
// --list-engines output, for example.
engineFiles.sort(&compareFSNode);
if (configure.fail())
error("Failed while reading from " + configureFile);
for (FileList::const_iterator i = engineFiles.begin(), end = engineFiles.end(); i != end; ++i) {
// Each engine requires its own sub directory thus we will skip all
// non directory file nodes here.
if (!i->isDirectory) {
continue;
}
EngineDesc desc;
if (parseEngine(line, desc))
engines.push_back(desc);
// Retrieve all engines defined in this sub directory and add them to
// the list of all engines.
EngineDescList list = parseEngineConfigure(srcDir + "/engines/" + i->name);
engineList.splice(engineList.end(), list);
}
return engines;
return engineList;
}
bool isSubEngine(const std::string &name, const EngineDescList &engines) {
@ -777,6 +765,21 @@ StringList getEngineDefines(const EngineDescList &engines) {
}
namespace {
/**
* Try to parse a given line and create an engine definition
* out of the result.
*
* This may take *any* input line, when the line is not used
* to define an engine the result of the function will be "false".
*
* Note that the contents of "engine" are undefined, when this
* function returns "false".
*
* @param line Text input line.
* @param engine Reference to an object, where the engine information
* is to be stored in.
* @return "true", when parsing succeeded, "false" otherwise.
*/
bool parseEngine(const std::string &line, EngineDesc &engine) {
// Format:
// add_engine engine_name "Readable Description" enable_default ["SubEngineList"]
@ -799,6 +802,36 @@ bool parseEngine(const std::string &line, EngineDesc &engine) {
return true;
}
EngineDescList parseEngineConfigure(const std::string &engineDir) {
std::string configureFile = engineDir + "/configure.engine";
std::ifstream configure(configureFile.c_str());
if (!configure)
return EngineDescList();
std::string line;
EngineDescList engines;
for (;;) {
std::getline(configure, line);
if (configure.eof())
break;
if (configure.fail())
error("Failed while reading from " + configureFile);
EngineDesc desc;
if (parseEngine(line, desc))
engines.push_back(desc);
}
return engines;
}
bool compareFSNode(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right) {
return left.name < right.name;
}
} // End of anonymous namespace
TokenList tokenize(const std::string &input, char separator) {
@ -1048,13 +1081,6 @@ bool compareNodes(const FileNode *l, const FileNode *r) {
}
}
/**
* Returns a list of all files and directories in the specified
* path.
*
* @param dir Directory which should be listed.
* @return List of all children.
*/
FileList listDirectory(const std::string &dir) {
FileList result;
#ifdef USE_WIN32_API
@ -1242,6 +1268,12 @@ void ProjectProvider::createProject(BuildSetup &setup) {
// Create other misc. build files
createOtherBuildFiles(setup);
// In case we create the main ScummVM project files we will need to
// generate engines/plugins_table.h too.
if (!setup.tests && !setup.devTools) {
createEnginePluginsTable(setup);
}
}
ProjectProvider::UUIDMap ProjectProvider::createUUIDMap(const BuildSetup &setup) const {
@ -1569,6 +1601,33 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin
error("Malformed file " + moduleMkFile);
}
void ProjectProvider::createEnginePluginsTable(const BuildSetup &setup) {
const std::string enginePluginsTableFile = setup.outputDir + "/engines/plugins_table.h";
std::ofstream enginePluginsTable(enginePluginsTableFile.c_str());
if (!enginePluginsTable) {
error("Could not open \"" + enginePluginsTableFile + "\" for writing");
}
enginePluginsTable << "/* This file is automatically generated by create_project */\n"
<< "/* DO NOT EDIT MANUALLY */\n"
<< "// This file is being included by \"base/plugins.cpp\"\n";
for (EngineDescList::const_iterator i = setup.engines.begin(), end = setup.engines.end(); i != end; ++i) {
// We ignore all sub engines here because they require no special
// handling.
if (isSubEngine(i->name, setup.engines)) {
continue;
}
// Make the engine name all uppercase.
std::string engineName;
std::transform(i->name.begin(), i->name.end(), std::back_inserter(engineName), toupper);
enginePluginsTable << "#if PLUGIN_ENABLED_STATIC(" << engineName << ")\n"
<< "LINK_PLUGIN(" << engineName << ")\n"
<< "#endif\n";
}
}
} // End of anonymous namespace
void error(const std::string &message) {

View file

@ -102,16 +102,17 @@ struct EngineDesc {
typedef std::list<EngineDesc> EngineDescList;
/**
* This function parses the project configure file and creates a list
* of available engines.
* This function parses the project directory and creates a list of
* available engines.
*
* It will also automatically setup the default build state (enabled
* or disabled) to the state specified in the "configure" file.
* or disabled) to the state specified in the individual configure.engine
* files.
*
* @param srcDir Path to the root of the project source.
* @return List of available engines.
*/
EngineDescList parseConfigure(const std::string &srcDir);
EngineDescList parseEngines(const std::string &srcDir);
/**
* Checks whether the specified engine is a sub engine. To determine this
@ -262,6 +263,22 @@ void NORETURN_PRE error(const std::string &message) NORETURN_POST;
namespace CreateProjectTool {
/**
* Structure for describing an FSNode. This is a very minimalistic
* description, which includes everything we need.
* It only contains the name of the node and whether it is a directory
* or not.
*/
struct FSNode {
FSNode() : name(), isDirectory(false) {}
FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {}
std::string name; ///< Name of the file system node
bool isDirectory; ///< Whether it is a directory or not
};
typedef std::list<FSNode> FileList;
/**
* Gets a proper sequence of \t characters for the given
* indentation level.
@ -314,6 +331,15 @@ bool producesObjectFile(const std::string &fileName);
*/
std::string toString(int num);
/**
* Returns a list of all files and directories in the specified
* path.
*
* @param dir Directory which should be listed.
* @return List of all children.
*/
FileList listDirectory(const std::string &dir);
/**
* Structure representing a file tree. This contains two
* members: name and children. "name" holds the name of
@ -474,6 +500,15 @@ protected:
* @return A new UUID as string.
*/
std::string createUUID() const;
private:
/**
* This creates the engines/plugins_table.h file required for building
* ScummVM.
*
* @param setup Description of the desired build.
*/
void createEnginePluginsTable(const BuildSetup &setup);
};
} // End of CreateProjectTool namespace