]> git.tdb.fi Git - libs/datafile.git/commitdiff
Add a compile mode to mspdatatool
authorMikko Rasa <tdb@tdb.fi>
Fri, 12 Sep 2008 18:58:06 +0000 (18:58 +0000)
committerMikko Rasa <tdb@tdb.fi>
Fri, 12 Sep 2008 18:58:06 +0000 (18:58 +0000)
Build
tool/compiler.cpp [new file with mode: 0644]
tool/compiler.h [new file with mode: 0644]
tool/tool.cpp
tool/tool.h

diff --git a/Build b/Build
index 53a4ebde438a6eb05beeb9e0dc0846e6bf0300f2..faf77b672591d9625dca0583d0c58c3b4898bd20 100644 (file)
--- a/Build
+++ b/Build
@@ -21,6 +21,7 @@ package "mspdatafile"
 
        program "mspdatatool"
        {
+               require "mspfs";
                source "tool";
                install true;
                build_info
diff --git a/tool/compiler.cpp b/tool/compiler.cpp
new file mode 100644 (file)
index 0000000..53c1b53
--- /dev/null
@@ -0,0 +1,179 @@
+/* $Id$
+
+This file is part of libmspdatafile
+Copyright © 2008  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <msp/datafile/parser.h>
+#include <msp/fs/dir.h>
+#include <msp/fs/utils.h>
+#include <msp/strings/regex.h>
+#include "compiler.h"
+
+using namespace std;
+using namespace Msp;
+
+Compiler::Compiler(DataFile::Writer &w):
+       writer(w)
+{
+       add("file",     &Compiler::file);
+       add("for_each", &Compiler::for_each);
+       add("write",    &Compiler::write);
+}
+
+void Compiler::file(const string &fn)
+{
+       File fl(*this, FS::dirname(get_source())/fn);
+       load_sub_with(fl);
+}
+
+void Compiler::for_each(const vector<string> &patterns)
+{
+       ForEach fe(*this, FS::dirname(get_source()), list<string>(patterns.begin(), patterns.end()));
+       load_sub_with(fe);
+}
+
+void Compiler::write(const DataFile::Statement &st)
+{
+       for(list<DataFile::Statement>::const_iterator i=st.sub.begin(); i!=st.sub.end(); ++i)
+               writer.write(*i);
+}
+
+bool Compiler::process_statement(const FS::Path &fn, DataFile::Statement &st)
+{
+       if(st.keyword=="_content")
+               return true;
+
+       for(vector<DataFile::Value>::iterator i=st.args.begin(); i!=st.args.end(); ++i)
+               if(i->get_type()==DataFile::STRING)
+               {
+                       if(i->get_raw()=="$filename")
+                               *i=DataFile::Value(FS::basename(fn.str()));
+                       else if(i->get_raw()=="$content")
+                       {
+                               IO::File in(fn.str());
+                               string data;
+                               while(!in.eof())
+                               {
+                                       char buf[4096];
+                                       unsigned len=in.read(buf, sizeof(buf));
+                                       data.append(buf, len);
+                               }
+                               *i=DataFile::Value(data);
+                       }
+               }
+
+       for(list<DataFile::Statement>::iterator i=st.sub.begin(); i!=st.sub.end();)
+       {
+               if(process_statement(fn, *i))
+               {
+                       IO::File in(fn.str());
+                       IO::Buffered buf(in);
+
+                       DataFile::Parser parser(in, fn.str());
+                       while(parser)
+                       {
+                               DataFile::Statement ss=parser.parse();
+                               if(ss.valid)
+                                       st.sub.insert(i, ss);
+                       }
+                       i=st.sub.erase(i);
+               }
+               else
+                       ++i;
+       }
+
+       return false;
+}
+
+void Compiler::process_file(const FS::Path &fn, const list<DataFile::Statement> &st)
+{
+       for(list<DataFile::Statement>::const_iterator i=st.begin(); i!=st.end(); ++i)
+       {
+               if(i->keyword=="_content")
+                       process_file(fn);
+               else
+               {
+                       DataFile::Statement s=*i;
+                       process_statement(fn, s);
+                       writer.write(s);
+               }
+       }
+}
+
+void Compiler::process_file(const FS::Path &fn)
+{
+       IO::File in(fn.str());
+       IO::Buffered buf(in);
+
+       DataFile::Parser parser(in, fn.str());
+       while(parser)
+       {
+               DataFile::Statement st=parser.parse();
+               if(st.valid)
+                       writer.write(st);
+       }
+}
+
+
+File::File(Compiler &c, const FS::Path &fn):
+       compiler(c),
+       filename(fn)
+{
+       add("write", &File::write);
+}
+
+void File::finish()
+{
+       if(write_st.empty())
+               compiler.process_file(filename);
+       else
+               compiler.process_file(filename, write_st);
+}
+
+void File::write(const DataFile::Statement &st)
+{
+       write_st.insert(write_st.end(), st.sub.begin(), st.sub.end());
+}
+
+
+ForEach::ForEach(Compiler &c, const FS::Path &b, const list<string> &p):
+       compiler(c),
+       base(b),
+       patterns(p)
+{
+       add("exclude", &ForEach::exclude);
+       add("pattern", &ForEach::pattern);
+       add("write",   &ForEach::write);
+}
+
+void ForEach::finish()
+{
+       list<string> files=FS::list_files(base);
+       for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
+       {
+               bool match=false;
+               for(list<string>::const_iterator j=patterns.begin(); (j!=patterns.end() && !match); ++j)
+                       match=Regex(*j).match(*i);
+               for(list<string>::const_iterator j=excludes.begin(); (j!=excludes.end() && match); ++j)
+                       match=!Regex(*j).match(*i);
+               if(match)
+                       compiler.process_file(base / *i, write_st);
+       }
+}
+
+void ForEach::exclude(const string &p)
+{
+       excludes.push_back(p);
+}
+
+void ForEach::pattern(const string &p)
+{
+       patterns.push_back(p);
+}
+
+void ForEach::write(const DataFile::Statement &st)
+{
+       write_st.insert(write_st.end(), st.sub.begin(), st.sub.end());
+}
diff --git a/tool/compiler.h b/tool/compiler.h
new file mode 100644 (file)
index 0000000..f77f04b
--- /dev/null
@@ -0,0 +1,70 @@
+/* $Id$
+
+This file is part of libmspdatafile
+Copyright © 2008  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef TOOL_COMPILER_H_
+#define TOOL_COMPILER_H_
+
+#include <msp/datafile/loader.h>
+#include <msp/datafile/statement.h>
+#include <msp/datafile/writer.h>
+#include <msp/fs/path.h>
+
+class Compiler: public Msp::DataFile::Loader
+{
+       friend class File;
+       friend class ForEach;
+
+private:
+       Msp::DataFile::Writer &writer;
+
+public:
+       Compiler(Msp::DataFile::Writer &);
+private:
+       void file(const std::string &);
+       void for_each(const std::vector<std::string> &);
+       void write(const Msp::DataFile::Statement &);
+
+       bool process_statement(const Msp::FS::Path &, Msp::DataFile::Statement &);
+       void process_file(const Msp::FS::Path &, const std::list<Msp::DataFile::Statement> &);
+       void process_file(const Msp::FS::Path &);
+};
+
+class File: public Msp::DataFile::Loader
+{
+private:
+       Compiler &compiler;
+       Msp::FS::Path filename;
+       std::list<Msp::DataFile::Statement> write_st;
+
+public:
+       File(Compiler &, const Msp::FS::Path &);
+private:
+       virtual void finish();
+
+       void write(const Msp::DataFile::Statement &);
+};
+
+class ForEach: public Msp::DataFile::Loader
+{
+private:
+       Compiler &compiler;
+       Msp::FS::Path base;
+       std::list<std::string> patterns;
+       std::list<std::string> excludes;
+       std::list<Msp::DataFile::Statement> write_st;
+
+public:
+       ForEach(Compiler &, const Msp::FS::Path &, const std::list<std::string> &);
+private:
+       virtual void finish();
+
+       void exclude(const std::string &);
+       void pattern(const std::string &);
+       void write(const Msp::DataFile::Statement &);
+};
+
+#endif
index ca415d30a0d9dc7d996d84b62021be90bc054f9e..36ee5c4abd6e760162934417a8d8ae4b1f355333 100644 (file)
@@ -12,6 +12,7 @@ Distributed under the LGPL
 #include <msp/datafile/parser.h>
 #include <msp/datafile/statement.h>
 #include <msp/datafile/writer.h>
+#include "compiler.h"
 #include "tool.h"
 
 using namespace std;
@@ -19,11 +20,14 @@ using namespace Msp;
 
 DataTool::DataTool(int argc, char **argv):
        in_fn("-"),
-       out_fn("-")
+       out_fn("-"),
+       binary(false),
+       compile(false)
 {
        GetOpt getopt;
-       getopt.add_option('o', "output", out_fn, GetOpt::REQUIRED_ARG);
        getopt.add_option('b', "binary", binary, GetOpt::NO_ARG);
+       getopt.add_option('c', "compile", compile, GetOpt::NO_ARG);
+       getopt.add_option('o', "output", out_fn, GetOpt::REQUIRED_ARG);
        getopt(argc, argv);
 
        const vector<string> &args=getopt.get_args();
@@ -53,13 +57,21 @@ int DataTool::main()
                if(binary)
                        writer.set_binary(true);
 
-               while(parser)
+               if(compile)
+               {
+                       Compiler compiler(writer);
+                       compiler.load(parser);
+               }
+               else
                {
-                       DataFile::Statement st=parser.parse();
-                       if(st.valid)
+                       while(parser)
                        {
-                               writer.write(st);
-                               out_buf.flush();
+                               DataFile::Statement st=parser.parse();
+                               if(st.valid)
+                               {
+                                       writer.write(st);
+                                       out_buf.flush();
+                               }
                        }
                }
        }
index 99e8297770ef9fd6cfd6a6e12c0f9cf0a2e680c4..ab399ad85a43ff58662b93b1cf7bd42b838988e5 100644 (file)
@@ -5,6 +5,9 @@ Copyright © 2008  Mikko Rasa, Mikkosoft Productions
 Distributed under the LGPL
 */
 
+#ifndef TOOL_H_
+#define TOOL_H_
+
 #include <string>
 #include <msp/core/application.h>
 
@@ -14,9 +17,13 @@ private:
        std::string in_fn;
        std::string out_fn;
        bool binary;
+       bool compile;
+
 public:
        DataTool(int argc, char **argv);
        int main();
 
        static Application::RegApp<DataTool> reg;
 };
+
+#endif