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; }
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; }
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; }
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; }
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; }
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; }
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; }
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 }
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 ); }
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; }
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; }
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 ); }
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; }
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; };
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; }
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; }
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; }
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; };
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; }
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; };
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; }
int hashify_read_hashes(stream_t* file, hashify_string_t** hashes) { //Read in hashes in file char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; string_const_t tokens[32]; memset(line_buffer, 0, sizeof(line_buffer)); do { string_t line = stream_read_line_buffer(file, line_buffer, sizeof(line_buffer), '\n'); string_const_t stripped_line = string_strip(STRING_ARGS(line), STRING_CONST("\n\r")); if ((string_find_string(STRING_ARGS(stripped_line), STRING_CONST("define"), 0) != STRING_NPOS) && (string_find_string(STRING_ARGS(stripped_line), STRING_CONST("static_hash"), 0) != STRING_NPOS)) { //Format is: #define HASH_<hashstring> static_hash_string( "<string>", 0x<hashvalue>ULL ) size_t num_tokens = string_explode(STRING_ARGS(stripped_line), STRING_CONST(" \t"), tokens, 32, false); if (num_tokens >= 6) { hashify_string_t hash_string; string_const_t stripped = string_strip(STRING_ARGS(tokens[3]), STRING_CONST(",")); stripped = string_strip(STRING_ARGS(stripped), STRING_CONST("\"")); hash_string.string = string_copy(hash_string.buffer, HASHIFY_STRING_LENGTH, STRING_ARGS(stripped)); hash_string.hash = string_to_uint64(STRING_ARGS(tokens[4]), true); if (hash(STRING_ARGS(hash_string.string)) != hash_string.hash) { log_errorf(0, ERROR_INVALID_VALUE, STRING_CONST(" hash output file is out of date, %.*s is set to 0x%" PRIx64 " but should be 0x%" PRIx64), STRING_FORMAT(hash_string.string), hash_string.hash, hash(STRING_ARGS(hash_string.string))); return HASHIFY_RESULT_OUTPUT_FILE_OUT_OF_DATE; } array_push_memcpy(*hashes, &hash_string); } } } while (!stream_eos(file)); return 0; }
int hashify_read_hashes( stream_t* file, hashify_string_t** hashes ) { //Read in hashes in file char* line; char line_buffer[HASHIFY_LINEBUFFER_LENGTH]; do { stream_read_line_buffer( file, line_buffer, HASHIFY_LINEBUFFER_LENGTH-1, '\n' ); line = string_strip( line_buffer, "\n\r" ); if( ( string_find_string( line, "define", 0 ) != STRING_NPOS ) && ( string_find_string( line, "static_hash", 0 ) != STRING_NPOS ) ) { //Format is: #define HASH_<hashstring> static_hash_string( "<string>", 0x<hashvalue>ULL ) char** tokens = string_explode( line, " \t", false ); if( array_size( tokens ) >= 6 ) { hashify_string_t hash_string; string_copy( hash_string.string, string_strip( string_strip( tokens[3], "," ), "\"" ), HASHIFY_STRING_LENGTH ); hash_string.hash = string_to_uint64( tokens[4], true ); if( hash( hash_string.string, string_length( hash_string.string ) ) != hash_string.hash ) { log_errorf( ERROR_INVALID_VALUE, " hash output file is out of date, %s is set to 0x%llx but should be 0x%llx ", hash_string.string, hash_string.hash, hash( hash_string.string, string_length( hash_string.string ) ) ); string_array_deallocate( tokens ); return HASHIFY_RESULT_OUTPUT_FILE_OUT_OF_DATE; } array_push_memcpy( *hashes, &hash_string ); } string_array_deallocate( tokens ); } } while( !stream_eos( file ) ); return 0; }
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); }
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; }
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 }
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); }
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; }