3 This file is part of libmspdatafile
4 Copyright © 2008, 2010 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):
21 add("file", &Compiler::file);
22 add("for_each", &Compiler::for_each);
23 add("write", &Compiler::write);
26 void Compiler::file(const string &fn)
28 File fl(*this, FS::dirname(get_source())/fn);
32 void Compiler::for_each(const vector<string> &patterns)
34 ForEach fe(*this, FS::dirname(get_source()), list<string>(patterns.begin(), patterns.end()));
38 void Compiler::write(const DataFile::Statement &st)
42 writer.write((DataFile::Statement("__src"), string()));
46 for(list<DataFile::Statement>::const_iterator i = st.sub.begin(); i!=st.sub.end(); ++i)
50 bool Compiler::process_statement(const FS::Path &fn, DataFile::Statement &st)
52 if(st.keyword=="_content")
55 for(vector<DataFile::Value>::iterator i = st.args.begin(); i!=st.args.end(); ++i)
56 if(i->get_signature()==DataFile::StringType::signature)
58 string value = i->get<string>();
59 if(value=="$filename")
60 *i = DataFile::Value(FS::basename(fn.str()));
61 else if(value=="$content")
63 IO::File in(fn.str());
68 unsigned len = in.read(buf, sizeof(buf));
69 data.append(buf, len);
71 *i = DataFile::Value(data);
75 for(list<DataFile::Statement>::iterator i = st.sub.begin(); i!=st.sub.end();)
77 if(process_statement(fn, *i))
79 IO::File in(fn.str());
82 DataFile::Parser parser(in, fn.str());
85 DataFile::Statement ss = parser.parse();
98 void Compiler::process_file(const FS::Path &fn, const list<DataFile::Statement> &st)
100 writer.write((DataFile::Statement("__src"), FS::basename(fn.str())));
107 for(list<DataFile::Statement>::const_iterator i = st.begin(); i!=st.end(); ++i)
109 if(i->keyword=="_content")
113 DataFile::Statement s = *i;
114 process_statement(fn, s);
121 void Compiler::process_file(const FS::Path &fn)
123 IO::File in(fn.str());
124 IO::Buffered buf(in);
126 DataFile::Parser parser(in, fn.str());
129 DataFile::Statement st = parser.parse();
136 File::File(Compiler &c, const FS::Path &fn):
140 add("write", &File::write);
145 compiler.process_file(filename, write_st);
148 void File::write(const DataFile::Statement &st)
150 write_st.insert(write_st.end(), st.sub.begin(), st.sub.end());
154 ForEach::ForEach(Compiler &c, const FS::Path &b, const list<string> &p):
159 add("exclude", &ForEach::exclude);
160 add("pattern", &ForEach::pattern);
161 add("write", &ForEach::write);
164 void ForEach::finish()
166 list<string> files = FS::list_files(base);
167 for(list<string>::iterator i = files.begin(); i!=files.end(); ++i)
170 for(list<string>::const_iterator j = patterns.begin(); (j!=patterns.end() && !match); ++j)
171 match = Regex(*j).match(*i);
172 for(list<string>::const_iterator j = excludes.begin(); (j!=excludes.end() && match); ++j)
173 match = !Regex(*j).match(*i);
175 compiler.process_file(base / *i, write_st);
179 void ForEach::exclude(const string &p)
181 excludes.push_back(p);
184 void ForEach::pattern(const string &p)
186 patterns.push_back(p);
189 void ForEach::write(const DataFile::Statement &st)
191 write_st.insert(write_st.end(), st.sub.begin(), st.sub.end());