diff --git a/Jamfile.v2 b/Jamfile.v2 old mode 100755 new mode 100644 index ccf923e..a957c5b --- a/Jamfile.v2 +++ b/Jamfile.v2 @@ -14,9 +14,11 @@ exe quickbook detail/actions.cpp detail/actions_class.cpp detail/utils.cpp + detail/input_path.cpp detail/post_process.cpp detail/collector.cpp detail/template_stack.cpp + detail/markups.cpp /boost//program_options /boost//filesystem : #QUICKBOOK_NO_DATES diff --git a/block.hpp b/block.hpp index aba5489..2ea6711 100644 --- a/block.hpp +++ b/block.hpp @@ -12,16 +12,16 @@ #include "./detail/utils.hpp" #include "./phrase.hpp" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include namespace quickbook { - using namespace boost::spirit; + using namespace boost::spirit::classic; template struct block_grammar : grammar > diff --git a/code_snippet.hpp b/code_snippet.hpp index f6f2911..5f2c3b4 100644 --- a/code_snippet.hpp +++ b/code_snippet.hpp @@ -9,8 +9,8 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_CODE_SNIPPET_HPP) #define BOOST_SPIRIT_QUICKBOOK_CODE_SNIPPET_HPP -#include -#include +#include +#include #include "./detail/template_stack.hpp" namespace quickbook diff --git a/detail/actions.cpp b/detail/actions.cpp index ffe59ca..dc230ee 100644 --- a/detail/actions.cpp +++ b/detail/actions.cpp @@ -27,7 +27,7 @@ namespace quickbook // Handles line-breaks (DEPRECATED!!!) void break_action::operator()(iterator first, iterator) const { - boost::spirit::file_position const pos = first.get_position(); + boost::spirit::classic::file_position const pos = first.get_position(); detail::outwarn(pos.file,pos.line) << "in column:" << pos.column << ", " << "[br] and \\n are deprecated" << ".\n"; phrase << break_mark; @@ -35,9 +35,10 @@ namespace quickbook void error_action::operator()(iterator first, iterator /*last*/) const { - boost::spirit::file_position const pos = first.get_position(); + boost::spirit::classic::file_position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Syntax Error near column " << pos.column << ".\n"; + ++error_count; } void phrase_action::operator()(iterator first, iterator last) const @@ -224,11 +225,12 @@ namespace quickbook if (mark != list_marks.top().first) // new_indent == list_indent { - boost::spirit::file_position const pos = first.get_position(); + boost::spirit::classic::file_position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Illegal change of list style near column " << pos.column << ".\n"; detail::outwarn(pos.file,pos.line) << "Ignoring change of list style" << std::endl; + ++error_count; } } @@ -240,8 +242,15 @@ namespace quickbook out << ""; } - void unexpected_char::operator()(char) const + void unexpected_char::operator()(iterator first, iterator last) const { + boost::spirit::classic::file_position const pos = first.get_position(); + + detail::outwarn(pos.file, pos.line) + << "in column:" << pos.column + << ", unexpected character: " << std::string(first, last) + << "\n"; + out << '#'; // print out an unexpected character } @@ -481,9 +490,10 @@ namespace quickbook BOOST_ASSERT(actions.template_info.size()); if (actions.templates.find_top_scope(actions.template_info[0])) { - boost::spirit::file_position const pos = first.get_position(); + boost::spirit::classic::file_position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Template Redefinition: " << actions.template_info[0] << std::endl; + ++actions.error_count; } actions.template_info.push_back(std::string(first, last)); @@ -498,12 +508,12 @@ namespace quickbook bool break_arguments( std::vector& template_info , std::vector const& template_ - , boost::spirit::file_position const& pos + , boost::spirit::classic::file_position const& pos ) { if (template_.size()-1 != template_info.size()) { - while (template_.size()-1 != template_info.size()) + while (template_.size()-1 > template_info.size()) { // Try to break the last argument at the first space found // and push it into the back of template_info. Do this @@ -516,6 +526,8 @@ namespace quickbook 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; template_info.push_back(second); @@ -540,7 +552,7 @@ namespace quickbook get_arguments( std::vector& template_info , std::vector const& template_ - , boost::spirit::file_position const& pos + , boost::spirit::classic::file_position const& pos , quickbook::actions& actions ) { @@ -555,10 +567,11 @@ namespace quickbook tinfo.push_back(*arg); template_symbol template_(tinfo, pos); - if (template_symbol* p = actions.templates.find_top_scope(*tpl)) + 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 @@ -573,7 +586,7 @@ namespace quickbook bool parse_template( std::string& body , std::string& result - , boost::spirit::file_position const& template_pos + , boost::spirit::classic::file_position const& template_pos , quickbook::actions& actions ) { @@ -604,7 +617,7 @@ namespace quickbook 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::parse(first, last, phrase_p).full; + r = boost::spirit::classic::parse(first, last, phrase_p).full; actions.phrase.swap(result); } else @@ -619,7 +632,7 @@ namespace quickbook 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::parse(first, last, block_p).full; + r = boost::spirit::classic::parse(first, last, block_p).full; actions.out.swap(result); } return r; @@ -628,13 +641,14 @@ namespace quickbook void do_template_action::operator()(iterator first, iterator) const { - boost::spirit::file_position const pos = first.get_position(); + boost::spirit::classic::file_position const pos = first.get_position(); ++actions.template_depth; if (actions.template_depth > actions.max_template_depth) { detail::outerr(pos.file,pos.line) << "Infinite loop detected" << std::endl; --actions.template_depth; + ++actions.error_count; return; } @@ -646,7 +660,7 @@ namespace quickbook BOOST_ASSERT(symbol); std::vector template_ = boost::get<0>(*symbol); - boost::spirit::file_position template_pos = boost::get<1>(*symbol); + boost::spirit::classic::file_position template_pos = boost::get<1>(*symbol); std::vector template_info; std::swap(template_info, actions.template_info); @@ -657,6 +671,7 @@ namespace quickbook { actions.pop(); // restore the actions' states --actions.template_depth; + ++actions.error_count; return; } @@ -682,7 +697,7 @@ namespace quickbook if (!parse_template(body, result, template_pos, actions)) { - boost::spirit::file_position const pos = first.get_position(); + boost::spirit::classic::file_position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Expanding template:" << template_info[0] << std::endl << "------------------begin------------------" << std::endl @@ -691,6 +706,7 @@ namespace quickbook << std::endl; actions.pop(); // restore the actions' states --actions.template_depth; + ++actions.error_count; return; } } @@ -885,9 +901,11 @@ namespace quickbook --section_level; if (section_level < 0) { - boost::spirit::file_position const pos = first.get_position(); + boost::spirit::classic::file_position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Mismatched [endsect] near column " << pos.column << ".\n"; + ++error_count; + // $$$ TODO: somehow fail parse else BOOST_ASSERT(std::string::npos != n) // $$$ below will assert. } @@ -1040,7 +1058,7 @@ namespace quickbook id.clear(); } - void load_snippets( + int load_snippets( std::string const& file , std::vector& storage // snippets are stored in a // vector of template_symbols @@ -1050,14 +1068,17 @@ namespace quickbook std::string code; int err = detail::load(file, code); if (err != 0) - return; // return early on error + return err; // return early on error typedef position_iterator iterator_type; iterator_type first(code.begin(), code.end(), file); iterator_type last(code.end(), code.end()); cpp_code_snippet_grammar g(storage, doc_id); - boost::spirit::parse(first, last, g); + // TODO: Should I check that parse succeeded? + boost::spirit::classic::parse(first, last, g); + + return 0; } namespace @@ -1096,16 +1117,18 @@ namespace quickbook fs::path path = include_search(actions.filename.branch_path(), std::string(first,last)); std::string ext = fs::extension(path); std::vector storage; - load_snippets(path.string(), storage, ext, actions.doc_id); + actions.error_count += + load_snippets(path.string(), storage, ext, actions.doc_id); BOOST_FOREACH(template_symbol const& ts, storage) { std::string tname = boost::get<0>(ts)[0]; if (actions.templates.find_top_scope(tname)) { - boost::spirit::file_position const pos = boost::get<1>(ts); + boost::spirit::classic::file_position const pos = boost::get<1>(ts); detail::outerr(pos.file, pos.line) << "Template Redefinition: " << tname << std::endl; + ++actions.error_count; } else { @@ -1142,7 +1165,7 @@ namespace quickbook } // update the __FILENAME__ macro - *boost::spirit::find(actions.macro, "__FILENAME__") = actions.filename.native_file_string(); + *boost::spirit::classic::find(actions.macro, "__FILENAME__") = actions.filename.native_file_string(); // parse the file quickbook::parse(actions.filename.native_file_string().c_str(), actions, true); diff --git a/detail/actions.hpp b/detail/actions.hpp old mode 100755 new mode 100644 index 036f137..b0f9f8d --- a/detail/actions.hpp +++ b/detail/actions.hpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -54,7 +54,13 @@ namespace quickbook { // Prints an error message to std::cerr + error_action( + int& error_count) + : error_count(error_count) {} + void operator()(iterator first, iterator /*last*/) const; + + int& error_count; }; struct phrase_action @@ -230,16 +236,19 @@ namespace quickbook list_format_action( collector& out , int& list_indent - , std::stack& list_marks) + , std::stack& list_marks + , int& error_count) : out(out) , list_indent(list_indent) - , list_marks(list_marks) {} + , list_marks(list_marks) + , error_count(error_count) {} void operator()(iterator first, iterator last) const; collector& out; int& list_indent; std::stack& list_marks; + int& error_count; }; struct span @@ -262,7 +271,7 @@ namespace quickbook unexpected_char(collector& out) : out(out) {} - void operator()(char) const; + void operator()(iterator first, iterator last) const; collector& out; }; @@ -671,16 +680,19 @@ namespace quickbook end_section_action( collector& out , int& section_level - , std::string& qualified_section_id) + , std::string& qualified_section_id + , int& error_count) : out(out) , section_level(section_level) - , qualified_section_id(qualified_section_id) {} + , qualified_section_id(qualified_section_id) + , error_count(error_count) {} void operator()(iterator first, iterator last) const; collector& out; int& section_level; std::string& qualified_section_id; + int& error_count; }; struct xinclude_action diff --git a/detail/actions_class.cpp b/detail/actions_class.cpp index d5f6bf2..7abeac5 100644 --- a/detail/actions_class.cpp +++ b/detail/actions_class.cpp @@ -62,9 +62,10 @@ namespace quickbook , template_depth(0) , template_escape(false) , templates() + , error_count(0) // actions - , error() + , error(error_count) , extract_doc_license(doc_license, phrase) , extract_doc_purpose(doc_purpose, phrase) @@ -96,7 +97,7 @@ namespace quickbook , cond_phrase_post(phrase, conditions, macro) , list(out, list_buffer, list_indent, list_marks) - , list_format(list_buffer, list_indent, list_marks) + , list_format(list_buffer, list_indent, list_marks, error_count) , list_item(list_buffer, phrase, list_item_pre, list_item_post) , funcref_pre(phrase, funcref_pre_) @@ -165,7 +166,7 @@ namespace quickbook , anchor(out) , begin_section(out, phrase, doc_id, section_id, section_level, qualified_section_id) - , end_section(out, section_level, qualified_section_id) + , end_section(out, section_level, qualified_section_id, error_count) , xinclude(out, *this) , include(*this) , import(out, *this) diff --git a/detail/actions_class.hpp b/detail/actions_class.hpp index 332d581..b0170fe 100644 --- a/detail/actions_class.hpp +++ b/detail/actions_class.hpp @@ -15,7 +15,7 @@ namespace quickbook { - using namespace boost::spirit; + using namespace boost::spirit::classic; namespace fs = boost::filesystem; struct actions @@ -90,6 +90,7 @@ namespace quickbook int template_depth; bool template_escape; template_stack templates; + int error_count; // push/pop the states and the streams void push(); diff --git a/detail/input_path.cpp b/detail/input_path.cpp new file mode 100644 index 0000000..076c7b8 --- /dev/null +++ b/detail/input_path.cpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2009 Daniel James + + 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 +#include "./input_path.hpp" + +#if defined(__cygwin__) || defined(__CYGWIN__) +#include +#include +#include +#endif + + +namespace quickbook { namespace detail +{ + void validate(boost::any& v, + const std::vector& values, + input_path*, int) + { + std::string path + = boost::program_options::validators::get_single_string(values); + +#if !(defined(__cygwin__) || defined(__CYGWIN__)) + v = input_path(path); +#elif defined(BOOST_WINDOWS_PATH) + char result[MAX_PATH + 1]; + cygwin_conv_to_win32_path(path.c_str(), result); + v = input_path(result); +#elif defined(BOOST_POSIX_PATH) + char result[MAX_PATH + 1]; + cygwin_conv_to_posix_path(path.c_str(), result); + v = input_path(result); +#else +# error "Bosot filesystem path type doesn't seem to be set." +#endif + } +}} \ No newline at end of file diff --git a/detail/input_path.hpp b/detail/input_path.hpp new file mode 100644 index 0000000..91badca --- /dev/null +++ b/detail/input_path.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + Copyright (c) 2009 Daniel James + + 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_QUICKBOOK_DETAIL_INPUT_PATH_HPP) +#define BOOST_QUICKBOOK_DETAIL_INPUT_PATH_HPP + +#include +#include +#include + +namespace quickbook { namespace detail +{ + // Use this class with Boost.Program Options to convert paths to the format + // the Boost.Filesystem expects. This is needed on cygwin to convert cygwin + // paths to windows paths (or vice versa, depending on how filesystem is set + // up). + // + // Note that we don't want to convert paths in quickbook files, as they + // should be platform independent, and aren't necessarily relative to the + // current directory. + + class input_path { + std::string path_; + public: + explicit input_path(char const* c) : path_(c) {} + explicit input_path(std::string const& c) : path_(c) {} + operator std::string() const { return path_; } + + friend void validate(boost::any&, const std::vector&, + input_path*, int); + }; +}} + +#endif diff --git a/detail/markups.cpp b/detail/markups.cpp new file mode 100644 index 0000000..7ed6bfb --- /dev/null +++ b/detail/markups.cpp @@ -0,0 +1,101 @@ +/*============================================================================= + 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 "./markups.hpp" + +namespace quickbook +{ + const char* comment_pre = ""; + const char* paragraph_pre = "\n"; + const char* paragraph_post = "\n"; + const char* h1_pre = ""; + const char* h1_post = ""; + const char* h2_pre = ""; + const char* h2_post = ""; + const char* h3_pre = ""; + const char* h3_post = ""; + const char* h4_pre = ""; + const char* h4_post = ""; + const char* h5_pre = ""; + const char* h5_post = ""; + const char* h6_pre = ""; + const char* h6_post = ""; + const char* hr_ = ""; + const char* blurb_pre = "\n"; + const char* blurb_post = "\n"; + const char* blockquote_pre = "
"; + const char* blockquote_post = "
"; + const char* preformatted_pre = ""; + const char* preformatted_post = ""; + const char* warning_pre = ""; + const char* warning_post = ""; + const char* caution_pre = ""; + const char* caution_post = ""; + const char* important_pre = ""; + const char* important_post = ""; + const char* note_pre = ""; + const char* note_post = ""; + const char* tip_pre = ""; + const char* tip_post = ""; + const char* list_item_pre = "\n"; + const char* list_item_post = "\n"; + const char* bold_pre_ = ""; + const char* bold_post_ = ""; + const char* italic_pre_ = ""; + const char* italic_post_ = ""; + const char* underline_pre_ = ""; + const char* underline_post_ = ""; + const char* teletype_pre_ = ""; + const char* teletype_post_ = ""; + const char* strikethrough_pre_ = ""; + const char* strikethrough_post_ = ""; + const char* quote_pre_ = ""; + const char* quote_post_ = ""; + const char* break_mark = "\n"; + const char* url_pre_ = ""; - const char* h1_post = ""; - const char* h2_pre = ""; - const char* h2_post = ""; - const char* h3_pre = ""; - const char* h3_post = ""; - const char* h4_pre = ""; - const char* h4_post = ""; - const char* h5_pre = ""; - const char* h5_post = ""; - const char* h6_pre = ""; - const char* h6_post = ""; - const char* hr_ = ""; - const char* blurb_pre = "\n"; - const char* blurb_post = "\n"; - const char* blockquote_pre = "
"; - const char* blockquote_post = "
"; - const char* preformatted_pre = ""; - const char* preformatted_post = ""; - const char* warning_pre = ""; - const char* warning_post = ""; - const char* caution_pre = ""; - const char* caution_post = ""; - const char* important_pre = ""; - const char* important_post = ""; - const char* note_pre = ""; - const char* note_post = ""; - const char* tip_pre = ""; - const char* tip_post = ""; - const char* list_item_pre = "\n"; - const char* list_item_post = "\n"; - const char* bold_pre_ = ""; - const char* bold_post_ = ""; - const char* italic_pre_ = ""; - const char* italic_post_ = ""; - const char* underline_pre_ = ""; - const char* underline_post_ = ""; - const char* teletype_pre_ = ""; - const char* teletype_post_ = ""; - const char* strikethrough_pre_ = ""; - const char* strikethrough_post_ = ""; - const char* quote_pre_ = ""; - const char* quote_post_ = ""; - const char* break_mark = "\n"; - const char* url_pre_ = " +#include #include #include #include @@ -16,7 +16,7 @@ namespace quickbook { - using namespace boost::spirit; + using namespace boost::spirit::classic; using boost::bind; typedef std::string::const_iterator iter_type; @@ -417,7 +417,7 @@ namespace quickbook int indent; }; - void post_process( + int post_process( std::string const& in , std::ostream& out , int indent @@ -437,6 +437,7 @@ namespace quickbook if (r.full) { out << tidy; + return 0; } else { @@ -445,6 +446,7 @@ namespace quickbook << "Warning: Post Processing Failed." << std::endl; out << in; + return 1; } } @@ -455,6 +457,7 @@ namespace quickbook << "Warning: Post Processing Failed." << std::endl; out << in; + return 1; } } } diff --git a/detail/post_process.hpp b/detail/post_process.hpp index 9f9941c..cfe220f 100644 --- a/detail/post_process.hpp +++ b/detail/post_process.hpp @@ -14,7 +14,7 @@ namespace quickbook { - void post_process( + int post_process( std::string const& in , std::ostream& out , int indent diff --git a/detail/quickbook.cpp b/detail/quickbook.cpp old mode 100755 new mode 100644 index 4335b1e..ece0154 --- a/detail/quickbook.cpp +++ b/detail/quickbook.cpp @@ -12,7 +12,8 @@ #include "../doc_info.hpp" #include "./post_process.hpp" #include "./utils.hpp" -#include +#include "./input_path.hpp" +#include #include #include #include @@ -31,7 +32,7 @@ namespace quickbook { - using namespace boost::spirit; + using namespace boost::spirit::classic; namespace fs = boost::filesystem; tm* current_time; // the current time tm* current_gm_time; // the current UTC time @@ -56,8 +57,10 @@ namespace quickbook std::string storage; int err = detail::load(filein_, storage); - if (err != 0) + if (err != 0) { + ++actor.error_count; return err; + } typedef position_iterator iterator_type; iterator_type first(storage.begin(), storage.end(), filein_); @@ -83,10 +86,10 @@ namespace quickbook file_position const pos = info.stop.get_position(); detail::outerr(pos.file,pos.line) << "Syntax Error near column " << pos.column << ".\n"; - return 1; + ++actor.error_count; } - return 0; + return actor.error_count ? 1 : 0; } static int @@ -120,7 +123,7 @@ namespace quickbook result = parse(filein_, outdir, buffer); if (result == 0) { - post_process(buffer.str(), fileout, indent, linewidth); + result = post_process(buffer.str(), fileout, indent, linewidth); } } else @@ -162,11 +165,11 @@ main(int argc, char* argv[]) ("no-pretty-print", "disable XML pretty printing") ("indent", value(), "indent spaces") ("linewidth", value(), "line width") - ("input-file", value(), "input file") - ("output-file", value(), "output file") + ("input-file", value(), "input file") + ("output-file", value(), "output file") ("debug", "debug mode (for developers)") ("ms-errors", "use Microsoft Visual Studio style error & warn message format") - ("include-path,I", value< std::vector >(), "include path") + ("include-path,I", value< std::vector >(), "include path") ; positional_options_description p; @@ -230,17 +233,22 @@ main(int argc, char* argv[]) if (vm.count("include-path")) { - quickbook::include_path = vm["include-path"].as< std::vector >(); + std::vector paths + = vm["include-path"].as< + std::vector >(); + quickbook::include_path + = std::vector(paths.begin(), paths.end()); } if (vm.count("input-file")) { - std::string filein = vm["input-file"].as(); + std::string filein + = vm["input-file"].as(); std::string fileout; if (vm.count("output-file")) { - fileout = vm["output-file"].as(); + fileout = vm["output-file"].as(); } else { @@ -257,6 +265,7 @@ main(int argc, char* argv[]) else { quickbook::detail::outerr("",0) << "Error: No filename given" << std::endl; + return 1; } } @@ -269,6 +278,7 @@ main(int argc, char* argv[]) catch(...) { quickbook::detail::outerr("",0) << "Error: Exception of unknown type caught\n"; + return 1; } return 0; diff --git a/detail/template_stack.cpp b/detail/template_stack.cpp index 9489c76..51e7b6e 100644 --- a/detail/template_stack.cpp +++ b/detail/template_stack.cpp @@ -25,7 +25,7 @@ namespace quickbook { for (deque::const_iterator i = scopes.begin(); i != scopes.end(); ++i) { - if (template_symbol* ts = boost::spirit::find(*i, symbol.c_str())) + if (template_symbol* ts = boost::spirit::classic::find(*i, symbol.c_str())) return ts; } return 0; @@ -33,7 +33,7 @@ namespace quickbook template_symbol* template_stack::find_top_scope(std::string const& symbol) const { - return boost::spirit::find(scopes.front(), symbol.c_str()); + return boost::spirit::classic::find(scopes.front(), symbol.c_str()); } template_symbols const& template_stack::top() const @@ -45,7 +45,7 @@ namespace quickbook void template_stack::add(std::string const& symbol, template_symbol const& ts) { BOOST_ASSERT(!scopes.empty()); - boost::spirit::add(scopes.front(), symbol.c_str(), ts); + boost::spirit::classic::add(scopes.front(), symbol.c_str(), ts); } void template_stack::push() diff --git a/detail/template_stack.hpp b/detail/template_stack.hpp index 3f9db1e..78d1529 100644 --- a/detail/template_stack.hpp +++ b/detail/template_stack.hpp @@ -14,9 +14,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include namespace quickbook @@ -26,16 +26,16 @@ namespace quickbook // template name // template param name[0] // template param name[1] - // ... + // ... // template param name[N] // template body typedef boost::tuple< std::vector - , boost::spirit::file_position> + , boost::spirit::classic::file_position> template_symbol; - typedef boost::spirit::symbols template_symbols; + typedef boost::spirit::classic::symbols template_symbols; struct template_stack { @@ -43,8 +43,8 @@ namespace quickbook struct parser { - typedef boost::spirit::nil_t result_t; - + typedef boost::spirit::classic::nil_t result_t; + parser(template_stack& ts) : ts(ts) {} @@ -58,7 +58,7 @@ namespace quickbook for (template_stack::deque::const_iterator i = ts.scopes.begin(); i != ts.scopes.end(); ++i) { - boost::spirit::match<> m = i->parse(scan); + boost::spirit::classic::match<> m = i->parse(scan); if (m.length() > len) len = m.length(); scan.first = f; @@ -67,7 +67,7 @@ namespace quickbook scan.first = boost::next(f, len); return len; } - + template_stack& ts; }; @@ -78,11 +78,11 @@ namespace quickbook void add(std::string const& symbol, template_symbol const& ts); void push(); void pop(); - - boost::spirit::functor_parser scope; + + boost::spirit::classic::functor_parser scope; private: - + friend struct parser; deque scopes; }; diff --git a/detail/utils.cpp b/detail/utils.cpp index 093a10a..a054539 100644 --- a/detail/utils.cpp +++ b/detail/utils.cpp @@ -8,7 +8,7 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #include "./utils.hpp" -#include +#include #include #include @@ -181,6 +181,25 @@ namespace quickbook { namespace detail } } + // Copy a string, converting mac and windows style newlines to unix + // newlines. + + template + void normalize_newlines(InputIterator begin, InputIterator end, + OutputIterator out) + { + while(begin != end) { + if(*begin == '\r') { + *out++ = '\n'; + ++begin; + if(begin != end && *begin == '\n') ++begin; + } + else { + *out++ = *begin++; + } + } + } + int load(std::string const& filename, std::string& storage) { using std::cerr; @@ -200,7 +219,7 @@ namespace quickbook { namespace detail // Turn off white space skipping on the stream in.unsetf(ios::skipws); - std::copy( + normalize_newlines( istream_iterator(in), istream_iterator(), std::back_inserter(storage)); diff --git a/doc_info.hpp b/doc_info.hpp old mode 100755 new mode 100644 index 874daf8..a473ad7 --- a/doc_info.hpp +++ b/doc_info.hpp @@ -11,14 +11,14 @@ #define BOOST_SPIRIT_QUICKBOOK_DOC_INFO_HPP #include "./phrase.hpp" -#include -#include -#include -#include +#include +#include +#include +#include namespace quickbook { - using namespace boost::spirit; + using namespace boost::spirit::classic; extern unsigned qbk_major_version; extern unsigned qbk_minor_version; diff --git a/phrase.hpp b/phrase.hpp index f637d72..4760e7f 100644 --- a/phrase.hpp +++ b/phrase.hpp @@ -11,15 +11,15 @@ #define BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP #include "detail/utils.hpp" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace quickbook { - using namespace boost::spirit; + using namespace boost::spirit::classic; template inline void diff --git a/syntax_highlight.hpp b/syntax_highlight.hpp old mode 100755 new mode 100644 index c037cb0..01e2f1c --- a/syntax_highlight.hpp +++ b/syntax_highlight.hpp @@ -10,16 +10,17 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_SYNTAX_HIGHLIGHT_HPP) #define BOOST_SPIRIT_QUICKBOOK_SYNTAX_HIGHLIGHT_HPP -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include "./phrase.hpp" namespace quickbook { - using namespace boost::spirit; + using namespace boost::spirit::classic; // Grammar for C++ highlighting template < @@ -58,7 +59,7 @@ namespace quickbook | string_ [Process("string", self.out)] | char_ [Process("char", self.out)] | number [Process("number", self.out)] - | anychar_p [Unexpected(self.out)] + | repeat_p(1)[anychar_p] [Unexpected(self.out)] ) ; @@ -74,13 +75,23 @@ namespace quickbook ) ; - escape - = str_p("``") [PreEscape(self.escape_actions, save)] - >> ( - (+(anychar_p - "``") >> eps_p("``")) - & qbk_phrase + escape = + str_p("``") [PreEscape(self.escape_actions, save)] + >> + ( + ( + ( + (+(anychar_p - "``") >> eps_p("``")) + & qbk_phrase + ) + >> str_p("``") ) - >> str_p("``") [PostEscape(self.out, self.escape_actions, save)] + | + ( + eps_p [self.escape_actions.error] + >> *anychar_p + ) + ) [PostEscape(self.out, self.escape_actions, save)] ; preprocessor @@ -193,7 +204,7 @@ namespace quickbook | special [Process("special", self.out)] | string_ [Process("string", self.out)] | number [Process("number", self.out)] - | anychar_p [Unexpected(self.out)] + | repeat_p(1)[anychar_p] [Unexpected(self.out)] ) ; @@ -209,13 +220,23 @@ namespace quickbook ) ; - escape - = str_p("``") [PreEscape(self.escape_actions, save)] - >> ( - (+(anychar_p - "``") >> eps_p("``")) - & qbk_phrase + escape = + str_p("``") [PreEscape(self.escape_actions, save)] + >> + ( + ( + ( + (+(anychar_p - "``") >> eps_p("``")) + & qbk_phrase + ) + >> str_p("``") ) - >> str_p("``") [PostEscape(self.out, self.escape_actions, save)] + | + ( + eps_p [self.escape_actions.error] + >> *anychar_p + ) + ) [PostEscape(self.out, self.escape_actions, save)] ; comment diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 516e60f..5559257 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -8,7 +8,7 @@ project test ; -import quickbook-testing : quickbook-test ; +import quickbook-testing : quickbook-test quickbook-fail-test ; test-suite quickbook.test : [ quickbook-test quickbook-manual ] @@ -21,4 +21,16 @@ test-suite quickbook.test : [ quickbook-test templates ] [ quickbook-test xinclude ] [ quickbook-test import ] + [ quickbook-fail-test fail-include ] + [ quickbook-fail-test fail-import ] + [ quickbook-fail-test fail-template-arguments1 ] + [ quickbook-fail-test fail-template-arguments2 ] + [ quickbook-fail-test fail-cpp-mismatched-escape ] + [ quickbook-fail-test fail-python-mismatched-escape ] + [ quickbook-fail-test fail-post-process ] + [ quickbook-fail-test fail-parse-error1 ] + [ quickbook-fail-test fail-parse-error2 ] ; + + + diff --git a/test/fail-cpp-mismatched-escape.quickbook b/test/fail-cpp-mismatched-escape.quickbook new file mode 100644 index 0000000..d5d332c --- /dev/null +++ b/test/fail-cpp-mismatched-escape.quickbook @@ -0,0 +1,5 @@ +[article Odd code markup. [quickbook 1.4] ] + +[c++] + + `` int main() {} diff --git a/test/fail-import.quickbook b/test/fail-import.quickbook new file mode 100644 index 0000000..d3bd31f --- /dev/null +++ b/test/fail-import.quickbook @@ -0,0 +1,11 @@ +[article Expect import Fail +] + +[section Failure] + +[import this-is-not-a-file.cpp] + +[endsect] + + + diff --git a/test/fail-include.quickbook b/test/fail-include.quickbook new file mode 100644 index 0000000..2268a1e --- /dev/null +++ b/test/fail-include.quickbook @@ -0,0 +1,11 @@ +[article Expect xinclude Fail +] + +[section Failure] + +[include this-is-not-a-file.qbk] + +[endsect] + + + diff --git a/test/fail-parse-error1.quickbook b/test/fail-parse-error1.quickbook new file mode 100644 index 0000000..79bf3d7 --- /dev/null +++ b/test/fail-parse-error1.quickbook @@ -0,0 +1,3 @@ +[article Parse error [quickbook 1.4]] + +[heading Incomplete heading diff --git a/test/fail-parse-error2.quickbook b/test/fail-parse-error2.quickbook new file mode 100644 index 0000000..a7e5896 --- /dev/null +++ b/test/fail-parse-error2.quickbook @@ -0,0 +1,5 @@ +[article Parse error [quickbook 1.4]] + +[variablelist Variable List +[[1234]] +] diff --git a/test/fail-post-process.quickbook b/test/fail-post-process.quickbook new file mode 100644 index 0000000..994a635 --- /dev/null +++ b/test/fail-post-process.quickbook @@ -0,0 +1,3 @@ +[article Fail post process due to invalid embedded xml [quickbook 1.4] ] + +Invalid xml follows: '''<>''' diff --git a/test/fail-python-mismatched-escape.quickbook b/test/fail-python-mismatched-escape.quickbook new file mode 100644 index 0000000..e93cf13 --- /dev/null +++ b/test/fail-python-mismatched-escape.quickbook @@ -0,0 +1,5 @@ +[article Odd code markup. [quickbook 1.4] ] + +[python] + + print "Hello World." `` diff --git a/test/fail-template-arguments1.quickbook b/test/fail-template-arguments1.quickbook new file mode 100644 index 0000000..de54836 --- /dev/null +++ b/test/fail-template-arguments1.quickbook @@ -0,0 +1,13 @@ +[article Expect template to fail because there are too many arguments. +] + +[template unary[x] [x]] + +[section Failure] + +[unary a..b ] + +[endsect] + + + diff --git a/test/fail-template-arguments2.quickbook b/test/fail-template-arguments2.quickbook new file mode 100644 index 0000000..6de33fe --- /dev/null +++ b/test/fail-template-arguments2.quickbook @@ -0,0 +1,13 @@ +[article Expect template to fail because there are not enough arguments. +] + +[template ternary[x y z] [x][y][z]] + +[section Failure] + +[ternary a b ] + +[endsect] + + + diff --git a/test/quickbook-testing.jam b/test/quickbook-testing.jam index b4f50d0..ed0ae3b 100644 --- a/test/quickbook-testing.jam +++ b/test/quickbook-testing.jam @@ -60,6 +60,30 @@ rule quickbook-test ( target-name : input ? : reference-output ? : requirements $(target-name).test $(reference-output) $(target-name).boostbook + on + ] + ; + + modules.poke testing : .all-tests : \$\(all-tests\) $(t) ; + + return $(t) ; +} + +rule quickbook-fail-test ( target-name : input ? : requirements * ) +{ + input ?= $(target-name).quickbook ; + + local project = [ project.current ] ; + requirements += $(input:J=" ") ; + + local t = + [ targets.create-typed-target RUN_FAIL + : $(project) + : $(target-name) + : ..//quickbook + : $(requirements) + on + $(input) ] ; @@ -79,3 +103,4 @@ actions process-quickbook bind quickbook-command { $(quickbook-command) $(>) --output-file=$(<) --debug } + diff --git a/test/src/text_diff.cpp b/test/src/text_diff.cpp index 9409dc5..bcac672 100644 --- a/test/src/text_diff.cpp +++ b/test/src/text_diff.cpp @@ -10,10 +10,10 @@ #include #include -#include -#include +#include +#include -namespace spirit = boost::spirit; +namespace spirit = boost::spirit::classic; typedef std::istream_iterator iterator; typedef spirit::scanner scanner;