]> git.tdb.fi Git - libs/datafile.git/blobdiff - tool/builtingenerator.cpp
Add support for generating .cpp files for BuiltinSource
[libs/datafile.git] / tool / builtingenerator.cpp
diff --git a/tool/builtingenerator.cpp b/tool/builtingenerator.cpp
new file mode 100644 (file)
index 0000000..45d5844
--- /dev/null
@@ -0,0 +1,78 @@
+#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;
+}