1 #include <msp/datafile/parser.h>
2 #include <msp/fs/dir.h>
3 #include <msp/fs/utils.h>
4 #include <msp/strings/regex.h>
10 Compiler::Compiler(DataFile::Writer &w):
14 add("file", &Compiler::file);
15 add("for_each", &Compiler::for_each);
16 add("write", &Compiler::write);
19 void Compiler::file(const string &fn)
21 File fl(*this, FS::dirname(get_source())/fn);
25 void Compiler::for_each(const vector<string> &patterns)
27 ForEach fe(*this, FS::dirname(get_source()), list<string>(patterns.begin(), patterns.end()));
31 void Compiler::write(const DataFile::Statement &st)
35 writer.write((DataFile::Statement("__src"), string()));
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 if(st.keyword=="_extension")
50 string ext = FS::extpart(FS::basename(fn));
51 if(ext.empty() || ext.size()==1)
52 throw invalid_argument("Compiler::process_statement");
53 st.keyword = ext.substr(1);
56 for(vector<DataFile::Value>::iterator i = st.args.begin(); i!=st.args.end(); ++i)
57 if(i->get_signature()==DataFile::StringType::signature)
59 string value = i->get<string>();
60 if(value=="$filename")
61 *i = DataFile::Value(FS::basename(fn.str()));
62 else if(value=="$content")
64 IO::File in(fn.str());
69 unsigned len = in.read(buf, sizeof(buf));
70 data.append(buf, len);
72 *i = DataFile::Value(data);
76 for(list<DataFile::Statement>::iterator i = st.sub.begin(); i!=st.sub.end();)
78 if(process_statement(fn, *i))
80 IO::File in(fn.str());
83 DataFile::Parser parser(in, fn.str());
86 DataFile::Statement ss = parser.parse();
99 void Compiler::process_file(const FS::Path &fn, const list<DataFile::Statement> &st)
101 writer.write((DataFile::Statement("__src"), FS::basename(fn.str())));
108 for(list<DataFile::Statement>::const_iterator i = st.begin(); i!=st.end(); ++i)
110 if(i->keyword=="_content")
114 DataFile::Statement s = *i;
115 process_statement(fn, s);
122 void Compiler::process_file(const FS::Path &fn)
124 IO::File in(fn.str());
125 IO::Buffered buf(in);
127 DataFile::Parser parser(in, fn.str());
130 DataFile::Statement st = parser.parse();
137 File::File(Compiler &c, const FS::Path &fn):
141 add("write", &File::write);
146 compiler.process_file(filename, write_st);
149 void File::write(const DataFile::Statement &st)
151 write_st.insert(write_st.end(), st.sub.begin(), st.sub.end());
155 ForEach::ForEach(Compiler &c, const FS::Path &b, const list<string> &p):
160 add("exclude", &ForEach::exclude);
161 add("pattern", &ForEach::pattern);
162 add("wrap", &ForEach::wrap);
163 add("wrap", &ForEach::wrap_keyword);
164 add("write", &ForEach::write);
167 void ForEach::finish()
169 for(const string &f: FS::list_files(base))
172 for(list<string>::const_iterator j = patterns.begin(); (j!=patterns.end() && !match); ++j)
173 match = static_cast<bool>(Regex(*j).match(f));
174 for(list<string>::const_iterator j = excludes.begin(); (j!=excludes.end() && match); ++j)
175 match = !Regex(*j).match(f);
177 compiler.process_file(base/f, write_st);
181 void ForEach::exclude(const string &p)
183 excludes.push_back(p);
186 void ForEach::pattern(const string &p)
188 patterns.push_back(p);
193 wrap_keyword("_extension");
196 void ForEach::wrap_keyword(const string &kwd)
198 DataFile::Statement st(kwd);
199 st.append("$filename");
200 st.sub.push_back(DataFile::Statement("_content"));
201 write_st.push_back(st);
204 void ForEach::write(const DataFile::Statement &st)
206 write_st.insert(write_st.end(), st.sub.begin(), st.sub.end());