void process_stack() { while (!m_stack.empty()) { string line; //putf8string line; string linemarker = new pfmt("# {0} \"{1}\"\n").op(m_stack.back().m_lineno, m_stack.back().m_name); push_out(linemarker); bool last_skipped = false; while ((line = m_stack.back().m_reader.ReadLine()) != null) { m_stack.back().m_lineno++; var r = process_line(line); if (r.second) { if (last_skipped) { push_out(new pfmt("# {0} \"{1}\"\n").op(m_stack.back().m_lineno, m_stack.back().m_name)); } push_out(r.first + "\n"); last_skipped = false; } else { last_skipped = true; } } m_stack.pop_back(); if (!m_stack.empty()) { linemarker = new pfmt("# {0} \"{1}\" 2\n").op(m_stack.back().m_lineno, m_stack.back().m_name); push_out(linemarker); } } }
std.pair <string, bool> process_line(string line_in) { bool line_cont = plib.pg.right(line_in, 1) == "\\"; string line = line_cont ? plib.pg.left(line_in, line_in.length() - 1) : line_in; if (m_state == state_e.LINE_CONTINUATION) { m_line += line; } else { m_line = line; } if (line_cont) { m_state = state_e.LINE_CONTINUATION; return(new std.pair <string, bool>("", false)); } m_state = state_e.PROCESS; line = process_comments(m_line); string lt = plib.pg.trim(plib.pg.replace_all(line, "\t", " ")); if (plib.pg.startsWith(lt, "#")) { ppreprocessor_string_list lti = plib.pg.psplit(lt, ' ', true); if (lti[0] == "#if") { m_if_level++; m_if_seen |= (1U << m_if_level); if (m_if_flag == 0) { lt = replace_macros(lt); simple_iter t = new simple_iter(this, tokenize(lt.substr(3), m_expr_sep, true, true)); //simple_iter<ppreprocessor> t(this, tokenize(lt.substr(3), m_expr_sep, true, true)); var val = (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 |= (1U << m_if_level); } else { m_elif |= (1U << m_if_level); } } } else if (lti[0] == "#ifdef") { m_if_level++; m_if_seen |= (1U << m_if_level); if (get_define(lti[1]) == null) { m_if_flag |= (1U << m_if_level); } else { m_elif |= (1U << m_if_level); } } else if (lti[0] == "#ifndef") { m_if_level++; m_if_seen |= (1U << m_if_level); if (get_define(lti[1]) != null) { m_if_flag |= (1U << m_if_level); } else { m_elif |= (1U << m_if_level); } } else if (lti[0] == "#else") // basically #elif (1) { if ((m_if_seen & (1U << m_if_level)) == 0) { error("#else without #if"); } if ((m_elif & (1U << m_if_level)) != 0) // elif disabled { m_if_flag |= (1U << m_if_level); } else { m_if_flag &= ~(1U << m_if_level); } m_elif |= (1U << m_if_level); } else if (lti[0] == "#elif") { if ((m_if_seen & (1U << m_if_level)) == 0) { error("#elif without #if"); } //if ((m_if_flag & (1 << m_if_level)) == 0) // m_if_flag ^= (1 << m_if_level); if ((m_elif & (1U << m_if_level)) != 0) // elif disabled { m_if_flag |= (1U << m_if_level); } else { m_if_flag &= ~(1U << m_if_level); } if (m_if_flag == 0) { //m_if_flag ^= (1 << m_if_level); lt = replace_macros(lt); simple_iter t = new simple_iter(this, tokenize(lt.substr(5), m_expr_sep, true, true)); //simple_iter<ppreprocessor> t(this, tokenize(lt.substr(5), m_expr_sep, true, true)); var val = (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 |= (1U << m_if_level); } else { m_elif |= (1U << m_if_level); } } } else if (lti[0] == "#endif") { if ((m_if_seen & (1U << m_if_level)) == 0) { error("#else without #if"); } m_if_seen &= ~(1U << m_if_level); m_elif &= ~(1U << m_if_level); m_if_flag &= ~(1U << m_if_level); m_if_level--; } else if (lti[0] == "#include") { if (m_if_flag == 0) { string arg = ""; for (size_t i = 1; i < lti.size(); i++) { arg += (lti[i] + " "); } arg = plib.pg.trim(arg); if (plib.pg.startsWith(arg, "\"") && plib.pg.endsWith(arg, "\"")) { arg = arg.substr(1, arg.length() - 2); // first try local context var l = plib.util.buildpath(m_stack.back().m_local_path, arg); var lstrm = m_sources.get_stream(l); if (!lstrm.empty()) { m_stack.emplace_back(new input_context(lstrm, plib.util.path(l), l)); //m_stack.emplace_back(input_context(lstrm.release_stream(), plib::util::path(l), l)); } else { var strm = m_sources.get_stream(arg); if (!strm.empty()) { m_stack.emplace_back(new input_context(strm, plib.util.path(arg), arg)); //m_stack.emplace_back(input_context(strm.release_stream(), plib::util::path(arg), arg)); } else { error("include not found:" + arg); } } } else { error("include misspelled:" + arg); } string linemarker = new pfmt("# {0} \"{1}\" 1\n").op(m_stack.back().m_lineno, m_stack.back().m_name); push_out(linemarker); } } else if (lti[0] == "#pragma") { if (m_if_flag == 0 && lti.size() > 3 && lti[1] == "NETLIST") { if (lti[2] == "warning") { error("NETLIST: " + catremainder(lti, 3, " ")); } } } else if (lti[0] == "#define") { if (m_if_flag == 0) { if (lti.size() < 2) { error("define needs at least one argument"); } simple_iter args = new simple_iter(this, tokenize(lt.substr(8), m_expr_sep, false, false)); //simple_iter<ppreprocessor> args(this, tokenize(lt.substr(8), m_expr_sep, false, false)); string n = args.next(); if (!is_valid_token(n)) { error("define expected identifier"); } var prevdef = get_define(n); if (lti.size() == 2) { if (prevdef != null && !prevdef.m_replace.empty()) { error("redefinition of " + n); } m_defines.insert(n, new define_t(n, "")); } else if (args.next_ws() == "(") { define_t def = new define_t(n); def.m_has_params = true; var token = args.next(); while (true) { if (token == ")") { break; } def.m_params.push_back(token); token = args.next(); if (token != "," && token != ")") { error(new pfmt("expected , or ), found <{0}>").op(token)); } if (token == ",") { token = args.next(); } } string r = ""; while (!args.eod()) { r += args.next_ws(); } def.m_replace = r; if (prevdef != null && prevdef.m_replace != r) { error("redefinition of " + n); } m_defines.insert(n, def); } else { string r = ""; while (!args.eod()) { r += args.next_ws(); } if (prevdef != null && prevdef.m_replace != r) { error("redefinition of " + n); } m_defines.insert(n, new define_t(n, r)); } } } else if (lti[0] == "#undef") { if (m_if_flag == 0) { if (lti.size() < 2) { error("undef needs at least one argument"); } simple_iter args = new simple_iter(this, tokenize(lt.substr(7), m_expr_sep, false, false)); //simple_iter<ppreprocessor> args(this, tokenize(lt.substr(7), m_expr_sep, false, false)); string n = args.next(); if (!is_valid_token(n)) { error("undef expected identifier"); } m_defines.erase(n); } } else { if (m_if_flag == 0) { error("unknown directive"); } } return(new std.pair <string, bool>("", false)); } if (m_if_flag == 0) { return(new std.pair <string, bool>(replace_macros(lt), true)); } return(new std.pair <string, bool>("", false)); }