From 2eeb5a5ac9508e41e6451590d20f1688cf490002 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 12 Jun 2019 19:43:28 +0300 Subject: [PATCH] Add support for generating .cpp files for BuiltinSource --- tool/builtingenerator.cpp | 78 +++++++++++++++++++++++++++++++++++++++ tool/builtingenerator.h | 26 +++++++++++++ tool/copier.h | 17 +++++++++ tool/tool.cpp | 30 ++++++++++++++- tool/tool.h | 4 ++ 5 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 tool/builtingenerator.cpp create mode 100644 tool/builtingenerator.h create mode 100644 tool/copier.h diff --git a/tool/builtingenerator.cpp b/tool/builtingenerator.cpp new file mode 100644 index 0000000..45d5844 --- /dev/null +++ b/tool/builtingenerator.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include "builtingenerator.h" + +using namespace std; +using namespace Msp; + +BuiltinGenerator::BuiltinGenerator(IO::Base &o): + out(o) +{ + out.write("#include \n\n"); +} + +void BuiltinGenerator::begin(const std::string &ns) +{ + if(!namespc.empty() || !filenames.empty()) + throw logic_error("BuiltinGenerator::begin"); + + if(!ns.empty()) + { + namespc = split(ns, "::"); + for(vector::const_iterator i=namespc.begin(); i!=namespc.end(); ++i) + out.write(format("namespace %s {\n", *i)); + } +} + +void BuiltinGenerator::add_file(const std::string &fn) +{ + IO::BufferedFile in(fn); + + string base_fn = FS::basename(fn); + filenames.push_back(base_fn); + + out.write(format("\nconst char %s_data[] =\n", mangle_filename(base_fn))); + string line; + while(!in.eof()) + { + char buf[19]; + unsigned len = in.read(buf, (79-line.size())/4); + line += c_escape(string(buf, len)); + if(line.size()>=76 || in.eof()) + { + out.write(format(" \"%s\"", line)); + line.clear(); + if(in.eof()) + out.put(';'); + out.put('\n'); + } + } +} + +void BuiltinGenerator::end(const string &module_name) +{ + out.write(format("\nvoid init_%s(DataFile::BuiltinSource &source)\n{\n", module_name)); + for(vector::const_iterator i=filenames.begin(); i!=filenames.end(); ++i) + out.write(format(" source.add_object(\"%s\", %s_data);\n", *i, mangle_filename(*i))); + out.write("}\n"); + + if(!namespc.empty()) + { + out.put('\n'); + for(vector::const_iterator i=namespc.begin(); i!=namespc.end(); ++i) + out.write(format("} // namespace %s\n", *i)); + + namespc.clear(); + filenames.clear(); + } +} + +string BuiltinGenerator::mangle_filename(const string &fn) +{ + string mangled = fn; + for(string::iterator i=mangled.begin(); i!=mangled.end(); ++i) + if(!isalnum(*i)) + *i = '_'; + return mangled; +} diff --git a/tool/builtingenerator.h b/tool/builtingenerator.h new file mode 100644 index 0000000..d6a0886 --- /dev/null +++ b/tool/builtingenerator.h @@ -0,0 +1,26 @@ +#ifndef TOOL_BUILTINGENERATOR_H_ +#define TOOL_BUILTINGENERATOR_H_ + +#include +#include +#include + +class BuiltinGenerator +{ +private: + Msp::IO::Base &out; + std::vector namespc; + std::vector filenames; + +public: + BuiltinGenerator(Msp::IO::Base &); + + void begin(const std::string &); + void add_file(const std::string &); + void end(const std::string &); + +private: + static std::string mangle_filename(const std::string &); +}; + +#endif diff --git a/tool/copier.h b/tool/copier.h new file mode 100644 index 0000000..ab5b9c7 --- /dev/null +++ b/tool/copier.h @@ -0,0 +1,17 @@ +#ifndef COPIER_H_ +#define COPIER_H_ + +class Copier +{ +private: + Msp::DataFile::Parser &parser; + Msp::DataFile::Writer &writer; + Msp::DataFile::Statement statement; + +public: + Copier(Msp::DataFile::Parser &, Msp::DataFile::Writer &); + + const Msp::DataFile::Statement ©_statement(); +}; + +#endif diff --git a/tool/tool.cpp b/tool/tool.cpp index 73c49f7..2f52724 100644 --- a/tool/tool.cpp +++ b/tool/tool.cpp @@ -1,10 +1,12 @@ #include +#include #include #include #include #include #include #include +#include "builtingenerator.h" #include "compiler.h" #include "packer.h" #include "tool.h" @@ -27,6 +29,9 @@ DataTool::DataTool(int argc, char **argv): getopt.add_option('c', "compile", compile, GetOpt::NO_ARG).set_help("Create a collection based on a template file"); getopt.add_option('f', "float-size", float_size, GetOpt::REQUIRED_ARG).set_help("Floating-point precision", "BITS"); getopt.add_option('g', "debug", debug, GetOpt::NO_ARG).set_help("Display control statements"); + getopt.add_option('i', "builtin", builtin, GetOpt::NO_ARG).set_help("Generate a source file for a BuiltinSource"); + getopt.add_option('m', "module", builtin_module, GetOpt::REQUIRED_ARG).set_help("Name of the builtin source module"); + getopt.add_option('n', "namespace", builtin_ns, GetOpt::REQUIRED_ARG).set_help("Namespace for the builtin source"); getopt.add_option('o', "output", out_fn, GetOpt::REQUIRED_ARG).set_help("Output to a file instead of stdout", "FILE"); getopt.add_option('p', "pack", pack, GetOpt::NO_ARG).set_help("Create a pack from multiple files"); getopt.add_option('u', "unpack", unpack, GetOpt::NO_ARG).set_help("Unpacks files from packs into the current directory"); @@ -34,8 +39,8 @@ DataTool::DataTool(int argc, char **argv): getopt.add_argument("infile", in_fns, GetOpt::OPTIONAL_ARG).set_help("Files to process"); getopt(argc, argv); - if(compile+pack+unpack>1) - throw usage_error("Only one of -c, -p and -u may be specified"); + if(compile+pack+unpack+builtin>1) + throw usage_error("Only one of -c, -p, -u and -i may be specified"); if(pack && out_fn=="-") throw usage_error("Can't write pack to stdout"); @@ -49,6 +54,14 @@ DataTool::DataTool(int argc, char **argv): if(*i=="-") throw usage_error("Can't unpack from stdout"); } + + if(builtin && builtin_module.empty()) + { + if(out_fn=="-") + throw usage_error("Can't determine builtin module name"); + else + builtin_module = FS::basepart(FS::basename(out_fn)); + } } int DataTool::main() @@ -59,6 +72,8 @@ int DataTool::main() do_unpack(); else if(compile) do_compile(); + else if(builtin) + do_generate_builtin(); else do_transfer(); @@ -139,6 +154,17 @@ void DataTool::do_unpack() } } +void DataTool::do_generate_builtin() +{ + IO::Base *out = open_output(out_fn); + BuiltinGenerator generator(*out); + generator.begin(builtin_ns); + for(list::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i) + generator.add_file(*i); + generator.end(builtin_module); + delete out; +} + IO::Base *DataTool::open_output(const string &fn) { if(fn=="-") diff --git a/tool/tool.h b/tool/tool.h index 88f849b..0333c0d 100644 --- a/tool/tool.h +++ b/tool/tool.h @@ -16,6 +16,9 @@ private: bool compress; bool pack; bool unpack; + bool builtin; + std::string builtin_ns; + std::string builtin_module; bool debug; public: @@ -27,6 +30,7 @@ private: void do_compile(); void do_pack(); void do_unpack(); + void do_generate_builtin(); Msp::IO::Base *open_output(const std::string &); Msp::IO::Base *open_input(const std::string &); public: -- 2.45.2