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 */ 00189 void set( 00190 char const *file, 00191 line_type line, 00192 column_type column = 0, 00193 line_type line_end = 0, 00194 column_type column_end = 0) { 00195 file_ = file; 00196 line_ = line; 00197 column_ = column; 00198 line_end_ = line_end; 00199 column_end_ = column_end; 00200 } 00201 00202 private: 00203 std::string file_; 00204 line_type line_; 00205 column_type column_; 00206 line_type line_end_; 00207 column_type column_end_; 00208 00209 // for plan serialization 00210 friend void serialization::operator&( serialization::Archiver&, location& ); 00211 }; 00212 00213 /////////////////////////////////////////////////////////////////////////////// 00214 00215 /** 00216 * \internal 00217 * A %parameters holds the parameters for an error message. 00218 */ 00219 class ZORBA_DLL_PUBLIC parameters { 00220 typedef std::vector<std::string> params_type; 00221 public: 00222 typedef params_type::value_type value_type; 00223 typedef params_type::size_type size_type; 00224 00225 /** 00226 * A empty instance for convenience. 00227 */ 00228 static parameters const empty; 00229 00230 /** 00231 * Constructs a %parameters object. 00232 */ 00233 parameters(); 00234 00235 /** 00236 * Adds the string representation of the given object as the next parameter. 00237 * 00238 * @tparam T The object type. 00239 * @param t The object. 00240 * @return Returns \c *this. 00241 */ 00242 template<typename T> 00243 parameters& operator,( T const &t ) { 00244 params_.push_back( ztd::to_string( t ) ); 00245 return *this; 00246 } 00247 00248 /** 00249 * Gets the i'th parameter value. 00250 * Parameter numbers start at 1. 00251 * 00252 * @param i The parameter to get. 00253 * @return Returns said parameter value. 00254 */ 00255 value_type const& operator[]( size_type i ) const { 00256 return params_[ i - 1 ]; 00257 } 00258 00259 /** 00260 * Substitutes substrings of the given string. There are two forms: 00261 * 00262 * - <code>$</code><em>i</em> 00263 * - <code>${</code><em>chars i chars</em><code>}</code> 00264 * 00265 * where <em>i</em> is an integer in the range <code>[1,9]</code> 00266 * and <em>chars</em> are any characters except <code>[1-9}]</code>. 00267 * 00268 * The second form elides the addition characacters if the value of the 00269 * <em>ith</em> parameter is empty. For example, <code>${"1"}</code> will 00270 * substitute the value of the 1st parameter quoted if non-empty; if empty, 00271 * the entire substitution set of characters (everything from the 00272 * <code>$</code> to the <code>}</code>) will be elided. 00273 * 00274 * @param s The string to perform the substitutions on. 00275 */ 00276 void substitute( value_type *s ) const; 00277 00278 private: 00279 params_type params_; 00280 00281 value_type lookup_param( size_type i ) const; 00282 }; 00283 00284 /////////////////////////////////////////////////////////////////////////////// 00285 00286 } // namespace diagnostic 00287 } // namespace internal 00288 } // namespace zorba 00289 #endif /* ZORBA_INTERNAL_DIAGNOSTIC_H */ 00290 /* vim:set et sw=2 ts=2: */