void __kmp_str_to_uint( // R: Error code. char const * str, // I: String of characters, unsigned number. kmp_uint64 * out, // O: Parsed number. char const * * error // O: Null if everything is ok, error message otherwise. ) { size_t value = 0; int overflow = 0; int i = 0; int digit; KMP_DEBUG_ASSERT( str != NULL ); // Skip spaces. while ( str[ i ] == ' ' || str[ i ] == '\t' ) { ++ i; }; // while // Parse number. if ( str[ i ] < '0' || str[ i ] > '9' ) { * error = KMP_I18N_STR( NotANumber ); return; }; // if do { digit = str[ i ] - '0'; overflow = overflow || ( value > ( KMP_SIZE_T_MAX - digit ) / 10 ); value = ( value * 10 ) + digit; ++ i; } while ( str[ i ] >= '0' && str[ i ] <= '9' ); // Skip spaces. while ( str[ i ] == ' ' || str[ i ] == '\t' ) { ++ i; }; // while if ( str[ i ] != 0 ) { * error = KMP_I18N_STR( IllegalCharacters ); return; }; // if if ( overflow ) { * error = KMP_I18N_STR( ValueTooLarge ); * out = (kmp_uint64) -1; return; }; // if * error = NULL; * out = value; } // __kmp_str_to_unit
int __kmp_debug_assert( char const * msg, char const * file, int line ) { if ( file == NULL ) { file = KMP_I18N_STR( UnknownFile ); } else { // Remove directories from path, leave only file name. File name is enough, there is no need // in bothering developers and customers with full paths. char const * slash = strrchr( file, '/' ); if ( slash != NULL ) { file = slash + 1; }; // if }; // if #ifdef KMP_DEBUG __kmp_acquire_bootstrap_lock( & __kmp_stdio_lock ); __kmp_debug_printf( "Assertion failure at %s(%d): %s.\n", file, line, msg ); __kmp_release_bootstrap_lock( & __kmp_stdio_lock ); #ifdef USE_ASSERT_BREAK #if KMP_OS_WINDOWS DebugBreak(); #endif #endif // USE_ASSERT_BREAK #ifdef USE_ASSERT_STALL /* __kmp_infinite_loop(); */ for(;;); #endif // USE_ASSERT_STALL #ifdef USE_ASSERT_SEG { int volatile * ZERO = (int*) 0; ++ (*ZERO); } #endif // USE_ASSERT_SEG #endif __kmp_msg( kmp_ms_fatal, KMP_MSG( AssertionFailure, file, line ), KMP_HNT( SubmitBugReport ), __kmp_msg_null ); return 0; } // __kmp_debug_assert
/* The routine parses input string. It is expected it is a unsigned integer with optional unit. Units are: "b" for bytes, "kb" or just "k" for kilobytes, "mb" or "m" for megabytes, ..., "yb" or "y" for yottabytes. :-) Unit name is case-insensitive. The routine returns 0 if everything is ok, or error code: -1 in case of overflow, -2 in case of unknown unit. *size is set to parsed value. In case of overflow *size is set to KMP_SIZE_T_MAX, in case of unknown unit *size is set to zero. */ void __kmp_str_to_size( // R: Error code. char const * str, // I: String of characters, unsigned number and unit ("b", "kb", etc). size_t * out, // O: Parsed number. size_t dfactor, // I: The factor if none of the letters specified. char const * * error // O: Null if everything is ok, error message otherwise. ) { size_t value = 0; size_t factor = 0; int overflow = 0; int bad_unit = 0; int i = 0; int digit; KMP_DEBUG_ASSERT( str != NULL ); // Skip spaces. while ( str[ i ] == ' ' || str[ i ] == '\t') { ++ i; }; // while // Parse number. if ( str[ i ] < '0' || str[ i ] > '9' ) { * error = KMP_I18N_STR( NotANumber ); return; }; // if do { digit = str[ i ] - '0'; overflow = overflow || ( value > ( KMP_SIZE_T_MAX - digit ) / 10 ); value = ( value * 10 ) + digit; ++ i; } while ( str[ i ] >= '0' && str[ i ] <= '9' ); // Skip spaces. while ( str[ i ] == ' ' || str[ i ] == '\t' ) { ++ i; }; // while // Parse unit. #define _case( ch, exp ) \ case ch : \ case ch - ( 'a' - 'A' ) : { \ size_t shift = (exp) * 10; \ ++ i; \ if ( shift < sizeof( size_t ) * 8 ) { \ factor = (size_t)( 1 ) << shift; \ } else { \ overflow = 1; \ }; \ } break; switch ( str[ i ] ) { _case( 'k', 1 ); // Kilo _case( 'm', 2 ); // Mega _case( 'g', 3 ); // Giga _case( 't', 4 ); // Tera _case( 'p', 5 ); // Peta _case( 'e', 6 ); // Exa _case( 'z', 7 ); // Zetta _case( 'y', 8 ); // Yotta // Oops. No more units... }; // switch #undef _case if ( str[ i ] == 'b' || str[ i ] == 'B' ) { // Skip optional "b". if ( factor == 0 ) { factor = 1; } ++ i; }; // if if ( ! ( str[ i ] == ' ' || str[ i ] == '\t' || str[ i ] == 0 ) ) { // Bad unit * error = KMP_I18N_STR( BadUnit ); return; }; // if if ( factor == 0 ) { factor = dfactor; } // Apply factor. overflow = overflow || ( value > ( KMP_SIZE_T_MAX / factor ) ); value *= factor; // Skip spaces. while ( str[ i ] == ' ' || str[ i ] == '\t' ) { ++ i; }; // while if ( str[ i ] != 0 ) { * error = KMP_I18N_STR( IllegalCharacters ); return; }; // if if ( overflow ) { * error = KMP_I18N_STR( ValueTooLarge ); * out = KMP_SIZE_T_MAX; return; }; // if * error = NULL; * out = value; } // __kmp_str_to_size