diff --git a/build/cmake/create_tests.cmake b/build/cmake/create_tests.cmake index 5535c3f6..ee57836b 100644 --- a/build/cmake/create_tests.cmake +++ b/build/cmake/create_tests.cmake @@ -5,7 +5,7 @@ enable_testing() # CTest args: -set(CMAKE_CTEST_ARGUMENTS "-j" "--schedule-random" "--output-on-failure" "--output-log" "${CMAKE_SOURCE_DIR}/out/test/all_tests.log") +set(CMAKE_CTEST_ARGUMENTS "-j" "--schedule-random" "--output-on-failure" "--extra-verbose" "--output-log" "${CMAKE_SOURCE_DIR}/out/test/all_tests.log") # Not all tests can be run on all platforms: if(IS_MACOS) diff --git a/src/Amalgam/Amalgam.h b/src/Amalgam/Amalgam.h index 7493f6fb..2629d4d7 100644 --- a/src/Amalgam/Amalgam.h +++ b/src/Amalgam/Amalgam.h @@ -5,7 +5,7 @@ #include #if defined(_MSC_VER) -//Microsoft +//Microsoft #define AMALGAM_EXPORT __declspec(dllexport) #elif defined(__GNUC__) //GCC @@ -25,7 +25,8 @@ extern "C" }; //loads the entity specified into handle - AMALGAM_EXPORT LoadEntityStatus LoadEntity(char *handle, char *path, bool persistent, bool load_contained_entities, char *write_log_filename, char *print_log_filename); + AMALGAM_EXPORT LoadEntityStatus LoadEntity(char *handle, char *path, bool persistent, bool load_contained_entities, + bool escape_filename, bool escape_contained_filenames, char *write_log_filename, char *print_log_filename); //loads the entity specified into handle //TODO 19512: deprecated - legacy method to support wrappers that can't call LoadEntity returning a LoadEntityStatus yet @@ -75,7 +76,7 @@ extern "C" AMALGAM_EXPORT void SetStringList(char *handle, char *label, char **list, size_t len); AMALGAM_EXPORT void SetJSONToLabel(char *handle, char *label, char *json); - + AMALGAM_EXPORT wchar_t *GetJSONPtrFromLabelWide(char *handle, char *label); AMALGAM_EXPORT char *GetJSONPtrFromLabel(char *handle, char *label); diff --git a/src/Amalgam/AmalgamAPI.cpp b/src/Amalgam/AmalgamAPI.cpp index 7495021f..cebfd65d 100644 --- a/src/Amalgam/AmalgamAPI.cpp +++ b/src/Amalgam/AmalgamAPI.cpp @@ -1,4 +1,4 @@ -//project headers: +//project headers: #include "Amalgam.h" #include "AmalgamVersion.h" #include "Concurrency.h" @@ -85,19 +85,20 @@ extern "C" // api methods // ************************************ - LoadEntityStatus LoadEntity(char *handle, char *path, bool persistent, bool load_contained_entities, char *write_log_filename, char *print_log_filename) + LoadEntityStatus LoadEntity(char *handle, char *path, bool persistent, bool load_contained_entities, + bool escape_filename, bool escape_contained_filenames, char *write_log_filename, char *print_log_filename) { std::string h(handle); std::string p(path); std::string wlfname(write_log_filename); std::string plfname(print_log_filename); - auto status = entint.LoadEntity(h, p, persistent, load_contained_entities, wlfname, plfname); + auto status = entint.LoadEntity(h, p, persistent, load_contained_entities, escape_filename, escape_contained_filenames, wlfname, plfname); return ConvertLoadStatusToCStatus(status); } bool LoadEntityLegacy(char *handle, char *path, bool persistent, bool load_contained_entities, char *write_log_filename, char *print_log_filename) { - auto status = LoadEntity(handle, path, persistent, load_contained_entities, write_log_filename, print_log_filename); + auto status = LoadEntity(handle, path, persistent, load_contained_entities, false, false, write_log_filename, print_log_filename); delete[] status.message; delete[] status.version; @@ -179,7 +180,7 @@ extern "C" return StringToCharPtr(ct); } - wchar_t *ExecuteEntityJsonPtrWide(char *handle, char *label, char *json) + wchar_t *ExecuteEntityJsonPtrWide(char *handle, char *label, char *json) { std::string h(handle); std::string l(label); @@ -310,7 +311,7 @@ extern "C" entint.SetNumberMatrix(h, l, list, rows, columns); } - size_t GetNumberListLength(char *handle, char *label) + size_t GetNumberListLength(char *handle, char *label) { std::string h(handle); std::string l(label); @@ -318,7 +319,7 @@ extern "C" return entint.GetNumberListLength(h, l); } - size_t GetNumberMatrixWidth(char *handle, char *label) + size_t GetNumberMatrixWidth(char *handle, char *label) { std::string h(handle); std::string l(label); @@ -326,7 +327,7 @@ extern "C" return entint.GetNumberMatrixWidth(h, l); } - size_t GetNumberMatrixHeight(char *handle, char *label) + size_t GetNumberMatrixHeight(char *handle, char *label) { std::string h(handle); std::string l(label); @@ -334,7 +335,7 @@ extern "C" return entint.GetNumberMatrixHeight(h, l); } - double *GetNumberListPtr(char *handle, char *label) + double *GetNumberListPtr(char *handle, char *label) { std::string h(handle); std::string l(label); @@ -347,7 +348,7 @@ extern "C" return ret; } - double *GetNumberMatrixPtr(char *handle, char *label) + double *GetNumberMatrixPtr(char *handle, char *label) { std::string h(handle); std::string l(label); @@ -391,7 +392,7 @@ extern "C" entint.SetStringList(h, l, list, len); } - size_t GetStringListLength(char *handle, char *label) + size_t GetStringListLength(char *handle, char *label) { std::string h(handle); std::string l(label); diff --git a/src/Amalgam/AmalgamTrace.cpp b/src/Amalgam/AmalgamTrace.cpp index 3c8133e1..0a8c1c57 100644 --- a/src/Amalgam/AmalgamTrace.cpp +++ b/src/Amalgam/AmalgamTrace.cpp @@ -36,6 +36,8 @@ int32_t RunAmalgamTrace(std::istream *in_stream, std::ostream *out_stream, std:: std::string data; std::string persistent; std::string use_contained; + std::string escape_filename; + std::string escape_contained_filenames; std::string print_listener_path; std::string transaction_listener_path; std::string response; @@ -61,17 +63,28 @@ int32_t RunAmalgamTrace(std::istream *in_stream, std::ostream *out_stream, std:: use_contained = command_tokens[3]; if(command_tokens.size() >= 5) - print_listener_path = command_tokens[4]; + escape_filename = command_tokens[4]; else - print_listener_path = ""; + escape_filename = "false"; if(command_tokens.size() >= 6) - transaction_listener_path = command_tokens[5]; + escape_contained_filenames = command_tokens[5]; + else + escape_contained_filenames = "true"; + + if(command_tokens.size() >= 7) + transaction_listener_path = command_tokens[6]; else transaction_listener_path = ""; + if(command_tokens.size() >= 8) + print_listener_path = command_tokens[7]; + else + print_listener_path = ""; + std::string new_rand_seed = random_stream.CreateOtherStreamStateViaString("trace"); - auto status = entint.LoadEntity(handle, data, persistent == "true", use_contained == "true", transaction_listener_path, print_listener_path, new_rand_seed); + auto status = entint.LoadEntity(handle, data, persistent == "true", use_contained == "true", + escape_filename == "true", escape_contained_filenames == "true", transaction_listener_path, print_listener_path, new_rand_seed); response = status.loaded ? SUCCESS_RESPONSE : FAILURE_RESPONSE; } else @@ -95,14 +108,14 @@ int32_t RunAmalgamTrace(std::istream *in_stream, std::ostream *out_stream, std:: persistent = command_tokens[3]; if(command_tokens.size() >= 5) - print_listener_path = command_tokens[4]; + transaction_listener_path = command_tokens[4]; else - print_listener_path = ""; + transaction_listener_path = ""; if(command_tokens.size() >= 6) - transaction_listener_path = command_tokens[5]; + print_listener_path = command_tokens[5]; else - transaction_listener_path = ""; + print_listener_path = ""; bool result = entint.CloneEntity(handle, clone_handle, data, persistent == "true", transaction_listener_path, print_listener_path); response = result ? SUCCESS_RESPONSE : FAILURE_RESPONSE; diff --git a/src/Amalgam/AssetManager.cpp b/src/Amalgam/AssetManager.cpp index 3d7400c6..4938afd2 100644 --- a/src/Amalgam/AssetManager.cpp +++ b/src/Amalgam/AssetManager.cpp @@ -304,10 +304,10 @@ bool AssetManager::StoreEntityToResourcePath(Entity *entity, std::string &resour { std::error_code ec; //create directory in case it doesn't exist - bool created_successfully = std::filesystem::create_directories(resource_base_path, ec); + std::filesystem::create_directories(resource_base_path, ec); //return that the directory could not be created - if(!created_successfully || ec) + if(ec) return false; //store any contained entities @@ -406,9 +406,9 @@ void AssetManager::CreateEntity(Entity *entity) //create contained entity directory in case it doesn't currently exist std::string new_path = slice_path + filename + traversal_path; std::error_code ec; - bool created_successfully = std::filesystem::create_directory(new_path, ec); + std::filesystem::create_directory(new_path, ec); - if(!ec && created_successfully) + if(!ec) { new_path += id_suffix; StoreEntityToResourcePath(entity, new_path, extension, false, true, false, true, false); diff --git a/src/Amalgam/entity/EntityExternalInterface.cpp b/src/Amalgam/entity/EntityExternalInterface.cpp index 92c3c18b..9e776f1e 100644 --- a/src/Amalgam/entity/EntityExternalInterface.cpp +++ b/src/Amalgam/entity/EntityExternalInterface.cpp @@ -30,7 +30,7 @@ void EntityExternalInterface::LoadEntityStatus::SetStatus(bool loaded_in, std::s } EntityExternalInterface::LoadEntityStatus EntityExternalInterface::LoadEntity(std::string &handle, std::string &path, bool persistent, bool load_contained_entities, - std::string &write_log_filename, std::string &print_log_filename, std::string rand_seed) + bool escape_filename, bool escape_contained_filenames, std::string &write_log_filename, std::string &print_log_filename, std::string rand_seed) { LoadEntityStatus status; @@ -42,7 +42,7 @@ EntityExternalInterface::LoadEntityStatus EntityExternalInterface::LoadEntity(st } std::string file_type = ""; - Entity *entity = asset_manager.LoadEntityFromResourcePath(path, file_type, persistent, load_contained_entities, false, true, rand_seed, status); + Entity *entity = asset_manager.LoadEntityFromResourcePath(path, file_type, persistent, load_contained_entities, escape_filename, escape_contained_filenames, rand_seed, status); if(!status.loaded) return status; diff --git a/src/Amalgam/entity/EntityExternalInterface.h b/src/Amalgam/entity/EntityExternalInterface.h index ab6cb092..db6fc2d4 100644 --- a/src/Amalgam/entity/EntityExternalInterface.h +++ b/src/Amalgam/entity/EntityExternalInterface.h @@ -12,7 +12,7 @@ /* * This class constitutes the C++ backing for the C API, and is fully functional as a C++ API. - * + * * Amalgam functions through the use of "Entities" which will have a predetermined set of "labels". * Loading an .amlg file with the LoadEntity command will assign the entity to a given handle. * The majority of the methods provided here allow manipulation of data associated with a label within an entity. @@ -37,7 +37,8 @@ class EntityExternalInterface }; LoadEntityStatus LoadEntity(std::string &handle, std::string &path, bool persistent, bool load_contained_entities, - std::string &write_log_filename, std::string &print_log_filename, std::string rand_seed = std::string("")); + bool escape_filename, bool escape_contained_filenames, std::string &write_log_filename, std::string &print_log_filename, + std::string rand_seed = std::string("")); LoadEntityStatus VerifyEntity(std::string &path); bool CloneEntity(std::string &handle, std::string &cloned_handle, std::string &path, bool persistent, @@ -66,7 +67,7 @@ class EntityExternalInterface void GetNumberList(EvaluableNode *label_val, double *out_arr, size_t len); void SetNumberList(std::string &handle, std::string &label, double *arr, size_t len); void AppendNumberList(std::string &handle, std::string &label, double *arr, size_t len); - + size_t GetNumberMatrixWidth(std::string &handle, std::string &label); size_t GetNumberMatrixHeight(std::string &handle, std::string &label); void GetNumberMatrix(std::string &handle, std::string &label, double *out_arr, size_t w, size_t h); @@ -216,7 +217,7 @@ class EntityExternalInterface const auto &[bundle_handle, bundle_inserted] = handleToBundle.emplace(handle, bundle); if(!bundle_inserted) { - //erase the previous + //erase the previous if(bundle_handle->second != nullptr) delete bundle_handle->second; @@ -236,15 +237,17 @@ class EntityExternalInterface if(bundle_handle == end(handleToBundle) || bundle_handle->second == nullptr) return; - handleToBundle.erase(handle); + //because handleToBundle is a flat hashmap, erasure will invalidate the iterator + //so delete first delete bundle_handle->second; + handleToBundle.erase(handle); } //for concurrent reading and writing the interface management data below #ifdef MULTITHREAD_INTERFACE Concurrency::ReadWriteMutex mutex; #endif - + //map between entity name and the bundle of the entity and its listeners, etc. FastHashMap handleToBundle; }; diff --git a/test/lib_smoke_test/main.cpp b/test/lib_smoke_test/main.cpp index b0c2e667..a47b0d2f 100644 --- a/test/lib_smoke_test/main.cpp +++ b/test/lib_smoke_test/main.cpp @@ -19,7 +19,7 @@ int main(int argc, char* argv[]) char* file = (argc > 1) ? argv[1] : (char*)"test.amlg"; char write_log[] = ""; char print_log[] = ""; - auto status = LoadEntity(handle, file, false, true, write_log, print_log); + auto status = LoadEntity(handle, file, false, true, false, false, write_log, print_log); if(status.loaded) { char label[] = "test";