Beispiel #1
0
int hashify_check_local_consistency( const char* string, hash_t hash_value, const hashify_string_t* local_hashes )
{
	int ilocal, localsize;
	for( ilocal = 0, localsize = array_size( local_hashes ); ilocal < localsize; ++ilocal )
	{
		if( local_hashes[ilocal].hash == hash_value )
		{
			if( !string_equal( local_hashes[ilocal].string, string ) )
			{
				log_errorf( ERROR_INVALID_VALUE, "  hash string mismatch, \"%s\" with hash 0x%llx stored in output file, read \"%s\" from input file", local_hashes[ilocal].string, local_hashes[ilocal].hash, string );
				return HASHIFY_RESULT_HASH_STRING_MISMATCH;
			}
			break;
		}
		else if( string_equal( local_hashes[ilocal].string, string ) )
		{
			log_errorf( ERROR_INVALID_VALUE, "  hash mismatch, \"%s\" with hash 0x%llx stored in output file, read \"%s\" with hash 0x%llx from input file", local_hashes[ilocal].string, local_hashes[ilocal].hash, string, hash_value );
			return HASHIFY_RESULT_HASH_MISMATCH;
		}
	}
	if( ilocal == localsize )
	{
		log_errorf( ERROR_INVALID_VALUE, "  hash missing in output file, \"%s\" with hash 0x%llx ", string, hash_value );
		return HASHIFY_RESULT_HASH_MISSING;
	}

	return HASHIFY_RESULT_OK;
}
Beispiel #2
0
int hashify_check_match( const hashify_string_t* hashes, const hashify_string_t* generated )
{
	//From hashify_check_local_consistency we know that generated array already is a subset of hashes
	//This test checks that hashes is a subset of generated, i.e sets are equal
	int ihash, hashes_size, igen, generated_size;
	for( ihash = 0, hashes_size = array_size( hashes ); ihash < hashes_size; ++ihash )
	{
		for( igen = 0, generated_size = array_size( generated ); igen < generated_size; ++igen )
		{
			if( hashes[ihash].hash == generated[igen].hash )
			{
				if( !string_equal( hashes[ihash].string, generated[igen].string ) )
				{
					log_errorf( ERROR_INVALID_VALUE, "  hash string mismatch, \"%s\" with hash 0x%llx stored in output file, generated by \"%s\" from input file", hashes[ihash].string, hashes[ihash].hash, generated[igen].string );
					return HASHIFY_RESULT_HASH_STRING_MISMATCH;
				}
				break;
			}
			else if( string_equal( hashes[ihash].string, generated[igen].string ) )
			{
				log_errorf( ERROR_INVALID_VALUE, "  hash mismatch, \"%s\" with hash 0x%llx stored in output file, \"%s\" generated hash 0x%llx from input file", hashes[ihash].string, hashes[ihash].hash, generated[igen].string, generated[igen].hash );
				return HASHIFY_RESULT_HASH_MISMATCH;
			}
		}
		if( igen == generated_size )
		{
			log_errorf( ERROR_INVALID_VALUE, "  extra hash \"%s\" with hash 0x%llx not found in input file", hashes[ihash].string, hashes[ihash].hash );
			return HASHIFY_RESULT_EXTRA_STRING;
		}
	}
	return HASHIFY_RESULT_OK;
}
Beispiel #3
0
int
hashify_check_local_consistency(string_const_t string, hash_t hash_value,
                                const hashify_string_t* local_hashes) {
	size_t ilocal, localsize;
	for (ilocal = 0, localsize = array_size(local_hashes); ilocal < localsize; ++ilocal) {
		if (local_hashes[ilocal].hash == hash_value) {
			if (!string_equal(local_hashes[ilocal].string.str, local_hashes[ilocal].string.length, string.str,
			                  string.length)) {
				log_errorf(0, ERROR_INVALID_VALUE,
				           STRING_CONST("  hash string mismatch, \"%.*s\" with hash 0x%" PRIx64
				                        " stored in output file, read \"%.*s\" from input file"),
				           STRING_FORMAT(local_hashes[ilocal].string), local_hashes[ilocal].hash, STRING_FORMAT(string));
				return HASHIFY_RESULT_HASH_STRING_MISMATCH;
			}
			break;
		}
		else if (string_equal(local_hashes[ilocal].string.str, local_hashes[ilocal].string.length,
		                      string.str, string.length)) {
			log_errorf(0, ERROR_INVALID_VALUE,
			           STRING_CONST("  hash mismatch, \"%.*s\" with hash 0x%" PRIx64
			                        " stored in output file, read \"%.*s\" with hash 0x%" PRIx64 " from input file"),
			           STRING_FORMAT(local_hashes[ilocal].string), local_hashes[ilocal].hash, STRING_FORMAT(string),
			           hash_value);
			return HASHIFY_RESULT_HASH_MISMATCH;
		}
	}
	if (ilocal == localsize) {
		log_errorf(0, ERROR_INVALID_VALUE,
		           STRING_CONST("  hash missing in output file, \"%.*s\" with hash 0x%" PRIx64), STRING_FORMAT(string),
		           hash_value);
		return HASHIFY_RESULT_HASH_MISSING;
	}

	return HASHIFY_RESULT_OK;
}
Beispiel #4
0
shaderprogram_t* program_create(shader_t& vertexShader, const char* vertexName, shader_t& fragmentShader, const char* fragmentName)
{
	GLint handle = glCreateProgram();

	glAttachShader(handle, vertexShader.buffer);
	glAttachShader(handle, fragmentShader.buffer);
	glLinkProgram(handle);
	mint_CHECKFORGLERROR;
		
	int32_t logLength, linked;
	glGetProgramiv(handle, GL_LINK_STATUS, &linked);
	glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &logLength);
	if (logLength)
	{
		int32_t charsWritten;
		ScopedRawBuffer<GLchar> logBuffer(malloc(logLength+128));
		glGetProgramInfoLog(handle, logLength, &charsWritten, logBuffer.get());
		log_errorf(ERROR_NONE,"Link results: %s", logBuffer.get());
	}
	if(!linked)
	{
		log_errorf(ERROR_NONE, "Link failed when creating shader program from %s and %s", vertexName, fragmentName);
		return NULL;
	}

	shaderprogram_t* shaderProgram = (shaderprogram_t*) memory_allocate(sizeof(shaderprogram_t), 4, MEMORY_PERSISTENT);
	shaderProgram->program = handle;
	shaderProgram->vertexShader = vertexShader;
	shaderProgram->fragmentShader = fragmentShader;
	return shaderProgram;
}
Beispiel #5
0
int
assert_report(hash_t context, const char* condition, size_t cond_length, const char* file,
              size_t file_length, unsigned int line, const char* msg, size_t msg_length) {
	static const char nocondition[] = "<Static fail>";
	static const char nofile[] = "<No file>";
	static const char nomsg[] = "<No message>";
	static const char assert_format[] =
	    "****** ASSERT FAILED ******\nCondition: %.*s\nFile/line: %.*s : %d\n%.*s%.*s\n%.*s\n";
#if BUILD_ENABLE_ASSERT
	string_t tracestr = { _assert_stacktrace_buffer, sizeof(_assert_stacktrace_buffer) };
	string_t contextstr = { _assert_context_buffer, sizeof(_assert_context_buffer) };
	string_t messagestr = { _assert_message_buffer, sizeof(_assert_message_buffer) };
#endif

	if (!condition || !cond_length) { condition = nocondition; cond_length = sizeof(nocondition); }
	if (!file || !file_length) { file = nofile; file_length = sizeof(nofile); }
	if (!msg || !msg_length) { msg = nomsg; msg_length = sizeof(nomsg); }

	if (_assert_handler && (_assert_handler != assert_report))
		return (*_assert_handler)(context, condition, cond_length, file, file_length, line, msg,
		                          msg_length);

#if BUILD_ENABLE_ASSERT
	contextstr = error_context_buffer(STRING_ARGS(contextstr));

	if (foundation_is_initialized()) {
		size_t num_frames = stacktrace_capture(_assert_stacktrace, ASSERT_STACKTRACE_MAX_DEPTH,
		                                       ASSERT_STACKTRACE_SKIP_FRAMES);
		if (num_frames)
			tracestr = stacktrace_resolve(STRING_ARGS(tracestr), _assert_stacktrace, num_frames, 0U);
		else
			tracestr = string_copy(STRING_ARGS(tracestr), STRING_CONST("<no stacktrace>"));
	}
	else {
		tracestr = string_copy(STRING_ARGS(tracestr), STRING_CONST("<no stacktrace - not initialized>"));
	}

	messagestr = string_format(STRING_ARGS(messagestr), assert_format, sizeof(assert_format) - 1,
	                           (int)cond_length, condition, (int)file_length, file, line,
	                           STRING_FORMAT(contextstr), (int)msg_length, msg,
	                           STRING_FORMAT(tracestr));

	log_errorf(context, ERROR_ASSERT, STRING_CONST("%.*s"), STRING_FORMAT(messagestr));

	system_message_box(STRING_CONST("Assert Failure"), STRING_ARGS(messagestr), false);
#else
	log_errorf(context, ERROR_ASSERT, assert_format, sizeof(assert_format) - 1,
	           (int)cond_length, condition, (int)file_length, file, line,
	           0, "", (int)msg_length, msg, 0, "");
#endif

	return 1;
}
Beispiel #6
0
int
hashify_write_file(stream_t* generated_file, string_t output_filename) {
	bool need_update = false;
	stream_t* output_file = 0;
	int result = HASHIFY_RESULT_OK;

	output_file = stream_open(STRING_ARGS(output_filename), STREAM_OUT | STREAM_IN);
	if (!output_file) {
		need_update = true;
		output_file = stream_open(STRING_ARGS(output_filename), STREAM_OUT);
		if (!output_file) {
			log_warnf(0, WARNING_INVALID_VALUE, STRING_CONST("Unable to open output file: %.*s"),
			          STRING_FORMAT(output_filename));
			return HASHIFY_RESULT_MISSING_OUTPUT_FILE;
		}
	}

	if (!need_update)
		need_update = !uint128_equal(stream_md5(generated_file), stream_md5(output_file));

	if (need_update) {
		char local_buffer[1024];
		size_t read = 0;
		size_t written = 0;
		uint64_t total_written = 0;

		stream_seek(generated_file, 0, STREAM_SEEK_BEGIN);
		stream_seek(output_file, 0, STREAM_SEEK_BEGIN);

		while (!stream_eos(generated_file)) {
			read = stream_read(generated_file, local_buffer, 1024);
			if (!read)
				break;

			written = stream_write(output_file, local_buffer, read);
			total_written += written;

			if (written != read) {
				log_errorf(0, ERROR_SYSTEM_CALL_FAIL,
				           STRING_CONST("Unable to write to output file '%.*s': %" PRIsize " of %" PRIsize " bytes written"),
				           STRING_FORMAT(output_filename), written, read);
				result = HASHIFY_RESULT_OUTPUT_FILE_WRITE_FAIL;
				break;
			}
		}

		if (result == HASHIFY_RESULT_OK) {
			stream_truncate(output_file, (size_t)total_written);
			log_infof(0, STRING_CONST("  wrote %.*s : %" PRIu64 " bytes"), STRING_FORMAT(output_filename),
			          total_written);
		}
	}
	else {
		log_info(0, STRING_CONST("  hash file already up to date"));
	}

	stream_deallocate(output_file);

	return result;
}
Beispiel #7
0
ControllerMgr::ControllerMgr() :
    m_KBCtrl(),
    m_GameCtrl(),
    m_MenuCtrl(m_GameCtrl)
{
    m_GameCtrl.Add(&m_KBCtrl);

    std::string mappings = Resources::Map("gamecontrollerdb.txt");
    if(SDL_GameControllerAddMappingsFromFile(mappings.c_str())<0 ) {
        log_errorf("Couldn't load %s. Some controllers might not work.\n",mappings.c_str());
    }

    // scan for already-attached controllers
    int i;
    for(i=0; i<SDL_NumJoysticks(); ++i)
    {
        if (!SDL_IsGameController(i)) {
//            printf("joy %d is not controller\n",i);
            continue;
        }
        SDLController* c = new SDLController(i);
        m_Attached.push_back(c);
        m_GameCtrl.Add(c);
//        printf("Found controller: %d\n",c->InstanceID());
        break;
    }
}
const char* environment_current_working_directory( void )
{
	if( _environment_current_working_dir[0] )
		return _environment_current_working_dir;
#if FOUNDATION_PLATFORM_WINDOWS
	{
		char* path;
		wchar_t* wd = memory_allocate_zero( sizeof( wchar_t ) * FOUNDATION_MAX_PATHLEN, 0, MEMORY_TEMPORARY );
		GetCurrentDirectoryW( FOUNDATION_MAX_PATHLEN-1, wd );
		path = path_clean( string_allocate_from_wstring( wd, 0 ), true );
		string_copy( _environment_current_working_dir, path, FOUNDATION_MAX_PATHLEN );
		string_copy( _environment_current_working_dir, path, FOUNDATION_MAX_PATHLEN );
		string_deallocate( path );
		memory_deallocate( wd );
	}
#elif FOUNDATION_PLATFORM_POSIX
	char* path = memory_allocate_zero( FOUNDATION_MAX_PATHLEN, 0, MEMORY_TEMPORARY );
	if( !getcwd( path, FOUNDATION_MAX_PATHLEN ) )
	{
		log_errorf( ERROR_SYSTEM_CALL_FAIL, "Unable to get cwd: %s", system_error_message( 0 ) );
		return "";
	}
	path = path_clean( path, true );
	string_copy( _environment_current_working_dir, path, FOUNDATION_MAX_PATHLEN );
	memory_deallocate( path );
#else
#  error Not implemented
#endif
	return _environment_current_working_dir;
}
Beispiel #9
0
void
mutex_signal(mutex_t* mutex) {
#if !BUILD_DEPLOY
	profile_signal(mutex->name.str, mutex->name.length);
#endif

#if FOUNDATION_PLATFORM_WINDOWS

	SetEvent(mutex->event);

#elif FOUNDATION_PLATFORM_POSIX || FOUNDATION_PLATFORM_PNACL

	mutex_lock(mutex);
	mutex->pending = true;

	int ret = pthread_cond_broadcast(&mutex->cond);
	if (ret != 0) {
		string_const_t errmsg = system_error_message(ret);
		log_errorf(0, ERROR_SYSTEM_CALL_FAIL, STRING_CONST("Unable to signal mutex '%.*s': %.*s (%d)"),
		           STRING_FORMAT(mutex->name), STRING_FORMAT(errmsg), ret);
	}

	mutex_unlock(mutex);

#else
#  error mutex_signal not implemented
#endif
}
Beispiel #10
0
stream_t* stream_open( const char* path, unsigned int mode )
{
	unsigned int protocol_end;

	//Check if protocol was given
	protocol_end = string_find_string( path, "://", 0 );
	if( protocol_end != STRING_NPOS )
	{
		//TODO: Proper pluggable protocol handling
#if FOUNDATION_PLATFORM_ANDROID
		if( ( protocol_end == 5 ) && string_equal_substr( path, "asset", 5 ) )
			return asset_stream_open( path, mode );
		else
#endif
		if( ( protocol_end == 4 ) && string_equal_substr( path, "file", 4 ) )
			return fs_open_file( path, mode );
		else if( ( protocol_end == 4 ) && string_equal_substr( path, "stdout", 4 ) )
			return stream_open_stdout();
		else if( ( protocol_end == 4 ) && string_equal_substr( path, "stderr", 4 ) )
			return stream_open_stderr();
		else if( ( protocol_end == 4 ) && string_equal_substr( path, "stdin", 4 ) )
			return stream_open_stdin();
		else if( ( protocol_end != 3 ) || !string_equal_substr( path, "vfs", protocol_end ) )
		{
			log_errorf( 0, ERROR_INVALID_VALUE, "Invalid protocol: %s", path );
			return 0;
		}
	}

	//No protocol, assume virtual file system path
	//TODO: Virtual file system

	return fs_open_file( path, mode );
}
Beispiel #11
0
shader_t* shader_create(const char* data, const int64_t dataSize, ShaderType type)
{
	GLuint shaderHandle = glCreateShader(type == VertexShader ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
	mint_CHECKFORGLERROR;
	{
		//Shader source should never exceed 4Gb anyway, riiight? 
		FOUNDATION_ASSERT(dataSize < 0xffffffff);
		int32_t shaderSourceSize = (int32_t) dataSize;
		glShaderSource(shaderHandle, 1, &data, &shaderSourceSize);
		mint_CHECKFORGLERROR;
		glCompileShader(shaderHandle);
		mint_CHECKFORGLERROR;

		int32_t logLength = 0, success;
		glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &success);
		glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &logLength);
		if (success != GL_TRUE && logLength > 1)
		{
			int32_t charsWritten;
			GLchar* log = (GLchar*) memory_allocate(sizeof(GLchar) * (logLength + 1), 4, MEMORY_TEMPORARY);
			glGetShaderInfoLog(shaderHandle, logLength + 1, &charsWritten, log);
			log_errorf(ERROR_NONE, "Compiler results: %s", (char*) log);
			memory_deallocate(log);
		}
	}

	shader_t* shader = (shader_t*) memory_allocate(sizeof(shader_t), 4, MEMORY_PERSISTENT);
	shader->buffer = shaderHandle;
	return shader;
}
Beispiel #12
0
int assert_report( uint64_t context, const char* condition, const char* file, int line, const char* msg )
{
	static const char nocondition[] = "<Static fail>";
	static const char nofile[] = "<No file>";
	static const char nomsg[] = "<No message>";
	static const char assert_format[] = "****** ASSERT FAILED ******\nCondition: %s\nFile/line: %s : %d\n%s%s\n%s\n";

	if( !condition ) condition = nocondition;
	if( !file      ) file      = nofile;
	if( !msg       ) msg       = nomsg;

	if( _assert_handler && ( _assert_handler != assert_report ) )
		return (*_assert_handler)( context, condition, file, line, msg );

#if BUILD_ENABLE_ASSERT
	_assert_context_buffer[0] = 0;
	error_context_buffer( _assert_context_buffer, ASSERT_BUFFER_SIZE );

	_assert_stacktrace_buffer[0] = 0;
	if( foundation_is_initialized() )
	{
		unsigned int num_frames = stacktrace_capture( _assert_stacktrace, ASSERT_STACKTRACE_MAX_DEPTH, ASSERT_STACKTRACE_SKIP_FRAMES );
		if( num_frames )
		{
			//TODO: Resolve directly into buffer to avoid memory allocations in assert handler
			char* trace = stacktrace_resolve( _assert_stacktrace, num_frames, 0U );
			string_copy( _assert_stacktrace_buffer, trace, ASSERT_BUFFER_SIZE );
			string_deallocate( trace );
		}
	}
	else
	{
		string_copy( _assert_stacktrace_buffer, "<no stacktrace - not initialized>", ASSERT_BUFFER_SIZE );
	}

	snprintf( _assert_box_buffer, (size_t)ASSERT_BUFFER_SIZE, assert_format, condition, file, line, _assert_context_buffer, msg, _assert_stacktrace_buffer );

	log_errorf( context, ERROR_ASSERT, "%s", _assert_box_buffer );

	system_message_box( "Assert Failure", _assert_box_buffer, false );
#else
	log_errorf( context, ERROR_ASSERT, assert_format, condition, file, line, "", msg, "" );
#endif

	return 1;
}
Beispiel #13
0
void profile_shutdown( void )
{
	profile_enable( 0 );

	while( thread_is_thread( _profile_io_thread ) )
		thread_sleep( 1 );
	_profile_io_thread = 0;

	//Discard and free up blocks remaining in queue
	_profile_thread_finalize();
	if( atomic_load32( &_profile_root ) )
		_profile_process_root_block();

	//Sanity checks
	{
		uint64_t num_blocks = 0;
		uint32_t free_block = atomic_load32( &_profile_free ) & 0xffff;

		if( atomic_load32( &_profile_root ) )
			log_error( 0, ERROR_INTERNAL_FAILURE, "Profile module state inconsistent on shutdown, at least one root block still allocated/active" );

		while( free_block )
		{
			profile_block_t* block = GET_BLOCK( free_block );
			if( block->sibling )
			       log_errorf( 0, ERROR_INTERNAL_FAILURE, "Profile module state inconsistent on shutdown, block %d has sibling set", free_block );
			++num_blocks;
			free_block = GET_BLOCK( free_block )->child;
		}
		if( _profile_num_blocks )
			++num_blocks; //Include the wasted block 0

		if( num_blocks != _profile_num_blocks )
		{
			//If profile output function (user) crashed, this will probably trigger since at least one block will be lost in space
			log_errorf( 0, ERROR_INTERNAL_FAILURE, "Profile module state inconsistent on shutdown, lost blocks (found %llu of %llu)", num_blocks, _profile_num_blocks );
		}
	}

	atomic_store32( &_profile_root, 0 );
	atomic_store32( &_profile_free, 0 );

	_profile_num_blocks = 0;
	_profile_identifier = 0;
}
static void _ringbuffer_stream_seek( stream_t* stream, int64_t offset, stream_seek_mode_t direction )
{
	if( ( direction != STREAM_SEEK_CURRENT ) || ( offset < 0 ) )
	{
		log_errorf( ERROR_UNSUPPORTED, "Invalid call, only forward seeking allowed on ringbuffer streams" );
		return;
	}
	
	_ringbuffer_stream_read( stream, 0, offset );
}
Beispiel #15
0
static FOUNDATION_NOINLINE int
lua_panic(lua_State* state) {
	string_const_t errmsg = {0, 0};
	errmsg.str = lua_tolstring(state, -1, &errmsg.length);
	//FOUNDATION_ASSERT_FAILFORMAT("unprotected error in call to Lua API: %.*s", errmsg.length,
	//                             errmsg.str);
	log_errorf(HASH_LUA, ERROR_EXCEPTION, STRING_CONST("unprotected error in call to Lua API: %.*s"),
	           STRING_FORMAT(errmsg));
	return 0;
}
Beispiel #16
0
static uint32_t fixup_library_section(section_t *Section, jmp_buf *OnError) {
	if (Section->State == UNLOADED) {
		Section->State = LOADING;
		Section->Data = (uint8_t *)module_load(Section->Path, Section->Name);
		if (Section->Data == 0) {
			log_errorf("Error: module not found %s\n", Section->Name);
			longjmp(OnError, 1);
		};
		Section->State = LOADED;
	};
	return (uint32_t)Section->Data;
};
Beispiel #17
0
int hashify_check_collisions( const char* string, hash_t hash_value, const hashify_string_t* history )
{
	int ihist, history_size;
	for( ihist = 0, history_size = array_size( history ); ihist < history_size; ++ihist )
	{
		if( history[ihist].hash == hash_value )
		{
			if( string_equal( history[ihist].string, string ) )
			{
				log_errorf( ERROR_INVALID_VALUE, "  global string duplication, \"%s\" ", string );
				return HASHIFY_RESULT_STRING_COLLISION;
			}
			else
			{
				log_errorf( ERROR_INVALID_VALUE, "  global hash collision, 0x%llx between: \"%s\" and \"%s\" ", hash_value, string, history[ihist].string );
				return HASHIFY_RESULT_HASH_COLLISION;
			}
		}
	}

	return 0;
}
Beispiel #18
0
static int
lua_import_stream(stream_t* stream, const uuid_t uuid, luaimport_dump_t* dump) {
	lua_t* env;
	lua_State* state;
	int result = 0;
	lua_readstream_t read_stream = {
		.stream = stream,
	};

	env = lua_allocate();
	state = lua_state(env);

	if (lua_load(state, lua_read_stream, &read_stream, "import") != 0) {
		log_errorf(HASH_LUA, ERROR_INTERNAL_FAILURE, STRING_CONST("Lua load failed: %s"),
		           lua_tostring(state, -1));
		lua_pop(state, 1);
		result = -1;
		goto exit;
	}

	lua_dump(state, lua_import_dump_writer, dump);

	if (lua_pcall(state, 0, 0, 0) != 0) {
		log_errorf(HASH_LUA, ERROR_INTERNAL_FAILURE, STRING_CONST("Lua pcall failed: %s"),
		           lua_tostring(state, -1));
		lua_pop(state, 1);
		result = -1;
		goto exit;
	}

	log_debug(HASH_LUA, STRING_CONST("Lua bytecode dump successful"));

exit:

	lua_deallocate(env);

	return result;
}
Beispiel #19
0
int
hashify_check_collisions(string_const_t string, hash_t hash_value,
                         const hashify_string_t* history) {
	size_t ihist, history_size;
	for (ihist = 0, history_size = array_size(history); ihist < history_size; ++ihist) {
		if (history[ihist].hash == hash_value) {
			if (string_equal(history[ihist].string.str, history[ihist].string.length, string.str,
			                 string.length)) {
				log_errorf(0, ERROR_INVALID_VALUE, STRING_CONST("  global string duplication, \"%.*s\""),
				           STRING_FORMAT(string));
				return HASHIFY_RESULT_STRING_COLLISION;
			}
			else {
				log_errorf(0, ERROR_INVALID_VALUE,
				           STRING_CONST("  global hash collision, 0x%" PRIx64 " between: \"%.*s\" and \"%.*s\" "),
				           hash_value, STRING_FORMAT(string), STRING_FORMAT(history[ihist].string));
				return HASHIFY_RESULT_HASH_COLLISION;
			}
		}
	}

	return 0;
}
Beispiel #20
0
static uint32_t fixup_import_section(section_t *Section, jmp_buf *OnError) {
	if (Section->State == UNLOADED) {
		Section->State = LOADING;
		module_t *Module = (module_t *)Section->Library->Fixup(Section->Library, OnError);
		int IsRef;
		if (module_import(Module, Section->Name, &IsRef, (void **)&Section->Data)) {
			Section->State = LOADED;
		} else {
			log_errorf("Error: symbol %s not exported from %s\n", Section->Name, Section->Library->Name);
			longjmp(OnError, 1);
		};
	};
	return (uint32_t)Section->Data;
};
Beispiel #21
0
void* library_symbol( object_t id, const char* name )
{
	library_t* library = objectmap_lookup( _library_map, id );
	if( library )
	{
#if FOUNDATION_PLATFORM_WINDOWS
		return GetProcAddress( library->dll, name );
#elif FOUNDATION_PLATFORM_POSIX
		return dlsym( library->lib, name );
#else
		log_errorf( 0, ERROR_NOT_IMPLEMENTED, "Dynamic library symbol lookup implemented for this platform: %s not found", name );
#endif
	}
	return 0;
}
Beispiel #22
0
module_t *module_load_file(const char *File, const char *Type) {
	struct stat Stat[1];
	if (stat(File, Stat)) return 0;
	module_t *Module = module_new(File);
	if (Type) {
		module_loader_t *Loader = module_get_loader(Type);
		if (Loader == 0) {
			log_errorf("Error: loader %s not found.\n", Type);
		} else {
			if (Loader->Load(Module->Providers, File)) return Module;
		};
	} else {
		for (module_loader_t *Loader = ModuleLoaders; Loader; Loader = Loader->Next) {
			if (Loader->Load(Module->Providers, File)) return Module;
		};
	};
	return 0;
};
Beispiel #23
0
int assert_report( const char* condition, const char* file, int line, const char* msg )
{
	static const char nocondition[] = "<Static fail>";
	static const char nofile[] = "<No file>";
	static const char nomsg[] = "<No message>";
	static const char assert_format[] = "****** ASSERT FAILED ******\nCondition: %s\nFile/line: %s : %d\n%s%s\n%s\n";
	int ret;

	if( !condition ) condition = nocondition;
	if( !file      ) file      = nofile;
	if( !msg       ) msg       = nomsg;
	
	if( _assert_handler && ( _assert_handler != assert_report ) )
		return (*_assert_handler)( condition, file, line, msg );

	_assert_context_buffer[0] = 0;
	error_context_buffer( _assert_context_buffer, ASSERT_BUFFER_SIZE );

	_assert_stacktrace_buffer[0] = 0;
	if( foundation_is_initialized() )
	{
		if( stacktrace_capture( _assert_stacktrace, 128, 1 ) > 0 )
		{
			//TODO: Resolve directly into buffer to avoid memory allocations in assert handler
			char* trace = stacktrace_resolve( _assert_stacktrace, 128, 0 );
			string_copy( _assert_stacktrace_buffer, trace, ASSERT_BUFFER_SIZE );
			string_deallocate( trace );
		}
	}
	else
	{
		string_copy( _assert_stacktrace_buffer, "<no stacktrace - not initialized>", ASSERT_BUFFER_SIZE );
	}
	
	ret = snprintf( _assert_box_buffer, (size_t)ASSERT_BUFFER_SIZE, assert_format, condition, file, line, _assert_context_buffer, msg, _assert_stacktrace_buffer );
	if( ( ret < 0 ) || ( ret >= ASSERT_BUFFER_SIZE ) )
		_assert_box_buffer[ASSERT_BUFFER_SIZE-1] = 0;

	log_errorf( 0, ERROR_ASSERT, "%s", _assert_box_buffer );

	system_message_box( "Assert Failure", _assert_box_buffer, false );

	return 1;
}
Beispiel #24
0
int
hashify_read_hashes(stream_t* file, hashify_string_t** hashes) {
	//Read in hashes in file
	char line_buffer[HASHIFY_LINEBUFFER_LENGTH];
	string_const_t tokens[32];

	memset(line_buffer, 0, sizeof(line_buffer));
	do {
		string_t line = stream_read_line_buffer(file, line_buffer, sizeof(line_buffer), '\n');
		string_const_t stripped_line = string_strip(STRING_ARGS(line), STRING_CONST("\n\r"));
		if ((string_find_string(STRING_ARGS(stripped_line), STRING_CONST("define"), 0) != STRING_NPOS) &&
		        (string_find_string(STRING_ARGS(stripped_line), STRING_CONST("static_hash"), 0) != STRING_NPOS)) {
			//Format is: #define HASH_<hashstring> static_hash_string( "<string>", 0x<hashvalue>ULL )
			size_t num_tokens = string_explode(STRING_ARGS(stripped_line), STRING_CONST(" \t"), tokens, 32,
			                                   false);

			if (num_tokens >= 6) {
				hashify_string_t hash_string;
				string_const_t stripped = string_strip(STRING_ARGS(tokens[3]), STRING_CONST(","));
				stripped = string_strip(STRING_ARGS(stripped), STRING_CONST("\""));
				hash_string.string = string_copy(hash_string.buffer, HASHIFY_STRING_LENGTH, STRING_ARGS(stripped));
				hash_string.hash = string_to_uint64(STRING_ARGS(tokens[4]), true);

				if (hash(STRING_ARGS(hash_string.string)) != hash_string.hash) {
					log_errorf(0, ERROR_INVALID_VALUE,
					           STRING_CONST("  hash output file is out of date, %.*s is set to 0x%" PRIx64 " but should be 0x%"
					                        PRIx64),
					           STRING_FORMAT(hash_string.string), hash_string.hash, hash(STRING_ARGS(hash_string.string)));
					return HASHIFY_RESULT_OUTPUT_FILE_OUT_OF_DATE;
				}

				array_push_memcpy(*hashes, &hash_string);
			}
		}
	}
	while (!stream_eos(file));

	return 0;
}
Beispiel #25
0
int hashify_read_hashes( stream_t* file, hashify_string_t** hashes )
{
	//Read in hashes in file
	char* line;
	char line_buffer[HASHIFY_LINEBUFFER_LENGTH];

	do
	{
		stream_read_line_buffer( file, line_buffer, HASHIFY_LINEBUFFER_LENGTH-1, '\n' );
		line = string_strip( line_buffer, "\n\r" );
		if( ( string_find_string( line, "define", 0 ) != STRING_NPOS ) && ( string_find_string( line, "static_hash", 0 ) != STRING_NPOS ) )
		{
			//Format is: #define HASH_<hashstring> static_hash_string( "<string>", 0x<hashvalue>ULL )
			char** tokens = string_explode( line, " \t", false );

			if( array_size( tokens ) >= 6 )
			{
				hashify_string_t hash_string;

				string_copy( hash_string.string, string_strip( string_strip( tokens[3], "," ), "\"" ), HASHIFY_STRING_LENGTH );
				hash_string.hash = string_to_uint64( tokens[4], true );

				if( hash( hash_string.string, string_length( hash_string.string ) ) != hash_string.hash )
				{
					log_errorf( ERROR_INVALID_VALUE, "  hash output file is out of date, %s is set to 0x%llx but should be 0x%llx ", hash_string.string, hash_string.hash, hash( hash_string.string, string_length( hash_string.string ) ) );
					string_array_deallocate( tokens );
					return HASHIFY_RESULT_OUTPUT_FILE_OUT_OF_DATE;
				}

				array_push_memcpy( *hashes, &hash_string );
			}

			string_array_deallocate( tokens );
		}
	} while( !stream_eos( file ) );

	return 0;
}
Beispiel #26
0
static int
blast_client_send_data_chunk(blast_client_t* client, uint64_t seq) {
	packet_payload_t packet;
	void* data;
	uint64_t res;

	packet.type = PACKET_PAYLOAD;
	packet.token = client->token;
	packet.timestamp = blast_timestamp(client->begin_send);
	packet.seq = seq;

	data = client->readers[client->current]->map(client->readers[client->current],
	                                             packet.seq * PACKET_CHUNK_SIZE, PACKET_CHUNK_SIZE);
	if (!data) {
		log_errorf(HASH_BLAST, ERROR_SYSTEM_CALL_FAIL,
		           STRING_CONST("Unable to map source segment at offset %lld"),
		           packet.seq * PACKET_CHUNK_SIZE);
		return BLAST_ERROR_UNABLE_TO_READ_FILE;
	}
	memcpy(packet.data, data, PACKET_CHUNK_SIZE);
	client->readers[client->current]->unmap(client->readers[client->current], data,
	                                        packet.seq * PACKET_CHUNK_SIZE, PACKET_CHUNK_SIZE);

	/*
	#if BUILD_ENABLE_LOG
		char* addr = network_address_to_string( client->target, true );
		log_infof( HASH_BLAST, "Send payload to %s (seq %lld, timestamp %lld) token %d (file %d/%d)", addr, packet.seq, (tick_t)packet.timestamp, packet.token, client->current + 1, array_size( client->readers ) );
		string_deallocate( addr );
	#endif
	*/

	size_t payload_size = sizeof(packet_payload_t);
	res = udp_socket_sendto(client->sock, &packet, payload_size, client->target);

	return (res == payload_size ? 0 : -1);
}
Beispiel #27
0
static lua_result_t
lua_do_call_custom(lua_t* env, const char* method, size_t length, lua_arg_t* arg) {
	lua_State* state;
	lua_result_t result;
	int numargs, i;
	int stacksize;
	size_t start, next;
	string_const_t part;

	state = env->state;
	stacksize = lua_gettop(state);
	result = LUA_OK;

	++env->calldepth;

	next = string_find(method, length, '.', 0);
	if (next != STRING_NPOS) {
		part = string_const(method, next);
		lua_getlglobal(state, part.str, part.length);
		if (lua_isnil(state, -1)) {
			log_errorf(HASH_LUA, ERROR_INVALID_VALUE,
			           STRING_CONST("Invalid script call, '%.*s' is not set (%.*s)"),
			           STRING_FORMAT(part), (int)length, method);
			--env->calldepth;
			lua_pop(state, lua_gettop(state) - stacksize);
			return LUA_ERROR;
		}
		else if (!lua_istable(state, -1)) {
			log_errorf(HASH_LUA, ERROR_INVALID_VALUE,
			           STRING_CONST("Invalid script call, existing data '%.*s' in '%.*s' is not a table"),
			           STRING_FORMAT(part), (int)length, method);
			--env->calldepth;
			lua_pop(state, lua_gettop(state) - stacksize);
			return LUA_ERROR;
		}
		//Top of stack is now table
		FOUNDATION_ASSERT(lua_istable(state, -1));
		++next;
		start = next;

		next = string_find(method, length, '.', next);
		while (next != STRING_NPOS) {
			part = string_const(method + start, next - start);
			lua_pushlstring(state, part.str, part.length);
			lua_gettable(state, -2);
			if (lua_isnil(state, -1)) {
				log_errorf(HASH_LUA, ERROR_INVALID_VALUE,
				           STRING_CONST("Invalid script call, '%.*s' is not set (%.*s)"),
				           STRING_FORMAT(part), (int)next, method);
				--env->calldepth;
				lua_pop(state, lua_gettop(state) - stacksize);
				return LUA_ERROR;
			}
			else if (!lua_istable(state, -1)) {
				log_errorf(HASH_LUA, ERROR_INVALID_VALUE,
				           STRING_CONST("Invalid script call, existing data '%.*s' in '%.*s' is not a table"),
				           STRING_FORMAT(part), (int)next, method);
				--env->calldepth;
				lua_pop(state, lua_gettop(state) - stacksize);
				return LUA_ERROR;
			}
			//Top of stack is now table
			FOUNDATION_ASSERT(lua_istable(state, -1));

			++next;
			start = next;
			next = string_find(method, length, '.', next);
		}

		part = string_const(method + start, length - start);
		lua_pushlstring(state, part.str, part.length);
		lua_gettable(state, -2);
	}
	else {
		lua_getlglobal(state, method, length);
	}

	if (lua_isnil(state, -1)) {
		--env->calldepth;
		lua_pop(state, lua_gettop(state) - stacksize);

		//Method does not exist in Lua context
		log_errorf(HASH_LUA, ERROR_INVALID_VALUE,
		           STRING_CONST("Invalid script call, '%.*s' is not a function"), (int)length, method);
		return LUA_ERROR;
	}

	numargs = 0;
	if (arg) {
		numargs = (arg->num < LUA_MAX_ARGS) ? arg->num : LUA_MAX_ARGS;
		for (i = 0; i < numargs; ++i) {
			switch (arg->type[i]) {
			case LUADATA_PTR:
				lua_pushlightuserdata(state, arg->value[i].ptr);
				break;

			case LUADATA_OBJ:
				lua_pushobject(state, arg->value[i].obj);
				break;

			case LUADATA_INT:
				lua_pushinteger(state, arg->value[i].ival);
				break;

			case LUADATA_REAL:
				lua_pushnumber(state, arg->value[i].val);
				break;

			case LUADATA_STR:
				lua_pushlstring(state, arg->value[i].str, arg->size[i]);
				break;

			case LUADATA_BOOL:
				lua_pushboolean(state, arg->value[i].flag);
				break;

			case LUADATA_INTARR: {
					const int* values = arg->value[i].ptr;
					lua_newtable(state);
					for (uint16_t ia = 0; ia < arg->size[i]; ++ia) {
						lua_pushinteger(state, ia + 1);
						lua_pushinteger(state, values[ia]);
						lua_settable(state, -3);
					}
					break;
				}

			case LUADATA_REALARR: {
					const real* values = arg->value[i].ptr;
					lua_newtable(state);
					for (uint16_t ia = 0; ia < arg->size[i]; ++ia) {
						lua_pushinteger(state, ia + 1);
						lua_pushnumber(state, values[ia]);
						lua_settable(state, -3);
					}
					break;
				}

			default:
				--numargs;
				break;
			}
		}
	}

	//TODO: Parse return value from call
	if (lua_pcall(state, numargs, 0, 0) != 0) {
		string_const_t errmsg = {0, 0};
		errmsg.str = lua_tolstring(state, -1, &errmsg.length);
		log_errorf(HASH_LUA, ERROR_INTERNAL_FAILURE, STRING_CONST("Calling %.*s : %.*s"),
		           (int)length, method, STRING_FORMAT(errmsg));
		result = LUA_ERROR;
	}

	--env->calldepth;

	lua_pop(state, lua_gettop(state) - stacksize);

	return result;
}
Beispiel #28
0
bool
mutex_try_wait(mutex_t* mutex, unsigned int milliseconds) {
#if FOUNDATION_PLATFORM_WINDOWS
	DWORD ret;
#elif FOUNDATION_PLATFORM_POSIX || FOUNDATION_PLATFORM_PNACL
	struct timeval now;
	struct timespec then;
#endif
#if FOUNDATION_PLATFORM_WINDOWS

#if !BUILD_DEPLOY
	profile_wait(STRING_ARGS(mutex->name));
#endif

	atomic_incr32(&mutex->waiting);

	ret = WaitForSingleObject(mutex->event, milliseconds);

	if (ret == WAIT_OBJECT_0)
		mutex_lock(mutex);

	if (atomic_decr32(&mutex->waiting) == 0)
		ResetEvent(mutex->event);

	return ret == WAIT_OBJECT_0;

#elif FOUNDATION_PLATFORM_POSIX || FOUNDATION_PLATFORM_PNACL

	mutex_lock(mutex);

	if (mutex->pending) {
		mutex->pending = false;
		return true;
	}
	if (!milliseconds) {
		mutex_unlock(mutex);
		return false;
	}

	--mutex->lockcount;

	bool was_signal = false;
	if (milliseconds == 0xFFFFFFFF) {
		int ret = pthread_cond_wait(&mutex->cond, &mutex->mutex);
		if (ret == 0) {
			was_signal = true;
		}
		else {
			string_const_t errmsg = system_error_message(ret);
			log_errorf(0, ERROR_SYSTEM_CALL_FAIL, STRING_CONST("Unable to wait on mutex '%.*s': %.*s (%d)"),
			           STRING_FORMAT(mutex->name), STRING_FORMAT(errmsg), ret);
		}
	}
	else {
		int ret;
		gettimeofday(&now, 0);
		then.tv_sec  = now.tv_sec + (time_t)(milliseconds / 1000);
		then.tv_nsec = (now.tv_usec * 1000) + (long)(milliseconds % 1000) * 1000000L;
		while (then.tv_nsec >= 1000000000L) {
			++then.tv_sec;
			then.tv_nsec -= 1000000000L;
		}
		ret = pthread_cond_timedwait(&mutex->cond, &mutex->mutex, &then);
		if (ret == 0) {
			was_signal = true;
		}
		else if (ret != ETIMEDOUT) {
			string_const_t errmsg = system_error_message(ret);
			log_errorf(0, ERROR_SYSTEM_CALL_FAIL,
			           STRING_CONST("Unable to wait (timed) on mutex '%.*s': %.*s (%d)"),
			           STRING_FORMAT(mutex->name), STRING_FORMAT(errmsg), ret);
		}
	}

	++mutex->lockcount;
	mutex->lockedthread = thread_id();

	if (was_signal)
		mutex->pending = false;
	else
		mutex_unlock(mutex);

	return was_signal;

#else
#  error mutex_wait not implemented
#endif
}
Beispiel #29
0
int
lua_compile(const uuid_t uuid, uint64_t platform, resource_source_t* source,
            const uint256_t source_hash, const char* type, size_t type_length) {
	int result = 0;
	uint64_t* subplatforms = 0;
	size_t iplat, psize;
	hashmap_fixed_t fixedmap;
	hashmap_t* map = (hashmap_t*)&fixedmap;
	hash_t resource_type_hash;

	resource_type_hash = hash(type, type_length);

	if (resource_type_hash != HASH_LUA)
		return -1;

	array_push(subplatforms, platform);

	hashmap_initialize(map, sizeof(fixedmap.bucket) / sizeof(fixedmap.bucket[0]), 8);
	resource_source_map_all(source, map, false);
	resource_source_map_reduce(source, map, &subplatforms, resource_source_platform_reduce);
	resource_source_map_clear(map);

	for (iplat = 1, psize = array_size(subplatforms); (iplat != psize) && (result == 0); ++iplat) {
		void* compiled_blob = 0;
		size_t compiled_size = 0;
		stream_t* stream;
		uint64_t subplatform = subplatforms[iplat];

		resource_change_t* sourcechange = resource_source_get(source, HASH_SOURCE, subplatform);
		if (sourcechange && (sourcechange->flags & RESOURCE_SOURCEFLAG_BLOB)) {
			compiled_size = sourcechange->value.blob.size;
			compiled_blob = memory_allocate(HASH_RESOURCE, compiled_size, 0, MEMORY_PERSISTENT);
			if (!resource_source_read_blob(uuid, HASH_SOURCE, subplatform, sourcechange->value.blob.checksum,
			                               compiled_blob, compiled_size)) {
				memory_deallocate(compiled_blob);
				compiled_blob = 0;
				compiled_size = 0;
			}
		}

		if (compiled_size <= 0)
			continue;

		stream = resource_local_create_static(uuid, subplatform);
		if (stream) {
			const uint32_t version = 1;
			resource_header_t header = {
				.type = resource_type_hash,
				.version = version,
				.source_hash = source_hash
			};
			resource_stream_write_header(stream, header);
			stream_deallocate(stream);

			if (compiled_size > 0) {
				stream = resource_local_create_dynamic(uuid, subplatform);
				if (stream) {
					stream_write_uint32(stream, version);
					stream_write_uint64(stream, compiled_size);
					stream_write(stream, compiled_blob, compiled_size);
					stream_deallocate(stream);
				}
				else {
					log_errorf(HASH_RESOURCE, ERROR_SYSTEM_CALL_FAIL,
					           STRING_CONST("Unable to create dynamic resource stream"));
					result = -1;
				}
			}
		}
		else {
			log_errorf(HASH_RESOURCE, ERROR_SYSTEM_CALL_FAIL,
			           STRING_CONST("Unable to create static resource stream"));
			result = -1;
		}

		memory_deallocate(compiled_blob);
	}
Beispiel #30
0
lua_result_t
lua_do_bind(lua_t* env, const char* property, size_t length, lua_command_t cmd, lua_value_t val) {
	lua_State* state;
	int stacksize;
	size_t start, next;
	string_const_t part;

	if (!env || !length)
		return LUA_ERROR;

	state = env->state;
	stacksize = lua_gettop(state);

	next = string_find(property, length, '.', 0);
	if (next != STRING_NPOS) {
		int tables;
		unsigned int numtables = 0;
		part = string_const(property, next);

		lua_getlglobal(state, part.str, part.length);
		if (lua_isnil(state, -1)) {
			//Create global table
			lua_pop(state, 1);
			lua_newtable(state);
			lua_pushvalue(state, -1);
			lua_setlglobal(state, part.str, part.length);
			log_debugf(HASH_LUA, STRING_CONST("Created global table: %.*s"), STRING_FORMAT(part));
		}
		else if (!lua_istable(state, -1)) {
			log_errorf(HASH_LUA, ERROR_INVALID_VALUE,
			           STRING_CONST("Invalid script bind call, existing data '%.*s' in '%.*s' is not a table"),
			           STRING_FORMAT(part), (int)length, property);
			lua_pop(state, lua_gettop(state) - stacksize);
			return LUA_ERROR;
		}
		//Top of stack is now table
		FOUNDATION_ASSERT(lua_istable(state, -1));

		++next;
		start = next;
		++numtables;

		next = string_find(property, length, '.', next);
		while (next != STRING_NPOS) {
			part = string_const(property + start, next - start);
			lua_pushlstring(state, part.str, part.length);
			lua_gettable(state, -2);
			if (lua_isnil(state, -1)) {
				//Create sub-table
				lua_pop(state, 1);
				lua_newtable(state);
				lua_pushlstring(state, part.str, part.length);
				lua_pushvalue(state, -2);
				lua_settable(state, -4);
				log_debugf(HASH_LUA, STRING_CONST("Created table: %.*s"), next, property);
			}
			else if (!lua_istable(state, -1)) {
				log_errorf(HASH_LUA, ERROR_INVALID_VALUE,
				           STRING_CONST("Invalid script bind call, existing data '%.*s' in '%.*s' is not a table"),
				           STRING_FORMAT(part), (int)next, property);
				lua_pop(state, lua_gettop(state) - stacksize);
				return LUA_ERROR;
			}
			//Top of stack is now table
			FOUNDATION_ASSERT(lua_istable(state, -1));

			++next;
			start = next;
			next = string_find(property, length, '.', next);
			++numtables;
		}

		part = string_const(property + start, length - start);

		switch (cmd) {
		case LUACMD_BIND:
			lua_push_method(state, STRING_ARGS(part), val.fn);
			break;
		case LUACMD_BIND_INT:
			lua_push_integer(state, STRING_ARGS(part), val.ival);
			break;
		case LUACMD_BIND_VAL:
			lua_push_number(state, STRING_ARGS(part), val.val);
			break;
		default:
			break;
		}

		tables = lua_gettop(state) - stacksize;
		lua_pop(state, tables);

		FOUNDATION_ASSERT(tables == (int)numtables);
	}
	else {
		part = string_const(property, length);
		switch (cmd) {
		case LUACMD_BIND:
			lua_push_method_global(state, STRING_ARGS(part), val.fn);
			break;
		case LUACMD_BIND_INT:
			lua_push_integer_global(state, STRING_ARGS(part), val.ival);
			break;
		case LUACMD_BIND_VAL:
			lua_push_number_global(state, STRING_ARGS(part), val.val);
			break;
		default:
			break;
		}
	}
	return LUA_OK;
}