• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2002 2004 2006 Joel de Guzman
3     http://spirit.sourceforge.net/
4 
5     Use, modification and distribution is subject to the Boost Software
6     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7     http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 
10 #include "template_stack.hpp"
11 #include <cassert>
12 #include "files.hpp"
13 
14 #ifdef BOOST_MSVC
15 #pragma warning(disable : 4355)
16 #endif
17 
18 namespace quickbook
19 {
template_symbol(std::string const & identifier_,std::vector<std::string> const & params_,value const & content_,template_scope const * lexical_parent_)20     template_symbol::template_symbol(
21         std::string const& identifier_,
22         std::vector<std::string> const& params_,
23         value const& content_,
24         template_scope const* lexical_parent_)
25         : identifier(identifier_)
26         , params(params_)
27         , content(content_)
28         , lexical_parent(lexical_parent_)
29     {
30         assert(
31             content.get_tag() == template_tags::block ||
32             content.get_tag() == template_tags::phrase ||
33             content.get_tag() == template_tags::snippet);
34     }
35 
template_stack()36     template_stack::template_stack()
37         : scope(template_stack::parser(*this)), scopes(), parent_1_4(0)
38     {
39         scopes.push_front(template_scope());
40         parent_1_4 = &scopes.front();
41     }
42 
find(std::string const & symbol) const43     template_symbol* template_stack::find(std::string const& symbol) const
44     {
45         for (template_scope const* i = &*scopes.begin(); i;
46              i = i->parent_scope) {
47             if (template_symbol* ts =
48                     boost::spirit::classic::find(i->symbols, symbol.c_str()))
49                 return ts;
50         }
51         return 0;
52     }
53 
find_top_scope(std::string const & symbol) const54     template_symbol* template_stack::find_top_scope(
55         std::string const& symbol) const
56     {
57         return boost::spirit::classic::find(
58             scopes.front().symbols, symbol.c_str());
59     }
60 
top() const61     template_symbols const& template_stack::top() const
62     {
63         BOOST_ASSERT(!scopes.empty());
64         return scopes.front().symbols;
65     }
66 
top_scope() const67     template_scope const& template_stack::top_scope() const
68     {
69         BOOST_ASSERT(!scopes.empty());
70         return scopes.front();
71     }
72 
add(template_symbol const & ts)73     bool template_stack::add(template_symbol const& ts)
74     {
75         BOOST_ASSERT(!scopes.empty());
76         BOOST_ASSERT(ts.lexical_parent);
77 
78         if (this->find_top_scope(ts.identifier)) {
79             return false;
80         }
81 
82         boost::spirit::classic::add(
83             scopes.front().symbols, ts.identifier.c_str(), ts);
84 
85         return true;
86     }
87 
push()88     void template_stack::push()
89     {
90         template_scope const& old_front = scopes.front();
91         scopes.push_front(template_scope());
92         scopes.front().parent_1_4 = parent_1_4;
93         scopes.front().parent_scope = &old_front;
94         parent_1_4 = &scopes.front();
95     }
96 
pop()97     void template_stack::pop()
98     {
99         parent_1_4 = scopes.front().parent_1_4;
100         scopes.pop_front();
101     }
102 
start_template(template_symbol const * symbol)103     void template_stack::start_template(template_symbol const* symbol)
104     {
105         // Quickbook 1.4-: When expanding the template continue to use the
106         //                 current scope (the dynamic scope).
107         // Quickbook 1.5+: Use the scope the template was defined in
108         //                 (the static scope).
109         if (symbol->content.get_file()->version() >= 105u) {
110             parent_1_4 = scopes.front().parent_1_4;
111             scopes.front().parent_scope = symbol->lexical_parent;
112         }
113         else {
114             scopes.front().parent_scope = scopes.front().parent_1_4;
115         }
116     }
117 }
118