#include <msp/strings/format.h>
#include "binaryparser.h"
-#include "dataerror.h"
+#include "except.h"
#include "parser.h"
#include "statement.h"
#include "textparser.h"
{
while(1)
{
- Statement st = mode->parse(raw);
- if(st.keyword=="__bin")
+ Statement st = mode->parse();
+ if(!st.keyword.compare(0, 2, "__"))
{
- delete mode;
- mode = new BinaryParser(in, src);
+ st.control = true;
+ process_control_statement(st);
}
- else if(st.keyword=="__text")
- {
- delete mode;
- mode = new TextParser(in, src);
- }
- else if(st.keyword=="__z")
- in.set_decompress();
- else if(st.keyword=="__src")
- {
- string s = st.args[0].get<string>();
- if(s.empty())
- src = main_src;
- else
- src = format("%s[%s]", main_src, s);
- }
- else if(st.keyword=="__end")
- {
- good = false;
- return raw ? st : Statement();
- }
- else
- return st;
- if(raw)
+ if(raw || !st.control)
return st;
+ else if(!good) // This will occur with an __end statement
+ return Statement();
}
}
catch(const exception &e)
}
}
+void Parser::process_control_statement(const Statement &st)
+{
+ if(st.keyword=="__bin")
+ {
+ delete mode;
+ mode = new BinaryParser(in, src);
+
+ while(in.peek()=='\n')
+ in.get();
+ }
+ else if(st.keyword=="__text")
+ {
+ delete mode;
+ mode = new TextParser(in, src);
+ }
+ else if(st.keyword=="__z")
+ in.set_decompress();
+ else if(st.keyword=="__src")
+ {
+ string s = st.args[0].get<string>();
+ if(s.empty())
+ src = main_src;
+ else
+ src = format("%s[%s]", main_src, s);
+ }
+ else if(st.keyword=="__end")
+ good = false;
+ else
+ mode->process_control_statement(st);
+}
+
+const StatementKey *Parser::peek(unsigned level)
+{
+ while(good)
+ {
+ const StatementKey *key = mode->peek(level);
+ if(key && !key->keyword.compare(0, 2, "__"))
+ process_control_statement(mode->parse());
+ else
+ return key;
+ }
+
+ return 0;
+}
+
+bool Parser::parse_and_load(unsigned level, Loader &ldr, const LoaderAction &act)
+{
+ // Peek first to get any control statements processed
+ peek(level);
+ return mode->parse_and_load(level, ldr, act);
+}
+
} // namespace DataFile
} // namespace Msp