diagnostic.h
Go to the documentation of this file.
1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ZORBA_DIAGNOSTIC_API_H
18 #define ZORBA_DIAGNOSTIC_API_H
19 
20 #include <cstring>
21 #include <iostream>
22 
23 #include <zorba/config.h>
24 
25 namespace zorba {
26 namespace diagnostic {
27 
28 ///////////////////////////////////////////////////////////////////////////////
29 
30 /**
31  * A %QName is the abstract base class for a QName.
32  */
33 class ZORBA_DLL_PUBLIC QName {
34 public:
35  virtual ~QName();
36 
37  /**
38  * Gets this QName's namespace URI.
39  *
40  * @return Returns said URI.
41  */
42  virtual char const* ns() const = 0;
43 
44  /**
45  * Gets this QName's prefix.
46  *
47  * @return Returns said prefix.
48  */
49  virtual char const* prefix() const = 0;
50 
51  /**
52  * Gets this QName's local name.
53  *
54  * @return Returns said local name.
55  */
56  virtual char const* localname() const = 0;
57 };
58 
59 /**
60  * Emits a QName to an ostream.
61  *
62  * @param o The ostream to emit to.
63  * @param qn The QName to emit.
64  * @return Returns \a o.
65  */
66 ZORBA_DLL_PUBLIC
67 std::ostream& operator<<( std::ostream &o, QName const &qn );
68 
69 /**
70  * Compares two QNames for equality.
71  *
72  * @param q1 The first QName.
73  * @param q2 The second QName.
74  * @return Returns \c true only if the QNames' namespaces and local names are
75  * equal.
76  */
77 ZORBA_DLL_PUBLIC
78 bool operator==( QName const &q1, QName const &q2 );
79 
80 /**
81  * Compares two QNames for equality.
82  *
83  * @param q1 The first QName.
84  * @param q2 The second QName. It can be in Clark notation,
85  * <code>{</code><em>namespace</em><code>}</code><em>local-name</em>, in which
86  * case the namespaces and local-names are compared; or as
87  * <em>prefix</em><code>:</code><em>local-name</em> in which case the prefixes
88  * and local-names are compared.
89  * @return Returns \c true only if the QNames are equal.
90  */
91 ZORBA_DLL_PUBLIC
92 bool operator==( QName const &q1, char const *q2 );
93 
94 /**
95  * Compares two QNames for equality.
96  *
97  * @param q1 The first QName. It can be in Clark notation,
98  * <code>{</code><em>namespace</em><code>}</code><em>local-name</em>, in which
99  * case the namespaces and local-names are compared; or as
100  * <em>prefix</em><code>:</code><em>local-name</em> in which case the prefixes
101  * and local-names are compared.
102  * @param q2 The second QName.
103  * @return Returns \c true only if the QNames are equal.
104  */
105 inline bool operator==( char const *q1, QName const &q2 ) {
106  return q2 == q1;
107 }
108 
109 /**
110  * Compares two QNames for equality.
111  *
112  * @tparam StringType The string type of \a q2.
113  * @param q1 The first QName.
114  * @param q2 The second QName. It can be in Clark notation,
115  * <code>{</code><em>namespace</em><code>}</code><em>local-name</em>, in which
116  * case the namespaces and local-names are compared; or as
117  * <em>prefix</em><code>:</code><em>local-name</em> in which case the prefixes
118  * and local-names are compared.
119  * @return Returns \c true only if the QNames are equal.
120  */
121 template<class StringType> inline
122 bool operator==( QName const &q1, StringType const &q2 ) {
123  return q1 == q2.c_str();
124 }
125 
126 /**
127  * Compares two QNames for equality.
128  *
129  * @tparam StringType The string type of \a q1.
130  * @param q1 The first QName. It can be in Clark notation,
131  * <code>{</code><em>namespace</em><code>}</code><em>local-name</em>, in which
132  * case the namespaces and local-names are compared; or as
133  * <em>prefix</em><code>:</code><em>local-name</em> in which case the prefixes
134  * and local-names are compared.
135  * @param q2 The second QName.
136  * @return Returns \c true only if the QNames are equal.
137  */
138 template<class StringType> inline
139 bool operator==( StringType const &q1, QName const &q2 ) {
140  return q1.c_str() == q2;
141 }
142 
143 /**
144  * Compares two QNames for inequality.
145  *
146  * @param q1 The first QName.
147  * @param q2 The second QName.
148  * @return Returns \c true only if either the QNames' namespaces or local names
149  * are not equal.
150  */
151 inline bool operator!=( QName const &q1, QName const &q2 ) {
152  return !(q1 == q2);
153 }
154 
155 /**
156  * Compares two QNames for inequality.
157  *
158  * @param q1 The first QName.
159  * @param q2 The second QName. It can be in Clark notation,
160  * <code>{</code><em>namespace</em><code>}</code><em>local-name</em>, in which
161  * case the namespaces and local-names are compared; or as
162  * <em>prefix</em><code>:</code><em>local-name</em> in which case the prefixes
163  * and local-names are compared.
164  * @return Returns \c true only if either the QNames' namespaces or local names
165  * are not equal.
166  */
167 inline bool operator!=( QName const &q1, char const *q2 ) {
168  return !(q1 == q2);
169 }
170 
171 /**
172  * Compares two QNames for inequality.
173  *
174  * @param q1 The first QName. It can be in Clark notation,
175  * <code>{</code><em>namespace</em><code>}</code><em>local-name</em>, in which
176  * case the namespaces and local-names are compared; or as
177  * <em>prefix</em><code>:</code><em>local-name</em> in which case the prefixes
178  * and local-names are compared.
179  * @param q2 The second QName.
180  * @return Returns \c true only if either the QNames' namespaces or local names
181  * are not equal.
182  */
183 inline bool operator!=( char const *q1, QName const &q2 ) {
184  return !(q1 == q2);
185 }
186 
187 /**
188  * Compares two QNames for inequality.
189  *
190  * @tparam StringType The string type of \a q2.
191  * @param q1 The first QName.
192  * @param q2 The second QName. It can be in Clark notation,
193  * <code>{</code><em>namespace</em><code>}</code><em>local-name</em>, in which
194  * case the namespaces and local-names are compared; or as
195  * <em>prefix</em><code>:</code><em>local-name</em> in which case the prefixes
196  * and local-names are compared.
197  * @return Returns \c true only if the QNames are not equal.
198  */
199 template<class StringType> inline
200 bool operator!=( QName const &q1, StringType const &q2 ) {
201  return q1 != q2.c_str();
202 }
203 
204 /**
205  * Compares two QNames for inequality.
206  *
207  * @tparam StringType The string type of \a q1.
208  * @param q1 The first QName. It can be in Clark notation,
209  * <code>{</code><em>namespace</em><code>}</code><em>local-name</em>, in which
210  * case the namespaces and local-names are compared; or as
211  * <em>prefix</em><code>:</code><em>local-name</em> in which case the prefixes
212  * and local-names are compared.
213  * @param q2 The second QName.
214  * @return Returns \c true only if the QNames are not equal.
215  */
216 template<class StringType> inline
217 bool operator!=( StringType const &q1, QName const &q2 ) {
218  return q1.c_str() != q2;
219 }
220 
221 ///////////////////////////////////////////////////////////////////////////////
222 
223 /**
224  * An diagnostic::category is the category of error.
225  */
226 enum category {
227  UNKNOWN_CATEGORY, // must have integer value of 0
228 
234  XQUERY_USER_DEFINED, // for fn:error()
235 
236  ZORBA_XQP, // Zorba XQuery Processor
237  ZORBA_API, // Zorba API
238  ZORBA_DDF, // Data Definition Facility
239  ZORBA_DEBUGGER, // Zorba Debugger
240  ZORBA_OS, // Operating System
243 
246 
247 # ifdef ZORBA_WITH_JSON
248  JSONIQ_CORE,
249  JSONIQ_UPDATE,
250 # endif /* ZORBA_WITH_JSON */
251 
252  ZORBA_CORE_MODULE // Zorba Core Module
253 };
254 
255 /**
256  * Emits the given diagnostic::category to the given ostream.
257  *
258  * @param o The ostream to emit to.
259  * @param c The category to emit.
260  * @return Returns \a o.
261  */
262 ZORBA_DLL_PUBLIC
263 std::ostream& operator<<( std::ostream &o, category c );
264 
265 /**
266  * An diagnostic::kind is the kind of error.
267  * See: http://www.w3.org/TR/xquery-30/#id-kinds-of-errors
268  */
269 enum kind {
270  UNKNOWN_KIND, // must have integer value of 0
271 
272  /**
273  * A static error is an error that must be detected during the static
274  * analysis phase. A syntax error is an example of a static error.
275  */
277 
278  /**
279  * A dynamic error is an error that must be detected during the dynamic
280  * evaluation phase and may be detected during the static analysis phase.
281  * Numeric overflow is an example of a dynamic error.
282  */
284 
285  /**
286  * A type error may be raised during the static analysis phase or the dynamic
287  * evaluation phase.
288  *
289  * During the static analysis phase, a type error occurs when the static type
290  * of an expression does not match the expected type of the context in which
291  * the expression occurs.
292  *
293  * During the dynamic evaluation phase, a type error occurs when the dynamic
294  * type of a value does not match the expected type of the context in which
295  * the value occurs.
296  */
298 };
299 
300 /**
301  * Emits the given diagnostic::kind to the given ostream.
302  *
303  * @param o The ostream to emit to.
304  * @param k The kind to emit.
305  * @return Returns \a o.
306  */
307 ZORBA_DLL_PUBLIC
308 std::ostream& operator<<( std::ostream &o, kind k );
309 
310 ///////////////////////////////////////////////////////////////////////////////
311 
312 } // namespace diagnostic
313 } // namespace zorba
314 
315 #include <zorba/internal/qname.h>
316 
317 namespace zorba {
318 
319 ///////////////////////////////////////////////////////////////////////////////
320 
321 /**
322  * A %Diagnostic is the base class for all Zorba diagnostics (errors and
323  * warnings).
324  */
325 class ZORBA_DLL_PUBLIC Diagnostic {
326 public:
327  /**
328  * Gets the QName for this diagnostic.
329  *
330  * @return Returns said QName.
331  */
332  virtual diagnostic::QName const& qname() const = 0;
333 
334  /**
335  * Gets the category of this diagnostic.
336  *
337  * @return Returns said category.
338  */
339  virtual diagnostic::category category() const;
340 
341  /**
342  * Gets the kind of this diagnostic.
343  *
344  * @return Returns said kind.
345  */
346  virtual diagnostic::kind kind() const;
347 
348  /**
349  * Gets the message of this diagnostic.
350  *
351  * @return Returns said message.
352  */
353  virtual char const* message() const;
354 
355 protected:
356  virtual ~Diagnostic();
357 
358  virtual Diagnostic const* clone() const = 0;
359 
360  /**
361  * Destroys a %Diagnostic. This is the only way a %Diagnostic should be
362  * destroyed.
363  */
364  virtual void destroy() const;
365 
366  // Only ZorbaException may call clone() and destroy().
367  friend class ZorbaException;
368 };
369 
370 /**
371  * Compares two diagnostics for equality.
372  *
373  * @param d1 The first diagnostic.
374  * @param d2 The second diagnostic.
375  * @return Returns \c true only if the diagnostics' QNames are equal.
376  */
377 inline bool operator==( Diagnostic const &d1, Diagnostic const &d2 ) {
378  return d1.qname() == d2.qname();
379 }
380 
381 /**
382  * Compares two diagnostics for inequality.
383  *
384  * @param d1 The first diagnostic.
385  * @param d2 The second diagnostic.
386  * @return Returns \c true only if the diagnostics' QNames are not equal.
387  */
388 inline bool operator!=( Diagnostic const &d1, Diagnostic const &d2 ) {
389  return !(d1 == d2);
390 }
391 
392 ///////////////////////////////////////////////////////////////////////////////
393 
394 } // namespace zorba
395 
397 
398 #endif /* ZORBA_DIAGNOSTIC_API_H */
399 /*
400  * Local variables:
401  * mode: c++
402  * End:
403  */
404 /* vim:set et sw=2 ts=2: */