DECLARE_TEST(stacktrace, resolve) { #define TEST_DEPTH 64 void* trace[TEST_DEPTH]; size_t num_frames; char* buffer; string_t resolved; if (system_platform() == PLATFORM_PNACL) return 0; num_frames = stacktrace_capture(trace, TEST_DEPTH, 0); EXPECT_GT(num_frames, 3); buffer = memory_allocate(0, 1024, 0, MEMORY_TEMPORARY); resolved = stacktrace_resolve(buffer, 1024, trace, num_frames, 0); EXPECT_NE(resolved.str, 0); EXPECT_NE(resolved.length, 0); //log_infof(HASH_TEST, STRING_CONST("Resolved stack trace:\n%.*s"), (int)resolved.length, // resolved.str); #if !FOUNDATION_PLATFORM_ANDROID && !(FOUNDATION_PLATFORM_WINDOWS && (FOUNDATION_COMPILER_GCC || FOUNDATION_COMPILER_CLANG)) EXPECT_NE(string_find_string(resolved.str, resolved.length, STRING_CONST("stacktraceresolve_fn"), 0), STRING_NPOS); EXPECT_NE(string_find_string(resolved.str, resolved.length, STRING_CONST("main"), 0), STRING_NPOS); #endif memory_deallocate(buffer); return 0; }
DECLARE_TEST(environment, builtin) { const string_const_t* cmdline = environment_command_line(); EXPECT_GE(array_size(cmdline), 1); #if !BUILD_MONOLITHIC EXPECT_NE_MSGFORMAT(string_find_string(STRING_ARGS(cmdline[0]), STRING_CONST("test-environment"), 0), STRING_NPOS, "Commandline: %.*s", (int)cmdline[0].length, cmdline[0].str); EXPECT_CONSTSTRINGEQ(environment_executable_name(), string_const(STRING_CONST("test-environment"))); #elif FOUNDATION_PLATFORM_ANDROID EXPECT_NE_MSGFORMAT(string_find_string(STRING_ARGS(cmdline[0]), STRING_CONST("com.rampantpixels.foundation.test"), 0), STRING_NPOS, "Commandline: %.*s", (int)cmdline[0].length, cmdline[0].str); #elif !FOUNDATION_PLATFORM_PNACL EXPECT_NE_MSGFORMAT(string_find_string(STRING_ARGS(cmdline[0]), STRING_CONST("test-all"), 0), STRING_NPOS, "Commandline: %.*s", (int)cmdline[0].length, cmdline[0].str); EXPECT_CONSTSTRINGEQ(environment_executable_name(), string_const(STRING_CONST("test-all"))); #endif EXPECT_NE(environment_initial_working_directory().str, 0); EXPECT_NE(environment_initial_working_directory().length, 0); EXPECT_CONSTSTRINGEQ(environment_initial_working_directory(), environment_current_working_directory()); EXPECT_NE(environment_home_directory().str, 0); EXPECT_NE(environment_home_directory().length, 0); EXPECT_NE(environment_temporary_directory().str, 0); EXPECT_NE(environment_temporary_directory().length, 0); #if !FOUNDATION_PLATFORM_PNACL EXPECT_NE(environment_variable(STRING_CONST("PATH")).str, 0); EXPECT_NE(environment_variable(STRING_CONST("PATH")).length, 0); #endif return 0; }
DECLARE_TEST( environment, builtin ) { char const* const* cmdline = environment_command_line(); EXPECT_GE( array_size( cmdline ), 1 ); #if !BUILD_MONOLITHIC EXPECT_NE_MSGFORMAT( string_find_string( cmdline[0], "test-environment", 0 ), STRING_NPOS, "Commandline: %s", cmdline[0] ); EXPECT_STREQ( environment_executable_name(), "test-environment" ); #elif FOUNDATION_PLATFORM_ANDROID EXPECT_NE_MSGFORMAT( string_find_string( cmdline[0], "com.rampantpixels.foundation.test", 0 ), STRING_NPOS, "Commandline: %s", cmdline[0] ); #elif !FOUNDATION_PLATFORM_PNACL EXPECT_NE_MSGFORMAT( string_find_string( cmdline[0], "test-all", 0 ), STRING_NPOS, "Commandline: %s", cmdline[0] ); EXPECT_STREQ( environment_executable_name(), "test-all" ); #endif EXPECT_NE( environment_initial_working_directory(), 0 ); EXPECT_NE( string_length( environment_initial_working_directory() ), 0 ); EXPECT_STREQ( environment_initial_working_directory(), environment_current_working_directory() ); EXPECT_NE( environment_home_directory(), 0 ); EXPECT_NE( string_length( environment_home_directory() ), 0 ); EXPECT_NE( environment_temporary_directory(), 0 ); EXPECT_NE( string_length( environment_temporary_directory() ), 0 ); #if !FOUNDATION_PLATFORM_PNACL EXPECT_NE( environment_variable( "PATH" ), 0 ); EXPECT_NE( string_length( environment_variable( "PATH" ) ), 0 ); #endif return 0; }
static NOINLINE char* _expand_string( hash_t section_current, char* str ) { char* expanded; char* variable; unsigned int var_pos, var_end_pos, variable_length, separator, var_offset; hash_t section, key; expanded = str; var_pos = string_find_string( expanded, "$(", 0 ); while( var_pos != STRING_NPOS ) { var_end_pos = string_find( expanded, ')', var_pos + 2 ); FOUNDATION_ASSERT_MSG( var_end_pos != STRING_NPOS, "Malformed config variable statement" ); variable = string_substr( expanded, var_pos, ( var_end_pos != STRING_NPOS ) ? ( 1 + var_end_pos - var_pos ) : STRING_NPOS ); section = section_current; key = 0; variable_length = string_length( variable ); separator = string_find( variable, ':', 0 ); if( separator != STRING_NPOS ) { if( separator != 2 ) section = hash( variable + 2, separator - 2 ); var_offset = separator + 1; } else { var_offset = 2; } key = hash( variable + var_offset, variable_length - ( var_offset + ( variable[ variable_length - 1 ] == ')' ? 1 : 0 ) ) ); if( expanded == str ) expanded = string_clone( str ); if( section != HASH_ENVIRONMENT ) expanded = string_replace( expanded, variable, config_string( section, key ), false ); else expanded = string_replace( expanded, variable, _expand_environment( key, variable + var_offset ), false ); string_deallocate( variable ); var_pos = string_find_string( expanded, "$(", 0 ); } #if BUILD_ENABLE_DEBUG_CONFIG if( str != expanded ) log_debugf( HASH_CONFIG, "Expanded config value \"%s\" to \"%s\"", str, expanded ); #endif return expanded; }
char* path_protocol( const char* uri ) { unsigned int end = string_find_string( uri, "://", 0 ); if( end == STRING_NPOS ) return string_allocate( 0 ); return string_substr( uri, 0, end ); }
stream_t* stream_open( const char* path, unsigned int mode ) { unsigned int protocol_end; //Check if protocol was given protocol_end = string_find_string( path, "://", 0 ); if( protocol_end != STRING_NPOS ) { //TODO: Proper pluggable protocol handling #if FOUNDATION_PLATFORM_ANDROID if( ( protocol_end == 5 ) && string_equal_substr( path, "asset", 5 ) ) return asset_stream_open( path, mode ); else #endif if( ( protocol_end == 4 ) && string_equal_substr( path, "file", 4 ) ) return fs_open_file( path, mode ); else if( ( protocol_end == 4 ) && string_equal_substr( path, "stdout", 4 ) ) return stream_open_stdout(); else if( ( protocol_end == 4 ) && string_equal_substr( path, "stderr", 4 ) ) return stream_open_stderr(); else if( ( protocol_end == 4 ) && string_equal_substr( path, "stdin", 4 ) ) return stream_open_stdin(); else if( ( protocol_end != 3 ) || !string_equal_substr( path, "vfs", protocol_end ) ) { log_errorf( 0, ERROR_INVALID_VALUE, "Invalid protocol: %s", path ); return 0; } } //No protocol, assume virtual file system path //TODO: Virtual file system return fs_open_file( path, mode ); }
DECLARE_TEST( environment, builtin ) { char const* const* cmdline = environment_command_line(); EXPECT_GE( array_size( cmdline ), 1 ); #if !FOUNDATION_PLATFORM_ANDROID && !FOUNDATION_PLATFORM_IOS EXPECT_NE( string_find_string( cmdline[0], "test-environment", 0 ), STRING_NPOS ); EXPECT_STREQ( environment_executable_name(), "test-environment" ); #endif EXPECT_NE( environment_initial_working_directory(), 0 ); EXPECT_NE( string_length( environment_initial_working_directory() ), 0 ); EXPECT_STREQ( environment_initial_working_directory(), environment_current_working_directory() ); EXPECT_NE( environment_home_directory(), 0 ); EXPECT_NE( string_length( environment_home_directory() ), 0 ); EXPECT_NE( environment_temporary_directory(), 0 ); EXPECT_NE( string_length( environment_temporary_directory() ), 0 ); EXPECT_NE( environment_variable( "PATH" ), 0 ); EXPECT_NE( string_length( environment_variable( "PATH" ) ), 0 ); return 0; }
int hashify_generate_preamble(stream_t* output_file, string_t output_filename) { //Read and preserve everything before #pragma once in case it contains header comments to be preserved char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; size_t capacity = 1024; string_t preamble = string_allocate(0, capacity); stream_t* prev_file = stream_open(STRING_ARGS(output_filename), STREAM_IN); memset(line_buffer, 0, sizeof(line_buffer)); while (prev_file && !stream_eos(prev_file)) { string_t line; string_const_t stripped_line; line = stream_read_line_buffer(prev_file, line_buffer, sizeof(line_buffer), '\n'); stripped_line = string_strip(STRING_ARGS(line), STRING_CONST("\n\r")); if ((string_find_string(STRING_ARGS(stripped_line), STRING_CONST("pragma"), 0) != STRING_NPOS) && (string_find_string(STRING_ARGS(stripped_line), STRING_CONST("once"), 0) != STRING_NPOS)) break; if (preamble.length + stripped_line.length + 1 >= capacity) { size_t newcapacity = capacity + 1024 + stripped_line.length; preamble.str = memory_reallocate(preamble.str, newcapacity, 0, capacity); capacity = newcapacity; } preamble = string_append(STRING_ARGS(preamble), capacity, STRING_ARGS(stripped_line)); if (line.length < sizeof(line_buffer)) preamble = string_append(STRING_ARGS(preamble), capacity, STRING_CONST(STRING_NEWLINE)); } stream_deallocate(prev_file); stream_seek(output_file, 0, STREAM_SEEK_BEGIN); if (preamble.length) stream_write_string(output_file, STRING_ARGS(preamble)); stream_write_string(output_file, STRING_CONST( "#pragma once\n\n" "#include <foundation/hash.h>\n\n" "/* ****** AUTOMATICALLY GENERATED, DO NOT EDIT ******\n" " Edit corresponding definitions file and rerun\n" " the foundation hashify tool to update this file */\n\n" )); string_deallocate(preamble.str); return 0; }
char* path_subdirectory_name( const char* path, const char* root ) { char* subpath; char* testpath; char* testroot; char* pathofpath; unsigned int pathprotocol, rootprotocol; char* cpath = string_clone( path ); char* croot = string_clone( root ); cpath = path_clean( cpath, path_is_absolute( cpath ) ); croot = path_clean( croot, path_is_absolute( croot ) ); pathofpath = path_directory_name( cpath ); testpath = pathofpath; pathprotocol = string_find_string( testpath, "://", 0 ); if( pathprotocol != STRING_NPOS ) testpath += pathprotocol + 2; // add two to treat as absolute path testroot = croot; rootprotocol = string_find_string( testroot, "://", 0 ); if( rootprotocol != STRING_NPOS ) testroot += rootprotocol + 2; if( ( rootprotocol != STRING_NPOS ) && ( ( pathprotocol == STRING_NPOS ) || ( pathprotocol != rootprotocol ) || !string_equal_substr( cpath, croot, rootprotocol ) ) ) subpath = string_allocate( 0 ); else if( !string_equal_substr( testpath, testroot, string_length( testroot ) ) ) subpath = string_allocate( 0 ); else { char* filename = path_file_name( cpath ); subpath = string_substr( testpath, string_length( testroot ), STRING_NPOS ); subpath = path_clean( path_append( subpath, filename ), false ); string_deallocate( filename ); } string_deallocate( pathofpath ); string_deallocate( cpath ); string_deallocate( croot ); return subpath; }
static renderimport_type_t render_import_shader_guess_type(stream_t* stream) { renderimport_type_t type = IMPORTTYPE_UNKNOWN; char buffer[1024]; while (!stream_eos(stream)) { string_t line = stream_read_line_buffer(stream, buffer, sizeof(buffer), '\n'); if (string_find_string(STRING_ARGS(line), STRING_CONST("gl_FragColor"), 0) != STRING_NPOS) { type = IMPORTTYPE_GLSL_PIXELSHADER; break; } else if (string_find_string(STRING_ARGS(line), STRING_CONST("gl_Position"), 0) != STRING_NPOS) { type = IMPORTTYPE_GLSL_VERTEXSHADER; break; } } stream_seek(stream, 0, STREAM_SEEK_BEGIN); return type; }
stream_t* stream_open(const char* path, size_t length, unsigned int mode) { size_t protocol_end; stream_open_fn open_fn; //Check if protocol was given protocol_end = string_find_string(path, length, STRING_CONST("://"), 0); open_fn = stream_protocol_handler((protocol_end != STRING_NPOS) ? path : "", (protocol_end != STRING_NPOS) ? protocol_end : 0); return open_fn ? open_fn(path, length, mode) : 0; }
int hashify_read_hashes(stream_t* file, hashify_string_t** hashes) { //Read in hashes in file char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; string_const_t tokens[32]; memset(line_buffer, 0, sizeof(line_buffer)); do { string_t line = stream_read_line_buffer(file, line_buffer, sizeof(line_buffer), '\n'); string_const_t stripped_line = string_strip(STRING_ARGS(line), STRING_CONST("\n\r")); if ((string_find_string(STRING_ARGS(stripped_line), STRING_CONST("define"), 0) != STRING_NPOS) && (string_find_string(STRING_ARGS(stripped_line), STRING_CONST("static_hash"), 0) != STRING_NPOS)) { //Format is: #define HASH_<hashstring> static_hash_string( "<string>", 0x<hashvalue>ULL ) size_t num_tokens = string_explode(STRING_ARGS(stripped_line), STRING_CONST(" \t"), tokens, 32, false); if (num_tokens >= 6) { hashify_string_t hash_string; string_const_t stripped = string_strip(STRING_ARGS(tokens[3]), STRING_CONST(",")); stripped = string_strip(STRING_ARGS(stripped), STRING_CONST("\"")); hash_string.string = string_copy(hash_string.buffer, HASHIFY_STRING_LENGTH, STRING_ARGS(stripped)); hash_string.hash = string_to_uint64(STRING_ARGS(tokens[4]), true); if (hash(STRING_ARGS(hash_string.string)) != hash_string.hash) { log_errorf(0, ERROR_INVALID_VALUE, STRING_CONST(" hash output file is out of date, %.*s is set to 0x%" PRIx64 " but should be 0x%" PRIx64), STRING_FORMAT(hash_string.string), hash_string.hash, hash(STRING_ARGS(hash_string.string))); return HASHIFY_RESULT_OUTPUT_FILE_OUT_OF_DATE; } array_push_memcpy(*hashes, &hash_string); } } } while (!stream_eos(file)); return 0; }
int hashify_read_hashes( stream_t* file, hashify_string_t** hashes ) { //Read in hashes in file char* line; char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; do { stream_read_line_buffer( file, line_buffer, HASHIFY_LINEBUFFER_LENGTH-1, '\n' ); line = string_strip( line_buffer, "\n\r" ); if( ( string_find_string( line, "define", 0 ) != STRING_NPOS ) && ( string_find_string( line, "static_hash", 0 ) != STRING_NPOS ) ) { //Format is: #define HASH_<hashstring> static_hash_string( "<string>", 0x<hashvalue>ULL ) char** tokens = string_explode( line, " \t", false ); if( array_size( tokens ) >= 6 ) { hashify_string_t hash_string; string_copy( hash_string.string, string_strip( string_strip( tokens[3], "," ), "\"" ), HASHIFY_STRING_LENGTH ); hash_string.hash = string_to_uint64( tokens[4], true ); if( hash( hash_string.string, string_length( hash_string.string ) ) != hash_string.hash ) { log_errorf( ERROR_INVALID_VALUE, " hash output file is out of date, %s is set to 0x%llx but should be 0x%llx ", hash_string.string, hash_string.hash, hash( hash_string.string, string_length( hash_string.string ) ) ); string_array_deallocate( tokens ); return HASHIFY_RESULT_OUTPUT_FILE_OUT_OF_DATE; } array_push_memcpy( *hashes, &hash_string ); } string_array_deallocate( tokens ); } } while( !stream_eos( file ) ); return 0; }
PluginData* PluginHandler_findPluginByFilename(const char* filename) { for (int i = 0; i < PRODBG_PLUGIN_COUNT; ++i) { int count = array_size(s_plugins[i]); for (int t = 0; t < count; ++t) { PluginData* pluginData = s_plugins[i][t]; if (string_find_string(pluginData->fullFilename, filename, 0) != STRING_NPOS) return pluginData; } } return 0; }
DECLARE_TEST( stacktrace, resolve ) { #define TEST_DEPTH 64 void* trace[TEST_DEPTH]; unsigned int num_frames = 0; char* resolved = 0; num_frames = stacktrace_capture( trace, TEST_DEPTH, 0 ); EXPECT_GT( num_frames, 3 ); resolved = stacktrace_resolve( trace, num_frames, 0 ); EXPECT_NE( resolved, 0 ); log_infof( HASH_TEST, "Resolved stack trace:\n%s", resolved ); EXPECT_NE( string_find_string( resolved, "stacktraceresolve_fn", 0 ), STRING_NPOS ); EXPECT_NE( string_find_string( resolved, "test_run", 0 ), STRING_NPOS ); //EXPECT_NE( string_find_string( resolved, "main_run", 0 ), STRING_NPOS ); memory_deallocate( resolved ); return 0; }
int hashify_generate_preamble( stream_t* output_file ) { //Read and preserve everything before #pragma once in case it contains header comments to be preserved char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; char* preamble = 0; while( !stream_eos( output_file ) ) { char* line; uint64_t read; read = stream_read_line_buffer( output_file, line_buffer, HASHIFY_LINEBUFFER_LENGTH-1, '\n' ); line = string_strip( line_buffer, "\n\r" ); if( ( string_find_string( line, "pragma", 0 ) != STRING_NPOS ) && ( string_find_string( line, "once", 0 ) != STRING_NPOS ) ) break; preamble = string_append( preamble, line ); if( read < HASHIFY_LINEBUFFER_LENGTH ) preamble = string_append( preamble, "\n" ); } stream_seek( output_file, 0, STREAM_SEEK_BEGIN ); stream_write_string( output_file, preamble ); stream_write_string( output_file, "#pragma once\n\n" "#include <foundation/foundation.h>\n\n" "/* ****** AUTOMATICALLY GENERATED, DO NOT EDIT ******\n" " Edit corresponding definitions file and rerun\n" " the foundation hashify tool to update this file */\n\n" ); string_deallocate( preamble ); return 0; }
char* path_directory_name( const char* path ) { char* pathname; unsigned int pathprotocol; unsigned int pathstart = 0; unsigned int end = string_find_last_of( path , "/\\", STRING_NPOS ); if( end == 0 ) return string_clone( "/" ); if( end == STRING_NPOS ) return string_allocate( 0 ); pathprotocol = string_find_string( path, "://", 0 ); if( pathprotocol != STRING_NPOS ) pathstart = pathprotocol +=2; // add two to treat as absolute path pathname = string_substr( path, pathstart, end - pathstart ); pathname = path_clean( pathname, path_is_absolute( pathname ) ); return pathname; }
void config_set_string( hash_t section, hash_t key, const char* value ) { config_key_t* key_val = config_key( section, key, true ); if( !FOUNDATION_VALIDATE( key_val ) ) return; if( key_val->expanded != key_val->sval ) string_deallocate( key_val->expanded ); if( ( key_val->type != CONFIGVALUE_STRING_CONST ) && ( key_val->type != CONFIGVALUE_STRING_CONST_VAR ) ) string_deallocate( key_val->sval ); key_val->sval = string_clone( value ); key_val->expanded = 0; key_val->type = ( ( string_find_string( key_val->sval, "$(", 0 ) != STRING_NPOS ) ? CONFIGVALUE_STRING_VAR : CONFIGVALUE_STRING ); if( key_val->type == CONFIGVALUE_STRING ) { bool is_true = string_equal( key_val->sval, "true" ); key_val->bval = ( string_equal( key_val->sval, "false" ) || string_equal( key_val->sval, "0" ) || !string_length( key_val->sval ) ) ? false : true; key_val->ival = is_true ? 1 : _config_string_to_int( key_val->sval ); key_val->rval = is_true ? REAL_C(1.0) : _config_string_to_real( key_val->sval ); } }
void config_set_string_constant( hash_t section, hash_t key, const char* value ) { config_key_t* key_val = config_key( section, key, true ); if( !FOUNDATION_VALIDATE( key_val ) ) return; if( !FOUNDATION_VALIDATE( value ) ) return; if( key_val->expanded != key_val->sval ) string_deallocate( key_val->expanded ); if( ( key_val->type != CONFIGVALUE_STRING_CONST ) && ( key_val->type != CONFIGVALUE_STRING_CONST_VAR ) ) string_deallocate( key_val->sval ); //key_val->sval = (char*)value; memcpy( &key_val->sval, &value, sizeof( char* ) ); //Yeah yeah, we're storing a const pointer in a non-const var key_val->expanded = 0; key_val->type = ( ( string_find_string( key_val->sval, "$(", 0 ) != STRING_NPOS ) ? CONFIGVALUE_STRING_CONST_VAR : CONFIGVALUE_STRING_CONST ); if( key_val->type == CONFIGVALUE_STRING_CONST ) { bool is_true = string_equal( key_val->sval, "true" ); key_val->bval = ( string_equal( key_val->sval, "false" ) || string_equal( key_val->sval, "0" ) || !string_length( key_val->sval ) ) ? false : true; key_val->ival = is_true ? 1 : _config_string_to_int( key_val->sval ); key_val->rval = is_true ? REAL_C(1.0) : _config_string_to_real( key_val->sval ); } }
DECLARE_TEST(error, output) { #if BUILD_ENABLE_LOG error_handler_fn handler_error = error_handler(); log_handler_fn handler_log = log_handler(); string_const_t shortmsg = string_const(STRING_CONST("Short message with prefix")); string_const_t longmsg = string_const(STRING_CONST("Longer message which should be output without a prefix")); error_set_handler(ignore_error_handler); log_set_handler(log_verify_handler); log_enable_stdout(false); EXPECT_EQ(log_stdout(), false); log_warn(HASH_TEST, WARNING_SUSPICIOUS, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(log_stdout(), true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_WARNING); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("WARNING [suspicious]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_warn(HASH_TEST, (warning_t)0x1000, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_WARNING); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("WARNING [4096]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_prefix(false); log_enable_stdout(false); log_warn(HASH_TEST, WARNING_SYSTEM_CALL_FAIL, STRING_ARGS(longmsg)); log_enable_stdout(true); log_enable_prefix(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_WARNING); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), 0); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_error(HASH_TEST, ERROR_DEPRECATED, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_ERROR); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("ERROR [deprecated]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_error(HASH_TEST, (error_t)0x1000, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_ERROR); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("ERROR [4096]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_prefix(false); log_enable_stdout(false); log_error(HASH_TEST, ERROR_INVALID_VALUE, STRING_ARGS(longmsg)); log_enable_stdout(true); log_enable_prefix(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_ERROR); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), 0); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_panic(HASH_TEST, ERROR_DEPRECATED, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_PANIC); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("PANIC [deprecated]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_panic(HASH_TEST, (error_t)0x1000, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_PANIC); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("PANIC [4096]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_prefix(false); log_enable_stdout(false); log_panic(HASH_TEST, ERROR_INVALID_VALUE, STRING_ARGS(longmsg)); log_enable_stdout(true); log_enable_prefix(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_PANIC); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), 0); # if BUILD_ENABLE_ERROR_CONTEXT error_context_push(STRING_CONST("one"), STRING_CONST("dataone")); error_context_push(STRING_CONST("two"), STRING_CONST("datatwo")); error_context_push(STRING_CONST("three"), STRING_CONST("datathree")); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_error_context(HASH_TEST, ERRORLEVEL_INFO); log_enable_stdout(true); error_context_pop(); error_context_pop(); error_context_pop(); EXPECT_SIZEEQ(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("When one: dataone"), 0), STRING_NPOS); EXPECT_SIZEEQ(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("When two: datatwo"), 0), STRING_NPOS); EXPECT_SIZENE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("When three: datathree"), 0), STRING_NPOS); # endif log_set_handler(handler_log); error_set_handler(handler_error); #endif return 0; }
DECLARE_TEST( string, queries ) { { char teststr[] = ""; char teststr2[] = "test"; char teststr3[] = "testing long string with more than 16 characters"; char teststr4[] = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"; char* str1 = string_substr( teststr, 0, 0 ); char* str2 = string_substr( teststr2, 0, 4 ); char* str3 = string_substr( teststr2, 0, 20 ); char* str4 = string_substr( teststr3, 0, 0 ); char* str5 = string_substr( teststr3, 0, 10 ); char* str6 = string_substr( teststr3, 0, STRING_NPOS ); char* str7 = string_substr( teststr4, 0, 0 ); char* str8 = string_substr( teststr4, 0, 20 ); char* str9 = string_substr( teststr4, 0, STRING_NPOS ); EXPECT_EQ( 0, str1[0] ); EXPECT_EQ( 0, str2[ string_length( str2 ) ] ); EXPECT_EQ( 0, str3[ string_length( str3 ) ] ); EXPECT_EQ( 0, str4[ string_length( str4 ) ] ); EXPECT_EQ( 0, str5[ string_length( str5 ) ] ); EXPECT_EQ( 0, str6[ string_length( str6 ) ] ); EXPECT_EQ( 0, str7[ string_length( str7 ) ] ); EXPECT_EQ( 0, str8[ string_length( str8 ) ] ); EXPECT_EQ( 0, str9[ string_length( str9 ) ] ); EXPECT_EQ( strlen( teststr ), string_length( str1 ) ); EXPECT_EQ( strlen( teststr2 ), string_length( str2 ) ); EXPECT_EQ( strlen( teststr2 ), string_length( str3 ) ); EXPECT_EQ( 0U, string_length( str4 ) ); EXPECT_EQ( 10U, string_length( str5 ) ); EXPECT_EQ( strlen( teststr3 ), string_length( str6 ) ); EXPECT_EQ( 0U, string_length( str7 ) ); EXPECT_EQ( 20U, string_length( str8 ) ); EXPECT_EQ( strlen( teststr4 ), string_length( str9 ) ); string_deallocate( str1 ); string_deallocate( str2 ); string_deallocate( str3 ); string_deallocate( str4 ); string_deallocate( str5 ); string_deallocate( str6 ); string_deallocate( str7 ); string_deallocate( str8 ); string_deallocate( str9 ); } { //Only ASCII characters, so wstring->string conversion should not introduce any extra UTF-8 sequences wchar_t teststr[] = L""; wchar_t teststr2[] = L"test"; wchar_t teststr3[] = L"testing long string with more than 16 characters"; wchar_t teststr4[] = L"01234567890123456789012345678901234567890123456789012345678901234567890123456789"; char* str1 = string_allocate_from_wstring( teststr, 0 ); char* str2 = string_allocate_from_wstring( teststr2, 0 ); char* str3 = string_allocate_from_wstring( teststr2, 20 ); char* str4 = string_allocate_from_wstring( teststr3, 0 ); char* str5 = string_allocate_from_wstring( teststr3, 10 ); char* str6 = string_allocate_from_wstring( teststr3, STRING_NPOS ); char* str7 = string_allocate_from_wstring( teststr4, 0 ); char* str8 = string_allocate_from_wstring( teststr4, 20 ); char* str9 = string_allocate_from_wstring( teststr4, STRING_NPOS ); EXPECT_EQ( 0, str1[0] ); EXPECT_EQ( 0, str2[ string_length( str2 ) ] ); EXPECT_EQ( 0, str3[ string_length( str3 ) ] ); EXPECT_EQ( 0, str4[ string_length( str4 ) ] ); EXPECT_EQ( 0, str5[ string_length( str5 ) ] ); EXPECT_EQ( 0, str6[ string_length( str6 ) ] ); EXPECT_EQ( 0, str7[ string_length( str7 ) ] ); EXPECT_EQ( 0, str8[ string_length( str8 ) ] ); EXPECT_EQ( 0, str9[ string_length( str9 ) ] ); EXPECT_EQ( wcslen( teststr ), string_length( str1 ) ); EXPECT_EQ( wcslen( teststr2 ), string_length( str2 ) ); EXPECT_EQ( wcslen( teststr2 ), string_length( str3 ) ); EXPECT_EQ( wcslen( teststr3 ), string_length( str4 ) ); EXPECT_EQ( 10U, string_length( str5 ) ); EXPECT_EQ( wcslen( teststr3 ), string_length( str6 ) ); EXPECT_EQ( wcslen( teststr4 ), string_length( str7 ) ); EXPECT_EQ( 20U, string_length( str8 ) ); EXPECT_EQ( wcslen( teststr4 ), string_length( str9 ) ); string_deallocate( str1 ); string_deallocate( str2 ); string_deallocate( str3 ); string_deallocate( str4 ); string_deallocate( str5 ); string_deallocate( str6 ); string_deallocate( str7 ); string_deallocate( str8 ); string_deallocate( str9 ); } { char* emptystr = string_allocate( 0 ); char* shortstr = string_clone( "short string" ); char* longstr = string_clone( "testing utility string methods like finds, split, merge, explode and similar." ); { unsigned int find = string_find( longstr, ' ', 0 ); unsigned int find2 = string_find( longstr, 12, 0 ); unsigned int find3 = string_find( emptystr, ' ', 0 ); unsigned int find4 = string_find( shortstr, ' ', 0 ); unsigned int find5 = string_find( shortstr, 'z', 0 ); unsigned int findofs = string_find( longstr, ' ', find ); unsigned int findofs2 = string_find( longstr, ' ', find + 1 ); unsigned int findofs3 = string_find( longstr, 'z', 10 ); unsigned int findofs4 = string_find( emptystr, 'z', STRING_NPOS ); unsigned int findofs5 = string_find( shortstr, 's', 10 ); unsigned int findofs6 = string_find( shortstr, 's', findofs5 ); unsigned int findofs7 = string_find( shortstr, 't', 0 ); unsigned int findofs8 = string_find( shortstr, ' ', 5 ); unsigned int findofs9 = string_find( longstr, ' ', STRING_NPOS ); EXPECT_EQ( find, 7U ); EXPECT_EQ( find2, STRING_NPOS ); EXPECT_EQ( find3, STRING_NPOS ); EXPECT_EQ( find4, 5U ); EXPECT_EQ( find5, STRING_NPOS ); EXPECT_EQ( findofs, find ); EXPECT_EQ( findofs2, 15U ); EXPECT_EQ( findofs3, STRING_NPOS ); EXPECT_EQ( findofs4, STRING_NPOS ); EXPECT_EQ( findofs5, STRING_NPOS ); EXPECT_EQ( findofs6, STRING_NPOS ); EXPECT_EQ( findofs7, 4U ); EXPECT_EQ( findofs8, 5U ); EXPECT_EQ( findofs9, STRING_NPOS ); } { unsigned int rfind = string_rfind( longstr, ' ', STRING_NPOS ); unsigned int rfind2 = string_rfind( longstr, ';', STRING_NPOS ); unsigned int rfind3 = string_rfind( emptystr, ';', STRING_NPOS ); unsigned int rfind4 = string_rfind( shortstr, 's', STRING_NPOS ); unsigned int rfind5 = string_rfind( shortstr, 'z', STRING_NPOS ); unsigned int rfindofs = string_rfind( longstr, ' ', rfind ); unsigned int rfindofs2 = string_rfind( longstr, ' ', rfind - 1 ); unsigned int rfindofs3 = string_rfind( longstr, ' ', string_length( longstr ) - 1 ); unsigned int rfindofs4 = string_rfind( emptystr, ' ', 0 ); unsigned int rfindofs5 = string_rfind( longstr, ' ', 0 ); unsigned int rfindofs6 = string_rfind( shortstr, 's', 5 ); unsigned int rfindofs7 = string_rfind( shortstr, 's', 0 ); EXPECT_EQ( rfind, 68U ); EXPECT_EQ( rfind2, STRING_NPOS ); EXPECT_EQ( rfind3, STRING_NPOS ); EXPECT_EQ( rfind4, 6U ); EXPECT_EQ( rfind5, STRING_NPOS ); EXPECT_EQ( rfindofs, rfind ); EXPECT_EQ( rfindofs2, 64U ); EXPECT_EQ( rfindofs3, rfind ); EXPECT_EQ( rfindofs4, STRING_NPOS ); EXPECT_EQ( rfindofs5, STRING_NPOS ); EXPECT_EQ( rfindofs6, 0U ); EXPECT_EQ( rfindofs7, 0U ); } { unsigned int findstr = string_find_string( longstr, "st", 0 ); unsigned int findstr2 = string_find_string( longstr, "xwqz", 0 ); unsigned int findstr3 = string_find_string( emptystr, "xwqz", 0 ); unsigned int findstr4 = string_find_string( longstr, "", 0 ); unsigned int findstr5 = string_find_string( longstr, "dslike", 0 ); unsigned int findstr6 = string_find_string( shortstr, "rt", 0 ); unsigned int findstr7 = string_find_string( shortstr, "long key that does not exist", 0 ); unsigned int findstr8 = string_find_string( shortstr, "so", 0 ); unsigned int findstrofs = string_find_string( longstr, "st", findstr ); unsigned int findstrofs2 = string_find_string( longstr, "st", findstr + 1 ); unsigned int findstrofs3 = string_find_string( longstr, "xwqz", string_length( longstr ) ); unsigned int findstrofs4 = string_find_string( emptystr, "xwqz", string_length( emptystr ) ); unsigned int findstrofs5 = string_find_string( shortstr, "", 5 ); unsigned int findstrofs6 = string_find_string( shortstr, "string", 0 ); unsigned int findstrofs7 = string_find_string( shortstr, "string", 7 ); unsigned int findstrofs8 = string_find_string( longstr, "utility", 14 ); unsigned int findstrofs9 = string_find_string( longstr, "", string_length( longstr ) ); unsigned int findstrofs10 = string_find_string( longstr, "", STRING_NPOS ); unsigned int findstrofs11 = string_find_string( longstr, "string", STRING_NPOS ); EXPECT_EQ( findstr, 2U ); EXPECT_EQ( findstr2, STRING_NPOS ); EXPECT_EQ( findstr3, STRING_NPOS ); EXPECT_EQ( findstr4, 0U ); EXPECT_EQ( findstr5, STRING_NPOS ); EXPECT_EQ( findstr6, 3U ); EXPECT_EQ( findstr7, STRING_NPOS ); EXPECT_EQ( findstr8, STRING_NPOS ); EXPECT_EQ( findstrofs, findstr ); EXPECT_EQ( findstrofs2, 16U ); EXPECT_EQ( findstrofs3, STRING_NPOS ); EXPECT_EQ( findstrofs4, STRING_NPOS ); EXPECT_EQ( findstrofs5, 5U ); EXPECT_EQ( findstrofs6, 6U ); EXPECT_EQ( findstrofs7, STRING_NPOS ); EXPECT_EQ( findstrofs8, STRING_NPOS ); EXPECT_EQ( findstrofs9, strlen( longstr ) ); EXPECT_EQ( findstrofs10, STRING_NPOS ); EXPECT_EQ( findstrofs11, STRING_NPOS ); } { unsigned int rfindstr = string_rfind_string( longstr, ", ", STRING_NPOS ); unsigned int rfindstr2 = string_rfind_string( longstr, ":;", STRING_NPOS ); unsigned int rfindstr3 = string_rfind_string( emptystr, ":;", STRING_NPOS ); unsigned int rfindstr4 = string_rfind_string( longstr, "", STRING_NPOS ); unsigned int rfindstr5 = string_rfind_string( shortstr, "string", STRING_NPOS ); unsigned int rfindstr6 = string_rfind_string( shortstr, " tring", STRING_NPOS ); unsigned int rfindstrofs = string_rfind_string( longstr, ", ", rfindstr ); unsigned int rfindstrofs2 = string_rfind_string( longstr, ", ", rfindstr - 1 ); unsigned int rfindstrofs3 = string_rfind_string( longstr, ":;", 0 ); unsigned int rfindstrofs4 = string_rfind_string( emptystr, ":;", 0 ); unsigned int rfindstrofs5 = string_rfind_string( longstr, "", 5 ); unsigned int rfindstrofs6 = string_rfind_string( shortstr, "ort str", 6 ); unsigned int rfindstrofs7 = string_rfind_string( shortstr, "ort str", 1 ); EXPECT_EQ( rfindstr, 55U ); EXPECT_EQ( rfindstr2, STRING_NPOS ); EXPECT_EQ( rfindstr3, STRING_NPOS ); EXPECT_EQ( rfindstr4, strlen( longstr ) ); EXPECT_EQ( rfindstr5, 6U ); EXPECT_EQ( rfindstr6, STRING_NPOS ); EXPECT_EQ( rfindstrofs, rfindstr ); EXPECT_EQ( rfindstrofs2, 48U ); EXPECT_EQ( rfindstrofs3, STRING_NPOS ); EXPECT_EQ( rfindstrofs4, STRING_NPOS ); EXPECT_EQ( rfindstrofs5, 5U ); EXPECT_EQ( rfindstrofs6, 2U ); EXPECT_EQ( rfindstrofs7, STRING_NPOS ); } { unsigned int findof = string_find_first_of( longstr, "ui", 0 ); unsigned int findof2 = string_find_first_of( longstr, ";:", 0 ); unsigned int findof3 = string_find_first_of( emptystr, "", 0 ); unsigned int findof4 = string_find_first_of( emptystr, " ", 0 ); unsigned int findof5 = string_find_first_of( shortstr, "", 0 ); unsigned int findofofs = string_find_first_of( longstr, "ui", findof ); unsigned int findofofs2 = string_find_first_of( longstr, "ui", findof - 1 ); unsigned int findofofs3 = string_find_first_of( longstr, "ui", findof + 1 ); unsigned int findofofs4 = string_find_first_of( longstr, "ui", string_length( longstr ) ); unsigned int findofofs5 = string_find_first_of( emptystr, "", string_length( emptystr ) ); unsigned int findofofs6 = string_find_first_of( shortstr, "string", 6 ); unsigned int findofofs7 = string_find_first_of( shortstr, "", 6 ); unsigned int findofofs8 = string_find_first_of( longstr, "", 10 ); unsigned int findofofs9 = string_find_first_of( longstr, "", string_length( longstr ) ); EXPECT_EQ( findof, 4U ); EXPECT_EQ( findof2, STRING_NPOS ); EXPECT_EQ( findof3, STRING_NPOS ); EXPECT_EQ( findof4, STRING_NPOS ); EXPECT_EQ( findof5, STRING_NPOS ); EXPECT_EQ( findofofs, 4U ); EXPECT_EQ( findofofs2, 4U ); EXPECT_EQ( findofofs3, 8U ); EXPECT_EQ( findofofs4, STRING_NPOS ); EXPECT_EQ( findofofs5, STRING_NPOS ); EXPECT_EQ( findofofs6, 6U ); EXPECT_EQ( findofofs7, STRING_NPOS ); EXPECT_EQ( findofofs8, STRING_NPOS ); EXPECT_EQ( findofofs9, STRING_NPOS ); } { unsigned int findnotof = string_find_first_not_of( longstr, "testing ", 0 ); unsigned int findnotof2 = string_find_first_not_of( longstr, longstr, 0 ); unsigned int findnotof3 = string_find_first_not_of( shortstr, "", 0 ); unsigned int findnotofofs = string_find_first_not_of( longstr, "testing ", findnotof ); unsigned int findnotofofs2 = string_find_first_not_of( longstr, "testing ", findnotof + 1 ); unsigned int findnotofofs3 = string_find_first_not_of( longstr, "testing ", string_length( longstr ) ); unsigned int findnotofofs4 = string_find_first_not_of( shortstr, "", string_length( shortstr ) ); EXPECT_EQ( findnotof, 8U ); EXPECT_EQ( findnotof2, STRING_NPOS ); EXPECT_EQ( findnotof3, 0U ); EXPECT_EQ( findnotofofs, 8U ); EXPECT_EQ( findnotofofs2, 11U ); EXPECT_EQ( findnotofofs3, STRING_NPOS ); EXPECT_EQ( findnotofofs4, STRING_NPOS ); } { unsigned int findlastof = string_find_last_of( longstr, "xp", STRING_NPOS ); unsigned int findlastof2 = string_find_last_of( longstr, ";:", STRING_NPOS ); unsigned int findlastof3 = string_find_last_of( emptystr, "", STRING_NPOS ); unsigned int findlastof4 = string_find_last_of( shortstr, "", STRING_NPOS ); unsigned int findlastofofs = string_find_last_of( longstr, "xp", findlastof ); unsigned int findlastofofs2 = string_find_last_of( longstr, "xp", findlastof - 2 ); unsigned int findlastofofs3 = string_find_last_of( longstr, "xp", 0 ); unsigned int findlastofofs4 = string_find_last_of( emptystr, "", 0 ); unsigned int findlastofofs5 = string_find_last_of( shortstr, "", 5 ); unsigned int findlastofofs6 = string_find_last_of( shortstr, "", string_length( shortstr ) ); unsigned int findlastofofs7 = string_find_last_of( shortstr, "short", 5 ); EXPECT_EQ( findlastof, 59U ); EXPECT_EQ( findlastof2, STRING_NPOS ); EXPECT_EQ( findlastof3, STRING_NPOS ); EXPECT_EQ( findlastof4, STRING_NPOS ); EXPECT_EQ( findlastofofs, 59U ); EXPECT_EQ( findlastofofs2, 44U ); EXPECT_EQ( findlastofofs3, STRING_NPOS ); EXPECT_EQ( findlastofofs4, STRING_NPOS ); EXPECT_EQ( findlastofofs5, STRING_NPOS ); EXPECT_EQ( findlastofofs6, STRING_NPOS ); EXPECT_EQ( findlastofofs7, 4U ); } { unsigned int findlastnotof = string_find_last_not_of( longstr, " similar.", STRING_NPOS ); unsigned int findlastnotof2 = string_find_last_not_of( longstr, longstr, STRING_NPOS ); unsigned int findlastnotof3 = string_find_last_not_of( emptystr, "", STRING_NPOS ); unsigned int findlastnotof4 = string_find_last_not_of( shortstr, "", STRING_NPOS ); unsigned int findlastnotof5 = string_find_last_not_of( longstr, " similar", STRING_NPOS ); unsigned int findlastnotofofs = string_find_last_not_of( longstr, " similar.", findlastnotof ); unsigned int findlastnotofofs2 = string_find_last_not_of( longstr, " and similar.", findlastnotof - 1 ); unsigned int findlastnotofofs3 = string_find_last_not_of( longstr, longstr, 0 ); unsigned int findlastnotofofs4 = string_find_last_not_of( emptystr, "", 0 ); unsigned int findlastnotofofs5 = string_find_last_not_of( shortstr, "string", 5 ); unsigned int findlastnotofofs6 = string_find_last_not_of( shortstr, "string ", 5 ); unsigned int findlastnotofofs7 = string_find_last_not_of( shortstr, "", 5 ); unsigned int findlastnotofofs8 = string_find_last_not_of( longstr, "", string_length( longstr ) ); EXPECT_EQ( findlastnotof, 67U ); EXPECT_EQ( findlastnotof2, STRING_NPOS ); EXPECT_EQ( findlastnotof3, STRING_NPOS ); EXPECT_EQ( findlastnotof4, 11U ); EXPECT_EQ( findlastnotof5, 76U ); EXPECT_EQ( findlastnotofofs, 67U ); EXPECT_EQ( findlastnotofofs2, 63U ); EXPECT_EQ( findlastnotofofs3, STRING_NPOS ); EXPECT_EQ( findlastnotofofs4, STRING_NPOS ); EXPECT_EQ( findlastnotofofs5, 5U ); EXPECT_EQ( findlastnotofofs6, 2U ); EXPECT_EQ( findlastnotofofs7, 5U ); EXPECT_EQ( findlastnotofofs8, strlen( longstr ) - 1 ); } string_deallocate( emptystr ); string_deallocate( shortstr ); string_deallocate( longstr ); } return 0; }
char* path_clean( char* path, bool absolute ) { //Since this function is used a lot we want to perform as much operations //in place instead of splicing up into a string array and remerge char* replace; char* inpath; char* next; unsigned int inlength, length, remain, protocollen, up, last_up, prev_up, driveofs; if( !path ) return string_allocate( 0 ); inpath = path; inlength = string_length( path ); protocollen = string_find_string( path, "://", 0 ); if( ( protocollen != STRING_NPOS ) && ( protocollen > 1 ) ) { absolute = true; protocollen += 3; //Also skip the "://" separator inlength -= protocollen; path += protocollen; } else { protocollen = 0; } length = inlength; driveofs = 0; replace = path; while( ( replace = strchr( replace, '\\' ) ) != 0 ) *replace++ = '/'; remain = length; replace = path; while( ( next = strstr( replace, "/./" ) ) != 0 ) { remain -= (unsigned int)( next - replace ) + 2; length -= 2; memmove( next + 1, next + 3, remain ); //Include terminating zero to avoid looping when string ends in "/./" replace = next; } remain = length; replace = path; while( ( next = strstr( replace, "//" ) ) != 0 ) { remain -= (unsigned int)( next - replace ) + 1; --length; memmove( next + 1, next + 2, remain ); //Include terminating zero to avoid looping when string ends in "//" replace = next; } path[length] = 0; if( string_equal( path, "." ) ) { length = 0; path[0] = 0; } else if( length > 1 ) { if( ( path[ length - 2 ] == '/' ) && ( path[ length - 1 ] == '.' ) ) { path[ length - 2 ] = 0; length -= 2; } if( string_equal( path, "." ) ) { length = 0; path[0] = 0; } else if( string_equal( path, "./" ) ) { length = 1; path[0] = '/'; path[1] = 0; } else if( ( length > 1 ) && ( path[0] == '.' ) && ( path[1] == '/' ) ) { --length; memmove( path, path + 1, length ); path[length] = 0; } } if( absolute ) { if( !length ) { if( !inlength ) { inlength = 2; inpath = memory_reallocate( inpath, inlength + protocollen + 1, 0, protocollen + 1 ); path = inpath + protocollen; } path[0] = '/'; path[1] = 0; ++length; } else if( ( length >= 2 ) && ( path[1] == ':' ) ) { driveofs = 2; //Make sure first character is upper case if( ( path[0] >= 'a' ) && ( path[0] <= 'z' ) ) path[0] = ( path[0] - (char)( (int)'a' - (int)'A' ) ); if( length == 2 ) { if( inlength <= 2 ) { inpath = memory_reallocate( inpath, inlength + 2 + protocollen + 1, 0, inlength + protocollen + 1 ); inlength += 2; path = inpath + protocollen; } path[2] = '/'; ++length; } else if( path[2] != '/' ) { //splice in slash in weird-format paths (C:foo/bar/...) if( inlength < ( length + 1 ) ) { //Need more space inpath = memory_reallocate( inpath, length + protocollen + 2, 0, inlength + protocollen + 1 ); inlength = length + 1; path = inpath + protocollen; } memmove( path + 3, path + 2, length + 1 - 2 ); path[2] = '/'; ++length; } } else if( !protocollen && ( path[0] != '/' ) ) { //make sure capacity is enough to hold additional character if( inlength < ( length + 1 ) ) { //Need more space inpath = memory_reallocate( inpath, length + protocollen + 2, 0, inlength + protocollen + 1 ); inlength = length + 1; path = inpath + protocollen; } memmove( path + 1, path, length + 1 ); path[0] = '/'; ++length; } } else //relative { if( length && ( path[0] == '/' ) ) { memmove( path, path + 1, length - 1 ); --length; } } //Deal with .. references last_up = driveofs; while( ( up = string_find_string( path, "/../", last_up ) ) != STRING_NPOS ) { if( up >= length ) break; if( up == driveofs ) { if( absolute ) { memmove( path + driveofs + 1, path + driveofs + 4, length - ( driveofs + 3 ) ); length -= 3; } else { last_up = driveofs + 3; } continue; } prev_up = string_rfind( path, '/', up - 1 ); if( prev_up == STRING_NPOS ) { if( absolute ) { memmove( path, path + up + 3, length - up - 2 ); length -= ( up + 3 ); } else { memmove( path, path + up + 4, length - up - 3 ); length -= ( up + 4 ); } } else if( prev_up >= last_up ) { memmove( path + prev_up, path + up + 3, length - up - 2 ); length -= ( up - prev_up + 3 ); } else { last_up = up + 1; } } if( length > 1 ) { if( path[ length - 1 ] == '/' ) { path[ length - 1 ] = 0; --length; } } if( protocollen ) { if( path[0] == '/' ) { if( length == 1 ) length = 0; else { memmove( path, path + 1, length ); --length; } } length += protocollen; path = inpath; } path[length] = 0; return path; }
DECLARE_TEST(exception, error) { error_handler_fn handler; int ret; error(); EXPECT_EQ(error(), ERROR_NONE); error_report(ERRORLEVEL_ERROR, ERROR_NONE); EXPECT_EQ(error(), ERROR_NONE); error_report(ERRORLEVEL_ERROR, ERROR_EXCEPTION); EXPECT_EQ(error(), ERROR_EXCEPTION); handler = error_handler(); error_set_handler(_error_handler_test); ret = error_report(ERRORLEVEL_WARNING, ERROR_INVALID_VALUE); EXPECT_EQ(error(), ERROR_INVALID_VALUE); EXPECT_EQ(ret, 2); EXPECT_EQ(_error_level_test, ERRORLEVEL_WARNING); EXPECT_EQ(_error_test, ERROR_INVALID_VALUE); EXPECT_EQ(error_handler(), _error_handler_test); error_set_handler(handler); { #if BUILD_ENABLE_ERROR_CONTEXT const char context_data[] = "another message"; #endif char context_buffer[512]; string_t contextstr; error_context_clear(); error_context_push(STRING_CONST("test context"), STRING_CONST("some message")); error_context_push(STRING_CONST("foo bar"), 0, 0); error_context_pop(); error_context_pop(); error_context_pop(); error_context_push(STRING_CONST("test context"), STRING_CONST(context_data)); #if BUILD_ENABLE_ERROR_CONTEXT EXPECT_NE(error_context(), 0); EXPECT_EQ(error_context()->depth, 1); EXPECT_CONSTSTRINGEQ(error_context()->frame[0].name, string_const(STRING_CONST("test context"))); EXPECT_EQ(error_context()->frame[0].data.str, context_data); EXPECT_EQ(error_context()->frame[0].data.length, sizeof(context_data) - 1); #endif contextstr = error_context_buffer(context_buffer, 512); #if BUILD_ENABLE_ERROR_CONTEXT EXPECT_NE_MSGFORMAT(string_find_string(STRING_ARGS(contextstr), STRING_CONST("test context"), 0), STRING_NPOS, "context name 'test context' not found in buffer: %s", context_buffer); EXPECT_NE_MSGFORMAT(string_find_string(STRING_ARGS(contextstr), STRING_CONST(context_data), 0), STRING_NPOS, "context data '%s' not found in buffer: %s", context_data, context_buffer); #else EXPECT_EQ(contextstr.length, 0); #endif error_context_clear(); contextstr = error_context_buffer(context_buffer, 512); #if BUILD_ENABLE_ERROR_CONTEXT EXPECT_STRINGEQ(contextstr, string_empty()); #endif } return 0; }
DECLARE_TEST(exception, assert_handler) { EXPECT_EQ(assert_handler(), 0); assert_set_handler(handle_assert); EXPECT_EQ(assert_handler(), handle_assert); log_enable_stdout(false); EXPECT_EQ(assert_report(1, STRING_CONST("condition"), STRING_CONST("file"), 2, STRING_CONST("msg")), 1234); log_enable_stdout(true); EXPECT_EQ(assert_handler(), handle_assert); EXPECT_EQ(handled_context, 1); EXPECT_STRINGEQ(string(handled_condition, string_length(handled_condition)), string_const(STRING_CONST("condition"))); EXPECT_STRINGEQ(string(handled_file, string_length(handled_file)), string_const(STRING_CONST("file"))); EXPECT_EQ(handled_line, 2); EXPECT_STRINGEQ(string(handled_msg, string_length(handled_msg)), string_const(STRING_CONST("msg"))); assert_set_handler(0); EXPECT_EQ(assert_handler(), 0); #if BUILD_ENABLE_LOG _global_log_handler = log_handler(); log_set_handler(handle_log); #endif log_enable_stdout(false); EXPECT_EQ(assert_report_formatted(1, STRING_CONST("assert_report_formatted"), STRING_CONST("file"), 2, STRING_CONST("%.*s"), 3, "msg"), 1); log_enable_stdout(true); EXPECT_EQ(error(), ERROR_ASSERT); #if BUILD_ENABLE_LOG EXPECT_TRUE(string_find_string(handled_log, string_length(handled_log), STRING_CONST("assert_report_formatted"), 0) != STRING_NPOS); EXPECT_TRUE(string_find_string(handled_log, string_length(handled_log), STRING_CONST("msg"), 0) != STRING_NPOS); log_enable_stdout(false); log_set_suppress(HASH_TEST, ERRORLEVEL_NONE); #if BUILD_ENABLE_DEBUG_LOG log_debugf(HASH_TEST, STRING_CONST("%s"), #else log_infof(HASH_TEST, STRING_CONST("%s"), #endif "To test log handler and memory handling this test will print " "a really long log line with complete nonsense. Log handlers only occur for non-suppressed " "log levels, which is why this will be visible. However, it will not be printed to stdout. " "Lorem ipsum dolor sit amet, an quas vivendum sed, in est summo conclusionemque, an est nulla nonumy option. " "Malorum invidunt et mel, mei et hinc adolescens, eu velit deleniti urbanitas cum. Ei pericula omittantur duo, " "eam ei malis pertinacia, eum hinc dictas et. Duo et velit dolorem explicari, an tacimates abhorreant qui, " "esse possit intellegat ad vis. Eros populo numquam pro ea. Eius altera volumus duo ex, offendit comprehensam " "sit te. Ea facete nostrum fabellas sea. Vel ea rebum ridens quodsi, etiam urbanitas mea an. Ornatus commune et his, " "quo habeo denique an, id his amet diceret. Eam ei essent denique, cu quaestio perpetua vim. Mei utamur maluisset ex, " "iriure tritani eu per. Pro at rebum maluisset, nec ei eirmod scaevola consulatu, ius in meis patrioque. Vis at summo " "ancillae omnesque, inani moderatius delicatissimi qui an. Et illum vocibus eum, aliquando intellegat ex ius. Ius at " "tation veritus. Scripta reprehendunt at sed. Hinc idque mollis in cum, at elit habemus civibus eam, sea et modus " "eripuit. Alii ipsum electram id vel, mei alterum percipitur cu. Pro cu minim erant graecis, no vis tation nominavi " "imperdiet, mei affert probatus ut. Quo veri modus ad, solet nostrud atomorum ius ea. Everti aliquid ne usu, populo " "sapientem pro te. Persecuti definitionem qui ei, dicit dicunt ea quo. Sed minimum copiosae ei, pri dicat possit " "urbanitas eu. Tritani interesset theophrastus id sit, phaedrum facilisis his eu. Dictas accusam eu quo. Ea democritum " "consetetur vel. Iudicabit definitionem est eu, oportere temporibus at nec." ); log_set_suppress(HASH_TEST, ERRORLEVEL_DEBUG); log_enable_stdout(true); EXPECT_TRUE(string_find_string(handled_log, string_length(handled_log), STRING_CONST("Lorem ipsum"), 0) != STRING_NPOS); log_set_handler(_global_log_handler); #endif return 0; }
char* path_make_absolute( const char* path ) { unsigned int up, last, length, protocollen; char* abspath = string_clone( path ); if( !path_is_absolute( abspath ) ) { abspath = string_prepend( abspath, "/" ); abspath = string_prepend( abspath, environment_current_working_directory() ); abspath = path_clean( abspath, true ); } else { abspath = path_clean( abspath, true ); } protocollen = string_find_string( abspath, "://", 0 ); if( protocollen != STRING_NPOS ) protocollen += 3; //Also skip the "://" separator else protocollen = 0; //Deal with .. references while( ( up = string_find_string( abspath, "/../", 0 ) ) != STRING_NPOS ) { char* subpath; if( ( protocollen && ( up == ( protocollen - 1 ) ) ) || ( !protocollen && ( up == 0 ) ) ) { //This moves mem so "prot://../path" ends up as "prot://path" memmove( abspath + protocollen, abspath + 3 + protocollen, string_length( abspath ) + 1 - ( 3 + protocollen ) ); continue; } last = string_rfind( abspath, '/', up - 1 ); if( last == STRING_NPOS ) { //Must be a path like C:/../something since other absolute paths last = up; } subpath = string_substr( abspath, 0, last ); subpath = string_append( subpath, abspath + up + 3 ); // +3 will include the / of the later part of the path string_deallocate( abspath ); abspath = subpath; } length = string_length( abspath ); if( length >= 3 ) { while( ( length >= 3 ) && ( abspath[length-3] == '/' ) && ( abspath[length-2] == '.' ) && ( abspath[length-1] == L'.' ) ) { //Step up if( length == 3 ) { abspath[1] = 0; length = 1; } else { length = string_rfind( abspath, '/', length - 4 ); abspath[length] = 0; } } } return abspath; }