summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/pparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/pparser.cpp')
-rw-r--r--src/lib/netlist/plib/pparser.cpp99
1 files changed, 92 insertions, 7 deletions
diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp
index 74d0b137829..11da93486a4 100644
--- a/src/lib/netlist/plib/pparser.cpp
+++ b/src/lib/netlist/plib/pparser.cpp
@@ -149,6 +149,23 @@ ptokenizer::token_t ptokenizer::get_token()
if (ret.is_type(ENDOFFILE))
return ret;
+ if (m_support_line_markers && ret.is_type(LINEMARKER))
+ {
+ // FIXME: do something with information gathered
+ ret = get_token_internal();
+ if (!ret.is_type(NUMBER))
+ error(pfmt("Expected line number after line marker but got <{1}>")(ret.str()) );
+ ret = get_token_internal();
+ if (!ret.is_type(STRING))
+ error(pfmt("Expected file name after line marker but got <{1}>")(ret.str()) );
+ ret = get_token_internal();
+ while (ret.is_type(NUMBER))
+ {
+ // FIXME: process flags; actually only 1 (file enter) and 2 (after file exit)
+ ret = get_token_internal();
+ }
+ }
+
if (ret.is(m_tok_comment_start))
{
do {
@@ -184,7 +201,9 @@ ptokenizer::token_t ptokenizer::get_token_internal()
return token_t(ENDOFFILE);
}
}
- if (m_number_chars_start.find(c) != pstring::npos)
+ if (m_support_line_markers && c == '#')
+ return token_t(LINEMARKER);
+ else if (m_number_chars_start.find(c) != pstring::npos)
{
/* read number while we receive number or identifier chars
* treat it as an identifier when there are identifier chars in it
@@ -259,11 +278,11 @@ ptokenizer::token_t ptokenizer::get_token_internal()
// A simple preprocessor
// ----------------------------------------------------------------------------------------
-ppreprocessor::ppreprocessor(defines_map_type *defines)
+ppreprocessor::ppreprocessor(psource_collection_t<> &sources, defines_map_type *defines)
: std::istream(new readbuffer(this))
+, m_sources(sources)
, m_if_flag(0)
, m_if_level(0)
-, m_lineno(0)
, m_pos(0)
, m_state(PROCESS)
, m_comment(false)
@@ -289,7 +308,20 @@ ppreprocessor::ppreprocessor(defines_map_type *defines)
void ppreprocessor::error(const pstring &err)
{
- throw pexception("PREPRO ERROR: " + err);
+ pstring s("");
+ pstring trail (" from ");
+ pstring trail_first("In file included from ");
+ pstring e = plib::pfmt("PREPRO ERROR: {1}:{2}:0: error: {3}\n")
+ (m_stack.top().m_name, m_stack.top().m_lineno, err);
+ m_stack.pop();
+ while (m_stack.size() > 0)
+ {
+ if (m_stack.size() == 1)
+ trail = trail_first;
+ s = trail + plib::pfmt("{1}:{2}:0\n")(m_stack.top().m_name, m_stack.top().m_lineno) + s;
+ m_stack.pop();
+ }
+ throw pexception("\n" + s + e);
}
#define CHECKTOK2(p_op, p_prio) \
@@ -504,7 +536,38 @@ pstring ppreprocessor::process_line(pstring line)
}
else if (lti[0] == "#include")
{
- // ignore
+ if (m_if_flag == 0)
+ {
+ pstring arg("");
+ for (std::size_t i=1; i<lti.size(); i++)
+ arg += (lti[i] + " ");
+
+ arg = plib::trim(arg);
+
+ if (startsWith(arg, "\"") && endsWith(arg, "\""))
+ {
+ arg = arg.substr(1, arg.length() - 2);
+ /* first try local context */
+ auto l(plib::util::buildpath({m_stack.top().m_local_path, arg}));
+ auto lstrm(m_sources.get_stream<>(l));
+ if (lstrm)
+ {
+ m_stack.emplace(input_context(std::move(lstrm), plib::util::path(l), l));
+ }
+ else
+ {
+ auto strm(m_sources.get_stream<>(arg));
+ if (strm)
+ {
+ m_stack.emplace(input_context(std::move(strm), plib::util::path(arg), arg));
+ }
+ else
+ error("include not found:" + arg);
+ }
+ }
+ else
+ error("include misspelled:" + arg);
+ }
}
else if (lti[0] == "#pragma")
{
@@ -519,7 +582,7 @@ pstring ppreprocessor::process_line(pstring line)
if (m_if_flag == 0)
{
if (lti.size() < 2)
- error("PREPRO: define needs at least one argument: " + line);
+ error("define needs at least one argument: " + line);
else if (lti.size() == 2)
m_defines.insert({lti[1], define_t(lti[1], "")});
else
@@ -535,7 +598,7 @@ pstring ppreprocessor::process_line(pstring line)
else
{
if (m_if_flag == 0)
- error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line)));
+ error(pfmt("unknown directive on line {1}: {2}")(m_stack.top().m_lineno)(replace_macros(line)));
}
}
else
@@ -547,6 +610,28 @@ pstring ppreprocessor::process_line(pstring line)
return ret;
}
+void ppreprocessor::process_stack()
+{
+ while (m_stack.size() > 0)
+ {
+ pstring line;
+ pstring linemarker = pfmt("# {1} \"{2}\" 1\n")(m_stack.top().m_lineno, m_stack.top().m_name);
+ m_outbuf += decltype(m_outbuf)(linemarker.c_str());
+ while (m_stack.top().m_reader.readline(line))
+ {
+ m_stack.top().m_lineno++;
+ line = process_line(line);
+ m_outbuf += decltype(m_outbuf)(line.c_str()) + static_cast<char>(10);
+ }
+ m_stack.pop();
+ if (m_stack.size() > 0)
+ {
+ linemarker = pfmt("# {1} \"{2}\" 2\n")(m_stack.top().m_lineno, m_stack.top().m_name);
+ m_outbuf += decltype(m_outbuf)(linemarker.c_str());
+ }
+ }
+}
+
} // namespace plib