00001 /* 00002 * Copyright 2006-2008 The FLWOR Foundation. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef ZORBA_INTERNAL_DIAGNOSTIC_H 00018 #define ZORBA_INTERNAL_DIAGNOSTIC_H 00019 00020 #include <string> 00021 #include <vector> 00022 00023 #include <zorba/diagnostic.h> 00024 00025 #include "ztd.h" 00026 00027 namespace zorba { 00028 00029 namespace internal { 00030 namespace diagnostic { 00031 class location; 00032 } 00033 } 00034 namespace serialization { 00035 class Archiver; 00036 void operator&( serialization::Archiver&, internal::diagnostic::location& ); 00037 } 00038 00039 namespace internal { 00040 namespace diagnostic { 00041 00042 /////////////////////////////////////////////////////////////////////////////// 00043 00044 /** 00045 * A %location hold the file location of an error. 00046 */ 00047 class ZORBA_DLL_PUBLIC location { 00048 public: 00049 /** 00050 * The line-number type. 00051 */ 00052 typedef unsigned line_type; 00053 00054 /** 00055 * The column-number type. 00056 */ 00057 typedef unsigned short column_type; 00058 00059 /** 00060 * A empty instance for convenience. 00061 */ 00062 static location const empty; 00063 00064 /** 00065 * Constructs a default (empty) %location. 00066 */ 00067 location() : line_( 0 ), column_( 0 ), line_end_( 0 ), column_end_( 0 ) { 00068 } 00069 00070 /** 00071 * Constructs a %location. 00072 * 00073 * @param file The name of the file where the error occurred. 00074 * @param line The line number of the file where the expression that 00075 * raises the error begins. 00076 * @param column The column number, if any, of the file where the expression 00077 * that raises the error begins. 00078 * @param line_end The end line number, if any, of the file where the expression 00079 * causing the error ends. 00080 * @param column_end The end column number, if any, of the file where 00081 * the xpression causing the error ends. 00082 */ 00083 location( 00084 char const *file, 00085 line_type line, 00086 column_type column = 0, 00087 line_type line_end = 0, 00088 column_type column_end = 0) : 00089 file_( file ), line_( line ), column_( column ), 00090 line_end_( line_end ), column_end_( column_end ) 00091 { 00092 } 00093 00094 /** 00095 * Constructs a %location. 00096 * 00097 * @tparam StringType The string type for \a file. 00098 * @param file The name of the file where the error occurred. 00099 * @param line The line number of the file where the error occurred. 00100 * @param column The column number, if any, of the file where the error occurred. 00101 * @param line_end The end line number, if any, of the file where the expression 00102 * causing the error ends. 00103 * @param column_end The end column number, if any, of the file where 00104 * the xpression causing the error ends. 00105 */ 00106 template<class StringType> 00107 location( 00108 StringType const &file, 00109 line_type line, 00110 column_type column = 0, 00111 line_type line_end = 0, 00112 column_type column_end = 0) : 00113 file_( file.c_str() ), line_( line ), column_( column ), 00114 line_end_( line_end ), column_end_( column_end ) 00115 { 00116 } 00117 00118 /** 00119 * Gets the file name, if any. 00120 * 00121 * @return Returns the file name or the empty string if unset. 00122 */ 00123 char const* file() const { 00124 return file_.c_str(); 00125 } 00126 00127 /** 00128 * Gets the line number, if any. 00129 * 00130 * @return Returns the line number or 0 if unset. 00131 */ 00132 line_type line() const { 00133 return line_; 00134 } 00135 00136 /** 00137 * Gets the column number, if any. 00138 * 00139 * @return Returns the column number or 0 if unset. 00140 */ 00141 column_type column() const { 00142 return column_; 00143 } 00144 00145 /** 00146 * Gets the ending line number, if any. 00147 * 00148 * @return Returns the line number or 0 if unset. 00149 */ 00150 line_type line_end() const { 00151 return line_end_; 00152 } 00153 00154 /** 00155 * Gets the ending column number, if any. 00156 * 00157 * @return Returns the column number or 0 if unset. 00158 */ 00159 column_type column_end() const { 00160 return column_end_; 00161 } 00162 00163 /** 00164 * Conversion to \c bool for testing whether this %location has been set. 00165 * 00166 * @return Returns \c true only if this %location has been set. 00167 */ 00168 operator bool() const { 00169 return !!line_; 00170 } 00171 00172 /** 00173 * Checks whether this %location has not been set. 00174 * 00175 * @return Returns \c true only if this %location has not been set. 00176 */ 00177 bool operator!() const { 00178 return !line_; 00179 } 00180 00181 /** 00182 * Sets the %location information. 00183 * 00184 * @param file The name of the file where the error occurred. 00185 * @param line The line number of the file where the error occurred. 00186 * @param column The column number, if any, of the file where the error 00187 * occurred. 00188 * @param line_end The end line of the file where the error occured. 00189 * @param column_end The column number, if any, where the error ends. 00190 * occurred. 00191 */ 00192 void set( 00193 char const *file, 00194 line_type line, 00195 column_type column = 0, 00196 line_type line_end = 0, 00197 column_type column_end = 0) { 00198 file_ = file; 00199 line_ = line; 00200 column_ = column; 00201 line_end_ = line_end; 00202 column_end_ = column_end; 00203 } 00204 00205 private: 00206 std::string file_; 00207 line_type line_; 00208 column_type column_; 00209 line_type line_end_; 00210 column_type column_end_; 00211 00212 // for plan serialization 00213 friend void serialization::operator&( serialization::Archiver&, location& ); 00214 }; 00215 00216 /////////////////////////////////////////////////////////////////////////////// 00217 00218 /** 00219 * \internal 00220 * A %parameters holds the parameters for an error message. 00221 */ 00222 class ZORBA_DLL_PUBLIC parameters { 00223 typedef std::vector<std::string> params_type; 00224 public: 00225 typedef params_type::value_type value_type; 00226 typedef params_type::size_type size_type; 00227 00228 /** 00229 * A empty instance for convenience. 00230 */ 00231 static parameters const empty; 00232 00233 /** 00234 * Constructs a %parameters object. 00235 */ 00236 parameters(); 00237 00238 /** 00239 * Adds the string representation of the given object as the next parameter. 00240 * 00241 * @tparam T The object type. 00242 * @param t The object. 00243 * @return Returns \c *this. 00244 */ 00245 template<typename T> 00246 parameters& operator,( T const &t ) { 00247 params_.push_back( ztd::to_string( t ) ); 00248 return *this; 00249 } 00250 00251 /** 00252 * Gets the i'th parameter value. 00253 * Parameter numbers start at 1. 00254 * 00255 * @param i The parameter to get. 00256 * @return Returns said parameter value. 00257 */ 00258 value_type const& operator[]( size_type i ) const { 00259 return params_[ i - 1 ]; 00260 } 00261 00262 /** 00263 * Substitutes substrings of the given string. There are two forms: 00264 * 00265 * - <code>$</code><em>i</em> 00266 * - <code>${</code><em>chars i chars</em><code>}</code> 00267 * 00268 * where <em>i</em> is an integer in the range <code>[1,9]</code> 00269 * and <em>chars</em> are any characters except <code>[1-9}]</code>. 00270 * 00271 * The second form elides the addition characacters if the value of the 00272 * <em>ith</em> parameter is empty. For example, <code>${"1"}</code> will 00273 * substitute the value of the 1st parameter quoted if non-empty; if empty, 00274 * the entire substitution set of characters (everything from the 00275 * <code>$</code> to the <code>}</code>) will be elided. 00276 * 00277 * @param s The string to perform the substitutions on. 00278 */ 00279 void substitute( value_type *s ) const; 00280 00281 private: 00282 params_type params_; 00283 00284 value_type lookup_param( size_type i ) const; 00285 }; 00286 00287 /////////////////////////////////////////////////////////////////////////////// 00288 00289 } // namespace diagnostic 00290 } // namespace internal 00291 } // namespace zorba 00292 #endif /* ZORBA_INTERNAL_DIAGNOSTIC_H */ 00293 /* vim:set et sw=2 ts=2: */