Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r68563 - branches/quickbook-filenames/tools/quickbook/src
From: dnljms_at_[hidden]
Date: 2011-01-30 06:38:19


Author: danieljames
Date: 2011-01-30 06:38:17 EST (Sun, 30 Jan 2011)
New Revision: 68563
URL: http://svn.boost.org/trac/boost/changeset/68563

Log:
Support for wide output streams on windows.
Text files modified:
   branches/quickbook-filenames/tools/quickbook/src/actions.cpp | 16 ++--
   branches/quickbook-filenames/tools/quickbook/src/doc_info_actions.cpp | 4
   branches/quickbook-filenames/tools/quickbook/src/input_path.cpp | 155 ++++++++++++++++++++++++++++++++-------
   branches/quickbook-filenames/tools/quickbook/src/input_path.hpp | 79 +++++++++++++++++--
   branches/quickbook-filenames/tools/quickbook/src/quickbook.cpp | 54 ++++++++-----
   branches/quickbook-filenames/tools/quickbook/src/utils.cpp | 4
   6 files changed, 239 insertions(+), 73 deletions(-)

Modified: branches/quickbook-filenames/tools/quickbook/src/actions.cpp
==============================================================================
--- branches/quickbook-filenames/tools/quickbook/src/actions.cpp (original)
+++ branches/quickbook-filenames/tools/quickbook/src/actions.cpp 2011-01-30 06:38:17 EST (Sun, 30 Jan 2011)
@@ -335,7 +335,7 @@
 
         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
@@ -499,7 +499,7 @@
             ).second)
         {
             detail::outwarn(actions.filename, pos.line)
- << "Repeated attribute: " << attribute_name << ".\n";
+ << "Repeated attribute: " << detail::utf8(attribute_name) << ".\n";
         }
     }
 
@@ -666,7 +666,7 @@
         {
             file_position const pos = first.get_position();
             detail::outerr(actions.filename, pos.line)
- << "Template Redefinition: " << actions.template_identifier << std::endl;
+ << "Template Redefinition: " << detail::utf8(actions.template_identifier) << std::endl;
             ++actions.error_count;
         }
 
@@ -1000,10 +1000,10 @@
                 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
@@ -1016,7 +1016,7 @@
             {
                 file_position const pos = first.get_position();
                 detail::outerr(actions.filename, pos.line)
- << "Mismatched sections in template " << identifier << std::endl;
+ << "Mismatched sections in template " << detail::utf8(identifier) << std::endl;
                 actions.pop(); // restore the actions' states
                 --actions.template_depth;
                 ++actions.error_count;
@@ -1048,7 +1048,7 @@
                     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
                         ;
@@ -1392,7 +1392,7 @@
             if (!actions.templates.add(ts))
             {
                 detail::outerr(ts.body.filename, ts.body.position.line)
- << "Template Redefinition: " << tname << std::endl;
+ << "Template Redefinition: " << detail::utf8(tname) << std::endl;
                 ++actions.error_count;
             }
         }

Modified: branches/quickbook-filenames/tools/quickbook/src/doc_info_actions.cpp
==============================================================================
--- branches/quickbook-filenames/tools/quickbook/src/doc_info_actions.cpp (original)
+++ branches/quickbook-filenames/tools/quickbook/src/doc_info_actions.cpp 2011-01-30 06:38:17 EST (Sun, 30 Jan 2011)
@@ -125,8 +125,8 @@
                 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: branches/quickbook-filenames/tools/quickbook/src/input_path.cpp
==============================================================================
--- branches/quickbook-filenames/tools/quickbook/src/input_path.cpp (original)
+++ branches/quickbook-filenames/tools/quickbook/src/input_path.cpp 2011-01-30 06:38:17 EST (Sun, 30 Jan 2011)
@@ -11,12 +11,14 @@
 #include "input_path.hpp"
 #include "utils.hpp"
 
-#if defined(_WIN32)
+#if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS
 #include <boost/scoped_ptr.hpp>
 #include <windows.h>
+#include <io.h>
+#include <fcntl.h>
 #endif
 
-#if (defined(__cygwin__) || defined(__CYGWIN__))
+#if QUICKBOOK_CYGWIN_PATHS
 #include <boost/scoped_array.hpp>
 #include <boost/program_options/errors.hpp>
 #include <sys/cygwin.h>
@@ -28,7 +30,10 @@
 
 namespace quickbook {
 namespace detail {
-#if defined(_WIN32)
+
+// 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)
         {
@@ -57,43 +62,49 @@
             if (!MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count))
                 throw conversion_error("Error converting utf-8 to wide string.");
             
- return native_string(buffer.get());
+ return std::wstring(buffer.get());
         }
     }
 #endif
 
- std::string native_to_utf8(native_string const& x)
+#if QUICKBOOK_WIDE_PATHS
+ std::string input_to_utf8(input_string const& x)
     {
-#if QUICKBOOK_WIDE_NATIVE
         return to_utf8(x);
+ }
 #else
+ std::string input_to_utf8(input_string const& x)
+ {
         return x;
-#endif
     }
+#endif
 
+#if QUICKBOOK_WIDE_PATHS
     fs::path generic_to_path(std::string const& x)
     {
-#if defined(_WIN32)
         return fs::path(from_utf8(x));
-#else
- return fs::path(x);
-#endif
     }
 
     std::string path_to_generic(fs::path const& x)
     {
-#if defined(_WIN32)
         return to_utf8(x.generic_wstring());
+ }
 #else
+ 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
     }
 
- fs::path native_to_path(native_string const& path)
+#endif
+
+#if QUICKBOOK_CYGWIN_PATHS
+ fs::path input_to_path(input_string const& path)
     {
-#if !(defined(__cygwin__) || defined(__CYGWIN__))
- return fs::path(path);
-#else
         cygwin_conv_path_t flags = CCP_POSIX_TO_WIN_W | CCP_RELATIVE;
 
         ssize_t size = cygwin_conv_path(flags, path.c_str(), NULL, 0);
@@ -101,47 +112,135 @@
         if (size < 0)
             throw conversion_error("Error converting cygwin path to windows.");
 
- boost::scoped_array<char> result(new char[size]);
+ // 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.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;
+ }
+ }
+
+#else
+
+ void initialise_output()
+ {
     }
 
- std::ostream& outerr()
+ 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 std::clog << "Error: ";
+ return error_stream() << "Error: ";
     }
 
- std::ostream& outerr(fs::path const& file, int line)
+ ostream& outerr(fs::path const& file, int line)
     {
         if (line >= 0)
         {
             if (ms_errors)
- return std::clog << file.string() << "(" << line << "): error: ";
+ return error_stream() << path_to_stream(file) << "(" << line << "): error: ";
             else
- return std::clog << file.string() << ":" << line << ": error: ";
+ return error_stream() << path_to_stream(file) << ":" << line << ": error: ";
         }
         else
         {
- return std::clog << file.string() << ": error: ";
+ return error_stream() << path_to_stream(file) << ": error: ";
         }
     }
 
- std::ostream& outwarn(fs::path const& file, int line)
+ ostream& outwarn(fs::path const& file, int line)
     {
         if (line >= 0)
         {
             if (ms_errors)
- return std::clog << file.string() << "(" << line << "): warning: ";
+ return error_stream() << path_to_stream(file) << "(" << line << "): warning: ";
             else
- return std::clog << file.string() << ":" << line << ": warning: ";
+ return error_stream() << path_to_stream(file) << ":" << line << ": warning: ";
         }
         else
         {
- return std::clog << file.string() << ": warning: ";
+ return error_stream() << path_to_stream(file) << ": warning: ";
         }
     }
 }}

Modified: branches/quickbook-filenames/tools/quickbook/src/input_path.hpp
==============================================================================
--- branches/quickbook-filenames/tools/quickbook/src/input_path.hpp (original)
+++ branches/quickbook-filenames/tools/quickbook/src/input_path.hpp 2011-01-30 06:38:17 EST (Sun, 30 Jan 2011)
@@ -9,11 +9,33 @@
 #if !defined(BOOST_QUICKBOOK_DETAIL_INPUT_PATH_HPP)
 #define BOOST_QUICKBOOK_DETAIL_INPUT_PATH_HPP
 
+#include <boost/config.hpp>
 #include <boost/filesystem/v3/path.hpp>
 #include <string>
 #include <stdexcept>
 #include <iostream>
 
+#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
 {
     namespace fs = boost::filesystem;
@@ -27,36 +49,71 @@
 
         // 'generic': Paths in quickbook source and the generated boostbook.
         // Always UTF-8.
- // 'native': Paths (or other parameters) from the command line and
+ // '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 defined(_WIN32) && !(defined(__cygwin__) || defined(__CYGWIN__))
-#define QUICKBOOK_WIDE_NATIVE 1
- typedef std::wstring native_string;
+#if QUICKBOOK_WIDE_PATHS
+ typedef std::wstring input_string;
 #else
-#define QUICKBOOK_WIDE_NATIVE 0
- typedef std::string native_string;
+ typedef std::string input_string;
 #endif
 
- std::string native_to_utf8(native_string const&);
- fs::path native_to_path(native_string const& x);
+#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.
- std::ostream & outerr();
- std::ostream & outerr(fs::path const& file, int line = -1);
- std::ostream & outwarn(fs::path const& file, int line = -1);
+ 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));
+ }
     }
 }
 

Modified: branches/quickbook-filenames/tools/quickbook/src/quickbook.cpp
==============================================================================
--- branches/quickbook-filenames/tools/quickbook/src/quickbook.cpp (original)
+++ branches/quickbook-filenames/tools/quickbook/src/quickbook.cpp 2011-01-30 06:38:17 EST (Sun, 30 Jan 2011)
@@ -71,7 +71,6 @@
     int
     parse_file(fs::path const& filein_, actions& actor, bool ignore_docinfo)
     {
- using std::cerr;
         using std::vector;
         using std::string;
 
@@ -184,14 +183,17 @@
         using boost::program_options::notify;
         using boost::program_options::positional_options_description;
         
- using quickbook::detail::native_string;
+ using quickbook::detail::input_string;
 
         // First thing, the filesystem should record the current working directory.
         fs::initial_path<fs::path>();
+
+ // Setup out output stream.
+ quickbook::detail::initialise_output();
 
         options_description desc("Allowed options");
 
-#if QUICKBOOK_WIDE_NATIVE
+#if QUICKBOOK_WIDE_PATHS
 #define PO_VALUE po::wvalue
 #else
 #define PO_VALUE po::value
@@ -203,12 +205,12 @@
             ("no-pretty-print", "disable XML pretty printing")
             ("indent", PO_VALUE<int>(), "indent spaces")
             ("linewidth", PO_VALUE<int>(), "line width")
- ("input-file", PO_VALUE<native_string>(), "input file")
- ("output-file", PO_VALUE<native_string>(), "output file")
+ ("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", PO_VALUE< std::vector<native_string> >(), "include path")
- ("define,D", PO_VALUE< std::vector<native_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;
@@ -219,7 +221,7 @@
         int linewidth = -1;
         bool pretty_print = true;
 
-#if QUICKBOOK_WIDE_NATIVE
+#if QUICKBOOK_WIDE_PATHS
         int wide_argc;
         LPWSTR* wide_argv = CommandLineToArgvW(GetCommandLineW(), &wide_argc);
         if (!wide_argv)
@@ -239,13 +241,18 @@
 
         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;
         }
 
@@ -290,30 +297,30 @@
         if (vm.count("include-path"))
         {
             boost::transform(
- vm["include-path"].as<std::vector<native_string> >(),
+ vm["include-path"].as<std::vector<input_string> >(),
                 std::back_inserter(quickbook::include_path),
- quickbook::detail::native_to_path);
+ quickbook::detail::input_to_path);
         }
 
         quickbook::preset_defines.clear();
         if (vm.count("define"))
         {
             boost::transform(
- vm["define"].as<std::vector<native_string> >(),
+ vm["define"].as<std::vector<input_string> >(),
                 std::back_inserter(quickbook::preset_defines),
- quickbook::detail::native_to_utf8);
+ quickbook::detail::input_to_utf8);
         }
 
         if (vm.count("input-file"))
         {
- fs::path filein = quickbook::detail::native_to_path(
- vm["input-file"].as<native_string>());
+ fs::path filein = quickbook::detail::input_to_path(
+ vm["input-file"].as<input_string>());
             fs::path fileout;
 
             if (vm.count("output-file"))
             {
- fileout = quickbook::detail::native_to_path(
- vm["output-file"].as<native_string>());
+ fileout = quickbook::detail::input_to_path(
+ vm["output-file"].as<input_string>());
             }
             else
             {
@@ -321,23 +328,26 @@
                 fileout.replace_extension("xml");
             }
 
- std::cout << "Generating Output File: "
- << fileout.string()
+ quickbook::detail::out() << "Generating Output File: "
+ << quickbook::detail::path_to_stream(fileout)
                 << std::endl;
 
             return quickbook::parse_document(filein, fileout, indent, linewidth, pretty_print);
         }
         else
         {
+ std::ostringstream description_text;
+ description_text << desc;
+
             quickbook::detail::outerr() << "No filename given\n\n"
- << desc << std::endl;
+ << quickbook::detail::utf8(description_text.str()) << std::endl;
             return 1;
         }
     }
 
     catch(std::exception& e)
     {
- quickbook::detail::outerr() << e.what() << "\n";
+ quickbook::detail::outerr() << quickbook::detail::utf8(e.what()) << "\n";
         return 1;
     }
 

Modified: branches/quickbook-filenames/tools/quickbook/src/utils.cpp
==============================================================================
--- branches/quickbook-filenames/tools/quickbook/src/utils.cpp (original)
+++ branches/quickbook-filenames/tools/quickbook/src/utils.cpp 2011-01-30 06:38:17 EST (Sun, 30 Jan 2011)
@@ -196,7 +196,8 @@
         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;
@@ -218,7 +219,6 @@
 
     int load(fs::path const& filename, std::string& storage)
     {
- using std::cerr;
         using std::endl;
         using std::ios;
         using std::ifstream;


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