]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/quickbook/src/native_text.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / tools / quickbook / src / native_text.cpp
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 <boost/program_options.hpp>
10 #include <iostream>
11 #include "native_text.hpp"
12 #include "utils.hpp"
13 #include "files.hpp"
14
15 #if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS
16 #include <boost/scoped_ptr.hpp>
17 #include <windows.h>
18 #include <io.h>
19 #include <fcntl.h>
20 #endif
21
22 #if QUICKBOOK_CYGWIN_PATHS
23 #include <boost/scoped_array.hpp>
24 #include <boost/program_options/errors.hpp>
25 #include <sys/cygwin.h>
26 #endif
27
28 namespace quickbook {
29 namespace detail {
30 namespace {
31 bool ms_errors = false;
32 }
33
34 void set_ms_errors(bool x) {
35 ms_errors = x;
36 }
37
38 // This is used for converting paths to UTF-8 on cygin.
39 // Might be better not to use a windows
40 #if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS
41 namespace {
42 std::string to_utf8(std::wstring const& x)
43 {
44 int buffer_count = WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, 0, 0, 0, 0);
45
46 if (!buffer_count)
47 throw conversion_error("Error converting wide string to utf-8.");
48
49 boost::scoped_ptr<char> buffer(new char[buffer_count]);
50
51 if (!WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count, 0, 0))
52 throw conversion_error("Error converting wide string to utf-8.");
53
54 return std::string(buffer.get());
55 }
56
57 std::wstring from_utf8(boost::string_ref text)
58 {
59 std::string x(text.begin(), text.end());
60 int buffer_count = MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, 0, 0);
61
62 if (!buffer_count)
63 throw conversion_error("Error converting utf-8 to wide string.");
64
65 boost::scoped_ptr<wchar_t> buffer(new wchar_t[buffer_count]);
66
67 if (!MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count))
68 throw conversion_error("Error converting utf-8 to wide string.");
69
70 return std::wstring(buffer.get());
71 }
72 }
73 #endif
74
75 #if QUICKBOOK_WIDE_PATHS
76 std::string command_line_to_utf8(command_line_string const& x)
77 {
78 return to_utf8(x);
79 }
80 #else
81 std::string command_line_to_utf8(command_line_string const& x)
82 {
83 return x;
84 }
85 #endif
86
87 #if QUICKBOOK_WIDE_PATHS
88 fs::path generic_to_path(boost::string_ref x)
89 {
90 return fs::path(from_utf8(x));
91 }
92
93 std::string path_to_generic(fs::path const& x)
94 {
95 return to_utf8(x.generic_wstring());
96 }
97 #else
98 fs::path generic_to_path(boost::string_ref x)
99 {
100 return fs::path(x.begin(), x.end());
101 }
102
103 std::string path_to_generic(fs::path const& x)
104 {
105 return x.generic_string();
106 }
107
108 #endif
109
110
111 #if QUICKBOOK_CYGWIN_PATHS
112 fs::path command_line_to_path(command_line_string const& path)
113 {
114 cygwin_conv_path_t flags = CCP_POSIX_TO_WIN_W | CCP_RELATIVE;
115
116 ssize_t size = cygwin_conv_path(flags, path.c_str(), NULL, 0);
117
118 if (size < 0)
119 throw conversion_error("Error converting cygwin path to windows.");
120
121 boost::scoped_array<char> result(new char[size]);
122 void* ptr = result.get();
123
124 if(cygwin_conv_path(flags, path.c_str(), ptr, size))
125 throw conversion_error("Error converting cygwin path to windows.");
126
127 return fs::path(static_cast<wchar_t*>(ptr));
128 }
129
130 ostream::string path_to_stream(fs::path const& path)
131 {
132 cygwin_conv_path_t flags = CCP_WIN_W_TO_POSIX | CCP_RELATIVE;
133
134 ssize_t size = cygwin_conv_path(flags, path.native().c_str(), NULL, 0);
135
136 if (size < 0)
137 throw conversion_error("Error converting windows path to cygwin.");
138
139 boost::scoped_array<char> result(new char[size]);
140
141 if(cygwin_conv_path(flags, path.native().c_str(), result.get(), size))
142 throw conversion_error("Error converting windows path to cygwin.");
143
144 return std::string(result.get());
145 }
146 #else
147 fs::path command_line_to_path(command_line_string const& path)
148 {
149 return fs::path(path);
150 }
151
152 #if QUICKBOOK_WIDE_PATHS && !QUICKBOOK_WIDE_STREAMS
153 ostream::string path_to_stream(fs::path const& path)
154 {
155 return path.string();
156 }
157 #else
158 ostream::string path_to_stream(fs::path const& path)
159 {
160 return path.native();
161 }
162 #endif
163
164 #endif // QUICKBOOK_CYGWIN_PATHS
165
166 #if QUICKBOOK_WIDE_STREAMS
167
168 void initialise_output()
169 {
170 if (_isatty(_fileno(stdout))) _setmode(_fileno(stdout), _O_U16TEXT);
171 if (_isatty(_fileno(stderr))) _setmode(_fileno(stderr), _O_U16TEXT);
172 }
173
174 void write_utf8(ostream::base_ostream& out, boost::string_ref x)
175 {
176 out << from_utf8(x);
177 }
178
179 ostream& out()
180 {
181 static ostream x(std::wcout);
182 return x;
183 }
184
185 namespace
186 {
187 inline ostream& error_stream()
188 {
189 static ostream x(std::wcerr);
190 return x;
191 }
192 }
193
194 #else
195
196 void initialise_output()
197 {
198 }
199
200 void write_utf8(ostream::base_ostream& out, boost::string_ref x)
201 {
202 out << x;
203 }
204
205 ostream& out()
206 {
207 static ostream x(std::cout);
208 return x;
209 }
210
211 namespace
212 {
213 inline ostream& error_stream()
214 {
215 static ostream x(std::clog);
216 return x;
217 }
218 }
219
220 #endif
221
222 ostream& outerr()
223 {
224 return error_stream() << "Error: ";
225 }
226
227 ostream& outerr(fs::path const& file, int line)
228 {
229 if (line >= 0)
230 {
231 if (ms_errors)
232 return error_stream() << path_to_stream(file) << "(" << line << "): error: ";
233 else
234 return error_stream() << path_to_stream(file) << ":" << line << ": error: ";
235 }
236 else
237 {
238 return error_stream() << path_to_stream(file) << ": error: ";
239 }
240 }
241
242 ostream& outerr(file_ptr const& f, string_iterator pos)
243 {
244 return outerr(f->path, f->position_of(pos).line);
245 }
246
247 ostream& outwarn(fs::path const& file, int line)
248 {
249 if (line >= 0)
250 {
251 if (ms_errors)
252 return error_stream() << path_to_stream(file) << "(" << line << "): warning: ";
253 else
254 return error_stream() << path_to_stream(file) << ":" << line << ": warning: ";
255 }
256 else
257 {
258 return error_stream() << path_to_stream(file) << ": warning: ";
259 }
260 }
261
262 ostream& outwarn(file_ptr const& f, string_iterator pos)
263 {
264 return outwarn(f->path, f->position_of(pos).line);
265 }
266
267 ostream& ostream::operator<<(char c) {
268 assert(c > 0 && c <= 127);
269 base << c;
270 return *this;
271 }
272
273 inline bool check_ascii(char const* x) {
274 for(;*x;++x) if(*x <= 0 || *x > 127) return false;
275 return true;
276 }
277
278 ostream& ostream::operator<<(char const* x) {
279 assert(check_ascii(x));
280 base << x;
281 return *this;
282 }
283
284 ostream& ostream::operator<<(std::string const& x) {
285 write_utf8(base, x);
286 return *this;
287 }
288
289 ostream& ostream::operator<<(boost::string_ref x) {
290 write_utf8(base, x);
291 return *this;
292 }
293
294 ostream& ostream::operator<<(int x) {
295 base << x;
296 return *this;
297 }
298
299 ostream& ostream::operator<<(unsigned int x) {
300 base << x;
301 return *this;
302 }
303
304 ostream& ostream::operator<<(long x) {
305 base << x;
306 return *this;
307 }
308
309 ostream& ostream::operator<<(unsigned long x) {
310 base << x;
311 return *this;
312 }
313
314 #if !defined(BOOST_NO_LONG_LONG)
315 ostream& ostream::operator<<(long long x) {
316 base << x;
317 return *this;
318 }
319
320 ostream& ostream::operator<<(unsigned long long x) {
321 base << x;
322 return *this;
323 }
324 #endif
325
326 ostream& ostream::operator<<(fs::path const& x) {
327 base << path_to_stream(x);
328 return *this;
329 }
330
331 ostream& ostream::operator<<(base_ostream& (*x)(base_ostream&)) {
332 base << x;
333 return *this;
334 }
335
336 ostream& ostream::operator<<(base_ios& (*x)(base_ios&)) {
337 base << x;
338 return *this;
339 }
340 }}