|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r59324 - branches/quickbook-1.5-spirit2
From: daniel_james_at_[hidden]
Date: 2010-01-27 17:07:24
Author: danieljames
Date: 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
New Revision: 59324
URL: http://svn.boost.org/trac/boost/changeset/59324
Log:
Move most of the template implementation into template.[ch]pp
Added:
branches/quickbook-1.5-spirit2/template.cpp (contents, props changed)
- copied, changed from r59323, /branches/quickbook-1.5-spirit2/phrase_template.cpp
branches/quickbook-1.5-spirit2/template.hpp (contents, props changed)
Removed:
branches/quickbook-1.5-spirit2/phrase_template.cpp
branches/quickbook-1.5-spirit2/template_stack.cpp
branches/quickbook-1.5-spirit2/template_stack.hpp
Text files modified:
branches/quickbook-1.5-spirit2/Jamfile.v2 | 3
branches/quickbook-1.5-spirit2/actions_class.cpp | 1
branches/quickbook-1.5-spirit2/actions_class.hpp | 3
branches/quickbook-1.5-spirit2/block.hpp | 11 -
branches/quickbook-1.5-spirit2/block_actions.cpp | 33 +----
branches/quickbook-1.5-spirit2/code_snippet.cpp | 7
branches/quickbook-1.5-spirit2/code_snippet_types.hpp | 6
branches/quickbook-1.5-spirit2/fwd.hpp | 8 +
branches/quickbook-1.5-spirit2/parse_types.hpp | 1
branches/quickbook-1.5-spirit2/phrase.cpp | 16 +-
branches/quickbook-1.5-spirit2/phrase.hpp | 10
branches/quickbook-1.5-spirit2/template.cpp | 217 +++++++++++++++++++++++++++++++--------
12 files changed, 206 insertions(+), 110 deletions(-)
Modified: branches/quickbook-1.5-spirit2/Jamfile.v2
==============================================================================
--- branches/quickbook-1.5-spirit2/Jamfile.v2 (original)
+++ branches/quickbook-1.5-spirit2/Jamfile.v2 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -26,12 +26,11 @@
input_path.cpp
post_process.cpp
collector.cpp
- template_stack.cpp
+ template.cpp
markups.cpp
phrase.cpp
phrase_actions.cpp
phrase_image.cpp
- phrase_template.cpp
block.cpp
block_actions.cpp
block_list.cpp
Modified: branches/quickbook-1.5-spirit2/actions_class.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/actions_class.cpp (original)
+++ branches/quickbook-1.5-spirit2/actions_class.cpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -37,7 +37,6 @@
, source_mode("c++")
// temporary or global state
- , template_info()
, template_depth(0)
, templates()
, error_count(0)
Modified: branches/quickbook-1.5-spirit2/actions_class.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/actions_class.hpp (original)
+++ branches/quickbook-1.5-spirit2/actions_class.hpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -15,7 +15,7 @@
#include "fwd.hpp"
#include "actions.hpp"
#include "collector.hpp"
-#include "template_stack.hpp"
+#include "template.hpp"
namespace quickbook
{
@@ -61,7 +61,6 @@
std::stack<state_tuple> state_stack;
// temporary or global state
- string_list template_info;
int template_depth;
template_stack templates;
int error_count;
Modified: branches/quickbook-1.5-spirit2/block.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/block.hpp (original)
+++ branches/quickbook-1.5-spirit2/block.hpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -62,14 +62,6 @@
title content;
};
- struct define_template
- {
- std::string id;
- std::vector<std::string> params;
- quickbook::file_position position;
- std::string body;
- };
-
struct def_macro
{
std::string macro_identifier;
@@ -119,7 +111,6 @@
void process(quickbook::actions&, end_section const&);
void process(quickbook::actions&, heading const&);
void process(quickbook::actions&, def_macro const&);
- void process(quickbook::actions&, define_template const&);
void process(quickbook::actions&, variablelist const&);
void process(quickbook::actions&, table const&);
void process(quickbook::actions&, xinclude const&);
@@ -127,4 +118,4 @@
void process(quickbook::actions&, include const&);
}
-#endif
\ No newline at end of file
+#endif
Modified: branches/quickbook-1.5-spirit2/block_actions.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/block_actions.cpp (original)
+++ branches/quickbook-1.5-spirit2/block_actions.cpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -182,20 +182,11 @@
void process(quickbook::actions& actions, define_template const& x)
{
- if (actions.templates.find_top_scope(x.id))
- {
+ if(!actions.templates.add(x)) {
detail::outerr(x.position.file, x.position.line)
- << "Template Redefinition: " << actions.template_info[0] << std::endl;
+ << "Template Redefinition: " << x.id << std::endl;
++actions.error_count;
}
-
- std::vector<std::string> info;
- info.reserve(x.params.size() + 2);
- info.push_back(x.id);
- info.insert(info.end(), x.params.begin(), x.params.end());
- info.push_back(x.body);
-
- actions.templates.add(x.id, template_symbol(info, x.position));
}
void process(quickbook::actions& actions, variablelist const& x)
@@ -300,8 +291,8 @@
{
int load_snippets(
std::string const& file
- , std::vector<template_symbol>& storage // snippets are stored in a
- // vector of template_symbols
+ , std::vector<define_template>& storage // for storing snippets are stored in a
+ // vector of define_templates
, std::string const& extension
, std::string const& doc_id)
{
@@ -442,24 +433,18 @@
{
fs::path path = include_search(actions.filename.branch_path(), x.path);
std::string ext = fs::extension(path);
- std::vector<template_symbol> storage;
+ std::vector<define_template> storage;
actions.error_count +=
load_snippets(path.string(), storage, ext, actions.doc_id);
- BOOST_FOREACH(template_symbol const& ts, storage)
+ BOOST_FOREACH(define_template const& definition, storage)
{
- std::string tname = boost::get<0>(ts)[0];
- if (actions.templates.find_top_scope(tname))
+ if (!actions.templates.add(definition))
{
- file_position const pos = boost::get<1>(ts);
- detail::outerr(pos.file, pos.line)
- << "Template Redefinition: " << tname << std::endl;
+ detail::outerr(definition.position.file, definition.position.line)
+ << "Template Redefinition: " << definition.id << std::endl;
++actions.error_count;
}
- else
- {
- actions.templates.add(tname, ts);
- }
}
}
}
\ No newline at end of file
Modified: branches/quickbook-1.5-spirit2/code_snippet.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/code_snippet.cpp (original)
+++ branches/quickbook-1.5-spirit2/code_snippet.cpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -102,10 +102,9 @@
}
}
- std::vector<std::string> tinfo;
- tinfo.push_back(x.identifier);
- tinfo.push_back(actions.snippet);
- actions.storage.push_back(template_symbol(tinfo, x.position));
+ std::vector<std::string> empty_params;
+ actions.storage.push_back(define_template(
+ x.identifier, empty_params, actions.snippet, x.position));
callout_id += actions.callouts.size();
actions.callouts.clear();
Modified: branches/quickbook-1.5-spirit2/code_snippet_types.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/code_snippet_types.hpp (original)
+++ branches/quickbook-1.5-spirit2/code_snippet_types.hpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -17,8 +17,6 @@
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/support_unused.hpp>
#include "fwd.hpp"
-// TODO: Convert template_symbol into a struct so it can be forward declared.
-#include "template_stack.hpp"
namespace quickbook
{
@@ -67,7 +65,7 @@
struct code_snippet_actions
{
- code_snippet_actions(std::vector<template_symbol>& storage,
+ code_snippet_actions(std::vector<define_template>& storage,
std::string const& doc_id,
char const* source_type)
: process(*this)
@@ -104,7 +102,7 @@
std::string code;
std::string snippet;
std::vector<std::string> callouts;
- std::vector<template_symbol>& storage;
+ std::vector<define_template>& storage;
std::string const doc_id;
char const* const source_type;
};
Modified: branches/quickbook-1.5-spirit2/fwd.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/fwd.hpp (original)
+++ branches/quickbook-1.5-spirit2/fwd.hpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -22,10 +22,16 @@
struct collector;
struct string_stream;
-
+
typedef boost::spirit::classic::position_iterator<
std::string::const_iterator> iterator;
typedef boost::spirit::classic::file_position file_position;
+
+ // templates
+
+ struct call_template;
+ struct define_template;
+ struct template_symbol;
}
#endif
\ No newline at end of file
Modified: branches/quickbook-1.5-spirit2/parse_types.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/parse_types.hpp (original)
+++ branches/quickbook-1.5-spirit2/parse_types.hpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -16,7 +16,6 @@
namespace quickbook
{
-
struct markup {
markup()
: pre(""), post("") {}
Modified: branches/quickbook-1.5-spirit2/phrase.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/phrase.cpp (original)
+++ branches/quickbook-1.5-spirit2/phrase.cpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -25,9 +25,6 @@
#include "markups.hpp"
#include "quickbook.hpp"
#include "parse_utils.hpp"
-/*
-#include "utils.hpp"
-*/
BOOST_FUSION_ADAPT_STRUCT(
quickbook::anchor,
@@ -54,7 +51,6 @@
(char const*, dummy)
)
-
BOOST_FUSION_ADAPT_STRUCT(
quickbook::image,
(quickbook::file_position, position)
@@ -69,11 +65,11 @@
)
BOOST_FUSION_ADAPT_STRUCT(
- quickbook::template_,
+ quickbook::call_template,
(quickbook::file_position, position)
(bool, escape)
- (quickbook::template_symbol, symbol)
- (std::vector<std::string>, params)
+ (quickbook::template_symbol const*, symbol)
+ (std::vector<std::string>, args)
)
namespace quickbook
@@ -100,7 +96,7 @@
qi::rule<iterator, file_position()> position;
- qi::rule<iterator, quickbook::template_()> template_;
+ qi::rule<iterator, quickbook::call_template()> call_template;
qi::rule<iterator, std::string()> template_arg_1_4, template_arg_1_5;
qi::rule<iterator, std::vector<std::string>() > template_args;
@@ -193,7 +189,7 @@
// Template call
- template_ =
+ call_template =
position
>> ( '`' >> qi::attr(true)
| qi::attr(false)
@@ -306,7 +302,7 @@
| source_mode
| formatted
| footnote
- | template_
+ | call_template
| break_
)
>> ']'
Modified: branches/quickbook-1.5-spirit2/phrase.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/phrase.hpp (original)
+++ branches/quickbook-1.5-spirit2/phrase.hpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -10,11 +10,11 @@
#if !defined(BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP)
#define BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP
+#include <vector>
#include <string>
#include <map>
#include "fwd.hpp"
#include "parse_types.hpp"
-#include "template_stack.hpp"
namespace quickbook
{
@@ -25,11 +25,11 @@
std::string mode;
};
- struct template_ {
+ struct call_template {
file_position position;
bool escape;
- template_symbol symbol;
- std::vector<std::string> params;
+ template_symbol const* symbol;
+ std::vector<std::string> args;
};
struct anchor {
@@ -68,7 +68,7 @@
void process(quickbook::actions&, source_mode const&);
void process(quickbook::actions&, macro const&);
- void process(quickbook::actions&, template_ const&);
+ void process(quickbook::actions&, call_template const&);
void process(quickbook::actions&, anchor const&);
void process(quickbook::actions&, link const&);
void process(quickbook::actions&, simple_markup const&);
Deleted: branches/quickbook-1.5-spirit2/phrase_template.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/phrase_template.cpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
+++ (empty file)
@@ -1,301 +0,0 @@
-/*=============================================================================
- Copyright (c) 2002 2004 2006 Joel de Guzman
- Copyright (c) 2004 Eric Niebler
- http://spirit.sourceforge.net/
-
- Use, modification and distribution is subject to 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)
-=============================================================================*/
-
-#include "phrase.hpp"
-#include "grammars.hpp"
-#include "actions_class.hpp"
-#include "quickbook.hpp"
-#include "utils.hpp"
-
-namespace quickbook
-{
- namespace
- {
- std::string::size_type find_bracket_end(std::string const& str, std::string::size_type pos)
- {
- unsigned int depth = 1;
-
- while(depth > 0) {
- pos = str.find_first_of("[]\\", pos);
- if(pos == std::string::npos) return pos;
-
- if(str[pos] == '\\')
- {
- pos += 2;
- }
- else
- {
- depth += (str[pos] == '[') ? 1 : -1;
- ++pos;
- }
- }
-
- return pos;
- }
-
- std::string::size_type find_first_seperator(std::string const& str)
- {
- if(qbk_version_n < 105) {
- return str.find_first_of(" \t\r\n");
- }
- else {
- std::string::size_type pos = 0;
-
- while(true)
- {
- pos = str.find_first_of(" \t\r\n\\[", pos);
- if(pos == std::string::npos) return pos;
-
- switch(str[pos])
- {
- case '[':
- pos = find_bracket_end(str, pos + 1);
- break;
- case '\\':
- pos += 2;
- break;
- default:
- return pos;
- }
- }
- }
- }
-
- bool break_arguments(
- std::vector<std::string>& params
- , std::vector<std::string> const& template_
- , file_position const& pos
- )
- {
- // Quickbook 1.4-: If there aren't enough parameters seperated by
- // '..' then seperate the last parameter using
- // whitespace.
- // Quickbook 1.5+: If '..' isn't used to seperate the parameters
- // then use whitespace to separate them
- // (2 = template name + argument).
-
- if (qbk_version_n < 105 || params.size() == 1)
- {
- // template_.size() - 2 because template_ also includes the name and body.
- while (params.size() < template_.size() - 2 )
- {
- // Try to break the last argument at the first space found
- // and push it into the back of params. Do this
- // recursively until we have all the expected number of
- // arguments, or if there are no more spaces left.
-
- std::string& str = params.back();
- std::string::size_type l_pos = find_first_seperator(str);
- if (l_pos == std::string::npos)
- break;
- std::string first(str.begin(), str.begin()+l_pos);
- std::string::size_type r_pos = str.find_first_not_of(" \t\r\n", l_pos);
- if (r_pos == std::string::npos)
- break;
- std::string second(str.begin()+r_pos, str.end());
- str = first;
- params.push_back(second);
- }
- }
-
- if (params.size() != template_.size() - 2)
- {
- detail::outerr(pos.file, pos.line)
- << "Invalid number of arguments passed. Expecting: "
- << template_.size()-2
- << " argument(s), got: "
- << params.size()
- << " argument(s) instead."
- << std::endl;
- return false;
- }
- return true;
- }
-
- std::pair<bool, std::vector<std::string>::const_iterator>
- get_arguments(
- std::vector<std::string>& params
- , std::vector<std::string> const& template_
- , template_scope const& scope
- , file_position const& pos
- , quickbook::actions& actions
- )
- {
- std::vector<std::string>::const_iterator arg = params.begin();
- std::vector<std::string>::const_iterator tpl = template_.begin()+1;
-
- // Store each of the argument passed in as local templates:
- while (arg != params.end())
- {
- std::vector<std::string> tinfo;
- tinfo.push_back(*tpl);
- tinfo.push_back(*arg);
- template_symbol template_(tinfo, pos, &scope);
-
- if (actions.templates.find_top_scope(*tpl))
- {
- detail::outerr(pos.file,pos.line)
- << "Duplicate Symbol Found" << std::endl;
- ++actions.error_count;
- return std::make_pair(false, tpl);
- }
- else
- {
- actions.templates.add(*tpl, template_);
- }
- ++arg; ++tpl;
- }
- return std::make_pair(true, tpl);
- }
-
- bool parse_template(
- std::string& body
- , std::string& result
- , file_position const& template_pos
- , bool template_escape
- , quickbook::actions& actions
- )
- {
- // How do we know if we are to parse the template as a block or
- // a phrase? We apply a simple heuristic: if the body starts with
- // a newline, then we regard it as a block, otherwise, we parse
- // it as a phrase.
-
- std::string::const_iterator iter = body.begin();
- while (iter != body.end() && ((*iter == ' ') || (*iter == '\t')))
- ++iter; // skip spaces and tabs
- bool is_block = (iter != body.end()) && ((*iter == '\r') || (*iter == '\n'));
- bool r = false;
-
- if (template_escape)
- {
- // escape the body of the template
- // we just copy out the literal body
- result = body;
- r = true;
- }
- else if (!is_block)
- {
- simple_phrase_grammar phrase_p(actions);
-
- // do a phrase level parse
- iterator first(body.begin(), body.end(), actions.filename.native_file_string().c_str());
- first.set_position(template_pos);
- iterator last(body.end(), body.end());
- r = boost::spirit::qi::parse(first, last, phrase_p) && first == last;
- actions.phrase.swap(result);
- }
- else
- {
- block_grammar block_p(actions);
-
- // do a block level parse
- // ensure that we have enough trailing newlines to eliminate
- // the need to check for end of file in the grammar.
- body.push_back('\n');
- body.push_back('\n');
- while (iter != body.end() && ((*iter == '\r') || (*iter == '\n')))
- ++iter; // skip initial newlines
- iterator first(iter, body.end(), actions.filename.native_file_string().c_str());
- first.set_position(template_pos);
- iterator last(body.end(), body.end());
- r = boost::spirit::qi::parse(first, last, block_p) && first == last;
- actions.phrase.swap(result);
- }
- return r;
- }
- }
-
- void process(quickbook::actions& actions, template_ const& x)
- {
- ++actions.template_depth;
- if (actions.template_depth > actions.max_template_depth)
- {
- detail::outerr(x.position.file,x.position.line)
- << "Infinite loop detected" << std::endl;
- --actions.template_depth;
- ++actions.error_count;
- return;
- }
-
- // The template arguments should have the scope that the template was
- // called from, not the template's own scope.
- //
- // Note that for quickbook 1.4- this value is just ignored when the
- // arguments are expanded.
- template_scope const& call_scope = actions.templates.top_scope();
-
- std::string result;
- actions.push(); // scope the actions' states
- {
- // Quickbook 1.4-: When expanding the tempalte continue to use the
- // current scope (the dynamic scope).
- // Quickbook 1.5+: Use the scope the template was defined in
- // (the static scope).
- if (qbk_version_n >= 105)
- actions.templates.set_parent_scope(*boost::get<2>(x.symbol));
-
- std::vector<std::string> template_ = boost::get<0>(x.symbol);
- file_position template_pos = boost::get<1>(x.symbol);
-
- std::vector<std::string> params = x.params;
-
- ///////////////////////////////////
- // Break the arguments
- if (!break_arguments(params, template_, x.position))
- {
- actions.pop(); // restore the actions' states
- --actions.template_depth;
- ++actions.error_count;
- return;
- }
-
- ///////////////////////////////////
- // Prepare the arguments as local templates
- bool get_arg_result;
- std::vector<std::string>::const_iterator tpl;
- boost::tie(get_arg_result, tpl) =
- get_arguments(params, template_,
- call_scope, x.position, actions);
-
- if (!get_arg_result)
- {
- actions.pop(); // restore the actions' states
- --actions.template_depth;
- return;
- }
-
- ///////////////////////////////////
- // parse the template body:
- std::string body;
- body.assign(tpl->begin(), tpl->end());
- body.reserve(body.size()+2); // reserve 2 more
-
- if (!parse_template(body, result, template_pos, x.escape, actions))
- {
- detail::outerr(x.position.file,x.position.line)
- //<< "Expanding template:" << template_info[0] << std::endl
- << std::endl
- << "------------------begin------------------" << std::endl
- << body
- << "------------------end--------------------" << std::endl
- << std::endl;
- actions.pop(); // restore the actions' states
- --actions.template_depth;
- ++actions.error_count;
- return;
- }
- }
-
- actions.pop(); // restore the actions' states
- actions.phrase << result; // print it!!!
- --actions.template_depth;
- }
-}
\ No newline at end of file
Copied: branches/quickbook-1.5-spirit2/template.cpp (from r59323, /branches/quickbook-1.5-spirit2/phrase_template.cpp)
==============================================================================
--- /branches/quickbook-1.5-spirit2/phrase_template.cpp (original)
+++ branches/quickbook-1.5-spirit2/template.cpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2002 2004 2006 Joel de Guzman
- Copyright (c) 2004 Eric Niebler
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
@@ -8,14 +7,149 @@
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
+#include <boost/spirit/include/qi_symbols.hpp>
+#include "template.hpp"
#include "phrase.hpp"
#include "grammars.hpp"
#include "actions_class.hpp"
#include "quickbook.hpp"
#include "utils.hpp"
+#ifdef BOOST_MSVC
+#pragma warning(disable : 4355)
+#endif
+
namespace quickbook
-{
+{
+ struct template_symbol
+ {
+ template_symbol(
+ std::string const& identifier,
+ std::vector<std::string> const& params,
+ std::string const& body,
+ file_position const& position,
+ template_scope const* parent)
+ : identifier(identifier)
+ , params(params)
+ , body(body)
+ , position(position)
+ , parent(parent) {}
+
+ std::string identifier;
+ std::vector<std::string> params;
+ std::string body;
+ file_position position;
+ template_scope const* parent;
+ };
+
+ typedef boost::spirit::qi::symbols<char, template_symbol> template_symbols;
+
+ // template scope
+ //
+ // 1.4-: parent_scope is the previous scope on the stack
+ // (the template's dynamic parent).
+ // 1.5+: parent_scope is the template's lexical parent.
+ //
+ // This means that a search along the parent_scope chain will follow the
+ // correct lookup chain for that version of quickboook.
+ //
+ // symbols contains the templates defined in this scope.
+
+ struct template_scope
+ {
+ template_scope() : parent_scope() {}
+ template_scope const* parent_scope;
+ template_symbols symbols;
+ };
+
+ template_stack::template_stack()
+ : scope(template_stack::parser(*this))
+ , scopes()
+ {
+ scopes.push_front(template_scope());
+ }
+
+ template_stack::~template_stack() {}
+
+ template_symbol const* template_stack::prefix_find(iterator& first, iterator const& last) const
+ {
+ // search all scopes for the longest matching symbol.
+ iterator found = first;
+ template_symbol const* result = 0;
+ for (template_scope const* i = &*scopes.begin(); i; i = i->parent_scope)
+ {
+ iterator iter = first;
+ template_symbol const* symbol = i->symbols.prefix_find(iter, last);
+ if(symbol && iter.base() > found.base())
+ {
+ found = iter;
+ result = symbol;
+ }
+ }
+ first = found;
+ return result;
+ }
+
+ template_symbol const* template_stack::find(std::string const& symbol) const
+ {
+ for (template_scope const* i = &*scopes.begin(); i; i = i->parent_scope)
+ {
+ if (template_symbol const* ts = i->symbols.find(symbol.c_str()))
+ return ts;
+ }
+ return 0;
+ }
+
+ template_symbol const* template_stack::find_top_scope(std::string const& symbol) const
+ {
+ return scopes.front().symbols.find(symbol.c_str());
+ }
+
+ template_scope const& template_stack::top_scope() const
+ {
+ BOOST_ASSERT(!scopes.empty());
+ return scopes.front();
+ }
+
+ bool template_stack::add(
+ define_template const& definition,
+ template_scope const* parent)
+ {
+ BOOST_ASSERT(!scopes.empty());
+
+ if (this->find_top_scope(definition.id)) {
+ return false;
+ }
+
+ template_symbol ts(
+ definition.id,
+ definition.params,
+ definition.body,
+ definition.position,
+ parent ? parent : &top_scope());
+
+ scopes.front().symbols.add(ts.identifier.c_str(), ts);
+
+ return true;
+ }
+
+ void template_stack::push()
+ {
+ template_scope const& old_front = scopes.front();
+ scopes.push_front(template_scope());
+ set_parent_scope(old_front);
+ }
+
+ void template_stack::pop()
+ {
+ scopes.pop_front();
+ }
+
+ void template_stack::set_parent_scope(template_scope const& parent)
+ {
+ scopes.front().parent_scope = &parent;
+ }
+
namespace
{
std::string::size_type find_bracket_end(std::string const& str, std::string::size_type pos)
@@ -69,8 +203,8 @@
}
bool break_arguments(
- std::vector<std::string>& params
- , std::vector<std::string> const& template_
+ std::vector<std::string>& args
+ , std::vector<std::string> const& params
, file_position const& pos
)
{
@@ -81,17 +215,16 @@
// then use whitespace to separate them
// (2 = template name + argument).
- if (qbk_version_n < 105 || params.size() == 1)
+ if (qbk_version_n < 105 || args.size() == 1)
{
- // template_.size() - 2 because template_ also includes the name and body.
- while (params.size() < template_.size() - 2 )
+ while (args.size() < params.size() )
{
// Try to break the last argument at the first space found
- // and push it into the back of params. Do this
+ // and push it into the back of args. Do this
// recursively until we have all the expected number of
// arguments, or if there are no more spaces left.
- std::string& str = params.back();
+ std::string& str = args.back();
std::string::size_type l_pos = find_first_seperator(str);
if (l_pos == std::string::npos)
break;
@@ -101,17 +234,17 @@
break;
std::string second(str.begin()+r_pos, str.end());
str = first;
- params.push_back(second);
+ args.push_back(second);
}
}
- if (params.size() != template_.size() - 2)
+ if (args.size() != params.size())
{
detail::outerr(pos.file, pos.line)
<< "Invalid number of arguments passed. Expecting: "
- << template_.size()-2
- << " argument(s), got: "
<< params.size()
+ << " argument(s), got: "
+ << args.size()
<< " argument(s) instead."
<< std::endl;
return false;
@@ -121,42 +254,37 @@
std::pair<bool, std::vector<std::string>::const_iterator>
get_arguments(
- std::vector<std::string>& params
- , std::vector<std::string> const& template_
+ std::vector<std::string>& args
+ , std::vector<std::string> const& params
, template_scope const& scope
, file_position const& pos
, quickbook::actions& actions
)
{
- std::vector<std::string>::const_iterator arg = params.begin();
- std::vector<std::string>::const_iterator tpl = template_.begin()+1;
+ std::vector<std::string>::const_iterator arg = args.begin();
+ std::vector<std::string>::const_iterator tpl = params.begin();
// Store each of the argument passed in as local templates:
- while (arg != params.end())
+ while (arg != args.end())
{
- std::vector<std::string> tinfo;
- tinfo.push_back(*tpl);
- tinfo.push_back(*arg);
- template_symbol template_(tinfo, pos, &scope);
+ std::vector<std::string> empty_params;
- if (actions.templates.find_top_scope(*tpl))
+ if (!actions.templates.add(
+ define_template(*tpl, empty_params, *arg, pos),
+ &scope))
{
detail::outerr(pos.file,pos.line)
<< "Duplicate Symbol Found" << std::endl;
++actions.error_count;
return std::make_pair(false, tpl);
}
- else
- {
- actions.templates.add(*tpl, template_);
- }
++arg; ++tpl;
}
return std::make_pair(true, tpl);
}
bool parse_template(
- std::string& body
+ std::string body
, std::string& result
, file_position const& template_pos
, bool template_escape
@@ -167,6 +295,8 @@
// a phrase? We apply a simple heuristic: if the body starts with
// a newline, then we regard it as a block, otherwise, we parse
// it as a phrase.
+
+ body.reserve(body.size() + 2);
std::string::const_iterator iter = body.begin();
while (iter != body.end() && ((*iter == ' ') || (*iter == '\t')))
@@ -199,8 +329,7 @@
// do a block level parse
// ensure that we have enough trailing newlines to eliminate
// the need to check for end of file in the grammar.
- body.push_back('\n');
- body.push_back('\n');
+ body += "\n\n";
while (iter != body.end() && ((*iter == '\r') || (*iter == '\n')))
++iter; // skip initial newlines
iterator first(iter, body.end(), actions.filename.native_file_string().c_str());
@@ -213,12 +342,12 @@
}
}
- void process(quickbook::actions& actions, template_ const& x)
+ void process(quickbook::actions& actions, call_template const& x)
{
++actions.template_depth;
if (actions.template_depth > actions.max_template_depth)
{
- detail::outerr(x.position.file,x.position.line)
+ detail::outerr(x.position.file, x.position.line)
<< "Infinite loop detected" << std::endl;
--actions.template_depth;
++actions.error_count;
@@ -240,16 +369,13 @@
// Quickbook 1.5+: Use the scope the template was defined in
// (the static scope).
if (qbk_version_n >= 105)
- actions.templates.set_parent_scope(*boost::get<2>(x.symbol));
+ actions.templates.set_parent_scope(*x.symbol->parent);
- std::vector<std::string> template_ = boost::get<0>(x.symbol);
- file_position template_pos = boost::get<1>(x.symbol);
-
- std::vector<std::string> params = x.params;
+ std::vector<std::string> args = x.args;
///////////////////////////////////
// Break the arguments
- if (!break_arguments(params, template_, x.position))
+ if (!break_arguments(args, x.symbol->params, x.position))
{
actions.pop(); // restore the actions' states
--actions.template_depth;
@@ -262,7 +388,7 @@
bool get_arg_result;
std::vector<std::string>::const_iterator tpl;
boost::tie(get_arg_result, tpl) =
- get_arguments(params, template_,
+ get_arguments(args, x.symbol->params,
call_scope, x.position, actions);
if (!get_arg_result)
@@ -274,17 +400,14 @@
///////////////////////////////////
// parse the template body:
- std::string body;
- body.assign(tpl->begin(), tpl->end());
- body.reserve(body.size()+2); // reserve 2 more
- if (!parse_template(body, result, template_pos, x.escape, actions))
+ if (!parse_template(x.symbol->body, result, x.symbol->position, x.escape, actions))
{
detail::outerr(x.position.file,x.position.line)
- //<< "Expanding template:" << template_info[0] << std::endl
+ //<< "Expanding template:" << x.symbol->identifier << std::endl
<< std::endl
<< "------------------begin------------------" << std::endl
- << body
+ << x.symbol->body
<< "------------------end--------------------" << std::endl
<< std::endl;
actions.pop(); // restore the actions' states
@@ -298,4 +421,6 @@
actions.phrase << result; // print it!!!
--actions.template_depth;
}
-}
\ No newline at end of file
+}
+
+
Added: branches/quickbook-1.5-spirit2/template.hpp
==============================================================================
--- (empty file)
+++ branches/quickbook-1.5-spirit2/template.hpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
@@ -0,0 +1,102 @@
+/*=============================================================================
+ Copyright (c) 2002 2004 2006 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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(BOOST_SPIRIT_QUICKBOOK_TEMPLATE_STACK_HPP)
+#define BOOST_SPIRIT_QUICKBOOK_TEMPLATE_STACK_HPP
+
+#include <string>
+#include <deque>
+#include <vector>
+#include <boost/spirit/include/qi_parse.hpp>
+#include <boost/spirit/home/qi/detail/assign_to.hpp>
+#include "fwd.hpp"
+
+namespace quickbook
+{
+ namespace qi = boost::spirit::qi;
+
+ struct define_template
+ {
+ define_template() {}
+
+ define_template(
+ std::string id,
+ std::vector<std::string> params,
+ std::string body,
+ quickbook::file_position position)
+ :
+ id(id), params(params), body(body), position(position)
+ {}
+
+ std::string id;
+ std::vector<std::string> params;
+ std::string body;
+ quickbook::file_position position;
+ };
+
+ void process(quickbook::actions&, define_template const&);
+
+ struct template_scope;
+ struct template_symbol;
+
+ struct template_stack
+ {
+ typedef std::deque<template_scope> deque;
+
+ struct parser : boost::spirit::qi::primitive_parser<parser>
+ {
+ template <typename Ctx, typename Itr>
+ struct attribute {
+ typedef template_symbol const* type;
+ };
+
+ parser(template_stack& ts)
+ : ts(ts) {}
+
+ template <typename Context, typename Skipper, typename Attribute>
+ bool parse(iterator& first, iterator const& last
+ , Context& context, Skipper const& skipper, Attribute& attr) const
+ {
+ boost::spirit::qi::skip_over(first, last, skipper);
+ template_symbol const* symbol = ts.prefix_find(first, last);
+ if(symbol) boost::spirit::traits::assign_to(symbol, attr);
+ return symbol;
+ }
+
+ template_stack& ts;
+ };
+
+ template_stack();
+ ~template_stack();
+ template_symbol const* prefix_find(iterator& first, iterator const& last) const;
+ template_symbol const* find(std::string const& symbol) const;
+ template_symbol const* find_top_scope(std::string const& symbol) const;
+ template_scope const& top_scope() const;
+ // Add the given template symbol to the current scope.
+ // If a parent scope isn't supplied, uses the current scope.
+ bool add(define_template const&, template_scope const* parent = 0);
+ void push();
+ void pop();
+
+ // Set the current scope's parent.
+ void set_parent_scope(template_scope const&);
+
+ parser scope;
+
+ private:
+
+ friend struct parser;
+ deque scopes;
+
+ template_stack(template_stack const&);
+ template_stack& operator=(template_stack const&);
+ };
+}
+
+#endif // BOOST_SPIRIT_QUICKBOOK_TEMPLATE_STACK_HPP
+
Deleted: branches/quickbook-1.5-spirit2/template_stack.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/template_stack.cpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
+++ (empty file)
@@ -1,78 +0,0 @@
-/*=============================================================================
- Copyright (c) 2002 2004 2006 Joel de Guzman
- http://spirit.sourceforge.net/
-
- Use, modification and distribution is subject to 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)
-=============================================================================*/
-#include "template_stack.hpp"
-
-#ifdef BOOST_MSVC
-#pragma warning(disable : 4355)
-#endif
-
-namespace quickbook
-{
- template_stack::template_stack()
- : scope(template_stack::parser(*this))
- , scopes()
- {
- scopes.push_front(template_scope());
- }
-
- template_symbol const* template_stack::find(std::string const& symbol) const
- {
- for (template_scope const* i = &*scopes.begin(); i; i = i->parent_scope)
- {
- if (template_symbol const* ts = i->symbols.find(symbol.c_str()))
- return ts;
- }
- return 0;
- }
-
- template_symbol const* template_stack::find_top_scope(std::string const& symbol) const
- {
- return scopes.front().symbols.find(symbol.c_str());
- }
-
- template_symbols const& template_stack::top() const
- {
- BOOST_ASSERT(!scopes.empty());
- return scopes.front().symbols;
- }
-
- template_scope const& template_stack::top_scope() const
- {
- BOOST_ASSERT(!scopes.empty());
- return scopes.front();
- }
-
- // TODO: Should symbols defined by '[import]' use the current scope?
- void template_stack::add(std::string const& symbol, template_symbol const& ts)
- {
- BOOST_ASSERT(!scopes.empty());
- scopes.front().symbols.add(symbol.c_str(),
- boost::get<2>(ts) ? ts :
- template_symbol(boost::get<0>(ts), boost::get<1>(ts), &top_scope()));
- }
-
- void template_stack::push()
- {
- template_scope const& old_front = scopes.front();
- scopes.push_front(template_scope());
- set_parent_scope(old_front);
- }
-
- void template_stack::pop()
- {
- scopes.pop_front();
- }
-
- void template_stack::set_parent_scope(template_scope const& parent)
- {
- scopes.front().parent_scope = &parent;
- }
-}
-
-
Deleted: branches/quickbook-1.5-spirit2/template_stack.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/template_stack.hpp 2010-01-27 17:07:22 EST (Wed, 27 Jan 2010)
+++ (empty file)
@@ -1,131 +0,0 @@
-/*=============================================================================
- Copyright (c) 2002 2004 2006 Joel de Guzman
- http://spirit.sourceforge.net/
-
- Use, modification and distribution is subject to 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(BOOST_SPIRIT_QUICKBOOK_TEMPLATE_STACK_HPP)
-#define BOOST_SPIRIT_QUICKBOOK_TEMPLATE_STACK_HPP
-
-#include <string>
-#include <deque>
-#include <vector>
-#include <boost/tuple/tuple.hpp>
-#include <boost/spirit/include/qi_symbols.hpp>
-#include <boost/spirit/include/qi_parse.hpp>
-#include <boost/next_prior.hpp>
-#include "fwd.hpp"
-
-namespace quickbook
-{
- struct template_scope;
-
- // template symbols with N arguments are stored as follows:
- //
- // vector<std::string>
- // 0: template name
- // 1: template param name[0]
- // 2: template param name[1]
- // ...
- // N: template param name[N-1]
- // N+1: template body
- // file position
- // template scope (only used for 1.5+, 1.4- uses the dynamic scope)
-
- typedef boost::tuple<
- std::vector<std::string>
- , file_position
- , template_scope const*>
- template_symbol;
-
- typedef boost::spirit::qi::symbols<char, template_symbol> template_symbols;
-
- // template scope
- //
- // 1.4-: parent_scope is the previous scope on the stack
- // (the template's dynamic parent).
- // 1.5+: parent_scope is the template's lexical parent.
- //
- // This means that a search along the parent_scope chain will follow the
- // correct lookup chain for that version of quickboook.
- //
- // symbols contains the templates defined in this scope.
-
- struct template_scope
- {
- template_scope() : parent_scope() {}
- template_scope const* parent_scope;
- template_symbols symbols;
- };
-
- struct template_stack
- {
- typedef std::deque<template_scope> deque;
-
- struct parser : boost::spirit::qi::primitive_parser<parser>
- {
- template <typename Ctx, typename Itr>
- struct attribute {
- typedef template_symbol type;
- };
-
- parser(template_stack& ts)
- : ts(ts) {}
-
- template <typename Iterator, typename Context, typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper, Attribute& attr) const
- {
- boost::spirit::qi::skip_over(first, last, skipper);
-
- // TODO: Is this right?
- template_symbol result_attr;
-
- // search all scopes for the longest matching symbol.
- Iterator f = first;
- std::ptrdiff_t len = -1;
- for (template_scope const* i = &*ts.scopes.begin(); i; i = i->parent_scope)
- {
- // TODO: Implement this without calling 'base'.
- if(i->symbols.parse(first, last, context, skipper, result_attr) && first.base() - f.base() > len)
- {
- boost::spirit::traits::assign_to(result_attr, attr);
- len = first.base() - f.base();
- }
- first = f;
- }
- if (len >= 0)
- first = boost::next(f, len);
- return len > 0;
- }
-
- template_stack& ts;
- };
-
- template_stack();
- template_symbol const* find(std::string const& symbol) const;
- template_symbol const* find_top_scope(std::string const& symbol) const;
- template_symbols const& top() const;
- template_scope const& top_scope() const;
- // Add the given template symbol to the current scope.
- // If it doesn't have a scope, sets the symbol's scope to the current scope.
- void add(std::string const& symbol, template_symbol const& ts);
- void push();
- void pop();
-
- // Set the current scope's parent.
- void set_parent_scope(template_scope const&);
-
- parser scope;
-
- private:
-
- friend struct parser;
- deque scopes;
- };
-}
-
-#endif // BOOST_SPIRIT_QUICKBOOK_TEMPLATE_STACK_HPP
-
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk