--- /dev/null
+#include <msp/fs/utils.h>
+#include <msp/strings/format.h>
+#include <msp/strings/utils.h>
+#include "builtingenerator.h"
+
+using namespace std;
+using namespace Msp;
+
+BuiltinGenerator::BuiltinGenerator(IO::Base &o):
+ out(o)
+{
+ out.write("#include <msp/datafile/builtinsource.h>\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<string>::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<string>::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<string>::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;
+}
--- /dev/null
+#ifndef TOOL_BUILTINGENERATOR_H_
+#define TOOL_BUILTINGENERATOR_H_
+
+#include <string>
+#include <vector>
+#include <msp/io/file.h>
+
+class BuiltinGenerator
+{
+private:
+ Msp::IO::Base &out;
+ std::vector<std::string> namespc;
+ std::vector<std::string> 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
--- /dev/null
+#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
#include <msp/core/getopt.h>
+#include <msp/fs/utils.h>
#include <msp/io/buffered.h>
#include <msp/io/console.h>
#include <msp/io/file.h>
#include <msp/datafile/packsource.h>
#include <msp/datafile/parser.h>
#include <msp/datafile/statement.h>
+#include "builtingenerator.h"
#include "compiler.h"
#include "packer.h"
#include "tool.h"
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");
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");
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()
do_unpack();
else if(compile)
do_compile();
+ else if(builtin)
+ do_generate_builtin();
else
do_transfer();
}
}
+void DataTool::do_generate_builtin()
+{
+ IO::Base *out = open_output(out_fn);
+ BuiltinGenerator generator(*out);
+ generator.begin(builtin_ns);
+ for(list<string>::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=="-")
bool compress;
bool pack;
bool unpack;
+ bool builtin;
+ std::string builtin_ns;
+ std::string builtin_module;
bool debug;
public:
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: