pstring ppreprocessor::process_line(const pstring &line) { pstring lt = line.replace("\t"," ").trim(); pstringbuffer ret; m_lineno++; // FIXME ... revise and extend macro handling if (lt.startsWith("#")) { pstring_vector_t lti(lt, " ", true); if (lti[0].equals("#if")) { m_level++; std::size_t start = 0; lt = replace_macros(lt); pstring_vector_t t(lt.substr(3).replace(" ",""), m_expr_sep); int val = static_cast<int>(expr(t, start, 0)); if (val == 0) m_ifflag |= (1 << m_level); } else if (lti[0].equals("#ifdef")) { m_level++; if (get_define(lti[1]) == nullptr) m_ifflag |= (1 << m_level); } else if (lti[0].equals("#ifndef")) { m_level++; if (get_define(lti[1]) != nullptr) m_ifflag |= (1 << m_level); } else if (lti[0].equals("#else")) { m_ifflag ^= (1 << m_level); } else if (lti[0].equals("#endif")) { m_ifflag &= ~(1 << m_level); m_level--; } else if (lti[0].equals("#include")) { // ignore } else if (lti[0].equals("#pragma")) { if (m_ifflag == 0 && lti.size() > 3 && lti[1].equals("NETLIST")) { if (lti[2].equals("warning")) error("NETLIST: " + catremainder(lti, 3, " ")); } } else if (lti[0].equals("#define")) { if (m_ifflag == 0) { if (lti.size() != 3) error("PREPRO: only simple defines allowed: " + line); m_defines.insert({lti[1], define_t(lti[1], lti[2])}); } } else error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(line)); } else { lt = replace_macros(lt); if (m_ifflag == 0) { ret.cat(lt); } } return ret; }
pstring ppreprocessor::process(const pstring &contents) { pstringbuffer ret = ""; pstring_list_t lines(contents,"\n", false); UINT32 ifflag = 0; // 31 if levels int level = 0; std::size_t i=0; while (i<lines.size()) { pstring line = lines[i]; pstring lt = line.replace("\t"," ").trim(); // FIXME ... revise and extend macro handling if (lt.startsWith("#")) { pstring_list_t lti(lt, " ", true); if (lti[0].equals("#if")) { level++; std::size_t start = 0; lt = replace_macros(lt); pstring_list_t t = pstring_list_t::splitexpr(lt.substr(3).replace(" ",""), m_expr_sep); int val = expr(t, start, 0); if (val == 0) ifflag |= (1 << level); } else if (lti[0].equals("#ifdef")) { level++; if (get_define(lti[1]) == NULL) ifflag |= (1 << level); } else if (lti[0].equals("#ifndef")) { level++; if (get_define(lti[1]) != NULL) ifflag |= (1 << level); } else if (lti[0].equals("#else")) { ifflag ^= (1 << level); } else if (lti[0].equals("#endif")) { ifflag &= ~(1 << level); level--; } else if (lti[0].equals("#include")) { // ignore } else if (lti[0].equals("#pragma")) { if (ifflag == 0 && lti.size() > 3 && lti[1].equals("NETLIST")) { if (lti[2].equals("warning")) error("NETLIST: " + catremainder(lti, 3, " ")); } } else if (lti[0].equals("#define")) { if (ifflag == 0) { if (lti.size() != 3) error(pstring::sprintf("PREPRO: only simple defines allowed: %s", line.cstr())); m_defines.add(define_t(lti[1], lti[2])); } } else error(pstring::sprintf("unknown directive on line %" SIZETFMT ": %s\n", SIZET_PRINTF(i), line.cstr())); } else { //if (ifflag == 0 && level > 0) // fprintf(stderr, "conditional: %s\n", line.cstr()); lt = replace_macros(lt); if (ifflag == 0) { ret.cat(lt); ret.cat("\n"); } } i++; } return pstring(ret.cstr()); }
pstring ppreprocessor::process_line(pstring line) { bool line_cont = plib::right(line, 1) == "\\"; if (line_cont) line = plib::left(line, line.size() - 1); if (m_state == LINE_CONTINUATION) m_line += line; else m_line = line; if (line_cont) { m_state = LINE_CONTINUATION; return ""; } else m_state = PROCESS; line = process_comments(m_line); pstring lt = plib::trim(plib::replace_all(line, pstring("\t"), pstring(" "))); pstring ret; // FIXME ... revise and extend macro handling if (plib::startsWith(lt, "#")) { std::vector<pstring> lti(psplit(lt, " ", true)); if (lti[0] == "#if") { m_level++; std::size_t start = 0; lt = replace_macros(lt); std::vector<pstring> t(psplit(replace_all(lt.substr(3), pstring(" "), pstring("")), m_expr_sep)); int val = static_cast<int>(expr(t, start, 255)); if (val == 0) m_ifflag |= (1 << m_level); } else if (lti[0] == "#ifdef") { m_level++; if (get_define(lti[1]) == nullptr) m_ifflag |= (1 << m_level); } else if (lti[0] == "#ifndef") { m_level++; if (get_define(lti[1]) != nullptr) m_ifflag |= (1 << m_level); } else if (lti[0] == "#else") { m_ifflag ^= (1 << m_level); } else if (lti[0] == "#endif") { m_ifflag &= ~(1 << m_level); m_level--; } else if (lti[0] == "#include") { // ignore } else if (lti[0] == "#pragma") { if (m_ifflag == 0 && lti.size() > 3 && lti[1] == "NETLIST") { if (lti[2] == "warning") error("NETLIST: " + catremainder(lti, 3, " ")); } } else if (lti[0] == "#define") { if (m_ifflag == 0) { if (lti.size() != 3) error("PREPRO: only simple defines allowed: " + line); m_defines.insert({lti[1], define_t(lti[1], lti[2])}); } } else { if (m_ifflag == 0) error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line))); } } else { lt = replace_macros(lt); if (m_ifflag == 0) ret += lt; } return ret; }