1 /*=============================================================================
2     Copyright (c) 2009 Daniel James
3 
4     Use, modification and distribution is subject to the Boost Software
5     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6     http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 
9 #include "stream.hpp"
10 #include "files.hpp"
11 #include "path.hpp"
12 
13 #if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS
14 #include <fcntl.h>
15 #include <io.h>
16 #endif
17 
18 namespace quickbook
19 {
20     namespace detail
21     {
22         namespace
23         {
24             bool ms_errors = false;
25         }
26 
set_ms_errors(bool x)27         void set_ms_errors(bool x) { ms_errors = x; }
28 
29 #if QUICKBOOK_WIDE_STREAMS
30 
initialise_output()31         void initialise_output()
32         {
33             if (_isatty(_fileno(stdout))) _setmode(_fileno(stdout), _O_U16TEXT);
34             if (_isatty(_fileno(stderr))) _setmode(_fileno(stderr), _O_U16TEXT);
35         }
36 
write_utf8(ostream::base_ostream & out,quickbook::string_view x)37         void write_utf8(ostream::base_ostream& out, quickbook::string_view x)
38         {
39             out << from_utf8(x);
40         }
41 
out()42         ostream& out()
43         {
44             static ostream x(std::wcout);
45             return x;
46         }
47 
48         namespace
49         {
error_stream()50             inline ostream& error_stream()
51             {
52                 static ostream x(std::wcerr);
53                 return x;
54             }
55         }
56 
57 #else
58 
initialise_output()59         void initialise_output() {}
60 
write_utf8(ostream::base_ostream & out,quickbook::string_view x)61         void write_utf8(ostream::base_ostream& out, quickbook::string_view x)
62         {
63             out << x;
64         }
65 
out()66         ostream& out()
67         {
68             static ostream x(std::cout);
69             return x;
70         }
71 
72         namespace
73         {
error_stream()74             inline ostream& error_stream()
75             {
76                 static ostream x(std::clog);
77                 return x;
78             }
79         }
80 
81 #endif
82 
outerr()83         ostream& outerr() { return error_stream() << "Error: "; }
84 
outerr(fs::path const & file,std::ptrdiff_t line)85         ostream& outerr(fs::path const& file, std::ptrdiff_t line)
86         {
87             if (line >= 0) {
88                 if (ms_errors)
89                     return error_stream() << path_to_stream(file) << "(" << line
90                                           << "): error: ";
91                 else
92                     return error_stream() << path_to_stream(file) << ":" << line
93                                           << ": error: ";
94             }
95             else {
96                 return error_stream() << path_to_stream(file) << ": error: ";
97             }
98         }
99 
outerr(file_ptr const & f,string_iterator pos)100         ostream& outerr(file_ptr const& f, string_iterator pos)
101         {
102             return outerr(f->path, f->position_of(pos).line);
103         }
104 
outwarn(fs::path const & file,std::ptrdiff_t line)105         ostream& outwarn(fs::path const& file, std::ptrdiff_t line)
106         {
107             if (line >= 0) {
108                 if (ms_errors)
109                     return error_stream() << path_to_stream(file) << "(" << line
110                                           << "): warning: ";
111                 else
112                     return error_stream() << path_to_stream(file) << ":" << line
113                                           << ": warning: ";
114             }
115             else {
116                 return error_stream() << path_to_stream(file) << ": warning: ";
117             }
118         }
119 
outwarn(file_ptr const & f,string_iterator pos)120         ostream& outwarn(file_ptr const& f, string_iterator pos)
121         {
122             return outwarn(f->path, f->position_of(pos).line);
123         }
124 
operator <<(char c)125         ostream& ostream::operator<<(char c)
126         {
127             assert(c && !(c & 0x80));
128             base << c;
129             return *this;
130         }
131 
check_ascii(char const * x)132         inline bool check_ascii(char const* x)
133         {
134             for (; *x; ++x)
135                 if (*x & 0x80) return false;
136             return true;
137         }
138 
operator <<(char const * x)139         ostream& ostream::operator<<(char const* x)
140         {
141             assert(check_ascii(x));
142             base << x;
143             return *this;
144         }
145 
operator <<(std::string const & x)146         ostream& ostream::operator<<(std::string const& x)
147         {
148             write_utf8(base, x);
149             return *this;
150         }
151 
operator <<(quickbook::string_view x)152         ostream& ostream::operator<<(quickbook::string_view x)
153         {
154             write_utf8(base, x);
155             return *this;
156         }
157 
operator <<(int x)158         ostream& ostream::operator<<(int x)
159         {
160             base << x;
161             return *this;
162         }
163 
operator <<(unsigned int x)164         ostream& ostream::operator<<(unsigned int x)
165         {
166             base << x;
167             return *this;
168         }
169 
operator <<(long x)170         ostream& ostream::operator<<(long x)
171         {
172             base << x;
173             return *this;
174         }
175 
operator <<(unsigned long x)176         ostream& ostream::operator<<(unsigned long x)
177         {
178             base << x;
179             return *this;
180         }
181 
182 #if !defined(BOOST_NO_LONG_LONG)
operator <<(boost::long_long_type x)183         ostream& ostream::operator<<(boost::long_long_type x)
184         {
185             base << x;
186             return *this;
187         }
188 
operator <<(boost::ulong_long_type x)189         ostream& ostream::operator<<(boost::ulong_long_type x)
190         {
191             base << x;
192             return *this;
193         }
194 #endif
195 
operator <<(fs::path const & x)196         ostream& ostream::operator<<(fs::path const& x)
197         {
198             base << path_to_stream(x);
199             return *this;
200         }
201 
operator <<(base_ostream & (* x)(base_ostream &))202         ostream& ostream::operator<<(base_ostream& (*x)(base_ostream&))
203         {
204             base << x;
205             return *this;
206         }
207 
operator <<(base_ios & (* x)(base_ios &))208         ostream& ostream::operator<<(base_ios& (*x)(base_ios&))
209         {
210             base << x;
211             return *this;
212         }
213     }
214 }
215