ppreprocessor::ppreprocessor(defines_map_type *defines) : pistream() , m_ifflag(0) , m_level(0) , m_lineno(0) , m_pos(0) , m_state(PROCESS) , m_comment(false) { m_expr_sep.push_back("!"); m_expr_sep.push_back("("); m_expr_sep.push_back(")"); m_expr_sep.push_back("+"); m_expr_sep.push_back("-"); m_expr_sep.push_back("*"); m_expr_sep.push_back("/"); m_expr_sep.push_back("&&"); m_expr_sep.push_back("||"); m_expr_sep.push_back("=="); m_expr_sep.push_back(" "); m_expr_sep.push_back("\t"); m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")}); if (defines != nullptr) m_defines = *defines; }
ppreprocessor::ppreprocessor() { m_expr_sep.add("!"); m_expr_sep.add("("); m_expr_sep.add(")"); m_expr_sep.add("+"); m_expr_sep.add("-"); m_expr_sep.add("*"); m_expr_sep.add("/"); m_expr_sep.add("=="); m_expr_sep.add(" "); m_expr_sep.add("\t"); m_defines.add(define_t("__PLIB_PREPROCESSOR__", "1")); }
ppreprocessor::ppreprocessor(std::vector<define_t> *defines) : m_ifflag(0), m_level(0), m_lineno(0) { m_expr_sep.push_back("!"); m_expr_sep.push_back("("); m_expr_sep.push_back(")"); m_expr_sep.push_back("+"); m_expr_sep.push_back("-"); m_expr_sep.push_back("*"); m_expr_sep.push_back("/"); m_expr_sep.push_back("=="); m_expr_sep.push_back(" "); m_expr_sep.push_back("\t"); m_defines.insert({"__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1")}); if (defines != nullptr) { for (auto & p : *defines) { m_defines.insert({p.m_name, p}); } } }
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(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_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; }