Пример #1
0
        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);
                }
            }
        }
Пример #2
0
        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));
        }