summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/ppreprocessor.cpp
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2020-07-28 20:41:48 +0200
committer couriersud <couriersud@gmx.org>2020-07-28 20:41:51 +0200
commit45713f390cefd502a8f0d21f6f844c54ddb9cb1a (patch)
tree4fd88d56c8d323082c1616f528aadde41ac34fd7 /src/lib/netlist/plib/ppreprocessor.cpp
parentaf3118d0f1848bfe5414ab94baed1b4edc2f7ea4 (diff)
netlist: fix a bug in preprocessor if and elif parsing.
Diffstat (limited to 'src/lib/netlist/plib/ppreprocessor.cpp')
-rw-r--r--src/lib/netlist/plib/ppreprocessor.cpp76
1 files changed, 59 insertions, 17 deletions
diff --git a/src/lib/netlist/plib/ppreprocessor.cpp b/src/lib/netlist/plib/ppreprocessor.cpp
index 05cdb648f34..d183485789f 100644
--- a/src/lib/netlist/plib/ppreprocessor.cpp
+++ b/src/lib/netlist/plib/ppreprocessor.cpp
@@ -17,6 +17,8 @@ namespace plib {
: std::istream(new readbuffer(this))
, m_sources(sources)
, m_if_flag(0)
+ , m_if_seen(0)
+ , m_elif(0)
, m_if_level(0)
, m_pos(0)
, m_state(PROCESS)
@@ -197,7 +199,14 @@ namespace plib {
CHECKTOK2(||, 15)
else
{
- val = plib::pstonum<decltype(val)>(tok);
+ try
+ {
+ val = plib::pstonum<decltype(val)>(tok);
+ }
+ catch (pexception &e)
+ {
+ sexpr.error(e.text());
+ }
has_val = true;
sexpr.next();
}
@@ -460,45 +469,78 @@ namespace plib {
if (lti[0] == "#if")
{
m_if_level++;
- lt = replace_macros(lt);
- simple_iter<ppreprocessor> t(this, tokenize(lt.substr(3), m_expr_sep, true, true));
- auto val = narrow_cast<int>(prepro_expr(t, 255));
- t.skip_ws();
- if (!t.eod())
- error("found unprocessed content at end of line");
- if (val == 0)
- m_if_flag |= (1 << m_if_level);
+ m_if_seen |= (1 << m_if_level);
+ if (m_if_flag == 0)
+ {
+ lt = replace_macros(lt);
+ simple_iter<ppreprocessor> t(this, tokenize(lt.substr(3), m_expr_sep, true, true));
+ auto val = narrow_cast<int>(prepro_expr(t, 255));
+ t.skip_ws();
+ if (!t.eod())
+ error("found unprocessed content at end of line");
+ if (val == 0)
+ m_if_flag |= (1 << m_if_level);
+ else
+ m_elif |= (1 << m_if_level);
+ }
}
else if (lti[0] == "#ifdef")
{
m_if_level++;
+ m_if_seen |= (1 << m_if_level);
if (get_define(lti[1]) == nullptr)
m_if_flag |= (1 << m_if_level);
+ else
+ m_elif |= (1 << m_if_level);
}
else if (lti[0] == "#ifndef")
{
m_if_level++;
+ m_if_seen |= (1 << m_if_level);
if (get_define(lti[1]) != nullptr)
m_if_flag |= (1 << m_if_level);
+ else
+ m_elif |= (1 << m_if_level);
}
else if (lti[0] == "#else")
{
+ if (!(m_if_seen & (1 << m_if_level)))
+ error("#else without #if");
m_if_flag ^= (1 << m_if_level);
+ m_elif &= ~(1 << m_if_level);
}
else if (lti[0] == "#elif")
{
- m_if_flag ^= (1 << m_if_level);
- lt = replace_macros(lt);
- simple_iter<ppreprocessor> t(this, tokenize(lt.substr(5), m_expr_sep, true, true));
- auto val = narrow_cast<int>(prepro_expr(t, 255));
- t.skip_ws();
- if (!t.eod())
- error("found unprocessed content at end of line");
- if (val == 0)
+ if (!(m_if_seen & (1 << m_if_level)))
+ error("#elif without #if");
+
+ //if ((m_if_flag & (1 << m_if_level)) == 0)
+ // m_if_flag ^= (1 << m_if_level);
+ if (m_elif & (1 << m_if_level))
m_if_flag |= (1 << m_if_level);
+ else
+ m_if_flag &= ~(1 << m_if_level);
+ if (m_if_flag == 0)
+ {
+ //m_if_flag ^= (1 << m_if_level);
+ lt = replace_macros(lt);
+ simple_iter<ppreprocessor> t(this, tokenize(lt.substr(5), m_expr_sep, true, true));
+ auto val = narrow_cast<int>(prepro_expr(t, 255));
+ t.skip_ws();
+ if (!t.eod())
+ error("found unprocessed content at end of line");
+ if (val == 0)
+ m_if_flag |= (1 << m_if_level);
+ else
+ m_elif |= ~(1 << m_if_level);
+ }
}
else if (lti[0] == "#endif")
{
+ if (!(m_if_seen & (1 << m_if_level)))
+ error("#else without #if");
+ m_if_seen &= ~(1 << m_if_level);
+ m_elif &= ~(1 << m_if_level);
m_if_flag &= ~(1 << m_if_level);
m_if_level--;
}