/*=============================================================================
    Boost.Wave: A Standard compliant C++ preprocessor library
    Definition of the preprocessor context
    
    http://www.boost.org/

    Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost
    Software License, Version 1.0. (See accompanying file
    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

#if !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)
#define CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED

#include <string>
#include <vector>
#include <stack>

#include <boost/concept_check.hpp>
#include <boost/noncopyable.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/pool/pool_alloc.hpp>

#include <boost/wave/wave_config.hpp>
#if BOOST_WAVE_SERIALIZATION != 0
#include <boost/serialization/serialization.hpp>
#include <boost/wave/wave_config_constant.hpp>
#endif
#include <boost/wave/token_ids.hpp>

#include <boost/wave/util/unput_queue_iterator.hpp>
#include <boost/wave/util/cpp_ifblock.hpp>
#include <boost/wave/util/cpp_include_paths.hpp>
#include <boost/wave/util/iteration_context.hpp>
#include <boost/wave/util/cpp_iterator.hpp>
#include <boost/wave/util/cpp_macromap.hpp>

#include <boost/wave/preprocessing_hooks.hpp>
#include <boost/wave/whitespace_handling.hpp>
#include <boost/wave/cpp_iteration_context.hpp>
#include <boost/wave/language_support.hpp>

// this must occur after all of the includes and before any code appears
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_PREFIX
#endif

///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {

///////////////////////////////////////////////////////////////////////////////
// 
//  The C/C++ preprocessor context template class
//
//      The boost::wave::context template is the main interface class to 
//      control the behavior of the preprocessing engine.
//
//      The following template parameters has to be supplied:
//
//      IteratorT       The iterator type of the underlying input stream
//      LexIteratorT    The lexer iterator type to use as the token factory
//      InputPolicyT    The input policy type to use for loading the files
//                      to be included. This template parameter is optional and 
//                      defaults to the 
//                          iteration_context_policies::load_file_to_string
//                      type.
//      HooksT          The hooks policy to use for different notification 
//                      callbacks. This template parameter is optional and
//                      defaults to the
//                          context_policies::default_preprocessing_hooks
//                      type.
//      DerivedT        The type of the type being derived from the context
//                      type (if any). This template parameter is optional and
//                      defaults to 'this_type', which means that the context 
//                      type will be used assuming no derived type exists.
//
///////////////////////////////////////////////////////////////////////////////

struct this_type {};

template <
    typename IteratorT,
    typename LexIteratorT, 
    typename InputPolicyT = iteration_context_policies::load_file_to_string,
    typename HooksT = context_policies::eat_whitespace<typename LexIteratorT::token_type>,
    typename DerivedT = this_type
>
class context : private boost::noncopyable
{
private:
    typedef typename mpl::if_<
            is_same<DerivedT, this_type>, context, DerivedT
        >::type actual_context_type;

public:

// concept checks
// the given iterator should be at least a forward iterator type
    BOOST_CLASS_REQUIRE(IteratorT, boost, ForwardIteratorConcept);
    
// public typedefs
    typedef typename LexIteratorT::token_type       token_type;
    typedef typename token_type::string_type        string_type;

    typedef IteratorT                               target_iterator_type;
    typedef LexIteratorT                            lexer_type;
    typedef pp_iterator<context>                    iterator_type;

    typedef InputPolicyT                            input_policy_type;
    typedef typename token_type::position_type      position_type;

// type of a token sequence
    typedef std::list<token_type, boost::fast_pool_allocator<token_type> > 
        token_sequence_type;
// type of the policies
    typedef HooksT                                  hook_policy_type;

private:
// stack of shared_ptr's to the pending iteration contexts 
    typedef boost::shared_ptr<base_iteration_context<context, lexer_type> > 
        iteration_ptr_type;
    typedef boost::wave::util::iteration_context_stack<iteration_ptr_type> 
            iteration_context_stack_type;
    typedef typename iteration_context_stack_type::size_type iter_size_type;

    context *this_() { return this; }           // avoid warning in constructor

public:
    context(target_iterator_type const &first_, target_iterator_type const &last_, 
            char const *fname = "<Unknown>", HooksT const &hooks_ = HooksT())
    :   first(first_), last(last_), filename(fname)
      , has_been_initialized(false)
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
      , current_filename(fname)
#endif 
      , current_relative_filename(fname)
      , macros(*this_())
      , language(language_support(
                      support_cpp 
                    | support_option_convert_trigraphs 
                    | support_option_emit_line_directives 
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
                    | support_option_include_guard_detection
#endif
#if BOOST_WAVE_EMIT_PRAGMA_DIRECTIVES != 0
                    | support_option_emit_pragma_directives
#endif
                    | support_option_insert_whitespace
                   ))
      , hooks(hooks_)
    {
        macros.init_predefined_macros(fname);
    }

// default copy constructor
// default assignment operator
// default destructor

// iterator interface
    iterator_type begin() 
    { 
        std::string fname(filename);
        if (filename != "<Unknown>" && filename != "<stdin>") {
            using namespace boost::filesystem;
            path fpath(complete(path(filename)));
            fname = fpath.string();
        }
        return iterator_type(*this, first, last, position_type(fname.c_str())); 
    }
    iterator_type begin(
        target_iterator_type const &first_, 
        target_iterator_type const &last_) 
    { 
        std::string fname(filename);
        if (filename != "<Unknown>" && filename != "<stdin>") {
            using namespace boost::filesystem;
            path fpath(complete(path(filename)));
            fname = fpath.string();
        }
        return iterator_type(*this, first_, last_, position_type(fname.c_str())); 
    }
    iterator_type end() const 
        { return iterator_type(); }

// maintain include paths
    bool add_include_path(char const *path_)
        { return includes.add_include_path(path_, false);}
    bool add_sysinclude_path(char const *path_)
        { return includes.add_include_path(path_, true);}
    void set_sysinclude_delimiter() { includes.set_sys_include_delimiter(); }
    typename iteration_context_stack_type::size_type get_iteration_depth() const 
        { return iter_ctxs.size(); }

// maintain defined macros
#if BOOST_WAVE_ENABLE_COMMANDLINE_MACROS != 0
    template <typename StringT>
    bool add_macro_definition(StringT macrostring, bool is_predefined = false)
    { 
        return boost::wave::util::add_macro_definition(*this, 
            util::to_string<std::string>(macrostring), is_predefined, 
            get_language()); 
    }
#endif 
// Define and undefine macros, macro introspection
    template <typename StringT>
    bool add_macro_definition(StringT const &name, position_type const& pos, 
        bool has_params, std::vector<token_type> &parameters, 
        token_sequence_type &definition, bool is_predefined = false)
    { 
        return macros.add_macro(
            token_type(T_IDENTIFIER, util::to_string<string_type>(name), pos), 
            has_params, parameters, definition, is_predefined); 
    }
    template <typename StringT>
    bool is_defined_macro(StringT const &str) const
    { 
        return macros.is_defined(util::to_string<string_type>(str)); 
    }
    template <typename StringT>
    bool get_macro_definition(StringT const &name, 
        bool &has_params, bool &is_predefined, position_type &pos,
        std::vector<token_type> &parameters, 
        token_sequence_type &definition) const
    { 
        return macros.get_macro(util::to_string<string_type>(name), 
            has_params, is_predefined, pos, parameters, definition); 
    }
    template <typename StringT>
    bool remove_macro_definition(StringT const& undefname, bool even_predefined = false)
    { 
        // strip leading and trailing whitespace
        string_type name = util::to_string<string_type>(undefname);
        typename string_type::size_type pos = name.find_first_not_of(" \t");
        if (pos != string_type::npos) {
            typename string_type::size_type endpos = name.find_last_not_of(" \t");
            name = name.substr(pos, endpos-pos+1);
        }

#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
        // ensure this gets removed from the list of include guards as well
        includes.remove_pragma_once_header(
            util::to_string<std::string>(name));
#endif
        return macros.remove_macro(name, macros.get_main_pos(), even_predefined); 
    }
    void reset_macro_definitions() 
        { macros.reset_macromap(); macros.init_predefined_macros(); }

// Iterate over names of defined macros
    typedef boost::wave::util::macromap<context> macromap_type;
    typedef typename macromap_type::name_iterator name_iterator;
    typedef typename macromap_type::const_name_iterator const_name_iterator;

    name_iterator macro_names_begin() { return macros.begin(); }
    name_iterator macro_names_end() { return macros.end(); }
    const_name_iterator macro_names_begin() const { return macros.begin(); }
    const_name_iterator macro_names_end() const { return macros.end(); }

// This version now is used internally mainly, but since it was a documented
// API function we leave it in the public interface.
    bool add_macro_definition(token_type const &name, bool has_params,
        std::vector<token_type> &parameters, token_sequence_type &definition,
        bool is_predefined = false)
    { 
        return macros.add_macro(name, has_params, parameters, definition, 
            is_predefined); 
    }

// get the Wave version information 
    static std::string get_version()  
    { 
        boost::wave::util::predefined_macros p; 
        return util::to_string<std::string>(p.get_fullversion()); 
    }
    static std::string get_version_string()  
    {
        boost::wave::util::predefined_macros p;
        return util::to_string<std::string>(p.get_versionstr()); 
    }

// access current language options
    void set_language(boost::wave::language_support language_,
                      bool reset_macros = true) 
    { 
        language = language_; 
        if (reset_macros)
            reset_macro_definitions();
    }
    boost::wave::language_support get_language() const { return language; }

// change and ask for maximal possible include nesting depth
    void set_max_include_nesting_depth(iter_size_type new_depth)
        { iter_ctxs.set_max_include_nesting_depth(new_depth); }
    iter_size_type get_max_include_nesting_depth() const
        { return iter_ctxs.get_max_include_nesting_depth(); }

// access the policies
    hook_policy_type &get_hooks() { return hooks; }
    hook_policy_type const &get_hooks() const { return hooks; }

// return type of actually used context type (might be the derived type)
    actual_context_type& derived() 
        { return *static_cast<actual_context_type*>(this); } 
    actual_context_type const& derived() const
        { return *static_cast<actual_context_type const*>(this); } 

// return the directory of the currently preprocessed file
    boost::filesystem::path get_current_directory() const
        { return includes.get_current_directory(); }

#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
protected:
    friend class boost::wave::pp_iterator<context>;
    friend class boost::wave::impl::pp_iterator_functor<context>;
#endif

// make sure the context has been initialized    
    void init_context()
    {
        if (!has_been_initialized) {
            std::string fname(filename);
            if (filename != "<Unknown>" && filename != "<stdin>") {
                using namespace boost::filesystem;
                path fpath(complete(path(filename)));
                fname = fpath.string();
                includes.set_current_directory(fname.c_str());
            }
            has_been_initialized = true;  // execute once
        }
    }

    template <typename IteratorT2>
    bool is_defined_macro(IteratorT2 const &begin, IteratorT2 const &end) const
        { return macros.is_defined(begin, end); }

// maintain include paths (helper functions)
    bool find_include_file (std::string &s, std::string &d, bool is_system, 
        char const *current_file) const
    { return includes.find_include_file(s, d, is_system, current_file); }
    void set_current_directory(char const *path_) 
        { includes.set_current_directory(path_); }

// conditional compilation contexts
    bool get_if_block_status() const { return ifblocks.get_status(); }
    bool get_if_block_some_part_status() const 
        { return ifblocks.get_some_part_status(); } 
    bool get_enclosing_if_block_status() const
        { return ifblocks.get_enclosing_status(); }
    void enter_if_block(bool new_status) 
        { ifblocks.enter_if_block(new_status); }
    bool enter_elif_block(bool new_status) 
        { return ifblocks.enter_elif_block(new_status); }
    bool enter_else_block() { return ifblocks.enter_else_block(); }
    bool exit_if_block() { return ifblocks.exit_if_block(); }
    typename boost::wave::util::if_block_stack::size_type get_if_block_depth() const 
        { return ifblocks.get_if_block_depth(); }

// stack of iteration contexts
    iteration_ptr_type pop_iteration_context()
        { iteration_ptr_type top = iter_ctxs.top(); iter_ctxs.pop(); return top; }
    void push_iteration_context(position_type const &act_pos, iteration_ptr_type iter_ctx)
        { iter_ctxs.push(*this, act_pos, iter_ctx); }

    position_type &get_main_pos() { return macros.get_main_pos(); }

///////////////////////////////////////////////////////////////////////////////
//
//  expand_tokensequence(): 
//      expands all macros contained in a given token sequence, handles '##' 
//      and '#' pp operators and re-scans the resulting sequence 
//      (essentially pre-processes the token sequence).
//
//      The expand_undefined parameter is true during macro expansion inside
//      a C++ expression given for a #if or #elif statement. 
//
///////////////////////////////////////////////////////////////////////////////
    template <typename IteratorT2>
    token_type expand_tokensequence(IteratorT2 &first_, IteratorT2 const &last_, 
        token_sequence_type &pending, token_sequence_type &expanded, 
        bool& seen_newline, bool expand_undefined = false)
    {
        return macros.expand_tokensequence(first_, last_, pending, expanded, 
            seen_newline, expand_undefined);
    }

    template <typename IteratorT2>
    void expand_whole_tokensequence(IteratorT2 &first_, IteratorT2 const &last_, 
        token_sequence_type &expanded, bool expand_undefined = true)
    {
        macros.expand_whole_tokensequence(expanded, first_, last_, 
            expand_undefined);

    // remove any contained placeholder
        boost::wave::util::impl::remove_placeholders(expanded);
    }

public:
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
// support for #pragma once
// maintain the real name of the current preprocessed file
    void set_current_filename(char const *real_name)
        { current_filename = real_name; }
    std::string const &get_current_filename() const 
        { return current_filename; }

// maintain the list of known headers containing #pragma once 
    bool has_pragma_once(std::string const &filename_)
        { return includes.has_pragma_once(filename_); }
    bool add_pragma_once_header(std::string const &filename_,
            std::string const& guard_name)
    { 
        get_hooks().detected_include_guard(derived(), filename_, guard_name);
        return includes.add_pragma_once_header(filename_, guard_name); 
    }
    bool add_pragma_once_header(token_type const &pragma_, 
        std::string const &filename_)
    { 
        get_hooks().detected_pragma_once(derived(), pragma_, filename_);
        return includes.add_pragma_once_header(filename_, 
            "__BOOST_WAVE_PRAGMA_ONCE__"); 
    }
#endif 

    void set_current_relative_filename(char const *real_name)
        { current_relative_filename = real_name; }
    std::string const &get_current_relative_filename() const 
        { return current_relative_filename; }

#if BOOST_WAVE_SERIALIZATION != 0
public:
    BOOST_STATIC_CONSTANT(unsigned int, version = 0x10);
    BOOST_STATIC_CONSTANT(unsigned int, version_mask = 0x0f);

private:
    friend class boost::serialization::access;
    template<class Archive>
    void save(Archive & ar, const unsigned int version) const
    {
        using namespace boost::serialization;

        string_type cfg(BOOST_PP_STRINGIZE(BOOST_WAVE_CONFIG));
        string_type kwd(BOOST_WAVE_PRAGMA_KEYWORD);
        string_type strtype(BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE)));
        ar & make_nvp("config", cfg);
        ar & make_nvp("pragma_keyword", kwd);
        ar & make_nvp("string_type", strtype);

        ar & make_nvp("language_options", language);
        ar & make_nvp("macro_definitions", macros);
        ar & make_nvp("include_settings", includes);
    }
    template<class Archive>
    void load(Archive & ar, const unsigned int loaded_version)
    {
        using namespace boost::serialization;
        if (version != (loaded_version & ~version_mask)) {
            BOOST_WAVE_THROW_CTX((*this), preprocess_exception, 
                incompatible_config, "cpp_context state version", 
                get_main_pos());
            return;
        }

        // check compatibility of the stored information
        string_type config, pragma_keyword, string_type_str;

        // BOOST_PP_STRINGIZE(BOOST_WAVE_CONFIG)
        ar & make_nvp("config", config);
        if (config != BOOST_PP_STRINGIZE(BOOST_WAVE_CONFIG)) {
            BOOST_WAVE_THROW_CTX((*this), preprocess_exception, 
                incompatible_config, "BOOST_WAVE_CONFIG", get_main_pos());
            return;
        }

        // BOOST_WAVE_PRAGMA_KEYWORD
        ar & make_nvp("pragma_keyword", pragma_keyword);
        if (pragma_keyword != BOOST_WAVE_PRAGMA_KEYWORD) {
            BOOST_WAVE_THROW_CTX((*this), preprocess_exception, 
                incompatible_config, "BOOST_WAVE_PRAGMA_KEYWORD", 
                get_main_pos());
            return;
        }

        // BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE))
        ar & make_nvp("string_type", string_type_str);
        if (string_type_str != BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE))) {
            BOOST_WAVE_THROW_CTX((*this), preprocess_exception, 
                incompatible_config, "BOOST_WAVE_STRINGTYPE", get_main_pos());
            return;
        }

        try {
            // read in the useful bits
            ar & make_nvp("language_options", language);
            ar & make_nvp("macro_definitions", macros);
            ar & make_nvp("include_settings", includes);
        }
        catch (boost::wave::preprocess_exception const& e) {
        // catch version mismatch exceptions and call error handler
            get_hooks().throw_exception(derived(), e); 
        }
    }
    BOOST_SERIALIZATION_SPLIT_MEMBER()
#endif

private:
// the main input stream
    target_iterator_type first;         // underlying input stream
    target_iterator_type last;
    std::string filename;               // associated main filename
    bool has_been_initialized;          // set cwd once
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
    std::string current_filename;       // real name of current preprocessed file
#endif 
    std::string current_relative_filename;        // real relative name of current preprocessed file

    boost::wave::util::if_block_stack ifblocks;   // conditional compilation contexts
    boost::wave::util::include_paths includes;    // lists of include directories to search
    iteration_context_stack_type iter_ctxs;       // iteration contexts
    macromap_type macros;                         // map of defined macros
    boost::wave::language_support language;       // supported language/extensions
    hook_policy_type hooks;                       // hook policy instance
};

///////////////////////////////////////////////////////////////////////////////
}   // namespace wave
}   // namespace boost

#if BOOST_WAVE_SERIALIZATION != 0
namespace boost { namespace serialization {

template<
    typename Iterator, typename LexIterator, 
    typename InputPolicy, typename Hooks
>
struct tracking_level<boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks> >
{
    typedef mpl::integral_c_tag tag;
    typedef mpl::int_<track_never> type;
    BOOST_STATIC_CONSTANT(
        int,
        value = tracking_level::type::value
    );
};

template<
    typename Iterator, typename LexIterator, 
    typename InputPolicy, typename Hooks
>
struct version<boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks> >
{
    typedef boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks>
        target_type;
    typedef mpl::int_<target_type::version> type;
    typedef mpl::integral_c_tag tag;
    BOOST_STATIC_CONSTANT(unsigned int, value = version::type::value);
};

}}  // namespace boost::serialization
#endif

// the suffix header occurs after all of the code
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_SUFFIX
#endif

#endif // !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)
