DECLARE_TEST(foundation, environment) { lua_t* env = lua_allocate(); log_set_suppress(HASH_LUA, ERRORLEVEL_NONE); log_info(HASH_LUA, STRING_CONST("Running environment lua tests")); EXPECT_NE(env, 0); string_const_t testcode = string_const(STRING_CONST( "local ffi = require(\"ffi\")\n" "local foundation = require(\"foundation\")\n" "local C = ffi.C\n" "C.log_set_suppress(foundation.HASH_LUA, foundation.ERRORLEVEL_DEBUG)\n" "C.log_enable_prefix(false)\n" "foundation.log.info(\"Executable name: \" .. tostring(C.environment_executable_name()))\n" "local cmdline = \"\"\n" "local cmdline_tab = C.environment_command_line()\n" "local num = C.array_size(cmdline_tab)" "for i = 0, num-1 do\n" " cmdline = cmdline .. \" \" .. tostring(cmdline_tab[i])\n" "end\n" "foundation.log.info(\"Command line:\" .. cmdline)\n" "C.log_enable_prefix(true)\n" "C.log_set_suppress(foundation.HASH_LUA, foundation.ERRORLEVEL_INFO)\n" )); EXPECT_EQ(lua_eval_string(env, STRING_ARGS(testcode)), LUA_OK); log_info(HASH_LUA, STRING_CONST("Done running environment lua tests")); log_set_suppress(HASH_LUA, ERRORLEVEL_INFO); lua_deallocate(env); return 0; }
void buffer_stream_initialize(stream_buffer_t* stream, void* buffer, unsigned int mode, size_t size, size_t capacity, bool adopt, bool grow) { memset(stream, 0, sizeof(stream_buffer_t)); stream_initialize((stream_t*)stream, system_byteorder()); if (!adopt && grow) { log_warn(0, WARNING_INVALID_VALUE, STRING_CONST("Cannot grow buffer streams that are not adopted")); grow = false; } if (!buffer) { size = 0; capacity = 0; } if (size > capacity) size = capacity; stream->type = STREAMTYPE_MEMORY; stream->path = string_allocate_format(STRING_CONST("buffer://0x%" PRIfixPTR), (uintptr_t)stream); stream->mode = mode & (STREAM_OUT | STREAM_IN | STREAM_BINARY); stream->buffer = buffer; stream->size = size; stream->capacity = capacity; stream->own = adopt; stream->grow = (adopt && grow); stream->lastmod = time_current(); if ((mode & STREAM_OUT) && (mode & STREAM_TRUNCATE)) stream->size = 0; if (mode & STREAM_ATEND) stream->current = stream->size; stream->vtable = &_buffer_stream_vtable; }
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; }
DECLARE_TEST(md5, reference) { md5_t* md5; char md5str[32]; string_t digest; md5 = md5_allocate(); md5_digest_finalize(md5); md5_digest(md5, "testing md5 implementation", 26); md5_digest_finalize(md5); digest = md5_get_digest(md5, md5str, sizeof(md5str)); EXPECT_STRINGEQ(digest, string_const(STRING_CONST("4E24E37E5E06F23210FA1518E97A50C4"))); md5_digest(md5, "testing md5 implementation", 26); md5_digest(md5, "", 0); md5_digest(md5, "further testing md5 implementation with long buffer > 32 bytes", 62); md5_digest_finalize(md5); digest = md5_get_digest(md5, md5str, sizeof(md5str)); EXPECT_STRINGEQ(digest, string_const(STRING_CONST("BD870884942EA7B32A9CB2547B02B871"))); md5_digest(md5, digest_test_string, 2000); md5_digest_finalize(md5); digest = md5_get_digest(md5, md5str, sizeof(md5str)); EXPECT_STRINGEQ(digest, string_const(STRING_CONST("137D3C94230A0E230C4DDFC97EACCCD2"))); md5_deallocate(md5); return 0; }
static void* stream_blocking_thread(void* arg) { int iloop; socket_t* sock = (socket_t*)arg; char buffer_out[317] = {0}; char buffer_in[317] = {0}; stream_t* stream = socket_stream(sock); for (iloop = 0; !thread_try_wait(0) && iloop < 512; ++iloop) { log_infof(HASH_NETWORK, STRING_CONST("UDP write pass %d"), iloop); EXPECT_SIZEEQ(stream_write(stream, buffer_out, 127), 127); EXPECT_SIZEEQ(stream_write(stream, buffer_out + 127, 180), 180); stream_flush(stream); EXPECT_SIZEEQ(stream_write(stream, buffer_out + 307, 10), 10); stream_flush(stream); log_infof(HASH_NETWORK, STRING_CONST("UDP read pass %d"), iloop); EXPECT_SIZEEQ(stream_read(stream, buffer_in, 235), 235); EXPECT_SIZEEQ(stream_read(stream, buffer_in + 235, 82), 82); thread_yield(); } log_debugf(HASH_NETWORK, STRING_CONST("IO complete on socket 0x%llx"), sock); stream_deallocate(stream); return 0; }
DECLARE_TEST(mutex, sync) { mutex_t* mutex; thread_t thread[32]; size_t ith; mutex = mutex_allocate(STRING_CONST("test")); mutex_lock(mutex); for (ith = 0; ith < 32; ++ith) thread_initialize(&thread[ith], mutex_thread, mutex, STRING_CONST("mutex_thread"), THREAD_PRIORITY_NORMAL, 0); for (ith = 0; ith < 32; ++ith) thread_start(&thread[ith]); test_wait_for_threads_startup(thread, 32); mutex_unlock(mutex); test_wait_for_threads_finish(thread, 32); for (ith = 0; ith < 32; ++ith) thread_finalize(&thread[ith]); mutex_deallocate(mutex); EXPECT_EQ(thread_counter, 32 * 128); return 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; }
DECLARE_TEST(profile, initialize) { error_t err = error(); _test_profile_offset = 0; atomic_store32(&_test_profile_output_counter, 0); profile_initialize(STRING_CONST("test_profile"), _test_profile_buffer, TEST_PROFILE_BUFFER_SIZE); profile_enable(true); profile_log(STRING_CONST("testing")); thread_sleep(1000); profile_enable(false); profile_finalize(); #if BUILD_ENABLE_PROFILE EXPECT_GT(atomic_load32(&_test_profile_output_counter), 0); #else EXPECT_EQ(atomic_load32(&_test_profile_output_counter), 0); #endif err = error(); EXPECT_EQ(err, ERROR_NONE); return 0; }
DECLARE_TEST(stacktrace, resolve) { #define TEST_DEPTH 64 void* trace[TEST_DEPTH]; size_t num_frames; char* buffer; string_t resolved; if (system_platform() == PLATFORM_PNACL) return 0; num_frames = stacktrace_capture(trace, TEST_DEPTH, 0); EXPECT_GT(num_frames, 3); buffer = memory_allocate(0, 1024, 0, MEMORY_TEMPORARY); resolved = stacktrace_resolve(buffer, 1024, trace, num_frames, 0); EXPECT_NE(resolved.str, 0); EXPECT_NE(resolved.length, 0); //log_infof(HASH_TEST, STRING_CONST("Resolved stack trace:\n%.*s"), (int)resolved.length, // resolved.str); #if !FOUNDATION_PLATFORM_ANDROID && !(FOUNDATION_PLATFORM_WINDOWS && (FOUNDATION_COMPILER_GCC || FOUNDATION_COMPILER_CLANG)) EXPECT_NE(string_find_string(resolved.str, resolved.length, STRING_CONST("stacktraceresolve_fn"), 0), STRING_NPOS); EXPECT_NE(string_find_string(resolved.str, resolved.length, STRING_CONST("main"), 0), STRING_NPOS); #endif memory_deallocate(buffer); return 0; }
static void* datagram_client_blocking_thread(void* arg) { int iloop; test_datagram_arg_t* darg = arg; socket_t* sock = darg->sock; network_address_t* target = darg->target; const network_address_t* address; char buffer[1024] = {0}; size_t send = 973; size_t recv; log_debugf(HASH_NETWORK, STRING_CONST("IO start on socket 0x%llx"), sock); for (iloop = 0; iloop < 512; ++iloop) { log_infof(HASH_NETWORK, STRING_CONST("UDP read/write pass %d"), iloop); EXPECT_EQ(udp_socket_sendto(sock, buffer, send, target), send); recv = udp_socket_recvfrom(sock, buffer, send, &address); EXPECT_EQ(recv, send); EXPECT_TRUE(network_address_equal(target, address)); thread_yield(); } log_infof(HASH_NETWORK, STRING_CONST("IO complete on socket 0x%llx"), sock); return 0; }
static void blast_client_read_ack(blast_client_t* client) { const network_address_t* address = 0; char databuf[PACKET_DATABUF_SIZE]; size_t size = udp_socket_recvfrom(client->sock, databuf, sizeof(databuf), &address); while (size > 0) { packet_t* packet = (packet_t*)databuf; if (network_address_equal(address, socket_address_remote(client->sock))) { if (packet->type == PACKET_ACK) { packet_ack_t* ack = (packet_ack_t*)packet; blast_client_process_ack(client, ack->ack, packet->timestamp); } else if (packet->type == PACKET_TERMINATE) { log_info(HASH_BLAST, STRING_CONST("Client terminating due to TERMINATE packet from server")); client->state = BLAST_STATE_FINISHED; break; } } else { char buffer[NETWORK_ADDRESS_NUMERIC_MAX_LENGTH]; string_t addr = network_address_to_string(buffer, sizeof(buffer), address, true); log_warnf(HASH_BLAST, WARNING_SUSPICIOUS, STRING_CONST("Ignoring datagram from unknown host %.*s"), STRING_FORMAT(addr)); } size = udp_socket_recvfrom(client->sock, databuf, sizeof(databuf), &address); } }
static application_t test_error_application(void) { application_t app; memset(&app, 0, sizeof(app)); app.name = string_const(STRING_CONST("Foundation error tests")); app.short_name = string_const(STRING_CONST("test_error")); app.company = string_const(STRING_CONST("Rampant Pixels")); app.flags = APPLICATION_UTILITY; app.exception_handler = test_exception_handler; return app; }
static application_t test_environment_application(void) { application_t app; memset(&app, 0, sizeof(app)); app.name = string_const(STRING_CONST("Foundation environment tests")); app.short_name = string_const(STRING_CONST("test_environment")); app.config_dir = string_const(STRING_CONST("test_environment")); app.flags = APPLICATION_UTILITY; app.dump_callback = test_crash_handler; return app; }
static application_t test_matrix_application(void) { application_t app = {0}; app.name = string_const(STRING_CONST("Matrix tests")); app.short_name = string_const(STRING_CONST("test_matrix")); app.company = string_const(STRING_CONST("Rampant Pixels")); app.version = vector_module_version(); app.flags = APPLICATION_UTILITY; app.exception_handler = test_exception_handler; return app; }
void test_exception_handler(const char* dump_file, size_t length) { FOUNDATION_UNUSED(dump_file); FOUNDATION_UNUSED(length); log_error(HASH_TEST, ERROR_EXCEPTION, STRING_CONST("Test raised exception")); #if (FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID) && !BUILD_ENABLE_LOG test_log_view_append(STRING_CONST("Test raised exception\n")); thread_sleep(5000); #endif process_exit(-1); }
int blast_client(network_address_t** * target, string_t* files) { int itarg, tsize = 0; int iclient, csize = 0; int ifile, fsize = 0; bool running = true; int result = BLAST_RESULT_OK; blast_reader_t* reader = 0; blast_reader_t** readers = 0; for (ifile = 0, fsize = array_size(files); ifile < fsize; ++ifile) { reader = blast_reader_open(files[ifile]); if (!reader) { log_warnf(HASH_BLAST, WARNING_SUSPICIOUS, STRING_CONST("Unable to open reader for: %.*s"), STRING_ARGS(files[ifile])); return BLAST_ERROR_UNABLE_TO_OPEN_FILE; } array_push(readers, reader); } if (array_size(readers) == 0) { log_warnf(HASH_BLAST, WARNING_INVALID_VALUE, STRING_CONST("No input files given")); return BLAST_ERROR_UNABLE_TO_OPEN_FILE; } for (itarg = 0, tsize = array_size(target); itarg < tsize; ++itarg) { blast_client_t client; if (blast_client_initialize(&client, target[itarg]) == BLAST_RESULT_OK) { client.readers = readers; array_push(clients, client); } } while (running && !blast_should_exit()) { running = false; for (iclient = 0, csize = array_size(clients); iclient < csize; ++iclient) running |= blast_client_process(clients + iclient); blast_process_system_events(); } for (iclient = 0, csize = array_size(clients); iclient < csize; ++iclient) blast_client_deallocate(&clients[iclient]); array_deallocate(clients); for (ifile = 0, fsize = array_size(readers); ifile < fsize; ++ifile) blast_reader_close(readers[ifile]); array_deallocate(readers); return result; }
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 main_initialize(void) { foundation_config_t config; application_t application; int ret; size_t iarg, asize; const string_const_t* cmdline = environment_command_line(); _test_memory_tracker = true; for (iarg = 0, asize = array_size(cmdline); iarg < asize; ++iarg) { if (string_equal(STRING_ARGS(cmdline[iarg]), STRING_CONST("--no-memory-tracker"))) _test_memory_tracker = false; } if (_test_memory_tracker) memory_set_tracker(memory_tracker_local()); memset(&config, 0, sizeof(config)); memset(&application, 0, sizeof(application)); application.name = string_const(STRING_CONST("Task library test suite")); application.short_name = string_const(STRING_CONST("test_all")); application.company = string_const(STRING_CONST("Rampant Pixels")); application.version = task_module_version(); application.flags = APPLICATION_UTILITY; application.exception_handler = test_exception_handler; log_set_suppress(0, ERRORLEVEL_INFO); #if ( FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID ) && BUILD_ENABLE_LOG log_set_handler(test_log_handler); #endif #if !FOUNDATION_PLATFORM_IOS && !FOUNDATION_PLATFORM_ANDROID && !FOUNDATION_PLATFORM_PNACL _test_should_start = true; #endif ret = foundation_initialize(memory_system_malloc(), application, config); #if BUILD_MONOLITHIC if (ret == 0) { task_config_t task_config; memset(&task_config, 0, sizeof(task_config)); ret = task_module_initialize(task_config); test_set_suitable_working_directory(); } #endif return ret; }
DECLARE_TEST(profile, thread) { thread_t thread[32]; int ith; uint64_t frame; error_t err = error(); _test_profile_offset = 0; atomic_store32(&_test_profile_output_counter, 0); profile_initialize(STRING_CONST("test_profile"), _test_profile_buffer, 30000); profile_enable(true); profile_set_output_wait(1); log_enable_stdout(false); for (ith = 0; ith < 32; ++ith) thread_initialize(&thread[ith], _profile_fail_thread, 0, STRING_CONST("profile_thread"), THREAD_PRIORITY_NORMAL, 0); for (ith = 0; ith < 32; ++ith) thread_start(&thread[ith]); test_wait_for_threads_startup(thread, 32); for (frame = 0; frame < 1000; ++frame) { thread_sleep(16); profile_end_frame(frame); } for (ith = 0; ith < 32; ++ith) thread_signal(&thread[ith]); test_wait_for_threads_finish(thread, 32); for (ith = 0; ith < 32; ++ith) thread_finalize(&thread[ith]); log_enable_stdout(true); err = error(); thread_sleep(1000); profile_enable(false); profile_finalize(); #if BUILD_ENABLE_PROFILE EXPECT_INTGT(atomic_load32(&_test_profile_output_counter), 0); //TODO: Implement parsing output results #else EXPECT_INTEQ(atomic_load32(&_test_profile_output_counter), 0); #endif EXPECT_INTEQ(err, ERROR_NONE); return 0; }
static void* event_loop(void* arg) { event_block_t* block; event_t* event = 0; FOUNDATION_UNUSED(arg); event_stream_set_beacon(system_event_stream(), &thread_self()->beacon); while (!_test_should_terminate) { block = event_stream_process(system_event_stream()); event = 0; while ((event = event_next(block, event))) { switch (event->id) { case FOUNDATIONEVENT_START: #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL log_debug(HASH_TEST, STRING_CONST("Application start event received")); _test_should_start = true; #endif break; case FOUNDATIONEVENT_TERMINATE: #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL log_debug(HASH_TEST, STRING_CONST("Application stop/terminate event received")); _test_should_terminate = true; break; #else log_warn(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Terminating tests due to event")); process_exit(-2); #endif case FOUNDATIONEVENT_FOCUS_GAIN: _test_have_focus = true; break; case FOUNDATIONEVENT_FOCUS_LOST: _test_have_focus = false; break; default: break; } test_event(event); } thread_wait(); } log_debug(HASH_TEST, STRING_CONST("Application event thread exiting")); return 0; }
static void _memory_deallocate_malloc(void* p) { #if FOUNDATION_SIZE_POINTER == 4 if (!p) return; # if BUILD_ENABLE_MEMORY_GUARD p = _memory_guard_verify(p); # endif # if FOUNDATION_PLATFORM_WINDOWS _aligned_free(p); # else free(*((void**)p - 1)); # endif #else uintptr_t raw_ptr; if (!p) return; # if BUILD_ENABLE_MEMORY_GUARD p = _memory_guard_verify(p); # endif raw_ptr = *((uintptr_t*)p - 1); if (raw_ptr & 1) { raw_ptr &= ~(uintptr_t)1; # if FOUNDATION_PLATFORM_WINDOWS if (VirtualFree((void*)raw_ptr, 0, MEM_RELEASE) == 0) log_warnf(HASH_MEMORY, WARNING_SYSTEM_CALL_FAIL, STRING_CONST("Failed to VirtualFree 0x%" PRIfixPTR), (uintptr_t)raw_ptr); # else uintptr_t raw_size = *((uintptr_t*)p - 2); if (munmap((void*)raw_ptr, raw_size) < 0) log_warnf(HASH_MEMORY, WARNING_SYSTEM_CALL_FAIL, STRING_CONST("Failed to munmap 0x%" PRIfixPTR " size %" PRIsize), (uintptr_t)raw_ptr, raw_size); # endif } else { # if FOUNDATION_PLATFORM_WINDOWS _aligned_free((void*)raw_ptr); # else free((void*)raw_ptr); # endif } #endif }
int _stream_initialize(void) { _stream_protocol_table = hashtable64_allocate(32); stream_set_protocol_handler(0, 0, fs_open_file); #if FOUNDATION_PLATFORM_ANDROID stream_set_protocol_handler(STRING_CONST("asset"), asset_stream_open); #endif stream_set_protocol_handler(STRING_CONST("file"), fs_open_file); stream_set_protocol_handler(STRING_CONST("stdout"), _stream_open_stdout); stream_set_protocol_handler(STRING_CONST("stderr"), _stream_open_stderr); stream_set_protocol_handler(STRING_CONST("stdin"), _stream_open_stdin); return 0; }
int main_run(void* main_arg) { int result = RENDERCOMPILE_RESULT_OK; rendercompile_input_t input = rendercompile_parse_command_line(environment_command_line()); FOUNDATION_UNUSED(main_arg); if (input.display_help) { rendercompile_print_usage(); goto exit; } resource_source_set_path(STRING_ARGS(input.source_path)); resource_compile_register(render_compile); size_t ifile, fsize; for (ifile = 0, fsize = array_size(input.input_files); ifile < fsize; ++ifile) { uuid_t uuid = string_to_uuid(STRING_ARGS(input.input_files[ifile])); if (uuid_is_null(uuid)) { char buffer[BUILD_MAX_PATHLEN]; string_t pathstr = string_copy(buffer, sizeof(buffer), STRING_ARGS(input.input_files[ifile])); pathstr = path_clean(STRING_ARGS(pathstr), sizeof(buffer)); pathstr = path_absolute(STRING_ARGS(pathstr), sizeof(buffer)); uuid = resource_import_map_lookup(STRING_ARGS(pathstr)); } if (uuid_is_null(uuid)) { log_warnf(HASH_RESOURCE, WARNING_INVALID_VALUE, STRING_CONST("Failed to lookup: %.*s"), STRING_FORMAT(input.input_files[ifile])); result = RENDERCOMPILE_RESULT_INVALID_INPUT; break; } if (resource_compile(uuid, RESOURCE_PLATFORM_ALL)) { string_const_t uuidstr = string_from_uuid_static(uuid); log_infof(HASH_RESOURCE, STRING_CONST("Successfully compiled: %.*s (%.*s)"), STRING_FORMAT(uuidstr), STRING_FORMAT(input.input_files[ifile])); } else { string_const_t uuidstr = string_from_uuid_static(uuid); log_warnf(HASH_RESOURCE, WARNING_UNSUPPORTED, STRING_CONST("Failed to compile: %.*s (%.*s)"), STRING_FORMAT(uuidstr), STRING_FORMAT(input.input_files[ifile])); } } exit: array_deallocate(input.input_files); return result; }
int main_run(void* main_arg) { const char element[4][2] = { "X", "Y", "Z", "W" }; FOUNDATION_UNUSED(main_arg); log_set_suppress(HASH_TOOL, ERRORLEVEL_DEBUG); log_info(HASH_TOOL, STRING_CONST( "/* mask.h - Vector library - Public Domain - 2013 Mattias Jansson / Rampant Pixels\n" " *\n" " * This library provides a cross-platform vector math library in C11 providing basic support data types and\n" " * functions to write applications and games in a platform-independent fashion. The latest source code is\n" " * always available at\n" " *\n" " * https://github.com/rampantpixels/vector_lib\n" " *\n" " * This library is built on top of the foundation library available at\n" " *\n" " * https://github.com/rampantpixels/foundation_lib\n" " *\n" " * This library is put in the public domain; you can redistribute it and/or modify it without any restrictions.\n" " *\n" "*/\n\n" "#pragma once\n\n" "/*! \\file math/mask.h\n" " Vector mask definitions */\n\n" "#include <vector/types.h>\n\n" "#define VECTOR_MASK(x, y, z, w) (((w) << 6) | ((z) << 4) | ((y) << 2) | ((x)))\n\n" "/* Vector shuffle masks where the operation performed by\n" " v1 = vector_shuffle(v0, VECTOR_MASK_abcd)\n" " will be equal to\n" " v1.x = v0[a]\n" " v1.y = v0[b]\n" " v1.z = v0[c]\n" " v1.w = v0[d] */\n")); for (int e0 = 0; e0 < 4; ++e0) for (int e1 = 0; e1 < 4; ++e1) for (int e2 = 0; e2 < 4; ++e2) for (int e3 = 0; e3 < 4; ++e3) log_infof(HASH_TOOL, STRING_CONST("#define VECTOR_MASK_%s%s%s%s VECTOR_MASK(%d, %d, %d, %d)"), element[e0], element[e1], element[e2], element[e3], e0, e1, e2, e3); return 0; }
void lua_module_registry_finalize(lua_State* state) { lua_pushlstring(state, STRING_CONST(BUILD_REGISTRY_LOADED_MODULES)); lua_gettable(state, LUA_REGISTRYINDEX); lua_pushlstring(state, STRING_CONST(LOADED_MODULES_ENTRY_ARRAY)); lua_gettable(state, -2); lua_modulemap_entry_t** entryarr = lua_touserdata(state, -1); lua_pop(state, 2); if (entryarr) array_deallocate(entryarr); }
static lua_module_t lua_module_load_resource(const uuid_t uuid) { lua_module_t module = {0, 0}; bool success = false; const uint32_t expected_version = 1; uint64_t platform = 0; stream_t* stream; stream = resource_stream_open_static(uuid, platform); if (stream) { resource_header_t header = resource_stream_read_header(stream); if ((header.type == HASH_LUA) && (header.version == expected_version)) { success = true; } else { log_warnf(HASH_LUA, WARNING_INVALID_VALUE, STRING_CONST("Got unexpected type/version when loading Lua module: %" PRIx64 " : %u"), header.type, header.version); } stream_deallocate(stream); stream = nullptr; } if (success) stream = resource_stream_open_dynamic(uuid, platform); if (stream) { uint32_t version = stream_read_uint32(stream); size_t size = (size_t)stream_read_uint64(stream); if (version == expected_version) { void* buffer = memory_allocate(HASH_LUA, size, 0, MEMORY_TEMPORARY); if (stream_read(stream, buffer, size) == size) { module.bytecode = buffer; module.size = size; } else { memory_deallocate(buffer); } } else { log_warnf(HASH_LUA, WARNING_INVALID_VALUE, STRING_CONST("Got unexpected type/version when loading Lua module blob: %u"), version); } stream_deallocate(stream); stream = nullptr; } return module; }
DECLARE_TEST(mutex, basic) { mutex_t* mutex; mutex = mutex_allocate(STRING_CONST("test")); EXPECT_CONSTSTRINGEQ(mutex_name(mutex), string_const(STRING_CONST("test"))); EXPECT_TRUE(mutex_try_lock(mutex)); EXPECT_TRUE(mutex_lock(mutex)); EXPECT_TRUE(mutex_try_lock(mutex)); EXPECT_TRUE(mutex_lock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_WARNING); EXPECT_FALSE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_INFO); mutex_signal(mutex); thread_yield(); EXPECT_TRUE(mutex_try_wait(mutex, 1)); EXPECT_TRUE(mutex_unlock(mutex)); mutex_signal(mutex); thread_yield(); EXPECT_TRUE(mutex_wait(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_WARNING); EXPECT_FALSE(mutex_try_wait(mutex, 100)); EXPECT_FALSE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_INFO); mutex_signal(mutex); thread_yield(); EXPECT_TRUE(mutex_try_wait(mutex, 1)); log_set_suppress(0, ERRORLEVEL_WARNING); EXPECT_FALSE(mutex_try_wait(mutex, 100)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_FALSE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_INFO); mutex_deallocate(mutex); return 0; }
void test_exception_handler(const char* dump_file, size_t length) { FOUNDATION_UNUSED(dump_file); FOUNDATION_UNUSED(length); log_error(HASH_TEST, ERROR_EXCEPTION, STRING_CONST("Test raised exception")); process_exit(-1); }
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 }
bool network_poll_add_socket(network_poll_t* pollobj, socket_t* sock) { size_t num_sockets = pollobj->num_sockets; if ((sock->base >= 0) && (num_sockets < pollobj->max_sockets)) { socket_base_t* sockbase = _socket_base + sock->base; log_debugf(HASH_NETWORK, STRING_CONST("Network poll: Adding socket (0x%" PRIfixPTR " : %d)"), sock, sockbase->fd); pollobj->slots[ num_sockets ].sock = sock; pollobj->slots[ num_sockets ].base = sock->base; pollobj->slots[ num_sockets ].fd = sockbase->fd; if (sockbase->state == SOCKETSTATE_CONNECTING) _socket_poll_state(sockbase); #if FOUNDATION_PLATFORM_APPLE pollobj->pollfds[ num_sockets ].fd = sockbase->fd; pollobj->pollfds[ num_sockets ].events = ((sockbase->state == SOCKETSTATE_CONNECTING) ? POLLOUT : POLLIN) | POLLERR | POLLHUP; #elif FOUNDATION_PLATFORM_LINUX || FOUNDATION_PLATFORM_ANDROID struct epoll_event event; event.events = ((sockbase->state == SOCKETSTATE_CONNECTING) ? EPOLLOUT : EPOLLIN) | EPOLLERR | EPOLLHUP; event.data.fd = (int)pollobj->num_sockets; epoll_ctl(pollobj->fd_poll, EPOLL_CTL_ADD, sockbase->fd, &event); #endif ++pollobj->num_sockets; return true; } return false; }