Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r70044 - in trunk/tools/quickbook: . src
From: dnljms_at_[hidden]
Date: 2011-03-16 20:13:00


Author: danieljames
Date: 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
New Revision: 70044
URL: http://svn.boost.org/trac/boost/changeset/70044

Log:
Merge improved unicode support on windows for quickbook.

Added:
   trunk/tools/quickbook/src/iterator.hpp
      - copied, changed from r68397, /branches/quickbook-filenames/tools/quickbook/src/iterator.hpp
Properties modified:
   trunk/tools/quickbook/ (props changed)
Text files modified:
   trunk/tools/quickbook/src/Jamfile.v2 | 8 +
   trunk/tools/quickbook/src/actions.cpp | 184 ++++++++++++++++------------
   trunk/tools/quickbook/src/actions.hpp | 28 ++-
   trunk/tools/quickbook/src/actions_class.cpp | 12 +
   trunk/tools/quickbook/src/actions_class.hpp | 2
   trunk/tools/quickbook/src/code_snippet.cpp | 13 +
   trunk/tools/quickbook/src/doc_info_actions.cpp | 13 +
   trunk/tools/quickbook/src/fwd.hpp | 8
   trunk/tools/quickbook/src/input_path.cpp | 256 +++++++++++++++++++++++++++++++++------
   trunk/tools/quickbook/src/input_path.hpp | 127 ++++++++++++++++---
   trunk/tools/quickbook/src/iterator.hpp | 6
   trunk/tools/quickbook/src/post_process.cpp | 6
   trunk/tools/quickbook/src/quickbook.cpp | 144 +++++++++++++++-------
   trunk/tools/quickbook/src/quickbook.hpp | 7
   trunk/tools/quickbook/src/syntax_highlight.hpp | 4
   trunk/tools/quickbook/src/template_stack.hpp | 44 +-----
   trunk/tools/quickbook/src/utils.cpp | 63 +--------
   trunk/tools/quickbook/src/utils.hpp | 20 +--
   18 files changed, 612 insertions(+), 333 deletions(-)

Modified: trunk/tools/quickbook/src/Jamfile.v2
==============================================================================
--- trunk/tools/quickbook/src/Jamfile.v2 (original)
+++ trunk/tools/quickbook/src/Jamfile.v2 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -8,6 +8,8 @@
 # http://www.boost.org/LICENSE_1_0.txt)
 #==============================================================================
 
+import os ;
+
 project quickbook
     : requirements
         <toolset>gcc:<c++-template-depth>300
@@ -16,6 +18,11 @@
         <toolset>darwin:<cflags>-g0
     ;
 
+if [ os.name ] = NT
+{
+ lib shell32 ;
+}
+
 exe quickbook
     :
     quickbook.cpp
@@ -50,4 +57,5 @@
       <toolset>msvc:<cxxflags>/wd4800
       <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
       <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
+ <os>NT:<library>shell32
     ;

Modified: trunk/tools/quickbook/src/actions.cpp
==============================================================================
--- trunk/tools/quickbook/src/actions.cpp (original)
+++ trunk/tools/quickbook/src/actions.cpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -20,6 +20,7 @@
 #include "markups.hpp"
 #include "actions_class.hpp"
 #include "grammar.hpp"
+#include "input_path.hpp"
 
 namespace quickbook
 {
@@ -51,18 +52,19 @@
     {
         if(!actions.output_pre(phrase)) return;
 
- position const pos = first.get_position();
- detail::outwarn(pos.file,pos.line) << "in column:" << pos.column << ", "
+ file_position const pos = first.get_position();
+ detail::outwarn(actions.filename, pos.line)
+ << "in column:" << pos.column << ", "
             << "[br] and \\n are deprecated" << ".\n";
         phrase << break_mark;
     }
 
     void error_action::operator()(iterator first, iterator /*last*/) const
     {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
+ file_position const pos = first.get_position();
+ detail::outerr(actions.filename, pos.line)
             << "Syntax Error near column " << pos.column << ".\n";
- ++error_count;
+ ++actions.error_count;
     }
 
     void tagged_action::operator()(std::string const& str) const
@@ -306,10 +308,10 @@
 
         if (mark != list_marks.top().first) // new_indent == list_indent
         {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
+ file_position const pos = first.get_position();
+ detail::outerr(actions.filename, pos.line)
                 << "Illegal change of list style near column " << pos.column << ".\n";
- detail::outwarn(pos.file,pos.line)
+ detail::outwarn(actions.filename, pos.line)
                 << "Ignoring change of list style" << std::endl;
             ++error_count;
         }
@@ -327,11 +329,11 @@
 
     void unexpected_char::operator()(iterator first, iterator last) const
     {
- position const pos = first.get_position();
+ file_position const pos = first.get_position();
 
- detail::outwarn(pos.file, pos.line)
+ detail::outwarn(actions.filename, pos.line)
             << "in column:" << pos.column
- << ", unexpected character: " << std::string(first, last)
+ << ", unexpected character: " << detail::utf8(first, last)
             << "\n";
 
         // print out an unexpected character
@@ -402,9 +404,8 @@
         if (program.size() == 0)
             return; // Nothing left to do here. The program is empty.
 
- iterator first_(program.begin(), program.end());
- iterator last_(program.end(), program.end());
- first_.set_position(first.get_position());
+ iterator first_(program.begin(), first.get_position());
+ iterator last_(program.end());
 
         // TODO: Shouldn't phrase be empty here? Why would it be output
         // after the code block?
@@ -489,14 +490,14 @@
 
     void attribute_action::operator()(iterator first, iterator last) const
     {
- position const pos = first.get_position();
+ file_position const pos = first.get_position();
 
         if (!attributes.insert(
                 attribute_map::value_type(attribute_name, std::string(first, last))
             ).second)
         {
- detail::outwarn(pos.file,pos.line)
- << "Repeated attribute: " << attribute_name << ".\n";
+ detail::outwarn(actions.filename, pos.line)
+ << "Repeated attribute: " << detail::utf8(attribute_name) << ".\n";
         }
     }
 
@@ -504,17 +505,38 @@
     {
         if(!actions.output_pre(phrase)) return;
 
- fs::path const img_path(image_fileref);
-
+ // Find the file basename and extension.
+ //
+ // Not using Boost.Filesystem because I want to stay in UTF-8.
+ // Need to think about uri encoding.
+
+ std::string::size_type pos;
+ std::string stem,extension;
+
+ pos = image_fileref.rfind('/');
+ stem = pos == std::string::npos ?
+ image_fileref :
+ image_fileref.substr(pos + 1);
+
+ pos = stem.rfind('.');
+ if (pos != std::string::npos)
+ {
+ extension = stem.substr(pos + 1);
+ stem = stem.substr(0, pos);
+ }
+
+ // Extract the alt tag, to use as a text description.
+ // Or if there isn't one, use the stem of the file name.
+ // TODO: IMO if there isn't an alt tag, then the description should
+ // be empty or missing.
+
         attribute_map::iterator it = attributes.find("alt");
- std::string alt_text = it != attributes.end() ?
- it->second :
- img_path.stem().generic_string();
+ std::string alt_text = it != attributes.end() ? it->second : stem;
         attributes.erase("alt");
 
         attributes.insert(attribute_map::value_type("fileref", image_fileref));
 
- if(img_path.extension() == ".svg")
+ if(extension == ".svg")
         {
            //
            // SVG's need special handling:
@@ -531,11 +553,12 @@
            //
            // Image paths are relative to the html subdirectory:
            //
- fs::path img;
- if(img_path.root_path().empty())
- img = "html" / img_path; // relative path
- else
- img = img_path; // absolute path
+ // TODO: This seems wrong to me.
+ //
+ fs::path img = detail::generic_to_path(image_fileref);
+ if(img.root_path().empty())
+ img = "html" / img; // relative path
+
            //
            // Now load the SVG file:
            //
@@ -599,8 +622,8 @@
 
         phrase << "></imagedata></imageobject>";
 
- // Also add a textobject -- use the basename of the image file.
- // This will mean we get "alt" attributes of the HTML img.
+ // Add a textobject containing the alt tag from earlier.
+ // This will be used for the alt tag in html.
         phrase << "<textobject><phrase>";
         detail::print_string(alt_text, phrase.get());
         phrase << "</phrase></textobject>";
@@ -630,13 +653,18 @@
     {
         if(actions.suppress) return;
         if (!actions.templates.add(
- template_symbol(actions.template_identifier, actions.template_info,
- std::string(first, last), first.get_position(),
- actions.template_block, &actions.templates.top_scope())))
- {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
- << "Template Redefinition: " << actions.template_identifier << std::endl;
+ template_symbol(
+ actions.template_identifier,
+ actions.template_info,
+ std::string(first, last),
+ actions.filename,
+ first.get_position(),
+ actions.template_block,
+ &actions.templates.top_scope())))
+ {
+ file_position const pos = first.get_position();
+ detail::outerr(actions.filename, pos.line)
+ << "Template Redefinition: " << detail::utf8(actions.template_identifier) << std::endl;
             ++actions.error_count;
         }
 
@@ -704,7 +732,8 @@
         bool break_arguments(
             std::vector<template_body>& args
           , std::vector<std::string> const& params
- , position const& pos
+ , fs::path const& filename
+ , file_position const& pos
         )
         {
             // Quickbook 1.4-: If there aren't enough parameters seperated by
@@ -725,9 +754,8 @@
                     // arguments, or if there are no more spaces left.
 
                     template_body& body = args.back();
- iterator begin(body.content.begin(), body.content.end(),
- position(body.position.file.c_str(), body.position.line, body.position.column));
- iterator end(body.content.end(), body.content.end());
+ iterator begin(body.content.begin(), body.position);
+ iterator end(body.content.end());
                     
                     iterator l_pos = find_first_seperator(begin, end);
                     if (l_pos == end)
@@ -738,7 +766,7 @@
                     while(r_pos != end && std::find(whitespace, whitespace_end, *r_pos) != whitespace_end) ++r_pos;
                     if (r_pos == end)
                         break;
- template_body second(std::string(r_pos, end), r_pos.get_position(), false);
+ template_body second(std::string(r_pos, end), body.filename, r_pos.get_position(), false);
                     body.content = std::string(begin, l_pos);
                     args.push_back(second);
                 }
@@ -746,7 +774,7 @@
 
             if (args.size() != params.size())
             {
- detail::outerr(pos.file, pos.line)
+ detail::outerr(filename, pos.line)
                     << "Invalid number of arguments passed. Expecting: "
                     << params.size()
                     << " argument(s), got: "
@@ -763,7 +791,7 @@
             std::vector<template_body>& args
           , std::vector<std::string> const& params
           , template_scope const& scope
- , position const& pos
+ , file_position const& pos
           , quickbook::actions& actions
         )
         {
@@ -777,9 +805,9 @@
             {
                 if (!actions.templates.add(
                         template_symbol(*tpl, empty_params, arg->content,
- arg->position, arg->is_block, &scope)))
+ arg->filename, arg->position, arg->is_block, &scope)))
                 {
- detail::outerr(pos.file,pos.line)
+ detail::outerr(actions.filename, pos.line)
                         << "Duplicate Symbol Found" << std::endl;
                     ++actions.error_count;
                     return std::make_pair(false, tpl);
@@ -814,9 +842,10 @@
                 if (!body.is_block)
                 {
                     // do a phrase level parse
- iterator first(body.content.begin(), body.content.end(),
- position(body.position.file.c_str(), body.position.line, body.position.column));
- iterator last(body.content.end(), body.content.end());
+ actions.filename = body.filename;
+ iterator first(body.content.begin(), body.position);
+ iterator last(body.content.end());
+
                     return cl::parse(first, last, actions.grammar().simple_phrase).full;
                 }
                 else
@@ -825,10 +854,11 @@
                     // ensure that we have enough trailing newlines to eliminate
                     // the need to check for end of file in the grammar.
                     
+ actions.filename = body.filename;
                     std::string content = body.content + "\n\n";
- iterator first(content.begin(), content.end(),
- position(body.position.file.c_str(), body.position.line, body.position.column));
- iterator last(content.end(), content.end());
+ iterator first(content.begin(), body.position);
+ iterator last(content.end());
+
                     return cl::parse(first, last, actions.grammar().block).full;
                 }
             }
@@ -847,6 +877,7 @@
         actions.template_args.push_back(
             template_body(
                 std::string(first, last),
+ actions.filename,
                 first.get_position(),
                 actions.template_block));
     }
@@ -861,12 +892,12 @@
         std::string identifier;
         std::swap(args, actions.template_args);
         std::swap(identifier, actions.template_identifier);
- position const pos = first.get_position();
+ file_position const pos = first.get_position();
 
         ++actions.template_depth;
         if (actions.template_depth > actions.max_template_depth)
         {
- detail::outerr(pos.file,pos.line)
+ detail::outerr(actions.filename, pos.line)
                 << "Infinite loop detected" << std::endl;
             --actions.template_depth;
             ++actions.error_count;
@@ -906,7 +937,7 @@
             {
                 // Break the arguments for a template
             
- if (!break_arguments(args, symbol->params, pos))
+ if (!break_arguments(args, symbol->params, actions.filename, pos))
                 {
                     actions.pop(); // restore the actions' states
                     --actions.template_depth;
@@ -918,7 +949,7 @@
             {
                 if (!args.empty())
                 {
- detail::outerr(pos.file, pos.line)
+ detail::outerr(actions.filename, pos.line)
                         << "Arguments for code snippet."
                         <<std::endl;
                     ++actions.error_count;
@@ -939,7 +970,7 @@
                     code += "linkends=\"" + callout_id + "\" />";
                     code += "'''";
 
- args.push_back(template_body(code, first.get_position(), false));
+ args.push_back(template_body(code, actions.filename, pos, false));
                 }
             }
 
@@ -963,14 +994,14 @@
 
             if (!parse_template(symbol->body, actions.template_escape, actions))
             {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
+ file_position const pos = first.get_position();
+ detail::outerr(actions.filename, pos.line)
                     << "Expanding "
                     << (symbol->body.is_block ? "block" : "phrase")
- << " template: " << symbol->identifier << std::endl
+ << " template: " << detail::utf8(symbol->identifier) << std::endl
                     << std::endl
                     << "------------------begin------------------" << std::endl
- << symbol->body.content
+ << detail::utf8(symbol->body.content)
                     << "------------------end--------------------" << std::endl
                     << std::endl;
                 actions.pop(); // restore the actions' states
@@ -981,9 +1012,9 @@
 
             if (actions.section_level != actions.min_section_level)
             {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
- << "Mismatched sections in template " << identifier << std::endl;
+ file_position const pos = first.get_position();
+ detail::outerr(actions.filename, pos.line)
+ << "Mismatched sections in template " << detail::utf8(identifier) << std::endl;
                 actions.pop(); // restore the actions' states
                 --actions.template_depth;
                 ++actions.error_count;
@@ -1012,10 +1043,10 @@
 
                 if(!r)
                 {
- detail::outerr(c.position.file, c.position.line)
+ detail::outerr(c.filename, c.position.line)
                         << "Expanding callout." << std::endl
                         << "------------------begin------------------" << std::endl
- << c.content
+ << detail::utf8(c.content)
                         << std::endl
                         << "------------------end--------------------" << std::endl
                         ;
@@ -1241,8 +1272,8 @@
 
         if (section_level <= min_section_level)
         {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
+ file_position const pos = first.get_position();
+ detail::outerr(actions.filename, pos.line)
                 << "Mismatched [endsect] near column " << pos.column << ".\n";
             ++error_count;
             
@@ -1266,8 +1297,8 @@
     
     void element_id_warning_action::operator()(iterator first, iterator) const
     {
- position const pos = first.get_position();
- detail::outwarn(pos.file,pos.line) << "Empty id.\n";
+ file_position const pos = first.get_position();
+ detail::outwarn(actions.filename, pos.line) << "Empty id.\n";
     }
 
     fs::path path_difference(fs::path const& outdir, fs::path const& path)
@@ -1293,7 +1324,7 @@
     {
         // Given a source file and the current filename, calculate the
         // path to the source file relative to the output directory.
- fs::path path(std::string(first, last));
+ fs::path path = detail::generic_to_path(std::string(first, last));
         if (!path.is_complete())
         {
             fs::path infile = fs::absolute(actions.filename).normalize();
@@ -1330,9 +1361,8 @@
                 }
 
                 // Search in each of the include path locations.
- BOOST_FOREACH(std::string const & p, include_path)
+ BOOST_FOREACH(fs::path full, include_path)
                 {
- fs::path full(p);
                     full /= path;
                     if (fs::exists(full))
                     {
@@ -1361,9 +1391,8 @@
             ts.parent = &actions.templates.top_scope();
             if (!actions.templates.add(ts))
             {
- cl::file_position const pos = ts.body.position;
- detail::outerr(pos.file, pos.line)
- << "Template Redefinition: " << tname << std::endl;
+ detail::outerr(ts.body.filename, ts.body.position.line)
+ << "Template Redefinition: " << detail::utf8(tname) << std::endl;
                 ++actions.error_count;
             }
         }
@@ -1414,7 +1443,8 @@
         }
 
         // update the __FILENAME__ macro
- *boost::spirit::classic::find(actions.macro, "__FILENAME__") = actions.filename.string();
+ *boost::spirit::classic::find(actions.macro, "__FILENAME__")
+ = detail::path_to_generic(actions.filename);
 
         // parse the file
         quickbook::parse_file(actions.filename.string().c_str(), actions, true);

Modified: trunk/tools/quickbook/src/actions.hpp
==============================================================================
--- trunk/tools/quickbook/src/actions.hpp (original)
+++ trunk/tools/quickbook/src/actions.hpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -125,13 +125,12 @@
     {
         // Prints an error message to std::cerr
 
- error_action(
- int& error_count)
- : error_count(error_count) {}
+ error_action(quickbook::actions& actions)
+ : actions(actions) {}
 
         void operator()(iterator first, iterator /*last*/) const;
 
- int& error_count;
+ quickbook::actions& actions;
     };
 
     struct tagged_action
@@ -397,12 +396,16 @@
     {
         // Handles unexpected chars in c++ syntax
 
- unexpected_char(collector& out)
- : out(out) {}
+ unexpected_char(
+ collector& out
+ , quickbook::actions& actions)
+ : out(out)
+ , actions(actions) {}
 
         void operator()(iterator first, iterator last) const;
 
         collector& out;
+ quickbook::actions& actions;
     };
 
     struct anchor_action
@@ -523,16 +526,16 @@
         attribute_action(
             attribute_map& attributes
           , std::string& attribute_name
- , int& error_count)
+ , quickbook::actions& actions)
         : attributes(attributes)
         , attribute_name(attribute_name)
- , error_count(error_count) {}
+ , actions(actions) {}
 
         void operator()(iterator first, iterator last) const;
 
         attribute_map& attributes;
         std::string& attribute_name;
- int& error_count;
+ quickbook::actions& actions;
     };
 
     struct image_action
@@ -826,7 +829,12 @@
    
    struct element_id_warning_action
    {
- void operator()(iterator first, iterator last) const;
+ element_id_warning_action(quickbook::actions& actions_)
+ : actions(actions_) {}
+
+ void operator()(iterator first, iterator last) const;
+
+ quickbook::actions& actions;
    };
 
     struct xinclude_action

Modified: trunk/tools/quickbook/src/actions_class.cpp
==============================================================================
--- trunk/tools/quickbook/src/actions_class.cpp (original)
+++ trunk/tools/quickbook/src/actions_class.cpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -12,6 +12,7 @@
 #include "markups.hpp"
 #include "quickbook.hpp"
 #include "grammar.hpp"
+#include "input_path.hpp"
 
 #if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
 #pragma warning(disable:4355)
@@ -19,7 +20,7 @@
 
 namespace quickbook
 {
- actions::actions(char const* filein_, fs::path const& outdir_, string_stream& out_)
+ actions::actions(fs::path const& filein_, fs::path const& outdir_, string_stream& out_)
         : grammar_()
 
     // header info
@@ -44,7 +45,7 @@
         , list_buffer()
 
     // state
- , filename(fs::absolute(fs::path(filein_)))
+ , filename(fs::absolute(filein_))
         , outdir(outdir_)
         , macro_change_depth(0)
         , macro()
@@ -77,7 +78,7 @@
         , suppress(false)
 
     // actions
- , error(error_count)
+ , error(*this)
         , extract_doc_title(doc_title, phrase, *this)
         , extract_doc_license(doc_license, phrase, *this)
         , extract_doc_purpose(doc_purpose, phrase, *this)
@@ -117,7 +118,7 @@
         , plain_char(phrase, *this)
         , raw_char(phrase, *this)
         , escape_unicode(phrase, *this)
- , attribute(attributes, attribute_name, error_count)
+ , attribute(attributes, attribute_name, *this)
         , image(phrase, attributes, image_fileref, *this)
         , cond_phrase_pre(condition, macro)
         , scoped_cond_phrase(*this)
@@ -192,6 +193,7 @@
 
         , begin_section(out, phrase, doc_id, section_id, section_level, qualified_section_id, element_id, *this)
         , end_section(out, section_level, min_section_level, qualified_section_id, error_count, *this)
+ , element_id_warning(*this)
         , xinclude(out, *this)
         , include(*this)
         , import(out, *this)
@@ -206,7 +208,7 @@
         // turn off __FILENAME__ macro on debug mode = true
         std::string filename_str = debug_mode ?
             std::string("NO_FILENAME_MACRO_GENERATED_IN_DEBUG_MODE") :
- filename.string();
+ detail::path_to_generic(filename);
 
         // add the predefined macros
         macro.add

Modified: trunk/tools/quickbook/src/actions_class.hpp
==============================================================================
--- trunk/tools/quickbook/src/actions_class.hpp (original)
+++ trunk/tools/quickbook/src/actions_class.hpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -22,7 +22,7 @@
 
     struct actions
     {
- actions(char const* filein_, fs::path const& outdir, string_stream& out_);
+ actions(fs::path const& filein_, fs::path const& outdir, string_stream& out_);
 
     private:
         boost::scoped_ptr<quickbook_grammar> grammar_;

Modified: trunk/tools/quickbook/src/code_snippet.cpp
==============================================================================
--- trunk/tools/quickbook/src/code_snippet.cpp (original)
+++ trunk/tools/quickbook/src/code_snippet.cpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -22,10 +22,12 @@
     struct code_snippet_actions
     {
         code_snippet_actions(std::vector<template_symbol>& storage,
+ std::string const& filename,
                                  std::string const& doc_id,
                                  char const* source_type)
             : callout_id(0)
             , storage(storage)
+ , filename(filename)
             , doc_id(doc_id)
             , source_type(source_type)
         {}
@@ -63,6 +65,7 @@
         std::string code;
         std::string id;
         std::vector<template_symbol>& storage;
+ fs::path filename;
         std::string const doc_id;
         char const* const source_type;
     };
@@ -271,13 +274,13 @@
         if (err != 0)
             return err; // return early on error
 
- iterator first(code.begin(), code.end(), file.c_str());
- iterator last(code.end(), code.end());
+ iterator first(code.begin());
+ iterator last(code.end());
 
         size_t fname_len = file.size();
         bool is_python = fname_len >= 3
             && file[--fname_len]=='y' && file[--fname_len]=='p' && file[--fname_len]=='.';
- code_snippet_actions a(storage, doc_id, is_python ? "[python]" : "[c++]");
+ code_snippet_actions a(storage, file, doc_id, is_python ? "[python]" : "[c++]");
         // TODO: Should I check that parse succeeded?
         if(is_python) {
             boost::spirit::classic::parse(first, last, python_code_snippet_grammar(a));
@@ -346,7 +349,7 @@
         code += "``[[callout" + boost::lexical_cast<std::string>(callout_id) + "]]``";
     
         snippet_stack.top().callouts.push_back(
- template_body(std::string(first, last), first.get_position(), true));
+ template_body(std::string(first, last), filename, first.get_position(), true));
         ++callout_id;
     }
 
@@ -400,7 +403,7 @@
         }
         
         // TODO: Save position in start_snippet
- template_symbol symbol(snippet.id, params, body, first.get_position(), true);
+ template_symbol symbol(snippet.id, params, body, filename, first.get_position(), true);
         symbol.callout = true;
         symbol.callouts = snippet.callouts;
         storage.push_back(symbol);

Modified: trunk/tools/quickbook/src/doc_info_actions.cpp
==============================================================================
--- trunk/tools/quickbook/src/doc_info_actions.cpp (original)
+++ trunk/tools/quickbook/src/doc_info_actions.cpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -13,6 +13,7 @@
 #include <boost/algorithm/string/join.hpp>
 #include "quickbook.hpp"
 #include "utils.hpp"
+#include "input_path.hpp"
 #include "actions_class.hpp"
 
 namespace quickbook
@@ -77,7 +78,7 @@
             qbk_major_version = 1;
             qbk_minor_version = 1;
             qbk_version_n = 101;
- detail::outwarn(actions.filename.string(),1)
+ detail::outwarn(actions.filename,1)
                 << "Warning: Quickbook version undefined. "
                 "Version 1.1 is assumed" << std::endl;
         }
@@ -89,13 +90,13 @@
         
         if (qbk_version_n == 106)
         {
- detail::outwarn(actions.filename.string(),1)
+ detail::outwarn(actions.filename,1)
                 << "Quickbook 1.6 is still under development and is "
                 "likely to change in the future." << std::endl;
         }
         else if(qbk_version_n < 100 || qbk_version_n > 106)
         {
- detail::outerr(actions.filename.string(),1)
+ detail::outerr(actions.filename,1)
                 << "Unknown version of quickbook: quickbook "
                 << qbk_major_version
                 << "."
@@ -121,11 +122,11 @@
 
             if(!invalid_attributes.empty())
             {
- detail::outwarn(actions.filename.string(),1)
+ detail::outwarn(actions.filename,1)
                     << (invalid_attributes.size() > 1 ?
                         "Invalid attributes" : "Invalid attribute")
- << " for '" << actions.doc_type << " document info': "
- << boost::algorithm::join(invalid_attributes, ", ")
+ << " for '" << detail::utf8(actions.doc_type) << " document info': "
+ << detail::utf8(boost::algorithm::join(invalid_attributes, ", "))
                     << "\n"
                     ;
             }

Modified: trunk/tools/quickbook/src/fwd.hpp
==============================================================================
--- trunk/tools/quickbook/src/fwd.hpp (original)
+++ trunk/tools/quickbook/src/fwd.hpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -11,18 +11,14 @@
 #if !defined(BOOST_SPIRIT_FWD_HPP)
 #define BOOST_SPIRIT_FWD_HPP
 
-#include <boost/spirit/include/classic_iterator.hpp>
-#include <boost/range.hpp>
-#include <boost/shared_ptr.hpp>
+#include "iterator.hpp"
 
 namespace quickbook
 {
     struct actions;
     struct quickbook_grammar;
 
- typedef boost::spirit::classic::file_position_base<char const*> position;
- typedef boost::spirit::classic::position_iterator<
- std::string::const_iterator, position> iterator;
+ typedef position_iterator<std::string::const_iterator> iterator;
 }
 
 #endif

Modified: trunk/tools/quickbook/src/input_path.cpp
==============================================================================
--- trunk/tools/quickbook/src/input_path.cpp (original)
+++ trunk/tools/quickbook/src/input_path.cpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -7,68 +7,240 @@
 =============================================================================*/
 
 #include <boost/program_options.hpp>
+#include <iostream>
 #include "input_path.hpp"
+#include "utils.hpp"
 
-#if !(defined(__cygwin__) || defined(__CYGWIN__))
+#if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS
+#include <boost/scoped_ptr.hpp>
+#include <windows.h>
+#include <io.h>
+#include <fcntl.h>
+#endif
 
-// Everything but cygwin
+#if QUICKBOOK_CYGWIN_PATHS
+#include <boost/scoped_array.hpp>
+#include <boost/program_options/errors.hpp>
+#include <sys/cygwin.h>
+#endif
 
-namespace quickbook { namespace detail
-{
- void validate(boost::any& v,
- const std::vector<std::string>& values,
- input_path*, int)
- {
- std::string path
- = boost::program_options::validators::get_single_string(values);
+namespace quickbook {
+ extern bool ms_errors;
+}
+
+namespace quickbook {
+namespace detail {
+
+// This is used for converting paths to UTF-8 on cygin.
+// Might be better not to use a windows
+#if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS
+ namespace {
+ std::string to_utf8(std::wstring const& x)
+ {
+ int buffer_count = WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, 0, 0, 0, 0);
+
+ if (!buffer_count)
+ throw conversion_error("Error converting wide string to utf-8.");
+
+ boost::scoped_ptr<char> buffer(new char[buffer_count]);
+
+ if (!WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count, 0, 0))
+ throw conversion_error("Error converting wide string to utf-8.");
+
+ return std::string(buffer.get());
+ }
 
- v = input_path(path);
+ std::wstring from_utf8(std::string const& x)
+ {
+ int buffer_count = MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, 0, 0);
+
+ if (!buffer_count)
+ throw conversion_error("Error converting utf-8 to wide string.");
+
+ boost::scoped_ptr<wchar_t> buffer(new wchar_t[buffer_count]);
+
+ if (!MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count))
+ throw conversion_error("Error converting utf-8 to wide string.");
+
+ return std::wstring(buffer.get());
+ }
     }
-}}
+#endif
 
+#if QUICKBOOK_WIDE_PATHS
+ std::string input_to_utf8(input_string const& x)
+ {
+ return to_utf8(x);
+ }
 #else
+ std::string input_to_utf8(input_string const& x)
+ {
+ return x;
+ }
+#endif
 
-// Cygwin 1.7.x
-
-#include <boost/filesystem/v3/config.hpp>
-#include <boost/scoped_array.hpp>
-#include <boost/program_options/errors.hpp>
-#include <windows.h>
-#include <sys/cygwin.h>
+#if QUICKBOOK_WIDE_PATHS
+ fs::path generic_to_path(std::string const& x)
+ {
+ return fs::path(from_utf8(x));
+ }
 
-namespace quickbook { namespace detail
-{
- void validate(boost::any& v,
- const std::vector<std::string>& values,
- input_path*, int)
- {
- std::string path
- = boost::program_options::validators::get_single_string(values);
-
-#if defined(BOOST_WINDOWS_PATH)
- cygwin_conv_path_t flags = CCP_POSIX_TO_WIN_A | CCP_RELATIVE;
-#elif defined(BOOST_POSIX_PATH)
- cygwin_conv_path_t flags = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
+ std::string path_to_generic(fs::path const& x)
+ {
+ return to_utf8(x.generic_wstring());
+ }
 #else
-# error "Boost filesystem path type doesn't seem to be set."
+ fs::path generic_to_path(std::string const& x)
+ {
+ return fs::path(x);
+ }
+
+ std::string path_to_generic(fs::path const& x)
+ {
+ return x.generic_string();
+ }
+
 #endif
 
+#if QUICKBOOK_CYGWIN_PATHS
+ fs::path input_to_path(input_string const& path)
+ {
+ cygwin_conv_path_t flags = CCP_POSIX_TO_WIN_W | CCP_RELATIVE;
+
         ssize_t size = cygwin_conv_path(flags, path.c_str(), NULL, 0);
         
- if (size < 0) {
- throw boost::program_options::validation_error(
- boost::program_options::validation_error::invalid_option_value);
- }
+ if (size < 0)
+ throw conversion_error("Error converting cygwin path to windows.");
+
+ // TODO: size is in bytes.
+ boost::scoped_array<wchar_t> result(new wchar_t[size]);
+
+ if(cygwin_conv_path(flags, path.c_str(), result.get(), size))
+ throw conversion_error("Error converting cygwin path to windows.");
+
+ return fs::path(result.get());
+ }
+
+ stream_string path_to_stream(fs::path const& path)
+ {
+ cygwin_conv_path_t flags = CCP_WIN_W_TO_POSIX | CCP_RELATIVE;
+
+ ssize_t size = cygwin_conv_path(flags, path.native().c_str(), NULL, 0);
+
+ if (size < 0)
+ throw conversion_error("Error converting windows path to cygwin.");
 
         boost::scoped_array<char> result(new char[size]);
 
- if(cygwin_conv_path(flags, path.c_str(), result.get(), size)) {
- throw boost::program_options::validation_error(
- boost::program_options::validation_error::invalid_option_value);
+ if(cygwin_conv_path(flags, path.native().c_str(), result.get(), size))
+ throw conversion_error("Error converting windows path to cygwin.");
+
+ return std::string(result.get());
+ }
+#else
+ fs::path input_to_path(input_string const& path)
+ {
+ return fs::path(path);
+ }
+
+#if QUICKBOOK_WIDE_PATHS && !QUICKBOOK_WIDE_STREAMS
+ stream_string path_to_stream(fs::path const& path)
+ {
+ return path.string();
+ }
+#else
+ stream_string path_to_stream(fs::path const& path)
+ {
+ return path.native();
+ }
+#endif
+
+#endif // QUICKBOOK_CYGWIN_PATHS
+
+#if QUICKBOOK_WIDE_STREAMS
+
+ void initialise_output()
+ {
+ if (_isatty(_fileno(stdout))) _setmode(_fileno(stdout), _O_U16TEXT);
+ if (_isatty(_fileno(stderr))) _setmode(_fileno(stderr), _O_U16TEXT);
+ }
+
+ void write_utf8(ostream& out, std::string const& x)
+ {
+ out << from_utf8(x);
+ }
+
+ ostream& out()
+ {
+ return std::wcout;
+ }
+
+ namespace
+ {
+ inline ostream& error_stream()
+ {
+ return std::wcerr;
         }
+ }
 
- v = input_path(result.get());
+#else
+
+ void initialise_output()
+ {
+ }
+
+ void write_utf8(ostream& out, std::string const& x)
+ {
+ out << x;
+ }
+
+ ostream& out()
+ {
+ return std::cout;
+ }
+
+ namespace
+ {
+ inline ostream& error_stream()
+ {
+ return std::clog;
+ }
     }
-}}
 
 #endif
+
+ ostream& outerr()
+ {
+ return error_stream() << "Error: ";
+ }
+
+ ostream& outerr(fs::path const& file, int line)
+ {
+ if (line >= 0)
+ {
+ if (ms_errors)
+ return error_stream() << path_to_stream(file) << "(" << line << "): error: ";
+ else
+ return error_stream() << path_to_stream(file) << ":" << line << ": error: ";
+ }
+ else
+ {
+ return error_stream() << path_to_stream(file) << ": error: ";
+ }
+ }
+
+ ostream& outwarn(fs::path const& file, int line)
+ {
+ if (line >= 0)
+ {
+ if (ms_errors)
+ return error_stream() << path_to_stream(file) << "(" << line << "): warning: ";
+ else
+ return error_stream() << path_to_stream(file) << ":" << line << ": warning: ";
+ }
+ else
+ {
+ return error_stream() << path_to_stream(file) << ": warning: ";
+ }
+ }
+}}

Modified: trunk/tools/quickbook/src/input_path.hpp
==============================================================================
--- trunk/tools/quickbook/src/input_path.hpp (original)
+++ trunk/tools/quickbook/src/input_path.hpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -9,31 +9,112 @@
 #if !defined(BOOST_QUICKBOOK_DETAIL_INPUT_PATH_HPP)
 #define BOOST_QUICKBOOK_DETAIL_INPUT_PATH_HPP
 
-#include <vector>
-#include <boost/any.hpp>
+#include <boost/config.hpp>
+#include <boost/filesystem/v3/path.hpp>
 #include <string>
+#include <stdexcept>
+#include <iostream>
 
-namespace quickbook { namespace detail
+#if defined(__cygwin__) || defined(__CYGWIN__)
+# define QUICKBOOK_CYGWIN_PATHS 1
+#elif defined(_WIN32)
+# define QUICKBOOK_WIDE_PATHS 1
+# if defined(BOOST_MSVC) && BOOST_MSVC >= 1400
+# define QUICKBOOK_WIDE_STREAMS 1
+# endif
+#endif
+
+#if !defined(QUICKBOOK_WIDE_PATHS)
+#define QUICKBOOK_WIDE_PATHS 0
+#endif
+
+#if !defined(QUICKBOOK_WIDE_STREAMS)
+#define QUICKBOOK_WIDE_STREAMS 0
+#endif
+
+#if !defined(QUICKBOOK_CYGWIN_PATHS)
+#define QUICKBOOK_CYGWIN_PATHS 0
+#endif
+
+namespace quickbook
 {
- // 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<std::string>&,
- input_path*, int);
- };
-}}
+ namespace fs = boost::filesystem;
+
+ namespace detail
+ {
+ struct conversion_error : std::runtime_error
+ {
+ conversion_error(char const* m) : std::runtime_error(m) {}
+ };
+
+ // 'generic': Paths in quickbook source and the generated boostbook.
+ // Always UTF-8.
+ // 'input': Paths (or other parameters) from the command line and
+ // possibly other sources in the future. Wide strings on
+ // normal windows, UTF-8 for cygwin and other platforms
+ // (hopefully).
+ // 'stream': Strings to be written to a stream.
+ // 'path': Stored as a boost::filesystem::path. Since
+ // Boost.Filesystem doesn't support cygwin, this
+ // is always wide on windows. UTF-8 on other
+ // platforms (again, hopefully).
+
+#if QUICKBOOK_WIDE_PATHS
+ typedef std::wstring input_string;
+#else
+ typedef std::string input_string;
+#endif
+
+#if QUICKBOOK_WIDE_STREAMS
+ typedef std::wostream ostream;
+ typedef std::wstring stream_string;
+#else
+ typedef std::ostream ostream;
+ typedef std::string stream_string;
+#endif
+
+ std::string input_to_utf8(input_string const&);
+ fs::path input_to_path(input_string const&);
+ stream_string path_to_stream(fs::path const&);
+
+ std::string path_to_generic(fs::path const&);
+ fs::path generic_to_path(std::string const&);
+
+ void initialise_output();
+
+ ostream& out();
+
+ // Preformats an error/warning message so that it can be parsed by
+ // common IDEs. Uses the ms_errors global to determine if VS format
+ // or GCC format. Returns the stream to continue ouput of the verbose
+ // error message.
+ ostream& outerr();
+ ostream& outerr(fs::path const& file, int line = -1);
+ ostream& outwarn(fs::path const& file, int line = -1);
+
+ struct utf8_proxy
+ {
+ std::string const& value;
+
+ explicit utf8_proxy(std::string const& v) : value(v) {}
+ };
+
+ void write_utf8(ostream& out, std::string const&);
+
+ inline ostream& operator<<(ostream& out, utf8_proxy const& p) {
+ write_utf8(out, p.value);
+ return out;
+ }
+
+ inline utf8_proxy utf8(std::string const& value) {
+ return utf8_proxy(value);
+ }
+
+ template <typename It>
+ inline utf8_proxy utf8(It begin, It end) {
+ return utf8_proxy(std::string(begin, end));
+ }
+ }
+}
 
 #endif

Copied: trunk/tools/quickbook/src/iterator.hpp (from r68397, /branches/quickbook-filenames/tools/quickbook/src/iterator.hpp)
==============================================================================
--- /branches/quickbook-filenames/tools/quickbook/src/iterator.hpp (original)
+++ trunk/tools/quickbook/src/iterator.hpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -16,7 +16,7 @@
 {
     struct file_position
     {
- file_position() : line(0), column(0) {}
+ file_position() : line(1), column(1) {}
         file_position(int l, int c) : line(l), column(c) {}
     
         int line;
@@ -52,12 +52,12 @@
     
             if (val == '\r') {
                 ++position_.line;
- position_.column = 0;
+ position_.column = 1;
             }
             else if (val == '\n') {
                 if (previous_ != '\r') {
                     ++position_.line;
- position_.column = 0;
+ position_.column = 1;
                 }
             }
             else {

Modified: trunk/tools/quickbook/src/post_process.cpp
==============================================================================
--- trunk/tools/quickbook/src/post_process.cpp (original)
+++ trunk/tools/quickbook/src/post_process.cpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -7,7 +7,7 @@
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 #include "post_process.hpp"
-#include "utils.hpp"
+#include "input_path.hpp"
 #include <boost/spirit/include/classic_core.hpp>
 #include <boost/bind.hpp>
 #include <set>
@@ -444,7 +444,7 @@
             else
             {
                 // fallback!
- ::quickbook::detail::outerr("")
+ ::quickbook::detail::outerr()
                     << "Warning: Post Processing Failed."
                     << std::endl;
                 out << in;
@@ -455,7 +455,7 @@
         catch(...)
         {
             // fallback!
- ::quickbook::detail::outerr("")
+ ::quickbook::detail::outerr()
                 << "Post Processing Failed."
                 << std::endl;
             out << in;

Modified: trunk/tools/quickbook/src/quickbook.cpp
==============================================================================
--- trunk/tools/quickbook/src/quickbook.cpp (original)
+++ trunk/tools/quickbook/src/quickbook.cpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -13,16 +13,21 @@
 #include "post_process.hpp"
 #include "utils.hpp"
 #include "input_path.hpp"
-#include <boost/spirit/include/classic_iterator.hpp>
 #include <boost/program_options.hpp>
 #include <boost/filesystem/v3/path.hpp>
 #include <boost/filesystem/v3/operations.hpp>
+#include <boost/filesystem/v3/fstream.hpp>
+#include <boost/range/algorithm.hpp>
 #include <boost/ref.hpp>
 
 #include <stdexcept>
-#include <fstream>
-#include <iostream>
 #include <vector>
+#include <iterator>
+
+#if defined(_WIN32)
+#include <windows.h>
+#include <shellapi.h>
+#endif
 
 #if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
 #pragma warning(disable:4355)
@@ -39,7 +44,7 @@
     tm* current_gm_time; // the current UTC time
     bool debug_mode; // for quickbook developers only
     bool ms_errors = false; // output errors/warnings as if for VS
- std::vector<std::string> include_path;
+ std::vector<fs::path> include_path;
     std::vector<std::string> preset_defines;
 
     static void set_macros(actions& actor)
@@ -49,8 +54,9 @@
                 end = preset_defines.end();
                 it != end; ++it)
         {
- iterator first(it->begin(), it->end(), "command line parameter");
- iterator last(it->end(), it->end());
+ // TODO: Set filename in actor???
+ iterator first(it->begin());
+ iterator last(it->end());
 
             cl::parse(first, last, actor.grammar().command_line_macro);
             // TODO: Check result?
@@ -63,9 +69,8 @@
     //
     ///////////////////////////////////////////////////////////////////////////
     int
- parse_file(char const* filein_, actions& actor, bool ignore_docinfo)
+ parse_file(fs::path const& filein_, actions& actor, bool ignore_docinfo)
     {
- using std::cerr;
         using std::vector;
         using std::string;
 
@@ -76,8 +81,8 @@
             return err;
         }
 
- iterator first(storage.begin(), storage.end(), filein_);
- iterator last(storage.end(), storage.end());
+ iterator first(storage.begin());
+ iterator last(storage.end());
 
         cl::parse_info<iterator> info = cl::parse(first, last, actor.grammar().doc_info);
 
@@ -94,8 +99,8 @@
 
         if (!info.full)
         {
- position const pos = info.stop.get_position();
- detail::outerr(pos.file,pos.line)
+ file_position const& pos = info.stop.get_position();
+ detail::outerr(actor.filename, pos.line)
                 << "Syntax Error near column " << pos.column << ".\n";
             ++actor.error_count;
         }
@@ -104,7 +109,7 @@
     }
 
     static int
- parse_document(char const* filein_, fs::path const& outdir, string_stream& out, bool ignore_docinfo = false)
+ parse_document(fs::path const& filein_, fs::path const& outdir, string_stream& out, bool ignore_docinfo = false)
     {
         actions actor(filein_, outdir, out);
 
@@ -117,7 +122,7 @@
 
         if(actor.error_count)
         {
- detail::outerr(filein_)
+ detail::outerr()
                 << "Error count: " << actor.error_count << ".\n";
         }
 
@@ -126,14 +131,14 @@
 
     static int
     parse_document(
- char const* filein_
- , char const* fileout_
+ fs::path const& filein_
+ , fs::path const& fileout_
       , int indent
       , int linewidth
       , bool pretty_print)
     {
         int result = 0;
- fs::path outdir = fs::path(fileout_).parent_path();
+ fs::path outdir = fileout_.parent_path();
         if (outdir.empty())
             outdir = ".";
         string_stream buffer;
@@ -141,7 +146,7 @@
 
         if (result == 0)
         {
- std::ofstream fileout(fileout_);
+ fs::ofstream fileout(fileout_);
 
             if (pretty_print)
             {
@@ -166,31 +171,46 @@
 {
     try
     {
+ namespace fs = boost::filesystem;
+ namespace po = boost::program_options;
+
         using boost::program_options::options_description;
         using boost::program_options::variables_map;
         using boost::program_options::store;
         using boost::program_options::parse_command_line;
+ using boost::program_options::wcommand_line_parser;
         using boost::program_options::command_line_parser;
         using boost::program_options::notify;
- using boost::program_options::value;
         using boost::program_options::positional_options_description;
+
+ using quickbook::detail::input_string;
 
         // First thing, the filesystem should record the current working directory.
- boost::filesystem::initial_path<boost::filesystem::path>();
+ fs::initial_path<fs::path>();
+
+ // Setup out output stream.
+ quickbook::detail::initialise_output();
 
         options_description desc("Allowed options");
+
+#if QUICKBOOK_WIDE_PATHS
+#define PO_VALUE po::wvalue
+#else
+#define PO_VALUE po::value
+#endif
+
         desc.add_options()
             ("help", "produce help message")
             ("version", "print version string")
             ("no-pretty-print", "disable XML pretty printing")
- ("indent", value<int>(), "indent spaces")
- ("linewidth", value<int>(), "line width")
- ("input-file", value<quickbook::detail::input_path>(), "input file")
- ("output-file", value<quickbook::detail::input_path>(), "output file")
+ ("indent", PO_VALUE<int>(), "indent spaces")
+ ("linewidth", PO_VALUE<int>(), "line width")
+ ("input-file", PO_VALUE<input_string>(), "input file")
+ ("output-file", PO_VALUE<input_string>(), "output file")
             ("debug", "debug mode (for developers)")
             ("ms-errors", "use Microsoft Visual Studio style error & warn message format")
- ("include-path,I", value< std::vector<quickbook::detail::input_path> >(), "include path")
- ("define,D", value< std::vector<std::string> >(), "define macro")
+ ("include-path,I", PO_VALUE< std::vector<input_string> >(), "include path")
+ ("define,D", PO_VALUE< std::vector<input_string> >(), "define macro")
         ;
 
         positional_options_description p;
@@ -200,18 +220,39 @@
         int indent = -1;
         int linewidth = -1;
         bool pretty_print = true;
+
+#if QUICKBOOK_WIDE_PATHS
+ int wide_argc;
+ LPWSTR* wide_argv = CommandLineToArgvW(GetCommandLineW(), &wide_argc);
+ if (!wide_argv)
+ {
+ quickbook::detail::outerr() << "Error getting argument values." << std::endl;
+ return 1;
+ }
+
+ store(wcommand_line_parser(wide_argc, wide_argv).options(desc).positional(p).run(), vm);
+
+ LocalFree(wide_argv);
+#else
         store(command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
+#endif
+
         notify(vm);
 
         if (vm.count("help"))
         {
- std::cout << desc << "\n";
+ std::ostringstream description_text;
+ description_text << desc;
+
+ quickbook::detail::out()
+ << quickbook::detail::utf8(description_text.str()) << "\n";
+
             return 0;
         }
 
         if (vm.count("version"))
         {
- std::cout << QUICKBOOK_VERSION << std::endl;
+ quickbook::detail::out() << QUICKBOOK_VERSION << std::endl;
             return 0;
         }
 
@@ -252,60 +293,67 @@
             quickbook::debug_mode = false;
         }
         
+ quickbook::include_path.clear();
         if (vm.count("include-path"))
         {
- std::vector<quickbook::detail::input_path> paths
- = vm["include-path"].as<
- std::vector<quickbook::detail::input_path> >();
- quickbook::include_path
- = std::vector<std::string>(paths.begin(), paths.end());
+ boost::transform(
+ vm["include-path"].as<std::vector<input_string> >(),
+ std::back_inserter(quickbook::include_path),
+ quickbook::detail::input_to_path);
         }
 
+ quickbook::preset_defines.clear();
         if (vm.count("define"))
         {
- quickbook::preset_defines
- = vm["define"].as<std::vector<std::string> >();
+ boost::transform(
+ vm["define"].as<std::vector<input_string> >(),
+ std::back_inserter(quickbook::preset_defines),
+ quickbook::detail::input_to_utf8);
         }
 
         if (vm.count("input-file"))
         {
- std::string filein
- = vm["input-file"].as<quickbook::detail::input_path>();
- std::string fileout;
+ fs::path filein = quickbook::detail::input_to_path(
+ vm["input-file"].as<input_string>());
+ fs::path fileout;
 
             if (vm.count("output-file"))
             {
- fileout = vm["output-file"].as<quickbook::detail::input_path>();
+ fileout = quickbook::detail::input_to_path(
+ vm["output-file"].as<input_string>());
             }
             else
             {
- fileout = quickbook::detail::remove_extension(filein.c_str());
- fileout += ".xml";
+ fileout = filein;
+ fileout.replace_extension(".xml");
             }
 
- std::cout << "Generating Output File: "
- << fileout
+ quickbook::detail::out() << "Generating Output File: "
+ << quickbook::detail::path_to_stream(fileout)
                 << std::endl;
 
- return quickbook::parse_document(filein.c_str(), fileout.c_str(), indent, linewidth, pretty_print);
+ return quickbook::parse_document(filein, fileout, indent, linewidth, pretty_print);
         }
         else
         {
- quickbook::detail::outerr("") << "Error: No filename given\n\n"
- << desc << std::endl;
+ std::ostringstream description_text;
+ description_text << desc;
+
+ quickbook::detail::outerr() << "No filename given\n\n"
+ << quickbook::detail::utf8(description_text.str()) << std::endl;
             return 1;
         }
     }
 
     catch(std::exception& e)
     {
- quickbook::detail::outerr("") << "Error: " << e.what() << "\n";
+ quickbook::detail::outerr() << quickbook::detail::utf8(e.what()) << "\n";
         return 1;
     }
 
     catch(...)
     {
- quickbook::detail::outerr("") << "Error: Exception of unknown type caught\n";
+ quickbook::detail::outerr() << "Exception of unknown type caught\n";
         return 1;
     }
 

Modified: trunk/tools/quickbook/src/quickbook.hpp
==============================================================================
--- trunk/tools/quickbook/src/quickbook.hpp (original)
+++ trunk/tools/quickbook/src/quickbook.hpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -15,17 +15,20 @@
 #include <time.h>
 #include <vector>
 #include <string>
+#include <boost/filesystem/v3/path.hpp>
 #include "fwd.hpp"
 
 namespace quickbook
 {
+ namespace fs = boost::filesystem;
+
     extern tm* current_time; // the current time
     extern tm* current_gm_time; // the current UTC time
     extern bool debug_mode;
- extern std::vector<std::string> include_path;
+ extern std::vector<fs::path> include_path;
     extern std::vector<std::string> preset_defines;
 
- int parse_file(char const* filein_, actions& actor, bool ignore_docinfo = false);
+ int parse_file(fs::path const& filein_, actions& actor, bool ignore_docinfo = false);
 }
 
 #endif

Modified: trunk/tools/quickbook/src/syntax_highlight.hpp
==============================================================================
--- trunk/tools/quickbook/src/syntax_highlight.hpp (original)
+++ trunk/tools/quickbook/src/syntax_highlight.hpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -57,7 +57,7 @@
                     | char_ [Process("char", self.out)]
                     | number [Process("number", self.out)]
                     | cl::repeat_p(1)[cl::anychar_p]
- [Unexpected(self.out)]
+ [Unexpected(self.out, self.escape_actions)]
                     )
                     ;
 
@@ -206,7 +206,7 @@
                     | string_ [Process("string", self.out)]
                     | number [Process("number", self.out)]
                     | cl::repeat_p(1)[cl::anychar_p]
- [Unexpected(self.out)]
+ [Unexpected(self.out, self.escape_actions)]
                     )
                     ;
 

Modified: trunk/tools/quickbook/src/template_stack.hpp
==============================================================================
--- trunk/tools/quickbook/src/template_stack.hpp (original)
+++ trunk/tools/quickbook/src/template_stack.hpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -14,41 +14,34 @@
 #include <vector>
 #include <boost/tuple/tuple.hpp>
 #include <boost/assert.hpp>
-#include <boost/spirit/include/classic_position_iterator.hpp>
 #include <boost/spirit/include/classic_functor_parser.hpp>
 #include <boost/spirit/include/classic_symbols.hpp>
 #include <boost/next_prior.hpp>
+#include <boost/filesystem/path.hpp>
+#include "fwd.hpp"
 
 namespace quickbook
 {
+ namespace fs = boost::filesystem;
+
     struct template_body
     {
         template_body(
                 std::string const& content,
- boost::spirit::classic::file_position const& position,
+ fs::path const& filename,
+ file_position const& position,
                 bool is_block
             )
             : content(content)
+ , filename(filename)
             , position(position)
             , is_block(is_block)
         {
         }
 
- template_body(
- std::string const& content,
- boost::spirit::classic::file_position_base<char const*> const& position,
- bool is_block
- )
- : content(content)
- , position(position.file, position.line, position.column)
- , is_block(is_block)
- {
- }
-
         std::string content;
- // Note: Using file_position to store the filename after the file
- // has been closed.
- boost::spirit::classic::file_position position;
+ fs::path filename;
+ file_position position;
         bool is_block;
     };
 
@@ -60,26 +53,13 @@
                 std::string const& identifier,
                 std::vector<std::string> const& params,
                 std::string const& body,
- boost::spirit::classic::file_position const& position,
- bool is_block,
- template_scope const* parent = 0)
- : identifier(identifier)
- , params(params)
- , body(body, position, is_block)
- , parent(parent)
- , callout(false)
- , callouts() {}
-
- template_symbol(
- std::string const& identifier,
- std::vector<std::string> const& params,
- std::string const& body,
- boost::spirit::classic::file_position_base<char const*> const& position,
+ fs::path const& filename,
+ file_position const& position,
                 bool is_block,
                 template_scope const* parent = 0)
            : identifier(identifier)
            , params(params)
- , body(body, position, is_block)
+ , body(body, filename, position, is_block)
            , parent(parent)
            , callout(false)
            , callouts() {}

Modified: trunk/tools/quickbook/src/utils.cpp
==============================================================================
--- trunk/tools/quickbook/src/utils.cpp (original)
+++ trunk/tools/quickbook/src/utils.cpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -8,19 +8,17 @@
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 #include "utils.hpp"
+#include "input_path.hpp"
 #include <boost/spirit/include/classic_core.hpp>
+#include <boost/filesystem/v3/fstream.hpp>
 
 #include <cctype>
 #include <cstring>
 #include <stdexcept>
 #include <fstream>
-#include <iostream>
+#include <ostream>
 #include <map>
 
-namespace quickbook {
- extern bool ms_errors;
-}
-
 namespace quickbook { namespace detail
 {
     void print_char(char ch, std::ostream& out)
@@ -118,21 +116,6 @@
         }
     }
 
- // remove the extension from a filename
- std::string
- remove_extension(std::string const& filename)
- {
- std::string::size_type const n = filename.find_last_of('.');
- if(std::string::npos == n)
- {
- return filename;
- }
- else
- {
- return std::string(filename.begin(), filename.begin()+n);
- }
- }
-
     std::string escape_uri(std::string uri)
     {
         for (std::string::size_type n = 0; n < uri.size(); ++n)
@@ -151,36 +134,6 @@
         return uri;
     }
 
- std::ostream& outerr(std::string const& file, int line)
- {
- if (line >= 0)
- {
- if (ms_errors)
- return std::clog << file << "(" << line << "): error: ";
- else
- return std::clog << file << ":" << line << ": error: ";
- }
- else
- {
- return std::clog << file << ": error: ";
- }
- }
-
- std::ostream& outwarn(std::string const& file, int line)
- {
- if (line >= 0)
- {
- if (ms_errors)
- return std::clog << file << "(" << line << "): warning: ";
- else
- return std::clog << file << ":" << line << ": warning: ";
- }
- else
- {
- return std::clog << file << ": warning: ";
- }
- }
-
     // Read the first few bytes in a file to see it starts with a byte order
     // mark. If it doesn't, then write the characters we've already read in.
     // Although, given how UTF-8 works, if we've read anything in, the files
@@ -238,12 +191,13 @@
 
     template <class InputIterator, class OutputIterator>
     bool normalize(InputIterator begin, InputIterator end,
- OutputIterator out, std::string const& filename)
+ OutputIterator out, fs::path const& filename)
     {
         std::string encoding = read_bom(begin, end, out);
 
         if(encoding != "UTF-8" && encoding != "") {
- outerr(filename) << encoding << " is not supported. Please use UTF-8."
+ outerr(filename) << encoding.c_str()
+ << " is not supported. Please use UTF-8."
                 << std::endl;
 
             return false;
@@ -263,15 +217,14 @@
         return true;
     }
 
- int load(std::string const& filename, std::string& storage)
+ int load(fs::path const& filename, std::string& storage)
     {
- using std::cerr;
         using std::endl;
         using std::ios;
         using std::ifstream;
         using std::istream_iterator;
 
- ifstream in(filename.c_str(), std::ios_base::in);
+ fs::ifstream in(filename, std::ios_base::in);
 
         if (!in)
         {

Modified: trunk/tools/quickbook/src/utils.hpp
==============================================================================
--- trunk/tools/quickbook/src/utils.hpp (original)
+++ trunk/tools/quickbook/src/utils.hpp 2011-03-16 20:12:56 EDT (Wed, 16 Mar 2011)
@@ -11,12 +11,16 @@
 #define BOOST_SPIRIT_QUICKBOOK_UTILS_HPP
 
 #include <string>
-#include <iostream>
 #include <cctype>
 #include <boost/ref.hpp>
 #include <boost/assert.hpp>
+#include <boost/filesystem/v3/path.hpp>
 
-namespace quickbook { namespace detail
+namespace quickbook {
+
+ namespace fs = boost::filesystem;
+
+namespace detail
 {
     void print_char(char ch, std::ostream& out);
     void print_string(std::basic_string<char> const& str, std::ostream& out);
@@ -54,21 +58,11 @@
     // un-indent a code segment
     void unindent(std::string& program);
 
- // remove the extension from a filename
- std::string remove_extension(std::string const& filename);
-
     std::string escape_uri(std::string uri);
 
- // Preformats an error/warning message so that it can be parsed by
- // common IDEs. Uses the ms_errors global to determine if VS format
- // or GCC format. Returns the stream to continue ouput of the verbose
- // error message.
- std::ostream & outerr(std::string const& file, int line = -1);
- std::ostream & outwarn(std::string const& file, int line = -1);
-
     // load file into memory with extra trailing newlines to eliminate
     // the need to check for end of file in the grammar.
- int load(std::string const& filename, std::string& storage);
+ int load(fs::path const& filename, std::string& storage);
 
     // given a file extension, return the type of the source file
     // we'll have an internal database for known file types.


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