00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #define MOCKPP_NEED_EXPORTS
00032 #include <mockpp/mockpp.h>
00033
00034 #include <cstdio>
00035 #include <cctype>
00036
00037 #include <mockpp/compat/Formatter.h>
00038 #include <mockpp/compat/Asserter.h>
00039 #include <mockpp/compat/AssertionFailedError.h>
00040
00041
00042 MOCKPP_NS_START
00043
00044 #undef MOCKPP_ENABLE_DEFAULT_FORMATTER // one never knows..
00045
00046
00047 MOCKPP_ANON_NS_START
00048
00052 template <typename T, typename uT>
00053 MOCKPP_API_IMPL(MOCKPP_NS::String) number_stpl( T n, unsigned base )
00054 {
00055 if ( base < 2 || base > 36 )
00056 {
00057 MOCKPP_NS::String fmt = mockpp_i18n( MOCKPP_PCHAR( "Conversion of T to String: base %1 not allowed" ) );
00058 fmt << number( ( uT ) base, 10 );
00059 MOCKPP_NS::assertionFailed( __LINE__, __FILE__, fmt );
00060 }
00061
00062 MOCKPP_NS::Char charbuf[ sizeof(T) * 65 * sizeof( MOCKPP_NS::Char ) ];
00063 MOCKPP_NS::Char *buf = ( MOCKPP_NS::Char* ) charbuf;
00064 MOCKPP_NS::Char *p = &buf[ sizeof(T) * 64 ];
00065 *p = MOCKPP_CHAR( '\0' );
00066 int len = 0;
00067 bool neg;
00068 if ( n < 0 )
00069 {
00070 neg = true;
00071 #ifdef HAVE_LIMITS
00072 if ( n == MOCKPP_STD_NS::numeric_limits<T>::min() )
00073 #else
00074 if ( n == INT_MIN )
00075 #endif
00076 {
00077 MOCKPP_NS::String s1, s2;
00078 s1 = number( n / ( T ) base, base );
00079 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00080 s2 = number( ( unsigned T ) ( -( n + ( T ) base ) ) % base, base );
00081 #else
00082 s2 = number( ( -( n + ( T ) base ) ) % base, base );
00083 #endif
00084 return s1 + s2;
00085 }
00086 n = -n;
00087 }
00088 else
00089 {
00090 neg = false;
00091 }
00092
00093 do
00094 {
00095 *--p = MOCKPP_PCHAR( "0123456789abcdefghijklmnopqrstuvwxyz" ) [ ( ( int ) ( n % base ) ) ];
00096 n /= base;
00097 len++;
00098 }
00099 while ( n );
00100
00101 if ( neg )
00102 {
00103 *--p = MOCKPP_CHAR( '-' );
00104 len++;
00105 }
00106 return p;
00107 }
00108
00109 MOCKPP_NS_END
00110
00111
00112 MOCKPP_API_IMPL(MOCKPP_NS::String) number( long n, unsigned base )
00113 {
00114 return number_stpl<long, unsigned long>(n, base);
00115 }
00116
00117
00118 #ifndef UPS_NO_LONG_LONG
00119
00120 MOCKPP_API_IMPL(MOCKPP_NS::String) number( long long n, unsigned base )
00121 {
00122 return number_stpl<long long, unsigned long long>(n, base);
00123 }
00124
00125 #endif
00126
00127 MOCKPP_ANON_NS_START
00128
00132 template <typename T>
00133 MOCKPP_API_IMPL(MOCKPP_NS::String) number_utpl(T n, unsigned base )
00134 {
00135 if ( base < 2 || base > 36 )
00136 {
00137 MOCKPP_NS::String fmt = mockpp_i18n( MOCKPP_PCHAR( "Conversion of unsigned T to String: base %1 not allowed" ) );
00138 fmt << number( ( T ) base, 10 );
00139 MOCKPP_NS::assertionFailed( __LINE__, __FILE__, fmt );
00140 }
00141
00142 MOCKPP_NS::Char charbuf[ sizeof(T) * 65 * sizeof( MOCKPP_NS::Char ) ];
00143 MOCKPP_NS::Char *buf = ( MOCKPP_NS::Char* ) charbuf;
00144 MOCKPP_NS::Char *p = &buf[ sizeof(T) * 64 ];
00145 int len = 0;
00146 *p = MOCKPP_CHAR( '\0' );
00147 do
00148 {
00149 *--p = MOCKPP_PCHAR( "0123456789abcdefghijklmnopqrstuvwxyz" ) [ ( ( int ) ( n % base ) ) ];
00150 n /= base;
00151 len++;
00152 }
00153 while ( n );
00154
00155 return p;
00156 }
00157
00158 MOCKPP_NS_END
00159
00160
00161 MOCKPP_API_IMPL(MOCKPP_NS::String) number( unsigned long n, unsigned base )
00162 {
00163 return number_utpl<unsigned long>(n, base);
00164 }
00165
00166
00167 #ifndef UPS_NO_LONG_LONG
00168
00169 MOCKPP_API_IMPL(MOCKPP_NS::String) number( unsigned long long n, unsigned base )
00170 {
00171 return number_utpl<unsigned long long>(n, base);
00172 }
00173
00174 #endif
00175
00176 namespace {
00177
00178 template<typename F, bool L>
00179 MOCKPP_NS::String floatConverter( F n, unsigned prec )
00180 {
00181 if ( prec > 99 )
00182 prec = 99;
00183
00184 char format[ 20 ];
00185 char buf[ 120 ];
00186 char *fs = format;
00187
00188 *fs++ = '%';
00189 if ( prec != 0 )
00190 {
00191 *fs++ = '.';
00192 if ( prec >= 10 )
00193 {
00194 *fs++ = prec / 10 + '0';
00195 *fs++ = prec % 10 + '0';
00196 }
00197 else
00198 *fs++ = prec + '0';
00199 }
00200
00201 if (L)
00202 *fs++ = 'L';
00203
00204 *fs++ = 'g';
00205 *fs = '\0';
00206 #if defined HAVE_SPRINTF_S
00207 sprintf_s( buf, format, n );
00208 #else
00209 MOCKPP_STD_NS::sprintf( buf, format, n );
00210 #endif
00211
00212 #ifdef MOCKPP_UNICODE
00213 return MOCKPP_NS::getUnicode( buf );
00214 #else
00215 return MOCKPP_NS::String( buf );
00216 #endif
00217 }
00218
00219 }
00220
00221
00222 MOCKPP_API_IMPL(MOCKPP_NS::String) number( double n, unsigned prec )
00223 {
00224 return floatConverter<double, false>(n, prec);
00225 }
00226
00227
00228 MOCKPP_API_IMPL(MOCKPP_NS::String) number( long double n, unsigned prec )
00229 {
00230 return floatConverter<long double, true>(n, prec);
00231 }
00232
00233
00237 static bool findArg( MOCKPP_NS::String &fmt, int& pos, int& len )
00238 {
00239 MOCKPP_NS::Char lowest = 0;
00240 for ( unsigned int i = 0; i < fmt.length(); i++ )
00241 {
00242 if ( fmt[ i ] == MOCKPP_CHAR( '%' ) && i + 1 < fmt.length() )
00243 {
00244 MOCKPP_NS::Char dig = fmt[ i + 1 ];
00245 if ( dig >= MOCKPP_CHAR( '0' ) && dig <= MOCKPP_CHAR( '9' ) )
00246 {
00247 if ( !lowest || dig < lowest )
00248 {
00249 lowest = dig;
00250 pos = i;
00251 len = 2;
00252 }
00253 }
00254 }
00255 }
00256 return lowest != 0;
00257 }
00258
00259
00260 MOCKPP_API_IMPL(String &) replaceFormatterString(MOCKPP_NS::String &formatter, const String &repdata)
00261 {
00262 int pos, len;
00263
00264 if ( !findArg(formatter, pos, len ) )
00265 fail(__LINE__, __FILE__, MOCKPP_PCHAR("No %-placeholder found to insert \'")
00266 + repdata
00267 + MOCKPP_PCHAR("\' into \'")
00268 + formatter
00269 + MOCKPP_PCHAR("\'"));
00270 else
00271 formatter.replace( pos, len, repdata);
00272
00273 return formatter;
00274 }
00275
00276
00280 static String charToReadable(unsigned x)
00281 {
00282 String text;
00283 #ifndef MOCKPP_MAKE_CHAR_READABLE
00284 text += x;
00285 #else
00286 #if (defined (_MSC_VER) && (_MSC_VER <= 1300)) || (defined (__GNUC__) && (__GNUC__ < 3))
00287 if (!isalnum(x))
00288 #else
00289 if (!MOCKPP_STD_NS::isalnum(x))
00290 #endif
00291 {
00292 text += MOCKPP_PCHAR("0x") + number((unsigned long)x, 16);
00293 }
00294 else
00295 {
00296 text += MOCKPP_PCHAR("{\"");
00297 text += x;
00298 text += MOCKPP_PCHAR("\", ");
00299 text += MOCKPP_PCHAR("0x") + number((unsigned long)x, 16);
00300 text += MOCKPP_PCHAR("}");
00301 }
00302 #endif
00303 return text;
00304 }
00305
00306
00307 MOCKPP_NS_END
00308
00309
00310 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const int &repdata )
00311 {
00312 formatter << MOCKPP_NS::number( ( long ) repdata );
00313 return formatter;
00314 }
00315
00316
00317 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const bool &repdata )
00318 {
00319 formatter << (repdata ? MOCKPP_PCHAR( "true" )
00320 : MOCKPP_PCHAR( "false" ));
00321 return formatter;
00322 }
00323
00324
00325 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const unsigned int &repdata )
00326 {
00327 formatter << MOCKPP_NS::number( ( unsigned long ) repdata );
00328 return formatter;
00329 }
00330
00331
00332 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const unsigned long &repdata )
00333 {
00334 formatter << MOCKPP_NS::number( repdata );
00335 return formatter;
00336 }
00337
00338
00339 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const signed char &repdata )
00340 {
00341 formatter << MOCKPP_NS::charToReadable(repdata);
00342 return formatter;
00343 }
00344
00345
00346 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const char &repdata )
00347 {
00348 formatter << MOCKPP_NS::charToReadable(repdata);
00349 return formatter;
00350 }
00351
00352
00353 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const unsigned char &repdata )
00354 {
00355 formatter << MOCKPP_NS::charToReadable(repdata);
00356 return formatter;
00357 }
00358
00359
00360 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const char *repdata )
00361 {
00362 formatter << MOCKPP_STL::string(repdata);
00363 return formatter;
00364 }
00365
00366
00367 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const float &repdata )
00368 {
00369 formatter << MOCKPP_NS::number( (double) repdata );
00370 return formatter;
00371 }
00372
00373
00374 #ifdef MOCKPP_UNICODE
00375
00376 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const wchar_t &repdata )
00377 {
00378 formatter << MOCKPP_NS::charToReadable(repdata);
00379 return formatter;
00380 }
00381
00382
00383 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const wchar_t * repdata )
00384 {
00385 formatter << MOCKPP_NS::String(repdata);
00386 return formatter;
00387 }
00388
00389 #endif
00390
00391
00392 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const long &repdata )
00393 {
00394 formatter << MOCKPP_NS::number( repdata );
00395 return formatter;
00396 }
00397
00398
00399 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const double &repdata )
00400 {
00401 formatter << MOCKPP_NS::number( repdata );
00402 return formatter;
00403 }
00404
00405
00406 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const long double &repdata )
00407 {
00408 formatter << MOCKPP_NS::number( repdata );
00409 return formatter;
00410 }
00411
00412
00413 #ifdef MOCKPP_UNICODE
00414
00415 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << ( MOCKPP_NS::String &formatter, const MOCKPP_STL::string &str )
00416 {
00417 formatter << MOCKPP_NS::getUnicode( str );
00418 return formatter;
00419 }
00420
00421 #else
00422
00423
00424
00425
00426
00427
00428
00429 #endif
00430
00431
00432 MOCKPP_API_IMPL(MOCKPP_NS::String &) operator << (MOCKPP_NS::String &formatter, const MOCKPP_NS::String &repdata)
00433 {
00434 return MOCKPP_NS::replaceFormatterString(formatter, repdata);
00435 }
00436
00437