/**************************************************************************** * config_disk_directive ****************************************************************************/ static cw_bool_t config_disk_directive( struct config *cfg, struct disk *dsk, struct disk_track *dsk_trk, struct disk_params *dsk_prm, cw_flag_t scope) { cw_char_t token[GLOBAL_MAX_NAME_SIZE]; cw_count_t len; len = config_token(cfg, token, sizeof (token)); if (len == 0) { if (scope & SCOPE_ENTER) config_error(cfg, "directive expected"); config_error(cfg, "} expected"); } if ((scope & SCOPE_ENTER) && (string_equal(token, "{"))) return (config_disk_enter(cfg, dsk, dsk_trk, dsk_prm, scope)); if ((scope & SCOPE_LEAVE) && (string_equal(token, "}"))) return (CW_BOOL_FAIL); if (scope & SCOPE_TRACK) { if (string_equal(token, "info")) return (config_disk_info(cfg, dsk)); if (string_equal(token, "copy")) return (config_disk_copy(cfg, dsk)); if (string_equal(token, "image")) return (config_disk_image(cfg, dsk)); if (string_equal(token, "trackmap")) return (config_disk_trackmap(cfg, dsk)); if (string_equal(token, "track")) return (config_disk_track(cfg, dsk, dsk_trk)); if (string_equal(token, "track_range")) return (config_disk_track_range(cfg, dsk, dsk_trk)); } if (scope & SCOPE_RW) { if (string_equal(token, "format")) return (config_disk_format(cfg, dsk_trk)); if (string_equal(token, "clock")) return (config_disk_clock(cfg, dsk_trk)); if (string_equal(token, "timeout")) return (config_disk_timeout(cfg, dsk_trk)); if (string_equal(token, "indexed")) return (config_disk_indexed(cfg, dsk_trk)); if (string_equal(token, "optional")) return (config_disk_optional(cfg, dsk_trk)); if (string_equal(token, "flip_side")) return (config_disk_flip_side(cfg, dsk_trk)); if (string_equal(token, "side_offset")) return (config_disk_side_offset(cfg, dsk_trk)); if (string_equal(token, "read")) return (config_disk_directive(cfg, NULL, dsk_trk, NULL, SCOPE_ENTER | SCOPE_READ)); if (string_equal(token, "write")) return (config_disk_directive(cfg, NULL, dsk_trk, NULL, SCOPE_ENTER | SCOPE_WRITE)); if (disk_get_format(dsk_trk) == NULL) config_disk_error_format(cfg); if (string_equal(token, "skew")) return (config_disk_skew(cfg, dsk_trk)); if (string_equal(token, "interleave")) return (config_disk_interleave(cfg, dsk_trk)); if (config_disk_rw(cfg, dsk_trk, token)) return (CW_BOOL_OK); } if (scope & SCOPE_READ) { if (string_equal(token, "timeout")) return (config_disk_timeout_read(cfg, dsk_trk)); if (string_equal(token, "indexed")) return (config_disk_indexed_read(cfg, dsk_trk)); if (disk_get_format(dsk_trk) == NULL) config_disk_error_format(cfg); if (config_disk_read(cfg, dsk_trk, token)) return (CW_BOOL_OK); } if (scope & SCOPE_WRITE) { if (string_equal(token, "timeout")) return (config_disk_timeout_write(cfg, dsk_trk)); if (string_equal(token, "indexed")) return (config_disk_indexed_write(cfg, dsk_trk)); if (disk_get_format(dsk_trk) == NULL) config_disk_error_format(cfg); if (config_disk_write(cfg, dsk_trk, token)) return (CW_BOOL_OK); } if ((scope & SCOPE_PARAMS) && (config_disk_params(cfg, dsk_trk, dsk_prm, token, len))) return (CW_BOOL_OK); config_error_invalid(cfg, token); /* never reached, only to make gcc happy */ return (CW_BOOL_FAIL); }
unsigned int stacktrace_capture( void** trace, unsigned int max_depth, unsigned int skip_frames ) { unsigned int num_frames = 0; if( !trace ) return 0; if( !max_depth ) max_depth = BUILD_SIZE_STACKTRACE_DEPTH; if( max_depth > BUILD_SIZE_STACKTRACE_DEPTH ) max_depth = BUILD_SIZE_STACKTRACE_DEPTH; if( !_stackwalk_initialized ) { if( !_initialize_stackwalker() ) { memset( trace, 0, sizeof( void* ) * max_depth ); return num_frames; } } #if FOUNDATION_PLATFORM_WINDOWS && ( FOUNDATION_COMPILER_MSVC || FOUNDATION_COMPILER_INTEL ) // Add 1 skip frame for this function call ++skip_frames; # if USE_CAPTURESTACKBACKTRACE if( CallRtlCaptureStackBackTrace ) { void* local_trace[BUILD_SIZE_STACKTRACE_DEPTH]; if( max_depth + skip_frames > BUILD_SIZE_STACKTRACE_DEPTH ) max_depth = BUILD_SIZE_STACKTRACE_DEPTH - skip_frames; num_frames = (unsigned int)CallRtlCaptureStackBackTrace( skip_frames, max_depth, local_trace, 0 ); if( num_frames > max_depth ) num_frames = max_depth; memcpy( trace, local_trace, sizeof( void* ) * num_frames ); memset( trace + num_frames, 0, sizeof( void* ) * ( max_depth - num_frames ) ); } else { # else { # endif # if FOUNDATION_PLATFORM_ARCH_X86_64 // Raise an exception so helper has access to context record. __try { RaiseException( 0, // Application-defined exception code. 0, // Zero indicates continuable exception. 0, // Number of arguments in args array (ignored if args is null) 0 ); // Array of arguments } __except( _capture_stack_trace_helper( trace, max_depth, skip_frames, (GetExceptionInformation())->ContextRecord ) ) { } # else // Use a bit of inline assembly to capture the information relevant to stack walking which is // basically EIP and EBP. CONTEXT context; memset( &context, 0, sizeof( CONTEXT ) ); context.ContextFlags = CONTEXT_FULL; log_warnf( WARNING_DEPRECATED, "********** REIMPLEMENT FALLBACK STACKTRACE **********" ); /* Use a fake function call to pop the return address and retrieve EIP.*/ __asm { call FakeStackTraceCall FakeStackTraceCall: pop eax mov context.Eip, eax mov context.Ebp, ebp mov context.Esp, esp } // Capture the back trace. _capture_stack_trace_helper( trace, max_depth, skip_frames, &context ); # endif } #elif FOUNDATION_PLATFORM_APPLE //TODO: Implement #elif FOUNDATION_PLATFORM_POSIX // Add 1 skip frames for this function call skip_frames += 1; void* localframes[BUILD_SIZE_STACKTRACE_DEPTH]; num_frames = (unsigned int)backtrace( localframes, BUILD_SIZE_STACKTRACE_DEPTH ); if( num_frames > skip_frames ) { num_frames -= skip_frames; if( num_frames > max_depth ) num_frames = max_depth; memcpy( trace, localframes + skip_frames, sizeof( void* ) * num_frames ); } else trace[0] = 0; #endif return num_frames; } static bool _symbol_resolve_initialized = false; static bool _initialize_symbol_resolve() { if( _symbol_resolve_initialized ) return true; #if FOUNDATION_PLATFORM_WINDOWS { unsigned int options; void* dll = LoadLibraryA( "PSAPI.DLL" ); if( !dll ) return _symbol_resolve_initialized; CallEnumProcesses = (EnumProcessesFn)GetProcAddress( dll, "EnumProcesses" ); CallEnumProcessModules = (EnumProcessModulesFn)GetProcAddress( dll, "EnumProcessModules" ); CallGetModuleFileNameEx = (GetModuleFileNameExFn)GetProcAddress( dll, "GetModuleFileNameExA" ); CallGetModuleBaseName = (GetModuleBaseNameFn)GetProcAddress( dll, "GetModuleBaseNameA" ); CallGetModuleInformation = (GetModuleInformationFn)GetProcAddress( dll, "GetModuleInformation" ); if( !CallEnumProcesses || !CallEnumProcessModules || !CallGetModuleFileNameEx || !CallGetModuleBaseName || !CallGetModuleInformation ) return _symbol_resolve_initialized; dll = LoadLibraryA( "DBGHELP.DLL" ); if( !dll ) return _symbol_resolve_initialized; CallSymInitialize = (SymInitializeFn)GetProcAddress( dll, "SymInitialize" ); CallSymSetOptions = (SymSetOptionsFn)GetProcAddress( dll, "SymSetOptions" ); CallSymGetOptions = (SymGetOptionsFn)GetProcAddress( dll, "SymGetOptions" ); CallSymLoadModule64 = (SymLoadModule64Fn)GetProcAddress( dll, "SymLoadModule64" ); CallSymSetSearchPath = (SymSetSearchPathFn)GetProcAddress( dll, "SymSetSearchPath" ); CallSymGetModuleInfo64 = (SymGetModuleInfo64Fn)GetProcAddress( dll, "SymGetModuleInfo64" ); CallSymGetLineFromAddr64 = (SymGetLineFromAddr64Fn)GetProcAddress( dll, "SymGetLineFromAddr64" ); CallSymGetSymFromAddr64 = (SymGetSymFromAddr64Fn)GetProcAddress( dll, "SymGetSymFromAddr64" ); CallSymGetModuleBase64 = (SymGetModuleBase64Fn)GetProcAddress( dll, "SymGetModuleBase64" ); CallSymFunctionTableAccess64 = (SymFunctionTableAccess64Fn)GetProcAddress( dll, "SymFunctionTableAccess64" ); if( !CallSymInitialize || !CallSymSetOptions || !CallSymGetOptions || !CallSymLoadModule64 || !CallSymSetSearchPath || !CallSymGetModuleInfo64 || !CallSymGetLineFromAddr64 || !CallSymGetSymFromAddr64 || !CallSymGetModuleBase64 || !CallSymFunctionTableAccess64 ) return _symbol_resolve_initialized; options = CallSymGetOptions(); options |= SYMOPT_LOAD_LINES; options |= SYMOPT_DEBUG; options |= SYMOPT_UNDNAME; options |= SYMOPT_LOAD_LINES; options |= SYMOPT_FAIL_CRITICAL_ERRORS; options |= SYMOPT_DEFERRED_LOADS; options |= SYMOPT_ALLOW_ABSOLUTE_SYMBOLS; options |= SYMOPT_EXACT_SYMBOLS; options |= SYMOPT_CASE_INSENSITIVE; CallSymSetOptions( options ); CallSymInitialize( GetCurrentProcess(), 0, TRUE ); } _load_process_modules(); _symbol_resolve_initialized = true; #else _symbol_resolve_initialized = true; #endif return _symbol_resolve_initialized; } static NOINLINE char** _resolve_stack_frames( void** frames, unsigned int max_frames ) { #if FOUNDATION_PLATFORM_WINDOWS char** lines = 0; char symbol_buffer[ sizeof( IMAGEHLP_SYMBOL64 ) + 512 ]; PIMAGEHLP_SYMBOL64 symbol; DWORD displacement = 0; uint64_t displacement64 = 0; unsigned int iaddr = 0; unsigned int last_error; bool found = false; HANDLE process_handle = GetCurrentProcess(); int buffer_offset = 0; bool last_was_main = false; IMAGEHLP_LINE64 line64; IMAGEHLP_MODULE64 module64; for( iaddr = 0; ( iaddr < max_frames ) && !last_was_main; ++iaddr ) { char* resolved = 0; const char* function_name = "??"; const char* file_name = "??"; const char* module_name = "??"; unsigned int line_number = 0; //Allow first frame to be null in case of a function call to a null pointer if( iaddr && !frames[iaddr] ) break; // Initialize symbol. symbol = (PIMAGEHLP_SYMBOL64)symbol_buffer; memset( symbol, 0, sizeof( symbol_buffer ) ); symbol->SizeOfStruct = sizeof( symbol_buffer ); symbol->MaxNameLength = 512; // Get symbol from address. if( CallSymGetSymFromAddr64 && CallSymGetSymFromAddr64( process_handle, (uint64_t)((uintptr_t)frames[iaddr]), &displacement64, symbol ) ) { int offset = 0; while( symbol->Name[offset] < 32 ) ++offset; function_name = symbol->Name + offset; } else { // No symbol found for this address. last_error = GetLastError(); } memset( &line64, 0, sizeof( line64 ) ); line64.SizeOfStruct = sizeof( line64 ); if( CallSymGetLineFromAddr64 && CallSymGetLineFromAddr64( process_handle, (uint64_t)((uintptr_t)frames[iaddr]), &displacement, &line64 ) ) { file_name = line64.FileName; line_number = line64.LineNumber; } memset( &module64, 0, sizeof( module64 ) ); module64.SizeOfStruct = sizeof( module64 ); if( CallSymGetModuleInfo64 && CallSymGetModuleInfo64( process_handle, (uint64_t)((uintptr_t)frames[iaddr]), &module64 ) ) { int last_slash = STRING_NPOS; module_name = module64.ImageName; last_slash = string_rfind( module_name, '\\', STRING_NPOS ); if( last_slash != STRING_NPOS ) module_name += last_slash + 1; } resolved = string_format( "[" STRING_FORMAT_POINTER "] %s (%s:%d +%d bytes) [in %s]", frames[iaddr], function_name, file_name, line_number, displacement, module_name ); array_push( lines, resolved ); if( string_equal( function_name, "main" ) ) last_was_main = true; } return lines; #elif FOUNDATION_PLATFORM_LINUX char** addrs = 0; char** lines = 0; const char** args = 0; process_t* proc = process_allocate(); unsigned int num_frames = 0; unsigned int requested_frames = 0; bool last_was_main = false; if( !string_length( environment_executable_path() ) ) { for( unsigned int iaddr = 0; iaddr < max_frames; ++iaddr ) { //Allow first frame to be null in case of a function call to a null pointer if( iaddr && !frames[iaddr] ) break; array_push( lines, string_format( "[" STRING_FORMAT_POINTER "]", frames[iaddr] ) ); } return lines; } array_push( args, "-e" ); array_push( args, environment_executable_path() ); array_push( args, "-f" ); for( unsigned int iaddr = 0; iaddr < max_frames; ++iaddr ) { //Allow first frame to be null in case of a function call to a null pointer if( iaddr && !frames[iaddr] ) break; char* addr = string_format( STRING_FORMAT_POINTER, frames[iaddr] ); array_push( addrs, addr ); array_push( args, addr ); ++requested_frames; } process_set_working_directory( proc, environment_initial_working_directory() ); process_set_executable_path( proc, "/usr/bin/addr2line" ); process_set_arguments( proc, args, array_size( args ) ); process_set_flags( proc, PROCESS_ATTACHED | PROCESS_STDSTREAMS ); process_spawn( proc ); stream_t* procout = process_stdout( proc ); while( !stream_eos( procout ) && ( num_frames < requested_frames ) && !last_was_main ) { char* function = stream_read_line( procout, '\n' ); char* filename = stream_read_line( procout, '\n' ); array_push( lines, string_format( "[" STRING_FORMAT_POINTER "] %s (%s)", frames[num_frames], function && string_length( function ) ? function : "??", filename && string_length( filename ) ? filename : "??" ) ); if( string_equal( function, "main" ) ) last_was_main = true; string_deallocate( function ); string_deallocate( filename ); ++num_frames; } process_wait( proc ); process_deallocate( proc ); string_array_deallocate( addrs ); array_deallocate( args ); return lines; #else char** lines = 0; for( unsigned int iaddr = 0; iaddr < max_frames; ++iaddr ) { //Allow first frame to be null in case of a function call to a null pointer if( iaddr && !frames[iaddr] ) break; array_push( lines, string_format( "[" STRING_FORMAT_POINTER "]\n", frames[iaddr] ) ); } return lines; #endif }
void LogConsole_importString( const char* string ){ g_Console_enableLogging = string_equal( string, "true" ); Sys_LogFile( g_Console_enableLogging ); }
static void parse_go(char string[]) { const char * ptr; bool infinite, ponder; int depth, mate, movestogo; sint64 nodes; double binc, btime, movetime, winc, wtime; double time, inc; double time_max, alloc; // init infinite = false; ponder = false; depth = -1; mate = -1; movestogo = -1; nodes = -1; binc = -1.0; btime = -1.0; movetime = -1.0; winc = -1.0; wtime = -1.0; // parse ptr = strtok(string," "); // skip "go" for (ptr = strtok(NULL," "); ptr != NULL; ptr = strtok(NULL," ")) { if (false) { } else if (string_equal(ptr,"binc")) { ptr = strtok(NULL," "); if (ptr == NULL) my_fatal("parse_go(): missing argument\n"); binc = double(atoi(ptr)) / 1000.0; ASSERT(binc>=0.0); } else if (string_equal(ptr,"btime")) { ptr = strtok(NULL," "); if (ptr == NULL) my_fatal("parse_go(): missing argument\n"); btime = double(atoi(ptr)) / 1000.0; ASSERT(btime>=0.0); } else if (string_equal(ptr,"depth")) { ptr = strtok(NULL," "); if (ptr == NULL) my_fatal("parse_go(): missing argument\n"); depth = atoi(ptr); ASSERT(depth>=0); } else if (string_equal(ptr,"infinite")) { infinite = true; } else if (string_equal(ptr,"mate")) { ptr = strtok(NULL," "); if (ptr == NULL) my_fatal("parse_go(): missing argument\n"); mate = atoi(ptr); ASSERT(mate>=0); } else if (string_equal(ptr,"movestogo")) { ptr = strtok(NULL," "); if (ptr == NULL) my_fatal("parse_go(): missing argument\n"); movestogo = atoi(ptr); ASSERT(movestogo>=0); } else if (string_equal(ptr,"movetime")) { ptr = strtok(NULL," "); if (ptr == NULL) my_fatal("parse_go(): missing argument\n"); movetime = double(atoi(ptr)) / 1000.0; ASSERT(movetime>=0.0); } else if (string_equal(ptr,"nodes")) { ptr = strtok(NULL," "); if (ptr == NULL) my_fatal("parse_go(): missing argument\n"); nodes = my_atoll(ptr); ASSERT(nodes>=0); } else if (string_equal(ptr,"ponder")) { ponder = true; } else if (string_equal(ptr,"searchmoves")) { // dummy } else if (string_equal(ptr,"winc")) { ptr = strtok(NULL," "); if (ptr == NULL) my_fatal("parse_go(): missing argument\n"); winc = double(atoi(ptr)) / 1000.0; ASSERT(winc>=0.0); } else if (string_equal(ptr,"wtime")) { ptr = strtok(NULL," "); if (ptr == NULL) my_fatal("parse_go(): missing argument\n"); wtime = double(atoi(ptr)) / 1000.0; ASSERT(wtime>=0.0); } } // init search_clear(); // depth limit // JAS int option_depth = 0; option_depth = option_get_int("Search Depth"); if (option_depth > 0) { depth = option_depth; } // JAS end if (depth >= 0) { SearchInput->depth_is_limited = true; SearchInput->depth_limit = depth; } else if (mate >= 0) { SearchInput->depth_is_limited = true; SearchInput->depth_limit = mate * 2 - 1; // HACK: move -> ply } // time limit if (COLOUR_IS_WHITE(SearchInput->board->turn)) { time = wtime; inc = winc; } else { time = btime; inc = binc; } if (movestogo <= 0 || movestogo > 30) movestogo = 30; // HACK was 30 if (inc < 0.0) inc = 0.0; // JAS int option_movetime = 0; option_movetime = option_get_int("Search Time"); if (option_movetime > 0) { movetime = option_movetime; } // JAS end if (movetime >= 0.0) { // fixed time SearchInput->time_is_limited = true; SearchInput->time_limit_1 = movetime * 5.0; // HACK to avoid early exit SearchInput->time_limit_2 = movetime; } else if (time >= 0.0) { // dynamic allocation time_max = time * 0.95 - 1.0; if (time_max < 0.0) time_max = 0.0; SearchInput->time_is_limited = true; alloc = (time_max + inc * double(movestogo-1)) / double(movestogo); alloc *= (option_get_bool("Ponder") ? PonderRatio : NormalRatio); if (alloc > time_max) alloc = time_max; SearchInput->time_limit_1 = alloc; alloc = (time_max + inc * double(movestogo-1)) * 0.5; if (alloc < SearchInput->time_limit_1) alloc = SearchInput->time_limit_1; if (alloc > time_max) alloc = time_max; SearchInput->time_limit_2 = alloc; } if (infinite || ponder) SearchInput->infinite = true; // search ASSERT(!Searching); ASSERT(!Delay); Searching = true; Infinite = infinite || ponder; Delay = false; search(); search_update_current(); ASSERT(Searching); ASSERT(!Delay); Searching = false; Delay = Infinite; if (!Delay) send_best_move(); }
static luacompile_input_t luacompile_parse_command_line(const string_const_t* cmdline) { luacompile_input_t input; size_t arg, asize; error_context_push(STRING_CONST("parse command line"), STRING_CONST("")); memset(&input, 0, sizeof(input)); for (arg = 1, asize = array_size(cmdline); arg < asize; ++arg) { if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--help"))) input.display_help = true; else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--source"))) { if (arg < asize - 1) input.source_path = cmdline[++arg]; } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--config"))) { if (arg < asize - 1) array_push(input.config_files, cmdline[++arg]); } /*else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--uuid"))) { if (arg < asize - 1) { ++arg; input.uuid = string_to_uuid(STRING_ARGS(cmdline[arg])); if (uuid_is_null(input.uuid)) log_warnf(HASH_RESOURCE, WARNING_INVALID_VALUE, STRING_CONST("Invalid UUID: %.*s"), STRING_FORMAT(cmdline[arg])); } } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--set"))) { if (arg < asize - 2) { input.key = cmdline[++arg]; input.value = cmdline[++arg]; } }*/ else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--binary"))) { input.binary = 1; } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--ascii"))) { input.binary = 0; } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--debug"))) { log_set_suppress(0, ERRORLEVEL_NONE); log_set_suppress(HASH_RESOURCE, ERRORLEVEL_NONE); log_set_suppress(HASH_SCRIPT, ERRORLEVEL_NONE); log_set_suppress(HASH_LUA, ERRORLEVEL_NONE); } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--"))) break; //Stop parsing cmdline options else { array_push(input.input_files, cmdline[arg]); } } error_context_pop(); if (!array_size(input.input_files)) { log_errorf(HASH_RESOURCE, ERROR_INVALID_VALUE, STRING_CONST("No input files given")); input.display_help = true; } return input; }
int main_run(void* main_arg) { #if !BUILD_MONOLITHIC string_const_t pattern; string_t* exe_paths = 0; size_t iexe, exesize; process_t* process = 0; string_t process_path = { 0, 0 }; unsigned int* exe_flags = 0; #else void* test_result; #endif #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL int remain_counter = 0; #endif #if BUILD_DEBUG const string_const_t build_name = string_const(STRING_CONST("debug")); #elif BUILD_RELEASE const string_const_t build_name = string_const(STRING_CONST("release")); #elif BUILD_PROFILE const string_const_t build_name = string_const(STRING_CONST("profile")); #elif BUILD_DEPLOY const string_const_t build_name = string_const(STRING_CONST("deploy")); #endif #if BUILD_MONOLITHIC const string_const_t build_type = string_const(STRING_CONST(" monolithic")); #else const string_const_t build_type = string_empty(); #endif char* pathbuf; int process_result = 0; thread_t event_thread; FOUNDATION_UNUSED(main_arg); FOUNDATION_UNUSED(build_name); log_set_suppress(HASH_TEST, ERRORLEVEL_DEBUG); log_infof(HASH_TEST, STRING_CONST("Foundation library v%s built for %s using %s (%.*s%.*s)"), string_from_version_static(foundation_version()).str, FOUNDATION_PLATFORM_DESCRIPTION, FOUNDATION_COMPILER_DESCRIPTION, STRING_FORMAT(build_name), STRING_FORMAT(build_type)); thread_initialize(&event_thread, event_loop, 0, STRING_CONST("event_thread"), THREAD_PRIORITY_NORMAL, 0); thread_start(&event_thread); pathbuf = memory_allocate(HASH_STRING, BUILD_MAX_PATHLEN, 0, MEMORY_PERSISTENT); while (!thread_is_running(&event_thread)) thread_sleep(10); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL while (!_test_should_start) { #if FOUNDATION_PLATFORM_ANDROID system_process_events(); #endif thread_sleep(100); } #endif fs_remove_directory(STRING_ARGS(environment_temporary_directory())); #if (FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID) && !BUILD_ENABLE_LOG test_log_view_append(STRING_CONST("Tests starting\n")); #endif #if BUILD_MONOLITHIC test_run_fn tests[] = { test_app_run, test_array_run, test_atomic_run, test_base64_run, test_beacon_run, test_bitbuffer_run, test_blowfish_run, test_bufferstream_run, test_exception_run, test_environment_run, test_error_run, test_event_run, test_fs_run, test_hash_run, test_hashmap_run, test_hashtable_run, test_json_run, test_library_run, test_math_run, test_md5_run, test_mutex_run, test_objectmap_run, test_path_run, test_pipe_run, test_process_run, test_profile_run, test_radixsort_run, test_random_run, test_regex_run, test_ringbuffer_run, test_semaphore_run, test_sha_run, test_stacktrace_run, test_stream_run, //stream test closes stdin test_string_run, test_system_run, test_time_run, test_uuid_run, 0 }; #if FOUNDATION_PLATFORM_ANDROID thread_t test_thread; thread_initialize(&test_thread, test_runner, tests, STRING_CONST("test_runner"), THREAD_PRIORITY_NORMAL, 0); thread_start(&test_thread); log_debug(HASH_TEST, STRING_CONST("Starting test runner thread")); while (!thread_is_started(&test_thread)) { system_process_events(); thread_sleep(100); } while (thread_is_running(&test_thread)) { system_process_events(); thread_sleep(100); } test_result = thread_join(&test_thread); process_result = (int)(intptr_t)test_result; thread_finalize(&test_thread); #else test_result = test_runner(tests); process_result = (int)(intptr_t)test_result; #endif if (process_result != 0) log_warnf(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Tests failed with exit code %d"), process_result); #if (FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID) && !BUILD_ENABLE_LOG if (process_result) test_log_view_append(STRING_CONST("Tests FAILED\n")); else test_log_view_append(STRING_CONST("Tests PASSED\n")); #endif #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL while (!_test_should_terminate && _test_have_focus && (remain_counter < 50)) { system_process_events(); thread_sleep(100); ++remain_counter; } #endif log_debug(HASH_TEST, STRING_CONST("Exiting main loop")); #else // !BUILD_MONOLITHIC //Find all test executables in the current executable directory #if FOUNDATION_PLATFORM_WINDOWS pattern = string_const(STRING_CONST("^test-.*\\.exe$")); #elif FOUNDATION_PLATFORM_MACOSX pattern = string_const(STRING_CONST("^test-.*$")); #elif FOUNDATION_PLATFORM_POSIX pattern = string_const(STRING_CONST("^test-.*$")); #else # error Not implemented #endif exe_paths = fs_matching_files(STRING_ARGS(environment_executable_directory()), STRING_ARGS(pattern), false); array_resize(exe_flags, array_size(exe_paths)); memset(exe_flags, 0, sizeof(unsigned int) * array_size(exe_flags)); #if FOUNDATION_PLATFORM_MACOSX //Also search for test applications string_const_t app_pattern = string_const(STRING_CONST("^test-.*\\.app$")); regex_t* app_regex = regex_compile(app_pattern.str, app_pattern.length); string_t* subdirs = fs_subdirs(STRING_ARGS(environment_executable_directory())); for (size_t idir = 0, dirsize = array_size(subdirs); idir < dirsize; ++idir) { if (regex_match(app_regex, subdirs[idir].str, subdirs[idir].length, 0, 0)) { string_t exe_path = string_clone(subdirs[idir].str, subdirs[idir].length - 4); array_push(exe_paths, exe_path); array_push(exe_flags, PROCESS_MACOSX_USE_OPENAPPLICATION); } } string_array_deallocate(subdirs); regex_deallocate(app_regex); #endif for (iexe = 0, exesize = array_size(exe_paths); iexe < exesize; ++iexe) { string_const_t* process_args = 0; string_const_t exe_file_name = path_base_file_name(STRING_ARGS(exe_paths[iexe])); if (string_equal(STRING_ARGS(exe_file_name), STRING_ARGS(environment_executable_name()))) continue; //Don't run self process_path = path_concat(pathbuf, BUILD_MAX_PATHLEN, STRING_ARGS(environment_executable_directory()), STRING_ARGS(exe_paths[iexe])); process = process_allocate(); process_set_executable_path(process, STRING_ARGS(process_path)); process_set_working_directory(process, STRING_ARGS(environment_executable_directory())); process_set_flags(process, PROCESS_ATTACHED | exe_flags[iexe]); if (!_test_memory_tracker) array_push(process_args, string_const(STRING_CONST("--no-memory-tracker"))); process_set_arguments(process, process_args, array_size(process_args)); log_infof(HASH_TEST, STRING_CONST("Running test executable: %.*s"), STRING_FORMAT(exe_paths[iexe])); process_result = process_spawn(process); while (process_result == PROCESS_WAIT_INTERRUPTED) { thread_sleep(10); process_result = process_wait(process); } process_deallocate(process); array_deallocate(process_args); if (process_result != 0) { #if (FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID) && !BUILD_ENABLE_LOG char buffer[64]; string_const_t msg = string_format(buffer, sizeof(buffer), "Test %.*s failed\n", STRING_FORMAT(exe_paths[iexe])); test_log_view_append(STRING_ARGS(msg)); #endif if (process_result >= PROCESS_INVALID_ARGS) log_warnf(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Tests failed, process terminated with error %x"), process_result); else log_warnf(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Tests failed with exit code %d"), process_result); process_set_exit_code(-1); goto exit; } #if (FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID) && !BUILD_ENABLE_LOG { char buffer[64]; string_const_t msg = string_format(buffer, sizeof(buffer), "Test %.*s PASSED\n", STRING_FORMAT(exe_paths[iexe])); test_log_view_append(STRING_ARGS(msg)); } #endif log_infof(HASH_TEST, STRING_CONST("All tests from %.*s passed (%d)"), STRING_FORMAT(exe_paths[iexe]), process_result); } log_info(HASH_TEST, STRING_CONST("All tests passed")); exit: if (exe_paths) string_array_deallocate(exe_paths); array_deallocate(exe_flags); #endif _test_should_terminate = true; thread_signal(&event_thread); thread_join(&event_thread); thread_finalize(&event_thread); memory_deallocate(pathbuf); log_infof(HASH_TEST, STRING_CONST("Tests exiting: %s (%d)"), process_result ? "FAILED" : "PASSED", process_result); if (process_result) memory_set_tracker(memory_tracker_none()); return process_result; }
int main (int argc, char **argv) { CamelSession *session; CamelCipherContext *ctx; CamelException *ex; CamelCipherValidity *valid; CamelStream *stream1, *stream2; struct _CamelMimePart *sigpart, *conpart, *encpart, *outpart; CamelDataWrapper *dw; GPtrArray *recipients; GByteArray *buf; char *before, *after; int ret; if (getenv("CAMEL_TEST_GPG") == NULL) return 77; camel_test_init (argc, argv); /* clear out any camel-test data */ system ("/bin/rm -rf /tmp/camel-test"); system ("/bin/mkdir /tmp/camel-test"); setenv ("GNUPGHOME", "/tmp/camel-test/.gnupg", 1); /* import the gpg keys */ if ((ret = system ("gpg < /dev/null > /dev/null 2>&1")) == -1) return 77; else if (WEXITSTATUS (ret) == 127) return 77; g_message ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.pub > /dev/null 2>&1"); system ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.pub > /dev/null 2>&1"); g_message ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.sec > /dev/null 2>&1"); system ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.sec > /dev/null 2>&1"); session = camel_pgp_session_new ("/tmp/camel-test"); ex = camel_exception_new (); ctx = camel_gpg_context_new (session); camel_gpg_context_set_always_trust (CAMEL_GPG_CONTEXT (ctx), TRUE); camel_test_start ("Test of PGP functions"); stream1 = camel_stream_mem_new (); camel_stream_write (stream1, "Hello, I am a test stream.\n", 27); camel_stream_reset (stream1); conpart = camel_mime_part_new(); dw = camel_data_wrapper_new(); camel_data_wrapper_construct_from_stream(dw, stream1); camel_medium_set_content_object((CamelMedium *)conpart, dw); camel_object_unref(stream1); camel_object_unref(dw); sigpart = camel_mime_part_new(); camel_test_push ("PGP signing"); camel_cipher_sign (ctx, "*****@*****.**", CAMEL_CIPHER_HASH_SHA1, conpart, sigpart, ex); if (camel_exception_is_set(ex)) { printf("PGP signing failed assuming non-functional environment\n%s", camel_exception_get_description (ex)); camel_test_pull(); return 77; } camel_test_pull (); camel_exception_clear (ex); camel_test_push ("PGP verify"); valid = camel_cipher_verify (ctx, sigpart, ex); check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex)); check_msg (camel_cipher_validity_get_valid (valid), "%s", camel_cipher_validity_get_description (valid)); camel_cipher_validity_free (valid); camel_test_pull (); camel_object_unref(conpart); camel_object_unref(sigpart); stream1 = camel_stream_mem_new (); camel_stream_write (stream1, "Hello, I am a test of encryption/decryption.", 44); camel_stream_reset (stream1); conpart = camel_mime_part_new(); dw = camel_data_wrapper_new(); camel_stream_reset(stream1); camel_data_wrapper_construct_from_stream(dw, stream1); camel_medium_set_content_object((CamelMedium *)conpart, dw); camel_object_unref(stream1); camel_object_unref(dw); encpart = camel_mime_part_new(); camel_exception_clear (ex); camel_test_push ("PGP encrypt"); recipients = g_ptr_array_new (); g_ptr_array_add (recipients, "*****@*****.**"); camel_cipher_encrypt (ctx, "*****@*****.**", recipients, conpart, encpart, ex); check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex)); g_ptr_array_free (recipients, TRUE); camel_test_pull (); camel_exception_clear (ex); camel_test_push ("PGP decrypt"); outpart = camel_mime_part_new(); valid = camel_cipher_decrypt (ctx, encpart, outpart, ex); check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex)); check_msg (valid->encrypt.status == CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED, "%s", valid->encrypt.description); stream1 = camel_stream_mem_new(); stream2 = camel_stream_mem_new(); camel_data_wrapper_write_to_stream((CamelDataWrapper *)conpart, stream1); camel_data_wrapper_write_to_stream((CamelDataWrapper *)outpart, stream2); buf = CAMEL_STREAM_MEM (stream1)->buffer; before = g_strndup (buf->data, buf->len); buf = CAMEL_STREAM_MEM (stream2)->buffer; after = g_strndup (buf->data, buf->len); check_msg (string_equal (before, after), "before = '%s', after = '%s'", before, after); g_free (before); g_free (after); camel_object_unref(stream1); camel_object_unref(stream2); camel_object_unref(conpart); camel_object_unref(encpart); camel_object_unref(outpart); camel_test_pull (); camel_object_unref (CAMEL_OBJECT (ctx)); camel_object_unref (CAMEL_OBJECT (session)); camel_test_end (); return 0; }
void Entity_createFromSelection( const char* name, const Vector3& origin ){ #if 0 if ( string_equal_nocase( name, "worldspawn" ) ) { gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), "Can't create an entity with worldspawn.", "info" ); return; } #else const scene::Node* world_node = Map_FindWorldspawn( g_map ); if ( world_node && string_equal( name, "worldspawn" ) ) { // GlobalRadiant().m_pfnMessageBox( GTK_WIDGET( MainFrame_getWindow() ), "There's already a worldspawn in your map!", "Info", eMB_OK, eMB_ICONDEFAULT ); UndoableCommand undo( "ungroupSelectedPrimitives" ); Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), Map_FindOrInsertWorldspawn( g_map ) ); //=no action, if no worldspawn (but one inserted) (since insertion deselects everything) //Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), *Map_FindWorldspawn( g_map ) ); = crash, if no worldspawn return; } #endif StringOutputStream command; command << "entityCreate -class " << name; UndoableCommand undo( command.c_str() ); EntityClass* entityClass = GlobalEntityClassManager().findOrInsert( name, true ); const bool isModel = entityClass->miscmodel_is || ( GlobalSelectionSystem().countSelected() == 0 && classname_equal( name, "func_static" ) && g_pGameDescription->mGameType == "doom3" ); const bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0; //is important to have retexturing here; if doing in the end, undo doesn't succeed; if ( string_compare_nocase_n( name, "trigger_", 8 ) == 0 && brushesSelected && !entityClass->fixedsize ){ //const char* shader = GetCommonShader( "trigger" ).c_str(); Scene_PatchSetShader_Selected( GlobalSceneGraph(), GetCommonShader( "trigger" ).c_str() ); Scene_BrushSetShader_Selected( GlobalSceneGraph(), GetCommonShader( "trigger" ).c_str() ); } if ( !( entityClass->fixedsize || isModel ) && !brushesSelected ) { globalErrorStream() << "failed to create a group entity - no brushes are selected\n"; return; } AABB workzone( aabb_for_minmax( Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max ) ); NodeSmartReference node( GlobalEntityCreator().createEntity( entityClass ) ); Node_getTraversable( GlobalSceneGraph().root() )->insert( node ); scene::Path entitypath( makeReference( GlobalSceneGraph().root() ) ); entitypath.push( makeReference( node.get() ) ); scene::Instance& instance = findInstance( entitypath ); if ( entityClass->fixedsize || ( isModel && !brushesSelected ) ) { //Select_Delete(); Transformable* transform = Instance_getTransformable( instance ); if ( transform != 0 ) { transform->setType( TRANSFORM_PRIMITIVE ); transform->setTranslation( origin ); transform->freezeTransform(); } GlobalSelectionSystem().setSelectedAll( false ); Instance_setSelected( instance, true ); } else { if ( g_pGameDescription->mGameType == "doom3" ) { Node_getEntity( node )->setKeyValue( "model", Node_getEntity( node )->getKeyValue( "name" ) ); } Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), node ); Scene_forEachChildSelectable( SelectableSetSelected( true ), instance.path() ); } // tweaking: when right click dropping a light entity, ask for light value in a custom dialog box // see SF bug 105383 if ( g_pGameDescription->mGameType == "hl" ) { // FIXME - Hydra: really we need a combined light AND color dialog for halflife. if ( string_equal_nocase( name, "light" ) || string_equal_nocase( name, "light_environment" ) || string_equal_nocase( name, "light_spot" ) ) { int intensity = g_iLastLightIntensity; if ( DoLightIntensityDlg( &intensity ) == eIDOK ) { g_iLastLightIntensity = intensity; char buf[30]; sprintf( buf, "255 255 255 %d", intensity ); Node_getEntity( node )->setKeyValue( "_light", buf ); } } } else if ( string_equal_nocase( name, "light" ) ) { if ( g_pGameDescription->mGameType != "doom3" ) { int intensity = g_iLastLightIntensity; if ( DoLightIntensityDlg( &intensity ) == eIDOK ) { g_iLastLightIntensity = intensity; char buf[10]; sprintf( buf, "%d", intensity ); Node_getEntity( node )->setKeyValue( "light", buf ); } } else if ( brushesSelected ) { // use workzone to set light position/size for doom3 lights, if there are brushes selected AABB bounds( Doom3Light_getBounds( workzone ) ); StringOutputStream key( 64 ); key << bounds.origin[0] << " " << bounds.origin[1] << " " << bounds.origin[2]; Node_getEntity( node )->setKeyValue( "origin", key.c_str() ); key.clear(); key << bounds.extents[0] << " " << bounds.extents[1] << " " << bounds.extents[2]; Node_getEntity( node )->setKeyValue( "light_radius", key.c_str() ); } } if ( isModel ) { const char* model = misc_model_dialog( GTK_WIDGET( MainFrame_getWindow() ) ); if ( model != 0 ) { Node_getEntity( node )->setKeyValue( entityClass->miscmodel_key() , model ); } } }
EntitySetClassnameSelected( const char* classname ) : m_classname( classname ), m_world( Map_FindWorldspawn( g_map ) ), m_2world( m_world && string_equal( m_classname, "worldspawn" ) ){ }
int main(int argc, char *argv[]) { string *s = NULL; string *s2 = NULL; string *s3 = NULL; s = string_append(s, "Hello There"); test(s, "Hello There"); s = string_append(s, "123"); test(s, "Hello There123"); s = string_insert(s, 1, "<new>"); test(s, "H<new>ello There123"); s = string_insert(s, 23, "<new>"); test(s, "H<new>ello There123<new>"); s = string_remove(s, 11, 5); test(s, "H<new>ello 123<new>"); s = string_replace(s, "<new>", "<nothing>"); test(s, "H<nothing>ello 123<nothing>"); s = string_remove(s, 0, 30); test(s, ""); s = string_append(s, "H<nothing>ello 123<nothing>"); test(s, "H<nothing>ello 123<nothing>"); s = string_trunc(s); test(s, ""); string_free(&s); s = string_append_int(s, 1); test(s, "1"); s = string_append_int(s, 10); test(s, "110"); s = string_append_int(s, 100); test(s, "110100"); s = string_append_int(s, 1000000000); test(s, "1101001000000000"); s = string_append_int(s, -2); test(s, "1101001000000000-2"); s = string_append_int(s, -345); test(s, "1101001000000000-2-345"); s = string_append_int(s, -3.45); test(s, "1101001000000000-2-345-3"); s = string_trunc(s); test(s,""); s = string_prepend_int(s, 1); test(s, "1"); s = string_prepend_int(s, 10); test(s, "101"); s = string_prepend_int(s, 100); test(s, "100101"); s = string_prepend_int(s, 1000000000); test(s, "1000000000100101"); s = string_prepend_int(s, -2); test(s, "-21000000000100101"); s = string_prepend_int(s, -345); test(s, "-345-21000000000100101"); s = string_prepend_int(s, -3.45); test(s, "-3-345-21000000000100101"); s = string_trunc(s); test(s,""); string_free(&s); s = string_new("\"Quoted String\""); test(s, "\"Quoted String\""); s = string_replace(s, "\"", ""); test(s, "Quoted String"); string_free(&s); s = string_prepend(s, "Nothing"); test(s, "Nothing"); s = string_prepend(s, "12345678901234567890"); test(s, "12345678901234567890Nothing"); s = string_prepend(s, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); test(s, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890Nothing"); string_free(&s); s = string_append(s, "Nothing"); test(s, "Nothing"); s = string_append(s, "12345678901234567890"); test(s, "Nothing12345678901234567890"); s = string_append(s, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); test(s, "Nothing12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); string_free(&s); s = string_new("printf_append"); test(s, "printf_append"); s = string_printf_append(s, "%8s %3d %10.6f", "string", 20, 3.4); test(s, "printf_append string 20 3.400000"); string_free(&s); s = string_new(""); s = string_printf(s, "%8s %3d %10.6f", "string", 20, 3.4); test(s, " string 20 3.400000"); s2 = string_copy(s); test(s2, " string 20 3.400000"); testi(string_equal_char(s, string_string(s2)), 1); testi(string_equal(s, s2), 1); testi(string_equal_char(s, " string 20 3.40"), 0); s3 = string_new(" string 20 3.40"); testi(string_equal(s, s3), 0); string_free(&s2); string_free(&s3); s = string_remove(s, 100000, 20); test(s, " string 20 3.400000"); s = string_remove(s, 15, 20); test(s, " string 20 "); s = string_remove(s, 13, -1); test(s, " string 20 "); s = string_remove(s, 1, 1); test(s, " string 20 "); s = string_remove(s, 7, 2); test(s, " string20 "); s = string_remove(s, 9, 1); test(s, " string20"); s = string_remove(s, -1, -1); test(s, ""); s = string_insert(s, -1, " string20"); test(s, " string20"); s = string_insert(s, 9, " "); test(s, " string20 "); s = string_insert(s, 7, " "); test(s, " string 20 "); s = string_insert(s, 1, " "); test(s, " string 20 "); s = string_insert(s, 13, " "); test(s, " string 20 "); s = string_insert(s, 15, "3.400000"); test(s, " string 20 3.400000"); s = string_insert(s, 10000, " morestuff"); test(s, " string 20 3.400000 morestuff"); s = string_insert(s, -1, " morestuff"); test(s, " morestuff string 20 3.400000 morestuff"); s2 = string_substr(s, 1, 4); test(s2, "more"); string_free(&s2); s2 = string_substr(s, 5, 7); test(s2, "stuff "); string_free(&s2); string_free(&s); return retval; }
int foundation_initialize(const memory_system_t memory, const application_t application, const foundation_config_t config) { int ret = 0; if (_foundation_initialized) return 0; process_set_exit_code(PROCESS_EXIT_SUCCESS); foundation_initialize_config(config); /*lint -e774 */ SUBSYSTEM_INIT(atomic); SUBSYSTEM_INIT_ARGS(memory, memory); SUBSYSTEM_INIT(static_hash); SUBSYSTEM_INIT(log); SUBSYSTEM_INIT(time); SUBSYSTEM_INIT(thread); SUBSYSTEM_INIT(random); SUBSYSTEM_INIT(stream); SUBSYSTEM_INIT(fs); SUBSYSTEM_INIT(stacktrace); SUBSYSTEM_INIT_ARGS(environment, application); SUBSYSTEM_INIT(library); SUBSYSTEM_INIT(system); SUBSYSTEM_INIT(config); if (ret) return ret; //Parse built-in command line options { /*lint --e{613} */ const string_const_t* cmdline = environment_command_line(); size_t iarg, argsize; for (iarg = 0, argsize = array_size(cmdline); iarg < argsize; ++iarg) { string_const_t arg = cmdline[iarg]; if (string_equal(arg.str, arg.length, STRING_CONST("--log-debug"))) log_set_suppress(0, ERRORLEVEL_NONE); else if (string_equal(arg.str, arg.length, STRING_CONST("--log-info"))) log_set_suppress(0, ERRORLEVEL_DEBUG); } config_parse_commandline(cmdline, array_size(cmdline)); } //Artificial references /*lint -e506 */ #if FOUNDATION_PLATFORM_ANDROID android_main(0); #elif FOUNDATION_PLATFORM_PNACL if (((uintptr_t)PPP_InitializeModule < 1) || ((uintptr_t)PPP_GetInterface < 1) || ((uintptr_t)PPP_ShutdownModule < 1)) return -1; #else if ((uintptr_t)main < 1) return -1; #endif _foundation_initialized = true; return 0; }
object_t library_load( const char* name ) { library_t* library; hash_t namehash; unsigned int i, size; uint64_t id; #if FOUNDATION_PLATFORM_WINDOWS char* dllname; HANDLE dll; #endif //Locate already loaded library library = 0; namehash = string_hash( name ); for( i = 0, size = objectmap_size( _library_map ); i < size; ++i ) { library = objectmap_raw_lookup( _library_map, i ); if( library && ( library->namehash == namehash ) ) { FOUNDATION_ASSERT( string_equal( library->name, name ) ); atomic_incr32( &library->ref ); return library->id; } } error_context_push( "loading library", name ); //Try loading library #if FOUNDATION_PLATFORM_WINDOWS dllname = string_format( "%s.dll", name ); dll = LoadLibraryA( dllname ); if( !dll ) { #if FOUNDATION_PLATFORM_ARCH_X86 string_deallocate( dllname ); dllname = string_format( "%s32.dll", name ); dll = LoadLibraryA( dllname ); #elif FOUNDATION_PLATFORM_ARCH_X86_64 string_deallocate( dllname ); dllname = string_format( "%s64.dll", name ); dll = LoadLibraryA( dllname ); #endif } string_deallocate( dllname ); if( !dll ) { log_warnf( 0, WARNING_SUSPICIOUS, "Unable to load DLL '%s': %s", name, system_error_message( 0 ) ); error_context_pop(); return 0; } #elif FOUNDATION_PLATFORM_POSIX # if FOUNDATION_PLATFORM_APPLE char* libname = string_format( "lib%s.dylib", name ); # else char* libname = string_format( "lib%s.so", name ); # endif void* lib = dlopen( libname, RTLD_LAZY ); string_deallocate( libname ); #if FOUNDATION_PLATFORM_ANDROID if( !lib ) { libname = string_format( "%s/lib%s.so", environment_executable_directory(), name ); lib = dlopen( libname, RTLD_LAZY ); string_deallocate( libname ); } #endif if( !lib ) { log_warnf( 0, WARNING_SUSPICIOUS, "Unable to load dynamic library '%s': %s", name, dlerror() ); error_context_pop(); return 0; } #else log_errorf( 0, ERROR_NOT_IMPLEMENTED, "Dynamic library loading not implemented for this platform: %s", name ); error_context_pop(); return 0; #endif id = objectmap_reserve( _library_map ); if( !id ) { #if FOUNDATION_PLATFORM_WINDOWS FreeLibrary( dll ); #elif FOUNDATION_PLATFORM_POSIX dlclose( lib ); #endif log_errorf( 0, ERROR_OUT_OF_MEMORY, "Unable to allocate new library '%s', map full", name ); error_context_pop(); return 0; } library = memory_allocate_zero( sizeof( library_t ), 0, MEMORY_PERSISTENT ); library->ref = 1; library->id = id; library->namehash = string_hash( name ); string_copy( library->name, name, 32 ); #if FOUNDATION_PLATFORM_WINDOWS library->dll = dll; #elif FOUNDATION_PLATFORM_POSIX library->lib = lib; #endif objectmap_set( _library_map, id, library ); error_context_pop(); return library->id; }
bool operator()(const BuildPair& self) const { return string_equal(self.first.c_str(), m_name); }
int main(int argc, char** argv) { if(argc != 2 && argc != 3) { c_print_format("Usage: %s FILE [cartridge/folder]\n", argv[0]); return 0; } Arena arena = arena_create(MB(512)); String cartridge_folder_path_name = (argc > 2) ? string_from_c_string(argv[2]) : L("SuperMarioWorld.sfc"); Path cartridge_folder_path; path_init(&cartridge_folder_path, cartridge_folder_path_name); Path manifest_path; path_init_from_c(&manifest_path, &cartridge_folder_path, "manifest.bml"); Buffer manifest_buffer = path_read_file(&manifest_path, &arena); Wdc65816MapperBuilder rom_builder = { }; char name[256]; Buffer name_buffer = buffer(name, 256); Buffer rom_buffer; for(Wdc65816RomLoader loader = wdc65816_rom_loader_begin(&rom_builder, string_from_buffer(manifest_buffer)); wdc65816_rom_loader_end(&loader); wdc65816_rom_loader_next(&loader)) { Wdc65816MemoryBufferRequest request = wdc65816_rom_loader_get_buffer_request(&loader, name_buffer); Buffer file_buffer = buffer(arena_alloc_array(&arena, request.size, u8), request.size); if(string_equal(request.name, L("program.rom")) && request.type == WDC65816_MEMORY_ROM) { rom_buffer = file_buffer; } wdc65816_rom_loader_set_buffer(&loader, file_buffer); } uint mapper_buffer_size = wdc65816_mapper_get_buffer_size(); u8* work_buffer = arena_alloc_array(&arena, mapper_buffer_size, u8); Wdc65816Mapper rom; wdc65816_mapper_init(&rom, &rom_builder, (u8**)work_buffer); nuts_global_init(); Path working_dir; path_init_working_directory(&working_dir); FreeList sentinel; free_list_init(&sentinel); ErrorList error_list; error_list_init(&error_list, arena_subarena(&arena, MB(10))); AST ast; ast_init(&ast, &arena); String file_name = string_from_c_string(argv[1]); /* struct timespec lex_start, lex_end, lex_time = { 0 }; */ /* struct timespec parse_start, parse_end, parse_time = { 0 }; */ /* struct timespec assemble_start, assemble_end, assemble_time = { 0 }; */ /* struct timespec all_start, all_end, all_time; */ /* clock_gettime(CLOCK_REALTIME, &all_start); */ Parser parser; parser_init(&parser, &arena, &sentinel, &error_list, &ast); int error_num = 0; while(1) { Path file; path_init(&file, file_name); Buffer file_buffer = path_read_file(&file, &arena); TokenList token_list; //c_print_format("read %.*s\n", file_name.length, file_name.data); Text file_text = { .buffer = file_buffer, .name = file_name }; /* clock_gettime(CLOCK_REALTIME, &lex_start); */ Result result = lex(file_text, &token_list, &arena, &error_list, &ast.identifier_map); if(result == RESULT_ERROR) { for(;error_num < error_list.length; error_num++) { describe_error(error_list.errors[error_num]); } } /* clock_gettime(CLOCK_REALTIME, &lex_end); */ /* lex_time = timespec_add(lex_time, timespec_sub(lex_start, lex_end)); */ /* clock_gettime(CLOCK_REALTIME, &parse_start); */ /* result = parse(&parser, token_list); */ /* clock_gettime(CLOCK_REALTIME, &parse_end); */ /* parse_time = timespec_add(parse_time, timespec_sub(parse_start, parse_end)); */ if(result == RESULT_NEED_TOKEN_STREAM) { file_name = parser.needed_token_stream_file_name; continue; } else if(result == RESULT_OK) { break; } else if(result == RESULT_ERROR) { for(;error_num < error_list.length; error_num++) { describe_error(error_list.errors[error_num]); } return 1; } else { invalid_code_path; } } /* clock_gettime(CLOCK_REALTIME, &assemble_start); */ Assembler assembler; assembler_init(&assembler, &error_list, &ast, &rom); Result result = RESULT_ERROR; while(result != RESULT_OK) { result = assemble(&assembler); if(result == RESULT_NEED_FILE) { String file_name = assembler_get_file_name(&assembler); Path file; path_init(&file, file_name); Buffer file_buffer = path_read_file(&file, &arena); assembler_give_buffer(&assembler, file_buffer); } else if(result == RESULT_ERROR) { break; } } /* clock_gettime(CLOCK_REALTIME, &assemble_end); */ /* assemble_time = timespec_add(assemble_time, timespec_sub(assemble_start, assemble_end)); */ for(int i = 0; i < error_list.length; i++) { describe_error(error_list.errors[i]); } /* parser_deinit(&parser); */ /* clock_gettime(CLOCK_REALTIME, &all_end); */ /* all_time = timespec_sub(all_start, all_end); */ /* c_print_format("Lex: %li.%06lims\n", lex_time.tv_sec * 1000 + lex_time.tv_nsec / 1000000, lex_time.tv_nsec % 1000000); */ /* c_print_format("Parse: %li.%06lims\n", parse_time.tv_sec * 1000 + parse_time.tv_nsec / 1000000, parse_time.tv_nsec % 1000000); */ /* c_print_format("Assemble: %li.%06lims\n", assemble_time.tv_sec * 1000 + assemble_time.tv_nsec / 1000000, assemble_time.tv_nsec % 1000000); */ /* c_print_format("All: %li.%06lims\n", all_time.tv_sec * 1000 + all_time.tv_nsec / 1000000, all_time.tv_nsec % 1000000); */ Path rom_path; path_create_from(&rom_path, &cartridge_folder_path, L("program.rom")); path_write_file(&rom_path, rom_buffer); 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; }
int main_run( void* main_arg ) { const char* pattern = 0; char** exe_paths = 0; unsigned int iexe, exesize; process_t* process = 0; char* process_path = 0; int process_result = 0; object_t thread = 0; thread = thread_create( event_thread, "event_thread", THREAD_PRIORITY_NORMAL, 0 ); thread_start( thread, 0 ); #if FOUNDATION_PLATFORM_ANDROID int test_fn = 0; test_run_fn tests[] = { //test_app_run test_array_run, test_atomic_run, test_base64_run, test_bitbuffer_run, test_blowfish_run, test_bufferstream_run, test_config_run, test_crash_run, test_environment_run, test_error_run, test_event_run, test_fs_run, test_hash_run, test_hashmap_run, test_hashtable_run, test_library_run, test_math_run, test_md5_run, test_mutex_run, test_objectmap_run, test_path_run, test_pipe_run, test_profile_run, test_radixsort_run, test_random_run, test_ringbuffer_run, test_semaphore_run, //test_stacktrace_run, test_string_run, test_uuid_run, 0 }; do { if( process_result >= 0 ) { if( ( process_result = tests[test_fn]() ) >= 0 ) log_infof( HASH_TEST, "All tests passed (%d)", process_result ); } ++test_fn; } while( tests[test_fn] && ( process_result >= 0 ) ); if( process_result != 0 ) { log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed with exit code %d", process_result ); } #else //Find all test executables in the current executable directory #if FOUNDATION_PLATFORM_WINDOWS pattern = "test-*.exe"; #elif FOUNDATION_PLATFORM_MACOSX || FOUNDATION_PLATFORM_IOS pattern = "test-*"; #elif FOUNDATION_PLATFORM_POSIX pattern = "test-*"; #else # error Not implemented #endif exe_paths = fs_matching_files( environment_executable_directory(), pattern, true ); for( iexe = 0, exesize = array_size( exe_paths ); iexe < exesize; ++iexe ) { bool is_self = false; char* exe_file_name = path_base_file_name( exe_paths[iexe] ); if( string_equal( exe_file_name, environment_executable_name() ) ) is_self = true; string_deallocate( exe_file_name ); if( is_self ) continue; //Don't run self process_path = path_merge( environment_executable_directory(), exe_paths[iexe] ); process = process_allocate(); process_set_executable_path( process, process_path ); process_set_working_directory( process, environment_executable_directory() ); process_set_flags( process, PROCESS_ATTACHED ); log_infof( HASH_TEST, "Running test executable: %s", exe_paths[iexe] ); process_result = process_spawn( process ); while( process_result == PROCESS_WAIT_INTERRUPTED ) { thread_sleep( 10 ); process_result = process_wait( process ); } process_deallocate( process ); string_deallocate( process_path ); if( process_result != 0 ) { if( process_result >= PROCESS_INVALID_ARGS ) log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed, process terminated with error %x", process_result ); else log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed with exit code %d", process_result ); process_set_exit_code( -1 ); goto exit; } log_infof( HASH_TEST, "All tests from %s passed (%d)", exe_paths[iexe], process_result ); } log_info( HASH_TEST, "All tests passed" ); exit: if( exe_paths ) string_array_deallocate( exe_paths ); #endif thread_terminate( thread ); thread_destroy( thread ); while( thread_is_running( thread ) ) thread_sleep( 10 ); return process_result; }
int main_initialize(void) { foundation_config_t config; application_t application; int ret; size_t iarg, asize; const string_const_t* cmdline = environment_command_line(); _test_memory_tracker = true; for (iarg = 0, asize = array_size(cmdline); iarg < asize; ++iarg) { if (string_equal(STRING_ARGS(cmdline[iarg]), STRING_CONST("--no-memory-tracker"))) _test_memory_tracker = false; } if (_test_memory_tracker) memory_set_tracker(memory_tracker_local()); memset(&config, 0, sizeof(config)); #if BUILD_MONOLITHIC //For fs monitor test config.fs_monitor_max = 1; //For temporary allocator test, 256KiB config.temporary_memory = 256 * 1024; //For testing static hash store config.hash_store_size = 32 * 1024; //Test preallocation of random state buffers config.random_state_prealloc = 4; #endif memset(&application, 0, sizeof(application)); application.name = string_const(STRING_CONST("Foundation library test suite")); application.short_name = string_const(STRING_CONST("test_all")); application.company = string_const(STRING_CONST("Rampant Pixels")); application.version = foundation_version(); application.flags = APPLICATION_UTILITY; application.exception_handler = test_exception_handler; log_set_suppress(0, ERRORLEVEL_INFO); #if (FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID) && BUILD_ENABLE_LOG log_set_handler(test_log_handler); #endif #if !FOUNDATION_PLATFORM_IOS && !FOUNDATION_PLATFORM_ANDROID && !FOUNDATION_PLATFORM_PNACL _test_should_start = true; #endif ret = foundation_initialize(memory_system_malloc(), application, config); #if BUILD_MONOLITHIC //For monolithic process test if (string_array_find(cmdline, array_size(cmdline), STRING_CONST("wait for kill")) >= 0) { while (true) thread_sleep(100); } test_set_suitable_working_directory(); #endif return ret; }
static void loop_step() { char string[65536]; // read a line get(string,65536); // parse if (false) { } else if (string_start_with(string,"debug ")) { // dummy } else if (string_start_with(string,"go ")) { if (!Searching && !Delay) { init(); parse_go(string); } else { ASSERT(false); } } else if (string_equal(string,"isready")) { if (!Searching && !Delay) { init(); } send("readyok"); // no need to wait when searching (dixit SMK) } else if (string_equal(string,"ponderhit")) { if (Searching) { ASSERT(Infinite); SearchInput->infinite = false; Infinite = false; } else if (Delay) { send_best_move(); Delay = false; } else { ASSERT(false); } } else if (string_start_with(string,"position ")) { if (!Searching && !Delay) { init(); parse_position(string); } else { ASSERT(false); } } else if (string_equal(string,"quit")) { ASSERT(!Searching); ASSERT(!Delay); exit(EXIT_SUCCESS); } else if (string_start_with(string,"setoption ")) { if (!Searching && !Delay) { parse_setoption(string); } else { ASSERT(false); } } else if (string_equal(string,"stop")) { if (Searching) { SearchInfo->stop = true; Infinite = false; } else if (Delay) { send_best_move(); Delay = false; } } else if (string_equal(string,"uci")) { ASSERT(!Searching); ASSERT(!Delay); send("id name Toga II " VERSION); send("id author Thomas Gaksch and Fabien Letouzey"); option_list(); send("uciok"); } else if (string_equal(string,"ucinewgame")) { if (!Searching && !Delay && Init) { trans_clear(Trans); } else { ASSERT(false); } } }
void config_load( const char* name, hash_t filter_section, bool built_in, bool overwrite ) { /*lint --e{838} Safety null assign all pointers for all preprocessor paths */ /*lint --e{750} Unused macros in some paths */ #define NUM_SEARCH_PATHS 10 #define ANDROID_ASSET_PATH_INDEX 5 char* sub_exe_path = 0; char* exe_parent_path = 0; char* exe_processed_path = 0; char* abs_exe_parent_path = 0; char* abs_exe_processed_path = 0; char* bundle_path = 0; char* home_dir = 0; char* cmdline_path = 0; char* cwd_config_path = 0; const char* paths[NUM_SEARCH_PATHS]; #if !FOUNDATION_PLATFORM_FAMILY_MOBILE const char* const* cmd_line; int icl, clsize; #endif int start_path, i, j; const char buildsuffix[4][9] = { "/debug", "/release", "/profile", "/deploy" }; const char platformsuffix[7][14] = { "/win32", "/win64", "/osx", "/ios", "/android", "/raspberrypi", "/unknown" }; const char binsuffix[1][5] = { "/bin" }; FOUNDATION_ASSERT( name ); sub_exe_path = path_merge( environment_executable_directory(), "config" ); exe_parent_path = path_merge( environment_executable_directory(), "../config" ); abs_exe_parent_path = path_make_absolute( exe_parent_path ); exe_processed_path = string_clone( environment_executable_directory() ); for( i = 0; i < 4; ++i ) { if( string_ends_with( exe_processed_path, buildsuffix[i] ) ) { exe_processed_path[ string_length( exe_processed_path ) - string_length( buildsuffix[i] ) ] = 0; break; } } for( i = 0; i < 7; ++i ) { if( string_ends_with( exe_processed_path, platformsuffix[i] ) ) { exe_processed_path[ string_length( exe_processed_path ) - string_length( platformsuffix[i] ) ] = 0; break; } } for( i = 0; i < 1; ++i ) { if( string_ends_with( exe_processed_path, binsuffix[i] ) ) { exe_processed_path[ string_length( exe_processed_path ) - string_length( binsuffix[i] ) ] = 0; break; } } exe_processed_path = path_append( exe_processed_path, "config" ); abs_exe_processed_path = path_make_absolute( exe_processed_path ); paths[0] = environment_executable_directory(); paths[1] = sub_exe_path; paths[2] = abs_exe_parent_path; paths[3] = abs_exe_processed_path; #if FOUNDATION_PLATFORM_FAMILY_DESKTOP && !BUILD_DEPLOY paths[4] = environment_initial_working_directory(); #else paths[4] = 0; #endif #if FOUNDATION_PLATFORM_APPLE bundle_path = path_merge( environment_executable_directory(), "../Resources/config" ); paths[5] = bundle_path; #elif FOUNDATION_PLATFORM_ANDROID paths[5] = "/config"; #else paths[5] = 0; #endif #if FOUNDATION_PLATFORM_FAMILY_DESKTOP paths[6] = environment_current_working_directory(); #else paths[6] = 0; #endif paths[7] = 0; paths[8] = 0; string_deallocate( exe_parent_path ); string_deallocate( exe_processed_path ); #if FOUNDATION_PLATFORM_FAMILY_DESKTOP cwd_config_path = path_merge( environment_current_working_directory(), "config" ); paths[7] = cwd_config_path; cmd_line = environment_command_line(); /*lint -e{850} We modify loop var to skip extra arg */ for( icl = 0, clsize = array_size( cmd_line ); icl < clsize; ++icl ) { /*lint -e{613} array_size( cmd_line ) in loop condition does the null pointer guard */ if( string_equal_substr( cmd_line[icl], "--configdir", 11 ) ) { if( string_equal_substr( cmd_line[icl], "--configdir=", 12 ) ) { paths[8] = cmdline_path = string_substr( cmd_line[icl], 12, STRING_NPOS ); } else if( icl < ( clsize - 1 ) ) { paths[8] = cmdline_path = string_clone( cmd_line[++icl] ); } } } #endif start_path = 0; if( !built_in ) { #if FOUNDATION_PLATFORM_WINDOWS home_dir = path_merge( environment_home_directory(), environment_application()->config_dir ); #elif FOUNDATION_PLATFORM_LINUX || FOUNDATION_PLATFORM_MACOSX home_dir = path_prepend( string_concat( ".", environment_application()->config_dir ), environment_home_directory() ); #endif if( home_dir ) paths[9] = home_dir; start_path = 9; } else { paths[9] = 0; } for( i = start_path; i < NUM_SEARCH_PATHS; ++i ) { char* filename; stream_t* istream; bool path_already_searched = false; if( !paths[i] ) continue; for( j = start_path; j < i; ++j ) { if( paths[j] && string_equal( paths[j], paths[i] ) ) { path_already_searched = true; break; } } if( path_already_searched ) continue; //TODO: Support loading configs from virtual file system (i.e in zip/other packages) filename = string_append( path_merge( paths[i], name ), ".ini" ); istream = 0; #if FOUNDATION_PLATFORM_ANDROID if( i == ANDROID_ASSET_PATH_INDEX ) istream = asset_stream_open( filename, STREAM_IN ); else #endif istream = stream_open( filename, STREAM_IN ); if( istream ) { config_parse( istream, filter_section, overwrite ); stream_deallocate( istream ); } string_deallocate( filename ); if( built_in ) { const char* FOUNDATION_PLATFORM_name = #if FOUNDATION_PLATFORM_WINDOWS "windows"; #elif FOUNDATION_PLATFORM_LINUX_RASPBERRYPI "raspberrypi"; #elif FOUNDATION_PLATFORM_LINUX "linux"; #elif FOUNDATION_PLATFORM_MACOSX "osx"; #elif FOUNDATION_PLATFORM_IOS "ios"; #elif FOUNDATION_PLATFORM_ANDROID "android"; #else # error Insert platform name "unknown"; #endif filename = string_append( path_append( path_merge( paths[i], FOUNDATION_PLATFORM_name ), name ), ".ini" ); #if FOUNDATION_PLATFORM_ANDROID if( i == ANDROID_ASSET_PATH_INDEX ) istream = asset_stream_open( filename, STREAM_IN ); else #endif istream = stream_open( filename, STREAM_IN ); if( istream ) { config_parse( istream, filter_section, overwrite ); stream_deallocate( istream ); } string_deallocate( filename ); } } string_deallocate( home_dir ); string_deallocate( cmdline_path ); string_deallocate( sub_exe_path ); string_deallocate( abs_exe_processed_path ); string_deallocate( abs_exe_parent_path ); string_deallocate( bundle_path ); string_deallocate( cwd_config_path ); }
int main_run( void* main_arg ) { #if !FOUNDATION_PLATFORM_IOS && !FOUNDATION_PLATFORM_ANDROID const char* pattern = 0; char** exe_paths = 0; unsigned int iexe, exesize; process_t* process = 0; char* process_path = 0; unsigned int* exe_flags = 0; #endif int process_result = 0; object_t thread = 0; log_set_suppress( HASH_TEST, ERRORLEVEL_DEBUG ); thread = thread_create( event_thread, "event_thread", THREAD_PRIORITY_NORMAL, 0 ); thread_start( thread, 0 ); while( !thread_is_running( thread ) ) thread_sleep( 10 ); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID while( !_test_should_start ) thread_sleep( 10 ); test_run_fn tests[] = { //test_app_run test_array_run, test_atomic_run, test_base64_run, test_bitbuffer_run, test_blowfish_run, test_bufferstream_run, test_config_run, test_crash_run, test_environment_run, test_error_run, test_event_run, test_fs_run, test_hash_run, test_hashmap_run, test_hashtable_run, test_library_run, test_math_run, test_md5_run, test_mutex_run, test_objectmap_run, test_path_run, test_pipe_run, test_profile_run, test_radixsort_run, test_random_run, test_ringbuffer_run, test_semaphore_run, test_stacktrace_run, test_string_run, test_uuid_run, 0 }; #if FOUNDATION_PLATFORM_ANDROID object_t test_thread = thread_create( test_runner, "test_runner", THREAD_PRIORITY_NORMAL, 0 ); thread_start( test_thread, tests ); while( !thread_is_running( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } while( thread_is_running( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } process_result = (int)(intptr_t)thread_result( test_thread ); thread_destroy( test_thread ); while( thread_is_thread( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } #else process_result = (int)(intptr_t)test_runner( 0, tests ); #endif if( process_result != 0 ) log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed with exit code %d", process_result ); while( !_test_should_terminate ) { system_process_events(); thread_sleep( 100 ); } log_debug( HASH_TEST, "Exiting main loop" ); #else //Find all test executables in the current executable directory #if FOUNDATION_PLATFORM_WINDOWS pattern = "test-*.exe"; #elif FOUNDATION_PLATFORM_MACOSX pattern = "test-*"; #elif FOUNDATION_PLATFORM_POSIX pattern = "test-*"; #else # error Not implemented #endif exe_paths = fs_matching_files( environment_executable_directory(), pattern, false ); array_resize( exe_flags, array_size( exe_paths ) ); memset( exe_flags, 0, sizeof( unsigned int ) * array_size( exe_flags ) ); #if FOUNDATION_PLATFORM_MACOSX //Also search for test-*.app const char* app_pattern = "test-*.app"; char** subdirs = fs_subdirs( environment_executable_directory() ); for( int idir = 0, dirsize = array_size( subdirs ); idir < dirsize; ++idir ) { if( string_match_pattern( subdirs[idir], app_pattern ) ) { array_push( exe_paths, string_substr( subdirs[idir], 0, string_length( subdirs[idir] ) - 4 ) ); array_push( exe_flags, PROCESS_OSX_USE_OPENAPPLICATION ); } } string_array_deallocate( subdirs ); #endif for( iexe = 0, exesize = array_size( exe_paths ); iexe < exesize; ++iexe ) { bool is_self = false; char* exe_file_name = path_base_file_name( exe_paths[iexe] ); if( string_equal( exe_file_name, environment_executable_name() ) ) is_self = true; string_deallocate( exe_file_name ); if( is_self ) continue; //Don't run self process_path = path_merge( environment_executable_directory(), exe_paths[iexe] ); process = process_allocate(); process_set_executable_path( process, process_path ); process_set_working_directory( process, environment_executable_directory() ); process_set_flags( process, PROCESS_ATTACHED | exe_flags[iexe] ); log_infof( HASH_TEST, "Running test executable: %s", exe_paths[iexe] ); process_result = process_spawn( process ); while( process_result == PROCESS_WAIT_INTERRUPTED ) { thread_sleep( 10 ); process_result = process_wait( process ); } process_deallocate( process ); string_deallocate( process_path ); if( process_result != 0 ) { if( process_result >= PROCESS_INVALID_ARGS ) log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed, process terminated with error %x", process_result ); else log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed with exit code %d", process_result ); process_set_exit_code( -1 ); goto exit; } log_infof( HASH_TEST, "All tests from %s passed (%d)", exe_paths[iexe], process_result ); } log_info( HASH_TEST, "All tests passed" ); exit: if( exe_paths ) string_array_deallocate( exe_paths ); array_deallocate( exe_flags ); #endif thread_terminate( thread ); thread_destroy( thread ); while( thread_is_running( thread ) ) thread_sleep( 10 ); while( thread_is_thread( thread ) ) thread_sleep( 10 ); return process_result; }