Ejemplo n.º 1
0
DECLARE_TEST( fs, directory )
{
	char* longpath;
	char* testpath = path_merge( environment_temporary_directory(), string_from_int_static( random64(), 0, 0 ) );

	if( !fs_is_file( testpath ) )
		fs_remove_file( testpath );
	if( !fs_is_directory( testpath ) )
		fs_make_directory( testpath );

	EXPECT_TRUE( fs_is_directory( testpath ) );

	fs_remove_directory( testpath );
	EXPECT_FALSE( fs_is_directory( testpath ) );

	longpath = path_merge( testpath, string_from_int_static( random64(), 0, 0 ) );
	EXPECT_FALSE( fs_is_directory( longpath ) );

	fs_make_directory( longpath );
	EXPECT_TRUE( fs_is_directory( longpath ) );

	fs_remove_directory( testpath );
	EXPECT_FALSE( fs_is_directory( testpath ) );
	EXPECT_FALSE( fs_is_directory( longpath ) );

	string_deallocate( longpath );
	string_deallocate( testpath );

	return 0;
}
Ejemplo n.º 2
0
DECLARE_TEST( fs, util )
{
	tick_t systime = time_system();
	tick_t lastmod = 0;
	char* testpath = path_merge( environment_temporary_directory(), string_from_int_static( random64(), 0, 0 ) );

	if( !fs_is_directory( environment_temporary_directory() ) )
		fs_make_directory( environment_temporary_directory() );

	if( fs_is_directory( testpath ) )
		fs_remove_directory( testpath );
	fs_remove_file( testpath );

	EXPECT_EQ( fs_last_modified( testpath ), 0 );

	thread_sleep( 1000 ); //For fs time granularity, make sure at least one second passed since systime

	stream_deallocate( fs_open_file( testpath, STREAM_OUT ) );
	EXPECT_TRUE( fs_is_file( testpath ) );
	EXPECT_GE( fs_last_modified( testpath ), systime );

	fs_remove_file( testpath );
	EXPECT_FALSE( fs_is_file( testpath ) );
	EXPECT_EQ( fs_last_modified( testpath ), 0 );

	stream_deallocate( fs_open_file( testpath, STREAM_OUT ) );
	EXPECT_TRUE( fs_is_file( testpath ) );
	EXPECT_GE( fs_last_modified( testpath ), systime );

	lastmod = fs_last_modified( testpath );

	thread_sleep( 5000 );

	EXPECT_EQ( fs_last_modified( testpath ), lastmod );

	fs_touch( testpath );
	EXPECT_GT( fs_last_modified( testpath ), lastmod );

	fs_remove_file( testpath );
	string_deallocate( testpath );

	return 0;
}
Ejemplo n.º 3
0
const char* environment_home_directory( void )
{
	if( _environment_home_dir[0] )
		return _environment_home_dir;
#if FOUNDATION_PLATFORM_WINDOWS
	{
		char* path;
		wchar_t* wpath = memory_allocate_zero( sizeof( wchar_t ) * FOUNDATION_MAX_PATHLEN, 0, MEMORY_TEMPORARY );
		SHGetFolderPathW( 0, CSIDL_LOCAL_APPDATA, 0, 0, wpath );
		path = path_clean( string_allocate_from_wstring( wpath, 0 ), true );
		string_copy( _environment_home_dir, path, FOUNDATION_MAX_PATHLEN );
		string_deallocate( path );
		memory_deallocate( wpath );
	}
#elif FOUNDATION_PLATFORM_LINUX
	string_copy( _environment_home_dir, environment_variable( "HOME" ), FOUNDATION_MAX_PATHLEN );
#elif FOUNDATION_PLATFORM_APPLE
	if( environment_application()->flags & APPLICATION_UTILITY )
	{
		CFStringRef home = NSHomeDirectory();
		CFStringGetCString( home, _environment_home_dir, FOUNDATION_MAX_PATHLEN, kCFStringEncodingUTF8 );
	}
	else
	{
		char bundle_identifier[FOUNDATION_MAX_PATHLEN+1];
		environment_bundle_identifier( bundle_identifier );
		
		char* path = path_append( path_merge( _environment_home_dir, "/Library/Application Support" ), bundle_identifier );
		string_copy( _environment_home_dir, path, FOUNDATION_MAX_PATHLEN );
		string_deallocate( path );
	}
#elif FOUNDATION_PLATFORM_ANDROID
	string_copy( _environment_home_dir, android_app()->activity->internalDataPath, FOUNDATION_MAX_PATHLEN );
#else
#  error Not implemented
#endif
	return _environment_home_dir;
}
Ejemplo n.º 4
0
int main_run( void* main_arg )
{
#if !BUILD_MONOLITHIC
	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
#if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL
	int remain_counter = 0;
#endif
#if BUILD_DEBUG
	const char* build_name = "debug";
#elif BUILD_RELEASE
	const char* build_name = "release";
#elif BUILD_PROFILE
	const char* build_name = "profile";
#elif BUILD_DEPLOY
	const char* build_name = "deploy";
#endif
	int process_result = 0;
	object_t thread = 0;
	FOUNDATION_UNUSED( main_arg );
	FOUNDATION_UNUSED( build_name );

	log_set_suppress( HASH_TEST, ERRORLEVEL_DEBUG );

	log_infof( HASH_TEST, "Foundation library v%s built for %s using %s (%s)", string_from_version_static( foundation_version() ), FOUNDATION_PLATFORM_DESCRIPTION, FOUNDATION_COMPILER_DESCRIPTION, build_name );

	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 )
	{
#if FOUNDATION_PLATFORM_ANDROID
		system_process_events();
#endif
		thread_sleep( 100 );
	}
#endif

	fs_remove_directory( environment_temporary_directory() );

#if BUILD_MONOLITHIC

	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_process_run,
		test_profile_run,
		test_radixsort_run,
		test_random_run,
		test_regex_run,
		test_ringbuffer_run,
		test_semaphore_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

	object_t test_thread = thread_create( test_runner, "test_runner", THREAD_PRIORITY_NORMAL, 0 );
	thread_start( test_thread, tests );

	log_debug( HASH_TEST, "Starting test runner thread" );

	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 );

#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, "Exiting main loop" );

#else // !BUILD_MONOLITHIC

	//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 applications
	const char* app_pattern = "^test-.*\\.app$";
	regex_t* app_regex = regex_compile( app_pattern );
	char** subdirs = fs_subdirs( environment_executable_directory() );
	for( int idir = 0, dirsize = array_size( subdirs ); idir < dirsize; ++idir )
	{
		if( regex_match( app_regex, subdirs[idir], string_length( subdirs[idir] ), 0, 0 ) )
		{
			array_push( exe_paths, string_substr( subdirs[idir], 0, string_length( subdirs[idir] ) - 4 ) );
			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 )
	{
		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 );

	log_infof( HASH_TEST, "Tests exiting: %d", process_result );

	return process_result;
}
Ejemplo n.º 5
0
DECLARE_TEST( profile, stream )
{
	object_t thread[32];
	int ith;
	int frame;
	char* filename;

	error();

	filename = path_merge( environment_temporary_directory(), "test.profile" );
	log_infof( HASH_TEST, "Output to profile file: %s", filename );
	fs_make_directory( environment_temporary_directory() );
	_profile_stream = fs_open_file( filename, STREAM_OUT | STREAM_BINARY );
	string_deallocate( filename );

	profile_initialize( "test_profile", _test_profile_buffer, _test_profile_buffer_size );
	profile_set_output( _profile_file_writer );
	profile_set_output_wait( 10 );
	profile_enable( true );

	for( ith = 0; ith < 32; ++ith )
	{
		thread[ith] = thread_create( _profile_stream_thread, "profile_thread", THREAD_PRIORITY_NORMAL, 0 );
		thread_start( thread[ith], 0 );
	}

	test_wait_for_threads_startup( thread, 32 );

	for( frame = 0; frame < 1000; ++frame )
	{
		thread_sleep( 16 );
		profile_log( "This is a really long profile log line that should break into multiple profile blocks automatically without causing any issues whatsoever if everything works as expected which it should or the code needs to be fixed" );
		profile_end_frame( frame++ );
		if( ( frame % 30 ) == 0 )
		{
			profile_enable( false );
			thread_sleep( 10 );
			profile_enable( true );
		}
	}

	for( ith = 0; ith < 32; ++ith )
	{
		thread_terminate( thread[ith] );
		thread_destroy( thread[ith] );
		thread_yield();
	}

	test_wait_for_threads_exit( thread, 32 );

	profile_end_frame( frame++ );
	profile_set_output_wait( 100 );

	thread_sleep( 1000 );

	profile_enable( false );
	profile_shutdown();

	error();

	stream_deallocate( _profile_stream );

	//TODO: Validate that output is sane
	log_debugf( HASH_TEST, "Generated %lld blocks", atomic_load64( &_profile_generated_blocks ) );

	return 0;
}
Ejemplo n.º 6
0
DECLARE_TEST( fs, file )
{
	char* testpath = path_merge( environment_temporary_directory(), string_from_int_static( random64(), 0, 0 ) );
	char* copypath = path_merge( environment_temporary_directory(), string_from_int_static( random64(), 0, 0 ) );
	stream_t* teststream = 0;

	if( !fs_is_directory( environment_temporary_directory() ) )
		fs_make_directory( environment_temporary_directory() );

	if( fs_is_directory( testpath ) )
		fs_remove_directory( testpath );
	fs_remove_file( testpath );

	if( fs_is_directory( copypath ) )
		fs_remove_directory( copypath );
	fs_remove_file( copypath );


	teststream = fs_open_file( testpath, STREAM_IN );
	EXPECT_EQ( teststream, 0 );
	EXPECT_FALSE( fs_is_file( testpath ) );

	teststream = fs_open_file( testpath, STREAM_IN | STREAM_OUT );
	EXPECT_NE( teststream, 0 );
	EXPECT_TRUE( fs_is_file( testpath ) );

	stream_deallocate( teststream );
	fs_remove_file( testpath );
	teststream = fs_open_file( testpath, STREAM_IN );
	EXPECT_EQ( teststream, 0 );
	EXPECT_FALSE( fs_is_file( testpath ) );

	teststream = fs_open_file( testpath, STREAM_OUT );
	EXPECT_NE( teststream, 0 );
	EXPECT_TRUE( fs_is_file( testpath ) );

	stream_deallocate( teststream );
	teststream = 0;

	fs_copy_file( testpath, copypath );
	EXPECT_TRUE( fs_is_file( copypath ) );

	fs_remove_file( copypath );
	EXPECT_FALSE( fs_is_file( copypath ) );

	teststream = fs_open_file( testpath, STREAM_OUT );
	EXPECT_NE( teststream, 0 );
	EXPECT_TRUE( fs_is_file( testpath ) );

	stream_write_string( teststream, "testing testing" );

	stream_deallocate( teststream );
	teststream = 0;

	fs_copy_file( testpath, copypath );
	EXPECT_TRUE( fs_is_file( copypath ) );

	fs_remove_file( copypath );
	EXPECT_FALSE( fs_is_file( copypath ) );

	stream_deallocate( teststream );
	string_deallocate( testpath );
	string_deallocate( copypath );

	return 0;
}
Ejemplo n.º 7
0
DECLARE_TEST( fs, monitor )
{
	char* testpath = path_merge( environment_temporary_directory(), string_from_int_static( random64(), 0, 0 ) );
	char* filetestpath = path_merge( testpath, string_from_int_static( random64(), 0, 0 ) );

	stream_t* test_stream;

	event_stream_t* stream;
	event_block_t* block;
	event_t* event;
	
	stream = fs_event_stream();

	if( fs_is_file( testpath ) )
		fs_remove_file( testpath );
	if( !fs_is_directory( testpath ) )
		fs_make_directory( testpath );
	if( fs_is_file( filetestpath ) )
		fs_remove_file( filetestpath );

	stream_deallocate( fs_open_file( filetestpath, STREAM_OUT ) );
	fs_remove_file( filetestpath );

	block = event_stream_process( stream );
	event = event_next( block, 0 );
	EXPECT_EQ( event, 0 );

	fs_monitor( testpath );
	thread_sleep( 1000 );

	stream_deallocate( fs_open_file( filetestpath, STREAM_OUT ) );
	thread_sleep( 100 );

	block = event_stream_process( stream );
	event = event_next( block, 0 );
	EXPECT_NE( event, 0 );
	EXPECT_EQ( event->system, SYSTEM_FOUNDATION );
	EXPECT_EQ( event->id, FOUNDATIONEVENT_FILE_CREATED );
	EXPECT_STREQ( event->payload, filetestpath );

	event = event_next( block, event );
	EXPECT_EQ( event, 0 );

	test_stream = fs_open_file( filetestpath, STREAM_IN | STREAM_OUT );
	stream_write_string( test_stream, filetestpath );
	stream_deallocate( test_stream );
	thread_sleep( 100 );

	block = event_stream_process( stream );
	event = event_next( block, 0 );
	EXPECT_NE( event, 0 );
	EXPECT_EQ( event->system, SYSTEM_FOUNDATION );
	EXPECT_EQ( event->id, FOUNDATIONEVENT_FILE_MODIFIED );
	EXPECT_STREQ( event->payload, filetestpath );

	event = event_next( block, event );
	EXPECT_EQ( event, 0 );

	fs_remove_file( filetestpath );
	thread_sleep( 100 );

	block = event_stream_process( stream );
	event = event_next( block, 0 );
	EXPECT_NE( event, 0 );
	EXPECT_EQ( event->system, SYSTEM_FOUNDATION );
	EXPECT_EQ( event->id, FOUNDATIONEVENT_FILE_DELETED );
	EXPECT_STREQ( event->payload, filetestpath );

	event = event_next( block, event );
	EXPECT_EQ( event, 0 );

	fs_unmonitor( testpath );
	thread_sleep( 1000 );
	
	block = event_stream_process( stream );
	event = event_next( block, 0 );
	EXPECT_EQ( event, 0 );

	stream_deallocate( fs_open_file( filetestpath, STREAM_OUT ) );
	thread_sleep( 100 );

	block = event_stream_process( stream );
	event = event_next( block, 0 );
	EXPECT_EQ( event, 0 );

	fs_remove_file( filetestpath );
	thread_sleep( 100 );

	block = event_stream_process( stream );
	event = event_next( block, 0 );
	EXPECT_EQ( event, 0 );

	fs_remove_directory( testpath );

	string_deallocate( testpath );
	string_deallocate( filetestpath );

	return 0;
}
Ejemplo n.º 8
0
DECLARE_TEST( fs, query )
{
	uint64_t subpathid = random64();
	uint64_t subfileid = random64();
	char* testpath = path_merge( environment_temporary_directory(), string_from_int_static( random64(), 0, 0 ) );
	char* subtestpath = path_merge( testpath, string_from_int_static( subpathid, 0, 0 ) );
	char* filepath[8];
	char** subdirs;
	char** files;
	int ifp = 0;
	char* subfilepath;

	if( fs_is_file( testpath ) )
		fs_remove_file( testpath );
	if( !fs_is_directory( testpath ) )
		fs_make_directory( testpath );
	if( !fs_is_directory( subtestpath ) )
		fs_make_directory( subtestpath );

	for( ifp = 0; ifp < 8; ++ifp )
	{
		filepath[ifp] = path_merge( testpath, string_from_int_static( random64(), 0, 0 ) );
		filepath[ifp] = string_append( string_append( filepath[ifp], "." ), string_from_int_static( ifp, 0, 0 ) );
		stream_deallocate( fs_open_file( filepath[ifp], STREAM_OUT ) );
	}

	subfilepath = path_merge( subtestpath, string_from_int_static( subfileid, 0, 0 ) );
	subfilepath = string_append( subfilepath, ".0" );
	stream_deallocate( fs_open_file( subfilepath, STREAM_OUT ) );

	files = fs_files( filepath[0] );
	EXPECT_EQ( array_size( files ), 0 );
	string_array_deallocate( files );

	subdirs = fs_subdirs( subtestpath );
	EXPECT_EQ( array_size( subdirs ), 0 );
	string_array_deallocate( subdirs );

	files = fs_files( testpath );
	EXPECT_EQ( array_size( files ), 8 );
	string_array_deallocate( files );

	subdirs = fs_subdirs( testpath );
	EXPECT_EQ( array_size( subdirs ), 1 );
	string_array_deallocate( subdirs );

	files = fs_matching_files( testpath, "*", false );
	EXPECT_EQ( array_size( files ), 8 );
	string_array_deallocate( files );

	files = fs_matching_files( testpath, "*", true );
	EXPECT_EQ( array_size( files ), 9 );
	string_array_deallocate( files );

	files = fs_matching_files( testpath, "*.0", false );
	EXPECT_EQ( array_size( files ), 1 );
	string_array_deallocate( files );

	files = fs_matching_files( testpath, "*.0", true );
	EXPECT_EQ( array_size( files ), 2 );
	string_array_deallocate( files );

	files = fs_matching_files( testpath, "*.1", false );
	EXPECT_EQ( array_size( files ), 1 );
	string_array_deallocate( files );

	files = fs_matching_files( testpath, "*.1", true );
	EXPECT_EQ( array_size( files ), 1 );
	string_array_deallocate( files );

	files = fs_matching_files( testpath, "*.?", true );
	EXPECT_EQ( array_size( files ), 9 );
	{
		char* verifypath = string_from_int( subpathid, 0, 0 );
		verifypath = path_append( verifypath, string_from_int_static( subfileid, 0, 0 ) );
		verifypath = string_append( verifypath, ".0" );
		EXPECT_STREQ( files[8], verifypath );
		string_deallocate( verifypath );
	}
	string_array_deallocate( files );

	fs_remove_directory( testpath );

	string_array_deallocate( subdirs );
	string_array_deallocate( files );
	string_deallocate( subfilepath );
	for( ifp = 0; ifp < 8; ++ifp )
		string_deallocate( filepath[ifp] );
	string_deallocate( subtestpath );
	string_deallocate( testpath );
	return 0;
}
Ejemplo n.º 9
0
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 );
}
Ejemplo n.º 10
0
char* path_make_temporary( void )
{
	char uintbuffer[18];
	return path_merge( environment_temporary_directory(), string_from_uint_buffer( uintbuffer, random64(), true, 0, '0' ) );
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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;
}