Пример #1
0
DECLARE_TEST( app, environment )
{
	EXPECT_STREQ( environment_application()->name, _global_app.name );
	EXPECT_STREQ( environment_application()->short_name, _global_app.short_name );
	EXPECT_STREQ( environment_application()->config_dir, _global_app.config_dir );
	EXPECT_TRUE( uint128_equal( environment_application()->version.version, _global_app.version.version ) );
	return 0;
}
Пример #2
0
static void _log_outputf( uint64_t context, int severity, const char* prefix, const char* format, va_list list, void* std )
{
	log_timestamp_t timestamp = _log_make_timestamp();
	uint64_t tid = thread_id();
	unsigned int pid = thread_hardware();
	int need, more, remain, size = 383;
	char local_buffer[385];
	char* buffer = local_buffer;
	while(1)
	{
		//This is guaranteed to always fit in minimum size of 383 bytes defined above, so need is always > 0
		if( _log_prefix )
			need = snprintf( buffer, size, "[%u:%02u:%02u.%03u] <%" PRIx64 ":%d> %s", timestamp.hours, timestamp.minutes, timestamp.seconds, timestamp.milliseconds, tid, pid, prefix );
		else
			need = snprintf( buffer, size, "%s", prefix );

		remain = size - need;
		{
			va_list clist;
			va_copy( clist, list );
			more = vsnprintf( buffer + need, remain, format, clist );
			va_end( clist );
		}
			
		if( ( more > -1 ) && ( more < remain ) )
		{
			buffer[need+more] = '\n';
			buffer[need+more+1] = 0;

#if FOUNDATION_PLATFORM_WINDOWS
			OutputDebugStringA( buffer );
#endif

#if FOUNDATION_PLATFORM_ANDROID
			if( _log_stdout )
				__android_log_write( ANDROID_LOG_DEBUG + severity - 1, environment_application()->short_name, buffer );
#else
			if( _log_stdout && std )
				fprintf( std, "%s", buffer );
#endif

			if( _log_callback )
				_log_callback( context, severity, buffer );

			break;
		}

		if( ( more > -1 ) && ( need > -1 ) )
			size = more + need + 1;
		else
			size *= 2;

		if( buffer != local_buffer )
			memory_deallocate( buffer );
		buffer = memory_allocate( size + 2, 0, MEMORY_TEMPORARY );
	}
	if( buffer != local_buffer )
		memory_deallocate( buffer );
}
Пример #3
0
int STDCALL
WinMain(HINSTANCE instance, HINSTANCE previnst, LPSTR cline, int cmd_show) {
	int ret;

	FOUNDATION_UNUSED(instance);
	FOUNDATION_UNUSED(previnst);
	FOUNDATION_UNUSED(cline);
	FOUNDATION_UNUSED(cmd_show);

	if (main_initialize() < 0)
		return -1;

	SetConsoleCtrlHandler(_main_console_handler, TRUE);

	thread_set_main();

	foundation_startup();

	system_post_event(FOUNDATIONEVENT_START);

#if BUILD_DEBUG
	ret = main_run(0);
#else
	{
		string_t name;
		const application_t* app = environment_application();
		string_const_t aname = app->short_name;
		string_const_t vstr = string_from_version_static(app->version);
		name = string_allocate_concat_varg(
			aname.length ? aname.str : "unknown", aname.length ? aname.length : 7,
			STRING_CONST("-"),
			STRING_CONST(vstr));

		if (app->dump_callback)
			crash_guard_set(app->dump_callback, STRING_ARGS(name));

		ret = crash_guard(main_run, 0, app->dump_callback, STRING_ARGS(name));

		string_deallocate(name.str);
	}
#endif

	main_finalize();

	return ret;
}
Пример #4
0
bool system_message_box( const char* title, const char* message, bool cancel_button )
{
	if( environment_application()->flags & APPLICATION_UTILITY )
		return true;

#if FOUNDATION_PLATFORM_WINDOWS
	return ( MessageBoxA( 0, message, title, cancel_button ? MB_OKCANCEL : MB_OK ) == IDOK );
#elif FOUNDATION_PLATFORM_APPLE
	return _system_show_alert( title, message, cancel_button ? 1 : 0 ) > 0;
#elif 0//FOUNDATION_PLATFORM_LINUX
	char* buf = string_format( "%s\n\n%s\n", title, message );
	pid_t pid = fork();

	switch( pid )
	{
		case -1:
			//error
			string_deallocate( buf );
			break;

		case 0:
			execlp( "xmessage", "xmessage", "-buttons", cancel_button ? "OK:101,Cancel:102" : "OK:101", "-default", "OK", "-center", buf, (char*)0 );
			_exit( -1 );
			break;

		default:
		{
			string_deallocate( buf );
			int status;
			waitpid( pid, &status, 0 );
			if( ( !WIFEXITED( status ) ) || ( WEXITSTATUS( status ) != 101 ) )
				return false;
			return true;
		}
	}

	return false;
#else
	//Not implemented
	return false;
#endif
}
Пример #5
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;
}
Пример #6
0
/*! Normal entry point for all platforms, including Windows console applications */
int
main(int argc, char** argv)
#endif
{
	int ret;

#if !FOUNDATION_PLATFORM_ANDROID && !FOUNDATION_PLATFORM_PNACL
	_environment_main_args(argc, (const char* const*)argv);
#elif FOUNDATION_PLATFORM_PNACL
	FOUNDATION_UNUSED(instance);
#endif

	ret = main_initialize();
	if (ret < 0)
		return ret;

#if FOUNDATION_PLATFORM_POSIX

	//Set signal handlers
	{
		struct sigaction action;
		memset(&action, 0, sizeof(action));

#if FOUNDATION_COMPILER_CLANG
#  pragma clang diagnostic push
#  pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
#endif

		//Signals we process globally
		action.sa_handler = sighandler;
		sigaction(SIGKILL, &action, 0);
		sigaction(SIGTERM, &action, 0);
		sigaction(SIGQUIT, &action, 0);
		sigaction(SIGINT,  &action, 0);
		sigaction(SIGABRT, &action, 0);

		//Ignore sigpipe
		action.sa_handler = SIG_IGN;
		sigaction(SIGPIPE, &action, 0);

#if FOUNDATION_COMPILER_CLANG
#  pragma clang diagnostic pop
#endif
	}

#endif

#if FOUNDATION_PLATFORM_ANDROID
	if ((ret = android_initialize()) < 0)
		return ret;
#endif

#if FOUNDATION_PLATFORM_TIZEN
	if ((ret = tizen_initialize()) < 0)
		return ret;
#endif

#if FOUNDATION_PLATFORM_WINDOWS

	SetConsoleCtrlHandler(_main_console_handler, TRUE);

#endif

	thread_set_main();

	foundation_startup();

#if FOUNDATION_PLATFORM_WINDOWS || FOUNDATION_PLATFORM_LINUX || FOUNDATION_PLATFORM_PNACL
	system_post_event(FOUNDATIONEVENT_START);
#endif

#if FOUNDATION_PLATFORM_APPLE
#  if FOUNDATION_PLATFORM_MACOSX
	if (!(environment_application()->flags & APPLICATION_UTILITY)) {
		delegate_start_main_ns_thread();

		extern int NSApplicationMain(int argc, char* argv[]);
		ret = NSApplicationMain(argc, argv);

#  elif FOUNDATION_PLATFORM_IOS
	{
		delegate_start_main_ns_thread();

		extern int UIApplicationMain(int argc, char* argv[], void* principalClassName,
		                             void* delegateClassName);
		ret = UIApplicationMain(argc, (char**)argv, 0, 0);

#  endif
		//NSApplicationMain and UIApplicationMain never returns though
		return ret;
	}
#endif

#if !FOUNDATION_PLATFORM_IOS

#  if FOUNDATION_PLATFORM_TIZEN
	tizen_start_main_thread();
	ret = tizen_app_main(argc, argv);
#  else
	{
		string_t name;
		const application_t* app = environment_application();
		{
			string_const_t vstr = string_from_version_static(app->version);
			string_const_t aname = app->short_name;
			if (!aname.length)
				aname = string_const(STRING_CONST("unknown"));
			name = string_allocate_format(STRING_CONST("%.*s-%.*s"), (int)aname.length, aname.str,
			                              (int)vstr.length, vstr.str);
		}

		if (app->dump_callback)
			crash_guard_set(app->dump_callback, name.str, name.length);

		if (system_debugger_attached())
			ret = main_run(0);
		else
			ret = crash_guard(main_run, 0, app->dump_callback, name.str, name.length);

		string_deallocate(name.str);
	}
#  endif

	main_finalize();

#if FOUNDATION_PLATFORM_ANDROID
	android_finalize();
#endif

#if FOUNDATION_PLATFORM_TIZEN
	tizen_finalize();
#endif

	return ret;
#endif
}

#if FOUNDATION_PLATFORM_ANDROID

/*! Android native glue entry point */
void
android_main(struct android_app * app) {
	if (!app)
		return;
	android_entry(app);
	real_main();
}

#endif

#if FOUNDATION_PLATFORM_PNACL

/*! PNaCl glue entry points */
PP_EXPORT int32_t
PPP_InitializeModule(PP_Module module_id, PPB_GetInterface get_browser) {
	return pnacl_module_initialize(module_id, get_browser);
}

PP_EXPORT const void*
PPP_GetInterface(const char* interface_name) {
	return pnacl_module_interface(interface_name, string_length(interface_name));
}

PP_EXPORT void
PPP_ShutdownModule() {
	pnacl_module_finalize();
}
Пример #7
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 );
}