diff options
author | 2020-07-28 20:41:48 +0200 | |
---|---|---|
committer | 2020-07-28 20:41:51 +0200 | |
commit | 45713f390cefd502a8f0d21f6f844c54ddb9cb1a (patch) | |
tree | 4fd88d56c8d323082c1616f528aadde41ac34fd7 /src/lib/netlist/plib/ppreprocessor.cpp | |
parent | af3118d0f1848bfe5414ab94baed1b4edc2f7ea4 (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.cpp | 76 |
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--; } |