Merge lp:~zorba-coders/zorba/zorba-error_printer_in_api into lp:zorba
- zorba-error_printer_in_api
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Paul J. Lucas |
Approved revision: | 11148 |
Merged at revision: | 11222 |
Proposed branch: | lp:~zorba-coders/zorba/zorba-error_printer_in_api |
Merge into: | lp:zorba |
Diff against target: |
1148 lines (+475/-273) 14 files modified
ChangeLog (+2/-0) bin/CMakeLists.txt (+3/-5) bin/error_printer.cpp (+0/-132) bin/error_printer.h (+0/-40) bin/zorbacmd.cpp (+23/-12) doc/cxx/examples/errors.cpp (+31/-0) include/zorba/xquery_exception.h (+55/-1) include/zorba/xquery_stack_trace.h (+3/-3) include/zorba/zorba_exception.h (+50/-2) src/diagnostics/xquery_exception.cpp (+171/-30) src/diagnostics/zorba_exception.cpp (+86/-24) src/runtime/json/common.h (+2/-23) src/util/fs_util.h (+1/-1) src/util/omanip.h (+48/-0) |
To merge this branch: | bzr merge lp:~zorba-coders/zorba/zorba-error_printer_in_api |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Paul J. Lucas | Approve | ||
Matthias Brantner | Approve | ||
William Candillon | Approve | ||
Review via email: mp+134405@code.launchpad.net |
Commit message
Moving the error printer from zorbacmd into the api.
Description of the change
Moving the error printer from zorbacmd into the api.
David Graf (davidagraf) wrote : | # |
William Candillon (wcandillon) : | # |
Matthias Brantner (matthias-brantner) wrote : | # |
I approve but I want to make sure the same or similar functionality (maybe without XML printing) is not already available in the API. Hence, I added Paul.
Paul J. Lucas (paul-lucas) wrote : | # |
It's a stupid API. There's no reason to have a class with a single static member function. If you're going to make it public, it needs to be better. Two things come to mind:
1. (Trivial) Simply make it a global function -- no need for a class.
2. (Less trivial) Create a (real) ErrorPrinter class that holds the configuration parameters; then using operator<<, you can write an XQueryException to it.
3. Regardless, the indentation parameter should be an unsigned int (not a bool): it will specify a multiplier for the amount of indentation (where 0 = none).
BTW: It should take a ZorbaException, not an XQueryException.
David Graf (davidagraf) wrote : | # |
Cool, now I can fix what someone else did wrong :-(.
Anyway, Paul, can you help me on one thing please? Can you tell me how I can use this ErrorPrinter for warnings too?
> It's a stupid API. There's no reason to have a class with a single static
> member function. If you're going to make it public, it needs to be better.
> Two things come to mind:
>
> 1. (Trivial) Simply make it a global function -- no need for a class.
>
> 2. (Less trivial) Create a (real) ErrorPrinter class that holds the
> configuration parameters; then using operator<<, you can write an
> XQueryException to it.
>
> 3. Regardless, the indentation parameter should be an unsigned int (not a
> bool): it will specify a multiplier for the amount of indentation (where 0 =
> none).
>
> BTW: It should take a ZorbaException, not an XQueryException.
Paul J. Lucas (paul-lucas) wrote : | # |
> Anyway, Paul, can you help me on one thing please? Can you tell me how I can
> use this ErrorPrinter for warnings too?
An XQueryWarning is just a typedef for XQueryException, so it should just work as-is.
That aside: generally, I don't like to decide for the user how errors should be printed. By putting an error-printer in the public API, you're essentially making that decision for them. If you're going to do that, you could just define operator<
If you want to set parameters (like XML or indentation), then the nice way to do it is via stream manipulators, e.g.:
// ...
}
catch ( XQueryException const &e ) {
cout << XQueryException
}
You can look at src/util/indent.h for how to do this kind of thing. The above manipulators, however, should be "one-shot" and auto-reset (which is trivial to do).
Paul J. Lucas (paul-lucas) wrote : | # |
I just checked: ZorbaException already has a global operator<
So why do you need to do anything at all?
David Graf (davidagraf) wrote : | # |
> I just checked: ZorbaException already has a global
> operator<
>
> So why do you need to do anything at all?
Hi Paul, sorry for not following up for a long time. We just need it to get the errors in xml format. I guess this is not supported in operator<
Paul J. Lucas (paul-lucas) wrote : | # |
I've done a lot of clean-up. You have the basic implementation correct. I've moved several functions inline. I've moved the printing of the stack trace constants to XQueryException since only XQueryException has stack traces. I've added doxygen comments that you didn't.
Why don't you include the "raised at" in the XML format?
Why don't you include the "applied at" in the XML format? (Not knowing what it is is not an acceptable reason.)
Why does ErrorPrinter need to exist at all? It seems redundant.
Paul J. Lucas (paul-lucas) wrote : | # |
The error code was printed in XML as:
<code>
I think it's better to print it as:
<code>http://
(as suggested in <http://
But is it better still to print it as:
<code ns="http://
?
Matthias Brantner (matthias-brantner) wrote : | # |
> The error code was printed in XML as:
>
> <code>err:
>
> I think it's better to print it as:
>
> <code>http://
>
> (as suggested in <http://
> But is it better still to print it as:
>
> <code ns="http://
> localname=
>
> ?
It would make sense to me but the problem is that the change is not backwards compatible. I know that 28msec relies on it.
on the current way the error is reported.
Paul J. Lucas (paul-lucas) wrote : | # |
> It would make sense to me but the problem is that the change is not backwards compatible.
> I know that 28msec relies on it.
> on the current way the error is reported.
There were other mistakes that whoever coded the original XML made. For example, not including a xmlns="..." attribute on the <exception> element; omitting the <raised-at ...> information; using localized strings for the <code> value (this is one case where the string should NOT be localized).
Will those changes break 28msec as well?
Can't we just update the 28msec code?
Paul J. Lucas (paul-lucas) wrote : | # |
Actually, in the short term, I'd like to revert the way the error code is printed to:
<code>
and merge the branch into the trunk immediately because this branch actually makes testing the branch for bug 1111786 much easier. I'll file a separate bug to change the form to:
<code namespace="http://
for 3.0.
OK?
Paul J. Lucas (paul-lucas) wrote : | # |
Also, does the 28msec code rely on the <kind> being like:
<kind>static error</kind>
or will:
<kind>
still work?
Paul J. Lucas (paul-lucas) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/zorba-error_printer_in_api into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job zorba-error_
finished. The final status was:
2 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
- 11148. By Paul J. Lucas
-
Fully reverted to old format.
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job zorba-error_
All tests succeeded!
Preview Diff
1 | === modified file 'ChangeLog' |
2 | --- ChangeLog 2013-01-31 19:52:13 +0000 |
3 | +++ ChangeLog 2013-02-07 01:30:37 +0000 |
4 | @@ -5,6 +5,7 @@ |
5 | New Features: |
6 | * Typeswitch expression extended to allow union of types in each case clause, |
7 | as specified by XQuery v3.0 |
8 | + * In C++ API, added optional XML formatting of exceptions. |
9 | * Extended sequence types to include unions, as specified by XQuery v3.0 |
10 | * Added millis-to-dateTime() function in datetime module. |
11 | |
12 | @@ -184,6 +185,7 @@ |
13 | http://www.zorba-xquery.com/modules/store/data-structures/unordered-map module. |
14 | * Added support for fragments to fn:path |
15 | * Positional pagination support for collections |
16 | + * Pagination by reference support for collections |
17 | * http://www.zorba-xquery.com/modules/archive module for creating, |
18 | reading, and updating various (compressed) archives (e.g. zip, tar.gz, |
19 | or tar.bz2) |
20 | |
21 | === modified file 'bin/CMakeLists.txt' |
22 | --- bin/CMakeLists.txt 2013-01-21 09:00:53 +0000 |
23 | +++ bin/CMakeLists.txt 2013-02-07 01:30:37 +0000 |
24 | @@ -46,14 +46,12 @@ |
25 | SET(SRCS |
26 | zorbacmd.cpp |
27 | zorbacmdproperties.cpp |
28 | - error_printer.cpp |
29 | util.cpp |
30 | path_util.cpp |
31 | ) |
32 | |
33 | ZORBA_GENERATE_EXE("zorbacmd" "${SRCS}" "" "zorba" "bin") |
34 | |
35 | - |
36 | IF(UNIX) |
37 | ADD_CUSTOM_TARGET(zorbacmd_man help2man -N -s1 -n Zorba -S "FLWOR Foundation" ./zorba > "${PROJECT_BINARY_DIR}/doc/zorba.1") |
38 | ADD_DEPENDENCIES(zorbacmd_man zorbacmd) |
39 | @@ -80,12 +78,12 @@ |
40 | ZORBA_SET_TEST_PROPERTY(bin/zorba_compilechk1 PASS_REGULAR_EXPRESSION ".*mymod.xq>:22,8:.*:XPST0008.*") |
41 | |
42 | ZORBA_ADD_TEST(bin/zorba_compilechk2 zorbacmd -q "${CMAKE_CURRENT_SOURCE_DIR}/test/mymod.xq" -f -l -x) |
43 | -ZORBA_SET_TEST_PROPERTY(bin/zorba_compilechk2 PASS_REGULAR_EXPRESSION ".*XPST0008.*mymod.xq' lineStart='22' columnStart='8' lineEnd='22' columnEnd='10'.*") |
44 | +ZORBA_SET_TEST_PROPERTY(bin/zorba_compilechk2 PASS_REGULAR_EXPRESSION ".*XPST0008.*mymod.xq.*lineStart=['\"]22['\"] columnStart=['\"]8['\"] lineEnd=['\"]22['\"] columnEnd=['\"]10['\"].*") |
45 | |
46 | # test compile checking to work with library modules that have an invalid target namespace uri |
47 | # test for bug #2934414 |
48 | ZORBA_ADD_TEST(bin/zorba_compilechk3 zorbacmd -q "${CMAKE_CURRENT_SOURCE_DIR}/test/mymod2.xq" -f -l -x) |
49 | -ZORBA_SET_TEST_PROPERTY(bin/zorba_compilechk3 PASS_REGULAR_EXPRESSION ".*XQST0046.*mymod2.xq' lineStart='17' columnStart='1' lineEnd='17' columnEnd='26'.*") |
50 | +ZORBA_SET_TEST_PROPERTY(bin/zorba_compilechk3 PASS_REGULAR_EXPRESSION ".*XQST0046.*mymod2.xq.*lineStart=['\"]17['\"] columnStart=['\"]1['\"] lineEnd=['\"]17['\"] columnEnd=['\"]26['\"].*") |
51 | |
52 | # test the --option option to set an option in the static context |
53 | ZORBA_ADD_TEST(bin/zorba_option zorbacmd -q "${CMAKE_CURRENT_SOURCE_DIR}/test/option.xq" -f --option "{http://www.zorba-xquery.com}option=value") |
54 | @@ -138,4 +136,4 @@ |
55 | ZORBA_ADD_TEST(bin/zorba_compilechk4 zorbacmd |
56 | -q "${CMAKE_CURRENT_SOURCE_DIR}/../test/zperf/src/start.xq" -f --compile-only) |
57 | ZORBA_SET_TEST_PROPERTY(bin/zorba_compilechk4 |
58 | - PASS_REGULAR_EXPRESSION "[]|[XQST0059]") |
59 | \ No newline at end of file |
60 | + PASS_REGULAR_EXPRESSION "[]|[XQST0059]") |
61 | |
62 | === removed file 'bin/error_printer.cpp' |
63 | --- bin/error_printer.cpp 2012-09-19 21:16:15 +0000 |
64 | +++ bin/error_printer.cpp 1970-01-01 00:00:00 +0000 |
65 | @@ -1,132 +0,0 @@ |
66 | -/* |
67 | - * Copyright 2006-2008 The FLWOR Foundation. |
68 | - * |
69 | - * Licensed under the Apache License, Version 2.0 (the "License"); |
70 | - * you may not use this file except in compliance with the License. |
71 | - * You may obtain a copy of the License at |
72 | - * |
73 | - * http://www.apache.org/licenses/LICENSE-2.0 |
74 | - * |
75 | - * Unless required by applicable law or agreed to in writing, software |
76 | - * distributed under the License is distributed on an "AS IS" BASIS, |
77 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
78 | - * See the License for the specific language governing permissions and |
79 | - * limitations under the License. |
80 | - */ |
81 | - |
82 | -#include <ostream> |
83 | -#include <sstream> |
84 | - |
85 | -#include <zorba/xquery_exception.h> |
86 | -#include <zorba/xquery_functions.h> |
87 | -#include <zorba/xquery_stack_trace.h> |
88 | -#include <zorba/zorba_string.h> |
89 | - |
90 | -#include "zorba/util/uri.h" |
91 | -#include "error_printer.h" |
92 | - |
93 | -namespace zorba { |
94 | - |
95 | - std::ostream& |
96 | - print_stack_trace( |
97 | - const XQueryException& aException, |
98 | - std::ostream& aOut, |
99 | - bool aAsXml, |
100 | - bool aIndent) |
101 | - { |
102 | - XQueryStackTrace const& lTrace = aException.query_trace(); |
103 | - if (!lTrace.empty()) { |
104 | - XQueryStackTrace::const_iterator it = lTrace.begin(); |
105 | - if (aAsXml) { |
106 | - if (aIndent) aOut << " "; |
107 | - aOut << "<stack>"; |
108 | - } |
109 | - for (; it != lTrace.end(); ++it) { |
110 | - XQueryStackTrace::fn_name_type const& lName = it->getFnName(); |
111 | - XQueryStackTrace::fn_arity_type lArity = it->getFnArity(); |
112 | - char const *const lPrefix = lName.prefix(); |
113 | - String lFileName = it->getFileName(); |
114 | - if (fn::starts_with(lFileName,"file:")) { |
115 | - lFileName = URIHelper::decodeFileURI(lFileName); |
116 | - while (fn::starts_with(lFileName,"//")) { |
117 | - lFileName = lFileName.substr(1); |
118 | - } |
119 | - } |
120 | - if (aAsXml) { |
121 | - if (aIndent) aOut << std::endl << " "; |
122 | - aOut << "<call "; |
123 | - if (lPrefix && *lPrefix) { |
124 | - aOut << "prefix=\"" << lPrefix << "\" "; |
125 | - } |
126 | - aOut << "arity=\"" << lArity << "\" "; |
127 | - aOut << "ns=\"" << lName.ns() << "\" "; |
128 | - aOut << "localName=\"" << lName.localname() << "\">"; |
129 | - if (aIndent) aOut << std::endl << " "; |
130 | - aOut << "<location "; |
131 | - aOut << "fileName=\"" << lFileName << "\" "; |
132 | - aOut << "lineStart=\"" << it->getLine() << "\" " |
133 | - << "columnStart=\"" << it->getColumn() << "\" "; |
134 | - if (it->getLineEnd()) |
135 | - aOut << "lineEnd=\"" << it->getLineEnd() << "\" "; |
136 | - if (it->getColumnEnd()) |
137 | - aOut << "lineEnd=\"" << it->getColumnEnd() << "\" "; |
138 | - aOut << "/>"; |
139 | - if (aIndent) aOut << std::endl << " "; |
140 | - aOut << "</call>"; |
141 | - } else { |
142 | - std::ostringstream oss; |
143 | - oss << lName; |
144 | - String lFName = oss.str(); |
145 | - aOut << "=================================================" << std::endl; |
146 | - aOut << lFName << "#" << lArity << " <" << lName.ns() << "> " << std::endl; |
147 | - aOut << lFileName << " at line " << it->getLine() << " column " << it->getColumn() << std::endl; |
148 | - } |
149 | - } |
150 | - if (aAsXml) { |
151 | - if (aIndent) aOut << std::endl << " "; |
152 | - aOut << "</stack>"; |
153 | - } |
154 | - } |
155 | - return aOut; |
156 | - } |
157 | - |
158 | - std::ostream& |
159 | - ErrorPrinter::print( |
160 | - const XQueryException& aException, |
161 | - std::ostream& aOut, |
162 | - bool aAsXml, |
163 | - bool aIndent) |
164 | - { |
165 | - if (!aAsXml) { |
166 | - aOut << aException << " "; |
167 | - aOut << std::endl; |
168 | - print_stack_trace(aException, aOut, aAsXml, aIndent); |
169 | - } else { |
170 | - aOut << "<errors>"; |
171 | - if (aIndent) aOut << std::endl << " "; |
172 | - //code |
173 | - aOut << "<error code='" << aException.diagnostic().qname() << "'>"; |
174 | - if (aIndent) aOut << std::endl << " "; |
175 | - //location |
176 | - aOut << "<location module='" << aException.source_uri(); |
177 | - aOut << "' lineStart='" << aException.source_line(); |
178 | - aOut << "' columnStart='" << aException.source_column() << "'"; |
179 | - if (aException.source_line_end()) |
180 | - aOut << " lineEnd='" << aException.source_line_end() << "'"; |
181 | - if (aException.source_column_end()) |
182 | - aOut << " columnEnd='" << aException.source_column_end() << "'"; |
183 | - aOut << "/>"; |
184 | - if (aIndent) aOut << std::endl << " "; |
185 | - //description |
186 | - aOut << "<description>" << aException.what() << "</description>"; |
187 | - if( aIndent ) aOut << std::endl << " "; |
188 | - print_stack_trace(aException, aOut, aAsXml, aIndent); |
189 | - if (aIndent) aOut << std::endl << " "; |
190 | - aOut << "</error>"; |
191 | - if (aIndent) aOut << std::endl; |
192 | - aOut << "</errors>"; |
193 | - } |
194 | - return aOut; |
195 | - } |
196 | - |
197 | -} // namespace zorba |
198 | |
199 | === removed file 'bin/error_printer.h' |
200 | --- bin/error_printer.h 2012-09-19 21:16:15 +0000 |
201 | +++ bin/error_printer.h 1970-01-01 00:00:00 +0000 |
202 | @@ -1,40 +0,0 @@ |
203 | -/* |
204 | - * Copyright 2006-2008 The FLWOR Foundation. |
205 | - * |
206 | - * Licensed under the Apache License, Version 2.0 (the "License"); |
207 | - * you may not use this file except in compliance with the License. |
208 | - * You may obtain a copy of the License at |
209 | - * |
210 | - * http://www.apache.org/licenses/LICENSE-2.0 |
211 | - * |
212 | - * Unless required by applicable law or agreed to in writing, software |
213 | - * distributed under the License is distributed on an "AS IS" BASIS, |
214 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
215 | - * See the License for the specific language governing permissions and |
216 | - * limitations under the License. |
217 | - */ |
218 | -#ifndef ZORBA_ERROR_PRINTER_H |
219 | -#define ZORBA_ERROR_PRINTER_H |
220 | - |
221 | -#include <ostream> |
222 | - |
223 | -namespace zorba { |
224 | - |
225 | -class XQueryException; |
226 | - |
227 | -class ErrorPrinter { |
228 | - |
229 | - public: |
230 | - |
231 | - static std::ostream& |
232 | - print( |
233 | - const XQueryException& lException, |
234 | - std::ostream& lOut, |
235 | - bool aAsXml, |
236 | - bool aIndent); |
237 | - |
238 | -}; /* class ErrorPrinter */ |
239 | - |
240 | -} /* namespace zorba */ |
241 | - |
242 | -#endif //ZORBA_ERROR_PRINTER_H |
243 | |
244 | === modified file 'bin/zorbacmd.cpp' |
245 | --- bin/zorbacmd.cpp 2013-01-24 02:27:45 +0000 |
246 | +++ bin/zorbacmd.cpp 2013-02-07 01:30:37 +0000 |
247 | @@ -51,7 +51,6 @@ |
248 | #include <zorba/audit_scoped.h> |
249 | #endif |
250 | |
251 | -#include "error_printer.h" |
252 | #include "util.h" |
253 | #include "path_util.h" |
254 | |
255 | @@ -103,6 +102,23 @@ |
256 | |
257 | URIMapperSerializationCallback theSerializationCallback; |
258 | |
259 | +/******************************************************************************* |
260 | + |
261 | +********************************************************************************/ |
262 | +static void print_exception( ZorbaException const &e, |
263 | + ZorbaCMDProperties const &props ) { |
264 | + using namespace std; |
265 | + |
266 | + if ( props.printErrorsAsXml() ) |
267 | + if ( props.indent() ) |
268 | + cerr << ZorbaException::format_xml_indented; |
269 | + else |
270 | + cerr << ZorbaException::format_xml; |
271 | + else |
272 | + cerr << ZorbaException::format_text; |
273 | + |
274 | + cerr << e << endl; |
275 | +} |
276 | |
277 | /******************************************************************************* |
278 | |
279 | @@ -779,7 +795,7 @@ |
280 | } |
281 | catch (zorba::XQueryException const& qe) |
282 | { |
283 | - ErrorPrinter::print(qe, std::cerr, properties.printErrorsAsXml(), lIndent); |
284 | + print_exception( qe, properties ); |
285 | return 11; |
286 | } |
287 | catch (zorba::ZorbaException const& ze) |
288 | @@ -830,7 +846,7 @@ |
289 | } |
290 | catch (zorba::XQueryException const& qe) |
291 | { |
292 | - ErrorPrinter::print(qe, std::cerr, properties.printErrorsAsXml(), lIndent); |
293 | + print_exception( qe, properties ); |
294 | return 22; |
295 | } |
296 | catch (zorba::ZorbaException const& ze) |
297 | @@ -872,7 +888,7 @@ |
298 | } |
299 | catch (zorba::XQueryException const& qe) |
300 | { |
301 | - ErrorPrinter::print(qe, std::cerr, properties.printErrorsAsXml(), lIndent); |
302 | + print_exception( qe, properties ); |
303 | return 31; |
304 | } |
305 | catch (zorba::ZorbaException const& ze) |
306 | @@ -1169,10 +1185,7 @@ |
307 | } |
308 | catch (zorba::XQueryException const& qe) |
309 | { |
310 | - ErrorPrinter::print(qe, |
311 | - std::cerr, |
312 | - properties.printErrorsAsXml(), |
313 | - properties.indent()); |
314 | + print_exception( qe, properties ); |
315 | return 6; |
316 | } |
317 | } |
318 | @@ -1258,10 +1271,7 @@ |
319 | } |
320 | catch (zorba::XQueryException const& qe) |
321 | { |
322 | - ErrorPrinter::print(qe, |
323 | - std::cerr, |
324 | - properties.printErrorsAsXml(), |
325 | - properties.indent()); |
326 | + print_exception( qe, properties ); |
327 | return 5; |
328 | } |
329 | catch (zorba::ZorbaException const& ze) |
330 | @@ -1303,3 +1313,4 @@ |
331 | } |
332 | return 0; |
333 | } |
334 | +/* vim:set et sw=2 ts=2: */ |
335 | |
336 | === modified file 'doc/cxx/examples/errors.cpp' |
337 | --- doc/cxx/examples/errors.cpp 2012-09-19 21:16:15 +0000 |
338 | +++ doc/cxx/examples/errors.cpp 2013-02-07 01:30:37 +0000 |
339 | @@ -157,6 +157,32 @@ |
340 | return false; |
341 | } |
342 | |
343 | +bool |
344 | +error_example_7(Zorba* aZorba) |
345 | +{ |
346 | + try { |
347 | + std::ostringstream s; |
348 | + s << "declare function local:test() { fn:error() };" << std::endl |
349 | + << "local:test()" << std::endl; |
350 | + XQuery_t lQuery = aZorba->compileQuery(s.str()); |
351 | + |
352 | + std::cout << lQuery << std::endl; |
353 | + } catch (ZorbaException const& ze) { |
354 | + std::cerr << "=== Error XML + Stacktrace ===" << std::endl; |
355 | + std::cerr << XQueryException::trace |
356 | + << ZorbaException::format_xml |
357 | + << ze |
358 | + << std::endl; |
359 | + std::cerr << "=== Error Text + Stacktrace ===" << std::endl; |
360 | + std::cerr << XQueryException::trace |
361 | + << ZorbaException::format_text |
362 | + << ze |
363 | + << std::endl; |
364 | + return true; |
365 | + } |
366 | + return false; |
367 | +} |
368 | + |
369 | int |
370 | errors(int argc, char* argv[]) |
371 | { |
372 | @@ -194,6 +220,11 @@ |
373 | if (!res) return 1; |
374 | std::cout << std::endl; |
375 | |
376 | + std::cout << "executing example 7" << std::endl; |
377 | + res = error_example_7(lZorba); |
378 | + if (!res) return 1; |
379 | + std::cout << std::endl; |
380 | + |
381 | lZorba->shutdown(); |
382 | zorba::StoreManager::shutdownStore(lStore); |
383 | return 0; |
384 | |
385 | === modified file 'include/zorba/xquery_exception.h' |
386 | --- include/zorba/xquery_exception.h 2012-12-01 00:06:15 +0000 |
387 | +++ include/zorba/xquery_exception.h 2013-02-07 01:30:37 +0000 |
388 | @@ -39,6 +39,15 @@ |
389 | typedef internal::diagnostic::location::column_type column_type; |
390 | |
391 | /** |
392 | + * Whether to include the XQuery stack trace for the XQueryException that's |
393 | + * printed to an ostream. |
394 | + */ |
395 | + enum print_trace { |
396 | + trace, |
397 | + no_trace |
398 | + }; |
399 | + |
400 | + /** |
401 | * Copy-constructs an %XQueryException. |
402 | * |
403 | * @param from The %XQueryException to copy from. |
404 | @@ -208,6 +217,17 @@ |
405 | ////////// XQuery stack trace /////////////////////////////////////////////// |
406 | |
407 | /** |
408 | + * Gets whether XQuery stack traces will be included when XQueryExceptions |
409 | + * are printed to the given ostream. |
410 | + * |
411 | + * @param o The ostream. |
412 | + * @return Returns \a true only if stack traces will be included. |
413 | + */ |
414 | + static bool get_print_trace( std::ostream &o ) { |
415 | + return static_cast<print_trace>( o.iword( get_ios_trace_index() ) ); |
416 | + } |
417 | + |
418 | + /** |
419 | * Gets the XQuery stack trace, if any. |
420 | * |
421 | * @return Returns said stack trace. |
422 | @@ -225,13 +245,29 @@ |
423 | return query_trace_; |
424 | } |
425 | |
426 | + /** |
427 | + * Sets whether XQuery stack traces will be included when XQueryExceptions |
428 | + * are printed to the given ostream. |
429 | + * |
430 | + * @param o The ostream to affect. |
431 | + * @param print If \a true, stack traces will be included. |
432 | + */ |
433 | + static void set_print_trace( std::ostream &o, bool print ) { |
434 | + o.iword( get_ios_trace_index() ) = print; |
435 | + } |
436 | + |
437 | + ///////////////////////////////////////////////////////////////////////////// |
438 | + |
439 | // inherited |
440 | void polymorphic_throw() const; |
441 | |
442 | protected: |
443 | + std::ostream& print_stack_trace( std::ostream& ) const; |
444 | + static bool print_uri( std::ostream&, char const *uri ); |
445 | + |
446 | // inherited |
447 | std::unique_ptr<ZorbaException> clone() const; |
448 | - std::ostream& print( std::ostream &o ) const; |
449 | + std::ostream& print_impl( std::ostream& ) const; |
450 | |
451 | private: |
452 | typedef internal::diagnostic::location location; |
453 | @@ -254,6 +290,8 @@ |
454 | location applied_loc_; |
455 | XQueryStackTrace query_trace_; |
456 | |
457 | + static int get_ios_trace_index(); |
458 | + |
459 | friend XQueryException make_xquery_exception( |
460 | char const*, ZorbaException::line_type, Diagnostic const&, |
461 | parameters const&, location const& |
462 | @@ -281,6 +319,22 @@ |
463 | |
464 | /////////////////////////////////////////////////////////////////////////////// |
465 | |
466 | +/** |
467 | + * Sets whether to include the XQuery stack trace for the next XQueryException |
468 | + * that's printed. |
469 | + * |
470 | + * @param o The ostream to affect. |
471 | + * @param t The print_trace value. |
472 | + * @return Returns \a o. |
473 | + */ |
474 | +inline std::ostream& operator<<( std::ostream &o, |
475 | + XQueryException::print_trace t ) { |
476 | + XQueryException::set_print_trace( o, t ); |
477 | + return o; |
478 | +} |
479 | + |
480 | +/////////////////////////////////////////////////////////////////////////////// |
481 | + |
482 | } // namespace zorba |
483 | #endif /* ZORBA_XQUERY_EXCEPTION_API_H */ |
484 | /* vim:set et sw=2 ts=2: */ |
485 | |
486 | === modified file 'include/zorba/xquery_stack_trace.h' |
487 | --- include/zorba/xquery_stack_trace.h 2012-09-19 21:16:15 +0000 |
488 | +++ include/zorba/xquery_stack_trace.h 2013-02-07 01:30:37 +0000 |
489 | @@ -44,13 +44,13 @@ |
490 | public: |
491 | Entry( fn_name_type const &fn_name, fn_arity_type fn_arity, |
492 | char const *file_name, line_type line, column_type column, |
493 | - line_type line_end, column_type column_end); |
494 | + line_type line_end, column_type column_end ); |
495 | |
496 | fn_name_type const& getFnName() const { |
497 | return fn_name_; |
498 | } |
499 | |
500 | - fn_arity_type const& getFnArity() const { |
501 | + fn_arity_type getFnArity() const { |
502 | return fn_arity_; |
503 | } |
504 | |
505 | @@ -74,7 +74,7 @@ |
506 | return col_end_; |
507 | } |
508 | |
509 | - fn_name_type& getFnNameRef() { |
510 | + fn_name_type& getFnNameRef() { |
511 | return fn_name_; |
512 | } |
513 | |
514 | |
515 | === modified file 'include/zorba/zorba_exception.h' |
516 | --- include/zorba/zorba_exception.h 2012-09-19 21:16:15 +0000 |
517 | +++ include/zorba/zorba_exception.h 2013-02-07 01:30:37 +0000 |
518 | @@ -44,6 +44,15 @@ |
519 | typedef internal::diagnostic::location::line_type line_type; |
520 | |
521 | /** |
522 | + * The format to print exceptions as to an ostream. |
523 | + */ |
524 | + enum print_format { |
525 | + format_text = 0, ///< plain text |
526 | + format_xml = 1, ///< XML without unnecessary whitespace |
527 | + format_xml_indented = 3 ///< XML with newlines and indentation |
528 | + }; |
529 | + |
530 | + /** |
531 | * Copy-constructs a %ZorbaException. |
532 | * |
533 | * @param from The %ZorbaException to copy from. |
534 | @@ -73,6 +82,16 @@ |
535 | } |
536 | |
537 | /** |
538 | + * Gets the current print_format associated with the given ostream. |
539 | + * |
540 | + * @param o The ostream to get the print_format of. |
541 | + * @return Returns said print_format. |
542 | + */ |
543 | + static print_format get_print_format( std::ostream &o ) { |
544 | + return static_cast<print_format>( o.iword( get_ios_format_index() ) ); |
545 | + } |
546 | + |
547 | + /** |
548 | * Throws itself polymorphically; see |
549 | * http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.16 |
550 | */ |
551 | @@ -105,6 +124,16 @@ |
552 | return raise_line_; |
553 | } |
554 | |
555 | + /** |
556 | + * Sets the print_format of the given ostream. |
557 | + * |
558 | + * @param o The ostream to set the print_format of. |
559 | + * @param f The print_format value. |
560 | + */ |
561 | + static void set_print_format( std::ostream &o, print_format f ) { |
562 | + o.iword( get_ios_format_index() ) = static_cast<long>( f ); |
563 | + } |
564 | + |
565 | // inherited |
566 | char const* what() const throw(); |
567 | |
568 | @@ -135,9 +164,9 @@ |
569 | * @param o The ostream to print to. |
570 | * @return Returns \a o. |
571 | */ |
572 | - virtual std::ostream& print( std::ostream &o ) const; |
573 | + std::ostream& print( std::ostream& ) const; |
574 | |
575 | - friend std::ostream& operator<<( std::ostream&, ZorbaException const& ); |
576 | + virtual std::ostream& print_impl( std::ostream &o ) const; |
577 | |
578 | private: |
579 | Diagnostic const *diagnostic_; |
580 | @@ -145,6 +174,8 @@ |
581 | line_type raise_line_; |
582 | std::string message_; |
583 | |
584 | + static int get_ios_format_index(); |
585 | + |
586 | friend std::unique_ptr<ZorbaException> clone( ZorbaException const& ); |
587 | |
588 | friend ZorbaException make_zorba_exception( |
589 | @@ -157,6 +188,8 @@ |
590 | internal::diagnostic::parameters const& |
591 | ); |
592 | |
593 | + friend std::ostream& operator<<( std::ostream&, ZorbaException const& ); |
594 | + |
595 | protected: |
596 | // for plan serialization |
597 | ZorbaException( serialization::Archiver& ); |
598 | @@ -164,6 +197,8 @@ |
599 | ZorbaException*& ); |
600 | }; |
601 | |
602 | +/////////////////////////////////////////////////////////////////////////////// |
603 | + |
604 | /** |
605 | * Emits the given ZorbaException to the given ostream. |
606 | * |
607 | @@ -175,6 +210,19 @@ |
608 | return e.print( o ); |
609 | } |
610 | |
611 | +/** |
612 | + * Sets the format for the next ZorbaException that's printed. |
613 | + * |
614 | + * @param o The ostream to affect. |
615 | + * @param f The print_format to use. |
616 | + * @return Returns \a o. |
617 | + */ |
618 | +inline std::ostream& operator<<( std::ostream &o, |
619 | + ZorbaException::print_format f ) { |
620 | + ZorbaException::set_print_format( o, f ); |
621 | + return o; |
622 | +} |
623 | + |
624 | /////////////////////////////////////////////////////////////////////////////// |
625 | |
626 | } // namespace zorba |
627 | |
628 | === modified file 'src/diagnostics/xquery_exception.cpp' |
629 | --- src/diagnostics/xquery_exception.cpp 2012-12-02 17:24:18 +0000 |
630 | +++ src/diagnostics/xquery_exception.cpp 2013-02-07 01:30:37 +0000 |
631 | @@ -19,14 +19,29 @@ |
632 | // standard |
633 | #include <cstring> |
634 | |
635 | +// API |
636 | +#include <zorba/xquery_stack_trace.h> |
637 | +#include <zorba/util/uri.h> |
638 | +#include <zorba/xquery_functions.h> |
639 | + |
640 | // Zorba |
641 | +#include "util/ascii_util.h" |
642 | #include "util/fs_util.h" |
643 | +#include "util/indent.h" |
644 | +#include "util/omanip.h" |
645 | #include "util/uri_util.h" |
646 | +#include "zorbatypes/URI.h" |
647 | |
648 | // local |
649 | #include "dict.h" |
650 | #include "xquery_exception.h" |
651 | |
652 | +#define if_inc_indent if_do( do_indent, inc_indent ) |
653 | +#define if_dec_indent if_do( do_indent, dec_indent ) |
654 | + |
655 | +#undef if_nl |
656 | +#define if_nl if_emit( do_indent, '\n' ) |
657 | + |
658 | using namespace std; |
659 | |
660 | namespace zorba { |
661 | @@ -77,6 +92,11 @@ |
662 | return unique_ptr<ZorbaException>( new XQueryException( *this ) ); |
663 | } |
664 | |
665 | +int XQueryException::get_ios_trace_index() { |
666 | + static int const index = ios_base::xalloc(); |
667 | + return index; |
668 | +} |
669 | + |
670 | void XQueryException::set_applied( char const *uri, |
671 | line_type line, |
672 | column_type col, |
673 | @@ -99,13 +119,159 @@ |
674 | throw *this; |
675 | } |
676 | |
677 | -static bool print_uri( ostream &o, char const *uri ) { |
678 | +ostream& XQueryException::print_impl( ostream &o ) const { |
679 | + print_format const format = get_print_format( o ); |
680 | + bool const as_xml = format != format_text; |
681 | + bool const do_indent = format == format_xml_indented; |
682 | + |
683 | + if ( as_xml ) { |
684 | + ZorbaException::print_impl( o ); |
685 | + if ( has_source() ) { |
686 | + o << indent << "<location"; |
687 | + print_uri( o, source_uri() ); |
688 | +#if 0 |
689 | + o << " line-begin=\"" << source_line() << '"'; |
690 | + if ( source_line_end() ) |
691 | + o << " line-end=\"" << source_line_end() << '"'; |
692 | + if ( source_column() ) |
693 | + o << " column-begin=\"" << source_column() << '"'; |
694 | + if ( source_column_end() ) |
695 | + o << " column-end=\"" << source_column_end() << '"'; |
696 | +#else |
697 | + o << " lineStart=\"" << source_line() << '"'; |
698 | + if ( source_column() ) |
699 | + o << " columnStart=\"" << source_column() << '"'; |
700 | + if ( source_line_end() ) |
701 | + o << " lineEnd=\"" << source_line_end() << '"'; |
702 | + if ( source_column_end() ) |
703 | + o << " columnEnd=\"" << source_column_end() << '"'; |
704 | +#endif |
705 | + o << "/>" << if_nl; // <location ... |
706 | + |
707 | + if ( has_applied() ) { |
708 | + o << indent << "<applied-at"; |
709 | + if ( applied_uri() && ::strcmp( applied_uri(), source_uri() ) != 0 ) |
710 | + print_uri( o, applied_uri() ); |
711 | + o << " line=\"" << applied_line() << '"'; |
712 | + if ( applied_column() ) |
713 | + o << " column=\"" << applied_column() << '"'; |
714 | + o << "/>" << if_nl; // <applied-at ... |
715 | + } |
716 | + |
717 | + if ( get_print_trace( o ) ) |
718 | + print_stack_trace( o ); |
719 | + } |
720 | + return o; |
721 | + } else { |
722 | + if ( has_source() ) { |
723 | + if ( !print_uri( o, source_uri() ) ) |
724 | + o << "(" << diagnostic::dict::lookup( ZED( NoSourceURI ) ) << ")"; |
725 | + o << ":" << source_line(); |
726 | + if ( source_column() ) |
727 | + o << "," << source_column(); |
728 | + |
729 | + if ( has_applied() ) { |
730 | + o << " (" << diagnostic::dict::lookup( ZED( AppliedAt ) ) << ' '; |
731 | + if ( applied_uri() && ::strcmp( applied_uri(), source_uri() ) != 0 ) { |
732 | + if ( print_uri( o, applied_uri() ) ) |
733 | + o << ':'; |
734 | + } |
735 | + o << applied_line(); |
736 | + if ( applied_column() ) |
737 | + o << ',' << applied_column(); |
738 | + o << ')'; |
739 | + } |
740 | + |
741 | + o << ": "; |
742 | + } |
743 | + return ZorbaException::print_impl( o ); |
744 | + } |
745 | +} |
746 | + |
747 | +ostream& XQueryException::print_stack_trace( ostream &o ) const { |
748 | + XQueryStackTrace const &trace = query_trace(); |
749 | + if ( !trace.empty() ) { |
750 | + print_format const format = get_print_format( o ); |
751 | + bool const as_xml = format != format_text; |
752 | + bool const do_indent = format == format_xml_indented; |
753 | + |
754 | + if ( as_xml ) |
755 | + o << indent << "<stack>" << if_nl << if_inc_indent; |
756 | + FOR_EACH( XQueryStackTrace, it, trace ) { |
757 | + XQueryStackTrace::fn_name_type const &fn_name = it->getFnName(); |
758 | + char const *const fn_prefix = fn_name.prefix(); |
759 | + XQueryStackTrace::fn_arity_type fn_arity = it->getFnArity(); |
760 | + |
761 | + zstring filename( it->getFileName() ); |
762 | + if ( ascii::begins_with( filename, "file:" ) ) { |
763 | + URI::decode_file_URI( filename, filename ); |
764 | + while ( ascii::begins_with( filename, "//" ) ) |
765 | + filename = filename.substr(1); |
766 | + } |
767 | + |
768 | + if ( as_xml ) { |
769 | + o << indent << "<call"; |
770 | + if ( fn_prefix && *fn_prefix ) |
771 | + o << " prefix=\"" << fn_prefix << '"'; |
772 | + |
773 | +#if 0 |
774 | + o << " namespace=\"" << fn_name.ns() << '"' |
775 | + << " local-name=\"" << fn_name.localname() |
776 | + << " arity=\"" << fn_arity << '"' |
777 | + << "\">" << if_nl; // <call ... |
778 | + |
779 | + o << if_inc_indent << indent << "<location uri=\"" << filename << '"'; |
780 | + |
781 | + o << " line-begin=\"" << it->getLine() << '"'; |
782 | + if ( it->getLineEnd() ) |
783 | + o << " line-end=\"" << it->getLineEnd() << '"'; |
784 | + |
785 | + o << " column-begin=\"" << it->getColumn() << '"'; |
786 | + if ( it->getColumnEnd() ) |
787 | + o << " column-end=\"" << it->getColumnEnd() << '"'; |
788 | +#else |
789 | + o << " ns=\"" << fn_name.ns() << '"' |
790 | + << " localName=\"" << fn_name.localname() |
791 | + << " arity=\"" << fn_arity << '"' |
792 | + << "\">" << if_nl; // <call ... |
793 | + |
794 | + o << if_inc_indent << indent << "<location fileName=\"" << filename << '"'; |
795 | + |
796 | + o << " lineStart=\"" << it->getLine() << '"'; |
797 | + o << " columnStart=\"" << it->getColumn() << '"'; |
798 | + |
799 | + if ( it->getLineEnd() ) |
800 | + o << " lineEnd=\"" << it->getLineEnd() << '"'; |
801 | + if ( it->getColumnEnd() ) |
802 | + o << " columnEnd=\"" << it->getColumnEnd() << '"'; |
803 | +#endif |
804 | + |
805 | + o << "/>" << if_nl // <location ... |
806 | + << if_dec_indent << "</call>" << if_nl; |
807 | + } else { |
808 | + o << fn_name << '#' << fn_arity |
809 | + << " <" << fn_name.ns() << "> " |
810 | + << '"' << filename << "\":" |
811 | + << it->getLine() << ',' << it->getColumn() |
812 | + << '\n'; |
813 | + } |
814 | + } // FOR_EACH |
815 | + if ( as_xml ) |
816 | + o << indent << "</stack>" << if_nl << if_dec_indent; |
817 | + } |
818 | + return o; |
819 | +} |
820 | + |
821 | +bool XQueryException::print_uri( ostream &o, char const *uri ) { |
822 | if ( uri && *uri ) { |
823 | + bool const as_xml = get_print_format( o ) != format_text; |
824 | switch ( uri::get_scheme( uri ) ) { |
825 | case uri::none: |
826 | case uri::file: |
827 | try { |
828 | - o << '<' << fs::get_normalized_path( uri ) << '>'; |
829 | + o << (as_xml ? " uri=\"" : "<") |
830 | + << fs::get_normalized_path( uri ) |
831 | + << (as_xml ? '"' : '>'); |
832 | break; |
833 | } |
834 | catch ( ... ) { |
835 | @@ -113,38 +279,13 @@ |
836 | } |
837 | // no break; |
838 | default: |
839 | - o << '<' << uri << '>'; |
840 | - } |
841 | + o << (as_xml ? " uri=\"" : "<" ) << uri << (as_xml ? '"' : '>'); |
842 | + } // switch |
843 | return true; |
844 | - } |
845 | + } // if |
846 | return false; |
847 | } |
848 | |
849 | -ostream& XQueryException::print( ostream &o ) const { |
850 | - if ( has_source() ) { |
851 | - if ( !print_uri( o, source_uri() ) ) |
852 | - o << '(' << diagnostic::dict::lookup( ZED( NoSourceURI ) ) << ')'; |
853 | - o << ':' << source_line(); |
854 | - if ( source_column() ) |
855 | - o << ',' << source_column(); |
856 | - |
857 | - if ( has_applied() ) { |
858 | - o << " (" << diagnostic::dict::lookup( ZED( AppliedAt ) ) << ' '; |
859 | - if ( applied_uri() && ::strcmp( applied_uri(), source_uri() ) != 0 ) { |
860 | - if ( print_uri( o, applied_uri() ) ) |
861 | - o << ':'; |
862 | - } |
863 | - o << applied_line(); |
864 | - if ( applied_column() ) |
865 | - o << ',' << applied_column(); |
866 | - o << ')'; |
867 | - } |
868 | - |
869 | - o << ": "; |
870 | - } |
871 | - return ZorbaException::print( o ); |
872 | -} |
873 | - |
874 | /////////////////////////////////////////////////////////////////////////////// |
875 | |
876 | XQueryException |
877 | |
878 | === modified file 'src/diagnostics/zorba_exception.cpp' |
879 | --- src/diagnostics/zorba_exception.cpp 2012-09-19 21:16:15 +0000 |
880 | +++ src/diagnostics/zorba_exception.cpp 2013-02-07 01:30:37 +0000 |
881 | @@ -20,6 +20,10 @@ |
882 | #include <zorba/zorba_exception.h> |
883 | #include <zorba/xquery_warning.h> |
884 | |
885 | +#include "util/indent.h" |
886 | +#include "util/omanip.h" |
887 | +#include "zorbamisc/ns_consts.h" |
888 | + |
889 | #include "dict.h" |
890 | |
891 | #ifndef NDEBUG |
892 | @@ -27,12 +31,24 @@ |
893 | ZORBA_DLL_PUBLIC bool g_abort_on_error; |
894 | #endif /* NDEBUG */ |
895 | |
896 | +#define if_inc_indent if_do( do_indent, inc_indent ) |
897 | +#define if_dec_indent if_do( do_indent, dec_indent ) |
898 | + |
899 | +#undef if_nl |
900 | +#define if_nl if_emit( do_indent, '\n' ) |
901 | + |
902 | using namespace std; |
903 | |
904 | namespace zorba { |
905 | |
906 | /////////////////////////////////////////////////////////////////////////////// |
907 | |
908 | +inline bool is_warning( Diagnostic const &d ) { |
909 | + return !!dynamic_cast<ZorbaWarningCode const*>( &d ); |
910 | +} |
911 | + |
912 | +/////////////////////////////////////////////////////////////////////////////// |
913 | + |
914 | ZorbaException::ZorbaException( Diagnostic const &diagnostic, |
915 | char const *raise_file, line_type raise_line, |
916 | char const *message ) : |
917 | @@ -56,7 +72,7 @@ |
918 | { |
919 | } |
920 | |
921 | -ZorbaException::ZorbaException( serialization::Archiver &ar ) |
922 | +ZorbaException::ZorbaException( serialization::Archiver& ) |
923 | { |
924 | } |
925 | |
926 | @@ -80,40 +96,86 @@ |
927 | return unique_ptr<ZorbaException>( new ZorbaException( *this ) ); |
928 | } |
929 | |
930 | +int ZorbaException::get_ios_format_index() { |
931 | + static int const index = ios_base::xalloc(); |
932 | + return index; |
933 | +} |
934 | + |
935 | void ZorbaException::polymorphic_throw() const { |
936 | throw *this; |
937 | } |
938 | |
939 | -ostream& ZorbaException::print( ostream &o ) const { |
940 | - // |
941 | - // We need to create an error phrase (e.g., "static error") and look that up |
942 | - // as a unit rather than looking up the error kind word and "error" |
943 | - // separately because many languages have the word order reversed (e.g., |
944 | - // "static error" becomes "erreur statique" in French). |
945 | - // |
946 | - ostringstream oss; |
947 | - oss << ZED_PREFIX; |
948 | +ostream& ZorbaException::print( ostream& o ) const { |
949 | + print_format const format = get_print_format( o ); |
950 | + bool const as_xml = format != format_text; |
951 | + bool const do_indent = format == format_xml_indented; |
952 | + if ( as_xml ) { |
953 | + o << "<exception xmlns=\"" |
954 | + << (is_warning( diagnostic() ) ? ZORBA_WARN_NS : ZORBA_ERR_NS) |
955 | + << "\">" << if_nl << if_inc_indent; |
956 | + } |
957 | + print_impl( o ); |
958 | + if ( as_xml ) |
959 | + o << if_dec_indent << "</exception>"; |
960 | + return o; |
961 | +} |
962 | |
963 | - streampos pos = oss.tellp(); |
964 | +ostream& ZorbaException::print_impl( ostream &o ) const { |
965 | Diagnostic const &d = diagnostic(); |
966 | - oss << d.category(); |
967 | - if ( oss.tellp() != pos ) // emit ' ' only if non-empty category |
968 | - oss << ' '; |
969 | - |
970 | - if ( diagnostic::kind const k = d.kind() ) |
971 | - oss << k << ' '; |
972 | - |
973 | - oss << (dynamic_cast<ZorbaWarningCode const*>( &d ) ? "warning" : "error"); |
974 | - |
975 | - o << diagnostic::dict::lookup( oss.str() ) << " [" << d.qname() << ']'; |
976 | + print_format const format = get_print_format( o ); |
977 | + bool const as_xml = format != format_text; |
978 | + bool const do_indent = format == format_xml_indented; |
979 | + |
980 | + if ( as_xml ) { |
981 | + diagnostic::QName const &q = d.qname(); |
982 | +#if 0 |
983 | + o << indent << "<kind>" << d.kind() << "</kind>" << if_nl |
984 | + << indent << "<code namespace=\"" << q.ns() |
985 | + << "\" local-name=\"" << q.localname() << "\"/>" |
986 | +#else |
987 | + o << indent << "<kind>" << d.kind() << ' ' |
988 | + << (is_warning( d ) ? "warning" : "error") << "</kind>" << if_nl |
989 | + << indent << "<code>" << q << "</code>" |
990 | +#endif |
991 | + << if_nl; |
992 | + } else { |
993 | + // |
994 | + // We need to create an error phrase (e.g., "static error") and look that |
995 | + // up as a unit rather than looking up the error kind word and "error" |
996 | + // separately because many languages have the word order reversed (e.g., |
997 | + // "static error" becomes "erreur statique" in French). |
998 | + // |
999 | + ostringstream oss; |
1000 | + oss << ZED_PREFIX; |
1001 | + |
1002 | + streampos pos = oss.tellp(); |
1003 | + oss << d.category(); |
1004 | + if ( oss.tellp() != pos ) // emit ' ' only if non-empty category |
1005 | + oss << ' '; |
1006 | + |
1007 | + if ( diagnostic::kind const k = d.kind() ) |
1008 | + oss << k << ' '; |
1009 | + |
1010 | + oss << (is_warning( d ) ? "warning" : "error"); |
1011 | + o << diagnostic::dict::lookup( oss.str() ) << " [" << d.qname() << ']'; |
1012 | + } |
1013 | |
1014 | if ( char const *const w = what() ) |
1015 | - if ( *w ) |
1016 | - o << ": " << w; |
1017 | + if ( *w ) { |
1018 | + if ( as_xml ) |
1019 | + o << indent << "<message>" << w << "</message>" << if_nl; |
1020 | + else |
1021 | + o << ": " << w; |
1022 | + } |
1023 | |
1024 | #ifndef NDEBUG |
1025 | - o << "; raised at " << raise_file() << ':' << raise_line(); |
1026 | + if ( as_xml ) |
1027 | + o << indent << "<raised-at file=\"" << raise_file() |
1028 | + << "\" line=\"" << raise_line() << "\"/>" << if_nl; |
1029 | + else |
1030 | + o << "; raised at " << raise_file() << ':' << raise_line(); |
1031 | #endif |
1032 | + |
1033 | return o; |
1034 | } |
1035 | |
1036 | |
1037 | === modified file 'src/runtime/json/common.h' |
1038 | --- src/runtime/json/common.h 2012-09-19 21:16:15 +0000 |
1039 | +++ src/runtime/json/common.h 2013-02-07 01:30:37 +0000 |
1040 | @@ -49,34 +49,13 @@ |
1041 | }; |
1042 | } |
1043 | |
1044 | +#define if_indent(WS,FN) if_do( (WS) == whitespace::indent, FN ) |
1045 | + |
1046 | /////////////////////////////////////////////////////////////////////////////// |
1047 | |
1048 | bool get_attribute_value( store::Item_t const &element, char const *att_name, |
1049 | zstring *att_value ); |
1050 | |
1051 | -typedef std::ostream& (*std_omanip_type)(std::ostream&); |
1052 | - |
1053 | -inline std::ostream& if_do_impl( std::ostream &o, bool expr, |
1054 | - std_omanip_type fn ) { |
1055 | - if ( expr ) |
1056 | - o << fn; |
1057 | - return o; |
1058 | -} |
1059 | -DEF_OMANIP2( if_do_impl, bool, std_omanip_type ) |
1060 | -// A macro with a !! is used to suppress a warning from MSVC++. |
1061 | -#define if_do(EXPR,FN) if_do_impl( !!(EXPR), (FN) ) |
1062 | - |
1063 | -#define if_indent(WS,FN) if_do( (WS) == whitespace::indent, FN ) |
1064 | - |
1065 | -inline std::ostream& if_emit_impl( std::ostream &o, bool expr, char c ) { |
1066 | - if ( expr ) |
1067 | - o << c; |
1068 | - return o; |
1069 | -} |
1070 | -DEF_OMANIP2( if_emit_impl, bool, char ) |
1071 | -// A macro with a !! is used to suppress a warning from MSVC++. |
1072 | -#define if_emit(EXPR,C) if_emit_impl( !!(EXPR), (C) ) |
1073 | - |
1074 | /////////////////////////////////////////////////////////////////////////////// |
1075 | |
1076 | #define IN_STATE(S) ztd::top_stack_equals( state_stack, (S) ) |
1077 | |
1078 | === modified file 'src/util/fs_util.h' |
1079 | --- src/util/fs_util.h 2013-01-24 02:27:45 +0000 |
1080 | +++ src/util/fs_util.h 2013-02-07 01:30:37 +0000 |
1081 | @@ -648,7 +648,7 @@ |
1082 | char const* (PathStringType::*)() const>::value, |
1083 | zstring>::type |
1084 | get_normalized_path( PathStringType const &path, |
1085 | - PathStringType const &base = "" ) { |
1086 | + PathStringType const &base = "" ) { |
1087 | return get_normalized_path( path.c_str(), base.c_str() ); |
1088 | } |
1089 | |
1090 | |
1091 | === modified file 'src/util/omanip.h' |
1092 | --- src/util/omanip.h 2012-09-19 21:16:15 +0000 |
1093 | +++ src/util/omanip.h 2013-02-07 01:30:37 +0000 |
1094 | @@ -298,6 +298,54 @@ |
1095 | |
1096 | /////////////////////////////////////////////////////////////////////////////// |
1097 | |
1098 | +/** |
1099 | + * A type for the standard, no-argument ostream manipulator. |
1100 | + */ |
1101 | +typedef std::ostream& (*std_omanip_type)(std::ostream&); |
1102 | + |
1103 | +/** |
1104 | + * Emits \a c to the given ostream only if \a expr is \c true. |
1105 | + * |
1106 | + * @param o The ostream to emit to. |
1107 | + * @param expr The boolean expression. |
1108 | + * @param c The character to emit only if \a expr is \c true. |
1109 | + * @return Returns \a o. |
1110 | + */ |
1111 | +inline std::ostream& if_emit_impl( std::ostream &o, bool expr, char c ) { |
1112 | + if ( expr ) |
1113 | + o << c; |
1114 | + return o; |
1115 | +} |
1116 | +DEF_OMANIP2( if_emit_impl, bool, char ) |
1117 | +// A macro with a !! is used to suppress a warning from MSVC++. |
1118 | +#define if_emit(EXPR,C) if_emit_impl( !!(EXPR), (C) ) |
1119 | + |
1120 | +/** |
1121 | + * Emits a newline only if the given expression is \c true. |
1122 | + */ |
1123 | +#define if_nl(EXPR) if_emit( EXPR, '\n' ) |
1124 | + |
1125 | +/** |
1126 | + * Calls the given manipulator function \a fn on the given ostream only if \a |
1127 | + * expr is \c true. |
1128 | + * |
1129 | + * @param o The ostream to emit to. |
1130 | + * @param expr The boolean expression. |
1131 | + * @param fn The manipulator function to call only if \a expr is \c true. |
1132 | + * @return Returns \a o. |
1133 | + */ |
1134 | +inline std::ostream& if_do_impl( std::ostream &o, bool expr, |
1135 | + std_omanip_type fn ) { |
1136 | + if ( expr ) |
1137 | + o << fn; |
1138 | + return o; |
1139 | +} |
1140 | +DEF_OMANIP2( if_do_impl, bool, std_omanip_type ) |
1141 | +// A macro with a !! is used to suppress a warning from MSVC++. |
1142 | +#define if_do(EXPR,FN) if_do_impl( !!(EXPR), (FN) ) |
1143 | + |
1144 | +/////////////////////////////////////////////////////////////////////////////// |
1145 | + |
1146 | } // namespace zorba |
1147 | |
1148 | #endif /* ZORBA_OMANIP_H */ |
It would be good to use this error printer for the warning reporter too. But I didn't figure out how that should work yet? Can you guys help?