]> git.tdb.fi Git - libs/datafile.git/blobdiff - tool/compiler.cpp
Add a shortcut for wrapping data for a collection file
[libs/datafile.git] / tool / compiler.cpp
index 53c1b5388c4792829743b2db13092c005b125573..49dd19031cc0408fc958e84afd3fcfa4063bc403 100644 (file)
@@ -1,10 +1,3 @@
-/* $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>
@@ -15,7 +8,8 @@ using namespace std;
 using namespace Msp;
 
 Compiler::Compiler(DataFile::Writer &w):
-       writer(w)
+       writer(w),
+       reset_src(false)
 {
        add("file",     &Compiler::file);
        add("for_each", &Compiler::for_each);
@@ -36,7 +30,13 @@ void Compiler::for_each(const vector<string> &patterns)
 
 void Compiler::write(const DataFile::Statement &st)
 {
-       for(list<DataFile::Statement>::const_iterator i=st.sub.begin(); i!=st.sub.end(); ++i)
+       if(reset_src)
+       {
+               writer.write((DataFile::Statement("__src"), string()));
+               reset_src = false;
+       }
+
+       for(list<DataFile::Statement>::const_iterator i = st.sub.begin(); i!=st.sub.end(); ++i)
                writer.write(*i);
 }
 
@@ -45,26 +45,35 @@ 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(st.keyword=="_extension")
+       {
+               string ext = FS::extpart(FS::basename(fn));
+               if(ext.empty() || ext.size()==1)
+                       throw invalid_argument("Compiler::process_statement");
+               st.keyword = ext.substr(1);
+       }
+
+       for(vector<DataFile::Value>::iterator i = st.args.begin(); i!=st.args.end(); ++i)
+               if(i->get_signature()==DataFile::StringType::signature)
                {
-                       if(i->get_raw()=="$filename")
-                               *i=DataFile::Value(FS::basename(fn.str()));
-                       else if(i->get_raw()=="$content")
+                       string value = i->get<string>();
+                       if(value=="$filename")
+                               *i = DataFile::Value(FS::basename(fn.str()));
+                       else if(value=="$content")
                        {
                                IO::File in(fn.str());
                                string data;
                                while(!in.eof())
                                {
                                        char buf[4096];
-                                       unsigned len=in.read(buf, sizeof(buf));
+                                       unsigned len = in.read(buf, sizeof(buf));
                                        data.append(buf, len);
                                }
-                               *i=DataFile::Value(data);
+                               *i = DataFile::Value(data);
                        }
                }
 
-       for(list<DataFile::Statement>::iterator i=st.sub.begin(); i!=st.sub.end();)
+       for(list<DataFile::Statement>::iterator i = st.sub.begin(); i!=st.sub.end();)
        {
                if(process_statement(fn, *i))
                {
@@ -74,11 +83,11 @@ bool Compiler::process_statement(const FS::Path &fn, DataFile::Statement &st)
                        DataFile::Parser parser(in, fn.str());
                        while(parser)
                        {
-                               DataFile::Statement ss=parser.parse();
+                               DataFile::Statement ss = parser.parse();
                                if(ss.valid)
                                        st.sub.insert(i, ss);
                        }
-                       i=st.sub.erase(i);
+                       i = st.sub.erase(i);
                }
                else
                        ++i;
@@ -89,15 +98,23 @@ bool Compiler::process_statement(const FS::Path &fn, DataFile::Statement &st)
 
 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)
+       writer.write((DataFile::Statement("__src"), FS::basename(fn.str())));
+       reset_src = true;
+
+       if(st.empty())
+               process_file(fn);
+       else
        {
-               if(i->keyword=="_content")
-                       process_file(fn);
-               else
+               for(list<DataFile::Statement>::const_iterator i = st.begin(); i!=st.end(); ++i)
                {
-                       DataFile::Statement s=*i;
-                       process_statement(fn, s);
-                       writer.write(s);
+                       if(i->keyword=="_content")
+                               process_file(fn);
+                       else
+                       {
+                               DataFile::Statement s = *i;
+                               process_statement(fn, s);
+                               writer.write(s);
+                       }
                }
        }
 }
@@ -110,7 +127,7 @@ void Compiler::process_file(const FS::Path &fn)
        DataFile::Parser parser(in, fn.str());
        while(parser)
        {
-               DataFile::Statement st=parser.parse();
+               DataFile::Statement st = parser.parse();
                if(st.valid)
                        writer.write(st);
        }
@@ -126,10 +143,7 @@ File::File(Compiler &c, const FS::Path &fn):
 
 void File::finish()
 {
-       if(write_st.empty())
-               compiler.process_file(filename);
-       else
-               compiler.process_file(filename, write_st);
+       compiler.process_file(filename, write_st);
 }
 
 void File::write(const DataFile::Statement &st)
@@ -145,19 +159,21 @@ ForEach::ForEach(Compiler &c, const FS::Path &b, const list<string> &p):
 {
        add("exclude", &ForEach::exclude);
        add("pattern", &ForEach::pattern);
+       add("wrap",    &ForEach::wrap);
+       add("wrap",    &ForEach::wrap_keyword);
        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)
+       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);
+               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);
        }
@@ -173,6 +189,19 @@ void ForEach::pattern(const string &p)
        patterns.push_back(p);
 }
 
+void ForEach::wrap()
+{
+       wrap_keyword("_extension");
+}
+
+void ForEach::wrap_keyword(const string &kwd)
+{
+       DataFile::Statement st(kwd);
+       st.append("$filename");
+       st.sub.push_back(DataFile::Statement("_content"));
+       write_st.push_back(st);
+}
+
 void ForEach::write(const DataFile::Statement &st)
 {
        write_st.insert(write_st.end(), st.sub.begin(), st.sub.end());