mirror of
https://github.com/holub/mame
synced 2025-04-22 00:11:58 +03:00
netlist: fix a bug in preprocessor if and elif parsing.
This commit is contained in:
parent
af3118d0f1
commit
45713f390c
@ -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--;
|
||||
}
|
||||
|
@ -139,7 +139,9 @@ namespace plib {
|
||||
psource_collection_t<> &m_sources;
|
||||
string_list m_expr_sep;
|
||||
|
||||
std::uint_least64_t m_if_flag; // 31 if levels
|
||||
std::uint_least64_t m_if_flag; // 63 if levels
|
||||
std::uint_least64_t m_if_seen; // 63 if levels
|
||||
std::uint_least64_t m_elif; // 63 if levels - for #elif
|
||||
int m_if_level;
|
||||
|
||||
struct input_context
|
||||
|
Loading…
Reference in New Issue
Block a user