3 This file is part of libmspdatafile
4 Copyright © 2008 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
8 #include <msp/datafile/parser.h>
9 #include <msp/fs/dir.h>
10 #include <msp/fs/utils.h>
11 #include <msp/strings/regex.h>
17 Compiler::Compiler(DataFile::Writer &w):
20 add("file", &Compiler::file);
21 add("for_each", &Compiler::for_each);
22 add("write", &Compiler::write);
25 void Compiler::file(const string &fn)
27 File fl(*this, FS::dirname(get_source())/fn);
31 void Compiler::for_each(const vector<string> &patterns)
33 ForEach fe(*this, FS::dirname(get_source()), list<string>(patterns.begin(), patterns.end()));
37 void Compiler::write(const DataFile::Statement &st)
39 for(list<DataFile::Statement>::const_iterator i=st.sub.begin(); i!=st.sub.end(); ++i)
43 bool Compiler::process_statement(const FS::Path &fn, DataFile::Statement &st)
45 if(st.keyword=="_content")
48 for(vector<DataFile::Value>::iterator i=st.args.begin(); i!=st.args.end(); ++i)
49 if(i->get_type()==DataFile::STRING)
51 if(i->get_raw()=="$filename")
52 *i=DataFile::Value(FS::basename(fn.str()));
53 else if(i->get_raw()=="$content")
55 IO::File in(fn.str());
60 unsigned len=in.read(buf, sizeof(buf));
61 data.append(buf, len);
63 *i=DataFile::Value(data);
67 for(list<DataFile::Statement>::iterator i=st.sub.begin(); i!=st.sub.end();)
69 if(process_statement(fn, *i))
71 IO::File in(fn.str());
74 DataFile::Parser parser(in, fn.str());
77 DataFile::Statement ss=parser.parse();
90 void Compiler::process_file(const FS::Path &fn, const list<DataFile::Statement> &st)
92 for(list<DataFile::Statement>::const_iterator i=st.begin(); i!=st.end(); ++i)
94 if(i->keyword=="_content")
98 DataFile::Statement s=*i;
99 process_statement(fn, s);
105 void Compiler::process_file(const FS::Path &fn)
107 IO::File in(fn.str());
108 IO::Buffered buf(in);
110 DataFile::Parser parser(in, fn.str());
113 DataFile::Statement st=parser.parse();
120 File::File(Compiler &c, const FS::Path &fn):
124 add("write", &File::write);
130 compiler.process_file(filename);
132 compiler.process_file(filename, write_st);
135 void File::write(const DataFile::Statement &st)
137 write_st.insert(write_st.end(), st.sub.begin(), st.sub.end());
141 ForEach::ForEach(Compiler &c, const FS::Path &b, const list<string> &p):
146 add("exclude", &ForEach::exclude);
147 add("pattern", &ForEach::pattern);
148 add("write", &ForEach::write);
151 void ForEach::finish()
153 list<string> files=FS::list_files(base);
154 for(list<string>::iterator i=files.begin(); i!=files.end(); ++i)
157 for(list<string>::const_iterator j=patterns.begin(); (j!=patterns.end() && !match); ++j)
158 match=Regex(*j).match(*i);
159 for(list<string>::const_iterator j=excludes.begin(); (j!=excludes.end() && match); ++j)
160 match=!Regex(*j).match(*i);
162 compiler.process_file(base / *i, write_st);
166 void ForEach::exclude(const string &p)
168 excludes.push_back(p);
171 void ForEach::pattern(const string &p)
173 patterns.push_back(p);
176 void ForEach::write(const DataFile::Statement &st)
178 write_st.insert(write_st.end(), st.sub.begin(), st.sub.end());