internal/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_INTERNAL_DIAGNOSTIC_H
18 #define ZORBA_INTERNAL_DIAGNOSTIC_H
19 
20 #include <string>
21 #include <vector>
22 
23 #include <zorba/diagnostic.h>
24 
25 #include "ztd.h"
26 
27 namespace zorba {
28 
29 namespace internal {
30  namespace diagnostic {
31  class location;
32  }
33 }
34 namespace serialization {
35  class Archiver;
36  void operator&( serialization::Archiver&, internal::diagnostic::location& );
37 }
38 
39 namespace internal {
40 namespace diagnostic {
41 
42 ///////////////////////////////////////////////////////////////////////////////
43 
44 /**
45  * A %location holds the file location of an error.
46  */
47 class ZORBA_DLL_PUBLIC location {
49 public:
50  /**
51  * The line-number type.
52  */
53  typedef unsigned line_type;
54 
55  /**
56  * The column-number type.
57  */
58  typedef unsigned short column_type;
59 
60  /**
61  * A empty instance for convenience.
62  */
63  static location const empty;
64 
65  /**
66  * Constructs a default (empty) %location.
67  */
68  location() : line_( 0 ), column_( 0 ), line_end_( 0 ), column_end_( 0 ) {
69  }
70 
71  /**
72  * Constructs a %location.
73  *
74  * @param file The name of the file where the expression causing the error
75  * occurred.
76  * @param line The line number of the file where the expression causing the
77  * error begins.
78  * @param column The column number, if any, of the file where the expression
79  * causing the error begins.
80  * @param line_end The end line number, if any, of the file where the
81  * expression causing the error ends.
82  * @param column_end The end column number, if any, of the file where the
83  * expression causing the error ends.
84  */
85  location( char const *file, line_type line, column_type column = 0,
86  line_type line_end = 0, column_type column_end = 0 ) :
87  file_( file ), line_( line ), column_( column ),
88  line_end_( line_end ), column_end_( column_end )
89  {
90  }
91 
92  /**
93  * Constructs a %location.
94  *
95  * @tparam StringType The string type for \a file.
96  * @param file The name of the file where the error occurred.
97  * @param line The line number of the file where the error occurred.
98  * @param column The column number, if any, of the file where the error
99  * occurred.
100  * @param line_end The end line number, if any, of the file where the
101  * expression causing the error ends.
102  * @param column_end The end column number, if any, of the file where the
103  * xpression causing the error ends.
104  */
105  template<class StringType>
106  location( StringType const &file, line_type line, column_type column = 0,
107  line_type line_end = 0, column_type column_end = 0 ) :
108  file_( file.c_str() ), line_( line ), column_( column ),
109  line_end_( line_end ), column_end_( column_end )
110  {
111  }
112 
113  /**
114  * Gets the file name, if any.
115  *
116  * @return Returns the file name or the empty string if unset.
117  */
118  char const* file() const {
119  return file_.c_str();
120  }
121 
122  /**
123  * Gets the line number, if any.
124  *
125  * @return Returns the line number or 0 if unset.
126  */
127  line_type line() const {
128  return line_;
129  }
130 
131  /**
132  * Gets the column number, if any.
133  *
134  * @return Returns the column number or 0 if unset.
135  */
136  column_type column() const {
137  return column_;
138  }
139 
140  /**
141  * Gets the ending line number, if any.
142  *
143  * @return Returns the line number or 0 if unset.
144  */
145  line_type line_end() const {
146  return line_end_;
147  }
148 
149  /**
150  * Gets the ending column number, if any.
151  *
152  * @return Returns the column number or 0 if unset.
153  */
155  return column_end_;
156  }
157 
158  /**
159  * Conversion to \c bool for testing whether this %location has been set.
160  *
161  * @return Returns \c true only if this %location has been set.
162  */
163  operator explicit_bool::type() const {
164  return explicit_bool::value_of( line_ );
165  }
166 
167  /**
168  * Checks whether this %location has not been set.
169  *
170  * @return Returns \c true only if this %location has not been set.
171  */
172  bool operator!() const {
173  return !line_;
174  }
175 
176  /**
177  * Sets the %location information.
178  *
179  * @param file The name of the file where the error occurred.
180  * @param line The line number of the file where the error occurred.
181  * @param column The column number, if any, of the file where the error
182  * occurred.
183  * @param line_end The end line of the file where the error occured.
184  * @param column_end The column number, if any, where the error ends.
185  * occurred.
186  */
187  void set( char const *file, line_type line, column_type column = 0,
188  line_type line_end = 0, column_type column_end = 0 ) {
189  file_ = file;
190  line_ = line;
191  column_ = column;
192  line_end_ = line_end;
193  column_end_ = column_end;
194  }
195 
196 private:
197  std::string file_;
198  line_type line_;
199  column_type column_;
200  line_type line_end_;
201  column_type column_end_;
202 
203  friend bool operator==( location const&, location const& );
204  friend bool operator!=( location const&, location const& );
205 
206  // for plan serialization
207  friend void serialization::operator&( serialization::Archiver&, location& );
208 };
209 
210 /**
211  * \internal
212  * Compares two locations for equality.
213  *
214  * @param i The first location.
215  * @param j The second location.
216  * @return Returns \c true only if the two locations are equal.
217  */
218 bool operator==( location const &i, location const &j );
219 
220 /**
221  * \internal
222  * Compares two locations for inequality.
223  *
224  * @param i The first location.
225  * @param j The second location.
226  * @return Returns \c true only if the two locations are not equal.
227  */
228 bool operator!=( location const &i, location const &j );
229 
230 ///////////////////////////////////////////////////////////////////////////////
231 
232 /**
233  * \internal
234  * A %parameters holds the parameters for an error message.
235  */
236 class ZORBA_DLL_PUBLIC parameters {
237  typedef std::vector<std::string> params_type;
238 public:
239  typedef params_type::value_type value_type;
240  typedef params_type::size_type size_type;
241 
242  /**
243  * A empty instance for convenience.
244  */
245  static parameters const empty;
246 
247  /**
248  * Constructs a %parameters object.
249  */
250  parameters();
251 
252  /**
253  * Adds the string representation of the given object as the next parameter.
254  *
255  * @tparam T The object type.
256  * @param t The object.
257  * @return Returns \c *this.
258  */
259  template<typename T>
260  parameters& operator,( T const &t ) {
261  add_param( ztd::to_string( t ) );
262  return *this;
263  }
264 
265  /**
266  * Gets the i'th parameter value.
267  * Parameter numbers start at 1.
268  *
269  * @param i The parameter to get.
270  * @return Returns said parameter value.
271  */
272  value_type const& operator[]( size_type i ) const {
273  return params_[ i - 1 ];
274  }
275 
276  /**
277  * Substitutes substrings of the given string. Substitutions are in three
278  * forms:
279  *
280  * - <code>$</code><em>i</em>
281  * - <code>${</code>[<em>chars</em>]<em>i</em>[<em>chars</em>]<code>}</code>
282  * - <code>$</code><em>i</em><code>?</code><em>then</em>[<code>:</code><em>else</em>]
283  *
284  * where \e i is a digit in the range <code>[1,9]</code> and refers to the
285  * value of the \e ith parameter, \e chars may be any characters except
286  * <code>[1-9}]</code>, and \e then and \e else are of one of the two forms:
287  *
288  * - <em>j</em>
289  * - <code>{</code>[<em>chars j chars k chars ...</em>]<code>}</code>
290  *
291  * where \e j is likewise a digit in the range <code>[1,9]</code> and refers
292  * to the value of the \e jth parameter.
293  *
294  * The first substitution form replaces <code>$</code><em>i</em> with the
295  * value of the \e ith parameter.
296  *
297  * The second form replaces everything from the \c $ to the \c } with the
298  * contents of the \c {} where \e i is replaced with the value of the \e ith
299  * parameter. However, if the value is empty, then everything from the \c $
300  * to the \c } is instead erased.
301  *
302  * For example, <code>${"1": }</code> will substitute the value of the 1st
303  * parameter quoted followed by a \c : and a space if non-empty; if empty,
304  * then everything from the \c $ to the \c } will instead be erased.
305  *
306  * The third form tests the value of the \c ith parameter: if non-empty, then
307  * the \e then portion is substituted; if empty, then the \e else portion is.
308  * Both the \e then and \e else portions can be either a digit in the range
309  * [1,9] or \e chars enclosed by \c {}. The \c {} here can contain multiple
310  * parameter indicies. If at least one is non-empty, then the substitution
311  * for the portion will be done; if all are empty, then everything for the
312  * portion will be erased.
313  *
314  *
315  * The \c \\ character can be used to escape the meaning of the
316  * <code>$</code>, <code>[1-9]</code>, <code>?</code>, <code>:</code>, and
317  * <code>}</code> characters and instead treat them as ordinary characters.
318  *
319  * Substitution is performed by making at most 9 passes over the string, one
320  * pass per parameter starting at 1. Substitutions may themselves have
321  * further substitutions, but, due to the way that substitution is performed,
322  * should only refer to parameters having higher digits. (Digits less than
323  * or equal to the current one will not be substituted.)
324  *
325  * @param s The string to perform the substitutions on.
326  */
327  void substitute( value_type *s ) const;
328 
329 private:
330  params_type params_;
331 
332  void add_param( value_type const& );
333  value_type lookup_param( size_type i ) const;
334  bool then_else( bool, value_type const&, value_type::size_type*,
335  value_type* ) const;
336  size_type to_index( value_type::value_type ) const;
337 };
338 
339 ///////////////////////////////////////////////////////////////////////////////
340 
341 } // namespace diagnostic
342 } // namespace internal
343 } // namespace zorba
344 #endif /* ZORBA_INTERNAL_DIAGNOSTIC_H */
345 /* vim:set et sw=2 ts=2: */
bool operator!() const
Checks whether this location has not been set.
char const * file() const
Gets the file name, if any.
A location holds the file location of an error.
line_type line_end() const
Gets the ending line number, if any.
std::enable_if<!ZORBA_TR1_NS::is_array< T >::value &&!ZORBA_TR1_NS::is_pointer< T >::value &&has_insertion_operator<T >::value, std::string >::type to_string(T const &t)
Definition: ztd.h:299
column_type column_end() const
Gets the ending column number, if any.
StringType::const_pointer c_str(StringType const &s)
Definition: ztd.h:179
location()
Constructs a default (empty) location.
unsigned short column_type
The column-number type.
bool operator!=(location const &i, location const &j)
Helper class for implementing a solution to the "explicit bool conversion" problem.
Definition: ztd.h:427
static location const empty
A empty instance for convenience.
parameters & operator,(T const &t)
Adds the string representation of the given object as the next parameter.
value_type const & operator[](size_type i) const
Gets the i'th parameter value.
column_type column() const
Gets the column number, if any.
unsigned line_type
The line-number type.
location(StringType const &file, line_type line, column_type column=0, line_type line_end=0, column_type column_end=0)
Constructs a location.
bool operator==(location const &i, location const &j)
location(char const *file, line_type line, column_type column=0, line_type line_end=0, column_type column_end=0)
Constructs a location.
line_type line() const
Gets the line number, if any.
void set(char const *file, line_type line, column_type column=0, line_type line_end=0, column_type column_end=0)
Sets the location information.
void operator&(serialization::Archiver &, const Diagnostic *&)
static parameters const empty
A empty instance for convenience.