diff --git a/.gitignore b/.gitignore index a545519..ec348ae 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,4 @@ build/ # debug information files *.dwo -lattice_files/expand.yaml \ No newline at end of file +lattice_files/expand.pals.yaml \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index aa850c7..5c81b42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.16) project(YAMLWrapper) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN YES) + set(CMAKE_CXX_STANDARD 17) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -85,7 +88,7 @@ file(COPY ${CMAKE_SOURCE_DIR}/lattice_files/ # endif() add_library(yaml_c_wrapper SHARED src/yaml_c_wrapper.cpp) -target_link_libraries(yaml_c_wrapper yaml-cpp) +target_link_libraries(yaml_c_wrapper PUBLIC yaml-cpp) add_executable(yaml_reader examples/yaml_reader.cpp) target_link_libraries(yaml_reader yaml_c_wrapper) diff --git a/examples/yaml_reader.cpp b/examples/yaml_reader.cpp index e49c896..02eef11 100644 --- a/examples/yaml_reader.cpp +++ b/examples/yaml_reader.cpp @@ -1,6 +1,8 @@ #include "../src/yaml_c_wrapper.h" #include +// See ex.pals.yaml for the example lattice file and expand.pals.yaml for the output of this file. + int main() { // reading a lattice from a yaml file YAMLNodeHandle handle = yaml_parse_file("../lattice_files/ex.pals.yaml"); @@ -8,13 +10,20 @@ int main() { std::cout << yaml_to_string(handle) << std::endl << std::endl; // type checking - std::cout << (yaml_is_sequence(handle)) << "\n"; + // prints "handle is of type sequence: 1", 1 meaning true + std::cout << "handle is of type sequence: " << (yaml_is_sequence(handle)) << "\n"; // accessing sequence YAMLNodeHandle node = yaml_get_index(handle, 0); + /* prints + the first element is: + thingB: + kind: Sextupole + */ std::cout << "the first element is: \n" << yaml_to_string(node) << "\n"; // accessing map + // prints "the value at key 'thingB' is: kind: Sextupole" std::cout << "\nthe value at key 'thingB' is: " << yaml_to_string(yaml_get_key(node, "thingB")) << "\n"; // creating a new node that's a map @@ -28,10 +37,15 @@ int main() { YAMLNodeHandle scalar = yaml_create_scalar(); yaml_set_scalar_string(scalar, "magnet2"); yaml_set_at_index(sequence, 1, scalar); + // give sequence a name by putting it in a map: + YAMLNodeHandle magnets = yaml_create_map(); + yaml_set_node(magnets, "magnets", sequence); // adding new nodes to lattice yaml_push_node(handle, map); - yaml_push_node(handle, sequence); + yaml_push_node(handle, magnets); + + yaml_expand(handle); // writing modified lattice file to expand.pals.yaml yaml_write_file(handle, "../lattice_files/expand.pals.yaml"); diff --git a/lattice_files/ex.pals.yaml b/lattice_files/ex.pals.yaml index a9e9898..1261101 100644 --- a/lattice_files/ex.pals.yaml +++ b/lattice_files/ex.pals.yaml @@ -14,4 +14,5 @@ length: 1.03 direction: -1 - a_subline: # Item a_subline is repeated three times - repeat: 3 \ No newline at end of file + repeat: 3 +- include: "include.pals.yaml" diff --git a/lattice_files/include.pals.yaml b/lattice_files/include.pals.yaml new file mode 100644 index 0000000..84ec631 --- /dev/null +++ b/lattice_files/include.pals.yaml @@ -0,0 +1,4 @@ +- line: + first: 1 + second: 2 + thrid: 3 \ No newline at end of file diff --git a/src/yaml_c_wrapper.cpp b/src/yaml_c_wrapper.cpp index 6fa9c15..6a417af 100644 --- a/src/yaml_c_wrapper.cpp +++ b/src/yaml_c_wrapper.cpp @@ -3,6 +3,12 @@ #include #include +#if defined(_WIN32) + #define YAML_API extern "C" __declspec(dllexport) +#else + #define YAML_API extern "C" __attribute__((visibility("default"))) +#endif + // ======= LATTICE EXPANSION UTILS // === REPLACE === YAML::Node replace_internal(YAML::Node name, std::map* seen) { @@ -25,6 +31,13 @@ YAML::Node expand_internal(YAML::Node node, std::map* s return replace_internal(node, seen); } else if (node.IsMap()) { for (auto ele : node) { + // will probably need to add better method of finding files + if (ele.first.as() == "include") { + std::string str = ele.second.as(); + std::string filename = str.substr(0, str.length()); + node = YAML::LoadFile("../lattice_files/" + filename); + break; + } seen->insert({ele.first.as(), ele.second}); node[ele.first.as()] = expand_internal(ele.second, seen); } @@ -35,37 +48,37 @@ YAML::Node expand_internal(YAML::Node node, std::map* s } extern "C" { - typedef void* YAMLNodeHandle; + YAML_API typedef void* YAMLNodeHandle; // === CREATION/DELETION === - YAMLNodeHandle yaml_create_node() { + YAML_API YAMLNodeHandle yaml_create_node() { return new YAML::Node(); } - YAMLNodeHandle yaml_create_map() { + YAML_API YAMLNodeHandle yaml_create_map() { auto node = new YAML::Node(); *node = YAML::Node(YAML::NodeType::Map); return node; } - YAMLNodeHandle yaml_create_sequence() { + YAML_API YAMLNodeHandle yaml_create_sequence() { auto node = new YAML::Node(); *node = YAML::Node(YAML::NodeType::Sequence); return node; } - YAMLNodeHandle yaml_create_scalar() { + YAML_API YAMLNodeHandle yaml_create_scalar() { auto node = new YAML::Node(); *node = YAML::Node(YAML::NodeType::Scalar); return node; } - void yaml_delete_node(YAMLNodeHandle handle) { + YAML_API void yaml_delete_node(YAMLNodeHandle handle) { delete static_cast(handle); } // === PARSING === - YAMLNodeHandle yaml_parse(const char* yaml_str) { + YAML_API YAML_API YAMLNodeHandle yaml_parse(const char* yaml_str) { try { return new YAML::Node(YAML::Load(yaml_str)); } catch (...) { @@ -73,7 +86,7 @@ extern "C" { } } - YAMLNodeHandle yaml_parse_file(const char* filename) { + YAML_API YAMLNodeHandle yaml_parse_file(const char* filename) { try { return new YAML::Node(YAML::LoadFile(filename)); } catch (...) { @@ -82,24 +95,24 @@ extern "C" { } // === TYPE CHECKS === - bool yaml_is_scalar(YAMLNodeHandle handle) { + YAML_API bool yaml_is_scalar(YAMLNodeHandle handle) { return static_cast(handle)->IsScalar(); } - bool yaml_is_sequence(YAMLNodeHandle handle) { + YAML_API bool yaml_is_sequence(YAMLNodeHandle handle) { return static_cast(handle)->IsSequence(); } - bool yaml_is_map(YAMLNodeHandle handle) { + YAML_API bool yaml_is_map(YAMLNodeHandle handle) { return static_cast(handle)->IsMap(); } - bool yaml_is_null(YAMLNodeHandle handle) { + YAML_API bool yaml_is_null(YAMLNodeHandle handle) { return static_cast(handle)->IsNull(); } // === ACCESS === - YAMLNodeHandle yaml_get_key(YAMLNodeHandle handle, const char* key) { + YAML_API YAMLNodeHandle yaml_get_key(YAMLNodeHandle handle, const char* key) { auto node = static_cast(handle); auto child = (*node)[key]; if (!child.IsDefined()) { @@ -108,7 +121,7 @@ extern "C" { return new YAML::Node(child); } - YAMLNodeHandle yaml_get_index(YAMLNodeHandle handle, int index) { + YAML_API YAMLNodeHandle yaml_get_index(YAMLNodeHandle handle, int index) { auto node = static_cast(handle); if (index < 0 || index >= node->size()) { return nullptr; @@ -116,16 +129,16 @@ extern "C" { return new YAML::Node((*node)[index]); } - bool yaml_has_key(YAMLNodeHandle handle, const char* key) { + YAML_API bool yaml_has_key(YAMLNodeHandle handle, const char* key) { auto node = static_cast(handle); return (*node)[key].IsDefined(); } - int yaml_size(YAMLNodeHandle handle) { + YAML_API int yaml_size(YAMLNodeHandle handle) { return static_cast(handle)->size(); } - char** yaml_get_keys(YAMLNodeHandle handle, int* out_count) { + YAML_API char** yaml_get_keys(YAMLNodeHandle handle, int* out_count) { auto node = static_cast(handle); if (!node->IsMap()) { *out_count = 0; @@ -147,7 +160,7 @@ extern "C" { } // === CONVERT TO C TYPES (caller must free returned strings) === - char* yaml_as_string(YAMLNodeHandle handle) { + YAML_API char* yaml_as_string(YAMLNodeHandle handle) { try { auto str = static_cast(handle)->as(); char* result = new char[str.length() + 1]; @@ -158,7 +171,7 @@ extern "C" { } } - int yaml_as_int(YAMLNodeHandle handle) { + YAML_API int yaml_as_int(YAMLNodeHandle handle) { try { return static_cast(handle)->as(); } catch (...) { @@ -166,7 +179,7 @@ extern "C" { } } - double yaml_as_float(YAMLNodeHandle handle) { + YAML_API double yaml_as_float(YAMLNodeHandle handle) { try { return static_cast(handle)->as(); } catch (...) { @@ -174,7 +187,7 @@ extern "C" { } } - bool yaml_as_bool(YAMLNodeHandle handle) { + YAML_API bool yaml_as_bool(YAMLNodeHandle handle) { try { return static_cast(handle)->as(); } catch (...) { @@ -183,79 +196,79 @@ extern "C" { } // === MODIFICATION === - void yaml_set_string(YAMLNodeHandle handle, const char* key, const char* value) { + YAML_API void yaml_set_string(YAMLNodeHandle handle, const char* key, const char* value) { auto node = static_cast(handle); (*node)[key] = value; } - void yaml_set_int(YAMLNodeHandle handle, const char* key, int value) { + YAML_API void yaml_set_int(YAMLNodeHandle handle, const char* key, int value) { auto node = static_cast(handle); (*node)[key] = value; } - void yaml_set_float(YAMLNodeHandle handle, const char* key, double value) { + YAML_API void yaml_set_float(YAMLNodeHandle handle, const char* key, double value) { auto node = static_cast(handle); (*node)[key] = value; } - void yaml_set_bool(YAMLNodeHandle handle, const char* key, bool value) { + YAML_API void yaml_set_bool(YAMLNodeHandle handle, const char* key, bool value) { auto node = static_cast(handle); (*node)[key] = value; } - void yaml_set_node(YAMLNodeHandle handle, const char* key, YAMLNodeHandle value) { + YAML_API void yaml_set_node(YAMLNodeHandle handle, const char* key, YAMLNodeHandle value) { auto node = static_cast(handle); auto val_node = static_cast(value); (*node)[key] = *val_node; } - void yaml_set_scalar_string(YAMLNodeHandle handle, const char* value) { + YAML_API void yaml_set_scalar_string(YAMLNodeHandle handle, const char* value) { if (handle == nullptr || value == nullptr) return; auto node = static_cast(handle); *node = value; } - void yaml_set_scalar_int(YAMLNodeHandle handle, int value) { + YAML_API void yaml_set_scalar_int(YAMLNodeHandle handle, int value) { if (handle == nullptr) return; auto node = static_cast(handle); *node = value; } - void yaml_set_scalar_float(YAMLNodeHandle handle, double value) { + YAML_API void yaml_set_scalar_float(YAMLNodeHandle handle, double value) { if (handle == nullptr) return; auto node = static_cast(handle); *node = value; } - void yaml_set_scalar_bool(YAMLNodeHandle handle, bool value) { + YAML_API void yaml_set_scalar_bool(YAMLNodeHandle handle, bool value) { if (handle == nullptr) return; auto node = static_cast(handle); *node = value; } // Set node at index for sequences - void yaml_set_at_index(YAMLNodeHandle handle, int index, YAMLNodeHandle value) { + YAML_API void yaml_set_at_index(YAMLNodeHandle handle, int index, YAMLNodeHandle value) { auto node = static_cast(handle); auto val_node = static_cast(value); (*node)[index] = *val_node; } - void yaml_push_string(YAMLNodeHandle handle, const char* value) { + YAML_API void yaml_push_string(YAMLNodeHandle handle, const char* value) { auto node = static_cast(handle); node->push_back(value); } - void yaml_push_int(YAMLNodeHandle handle, int value) { + YAML_API void yaml_push_int(YAMLNodeHandle handle, int value) { auto node = static_cast(handle); node->push_back(value); } - void yaml_push_float(YAMLNodeHandle handle, double value) { + YAML_API void yaml_push_float(YAMLNodeHandle handle, double value) { auto node = static_cast(handle); node->push_back(value); } - void yaml_push_node(YAMLNodeHandle handle, YAMLNodeHandle value) { + YAML_API void yaml_push_node(YAMLNodeHandle handle, YAMLNodeHandle value) { auto node = static_cast(handle); auto val_node = static_cast(value); node->push_back(*val_node); @@ -263,7 +276,7 @@ extern "C" { // === WRITE TO FILE WITH EMITTER === - bool yaml_write_file(YAMLNodeHandle handle, const char* filename) { + YAML_API bool yaml_write_file(YAMLNodeHandle handle, const char* filename) { try { auto node = static_cast(handle); @@ -284,7 +297,7 @@ extern "C" { } // Write with emitter control (removed SetWrap) - bool yaml_write_file_formatted(YAMLNodeHandle handle, const char* filename, + YAML_API bool yaml_write_file_formatted(YAMLNodeHandle handle, const char* filename, int indent, bool flow_maps, bool flow_seqs) { try { auto node = static_cast(handle); @@ -315,7 +328,7 @@ extern "C" { } // Get YAML string with emitter - char* yaml_emit(YAMLNodeHandle handle, int indent) { + YAML_API char* yaml_emit(YAMLNodeHandle handle, int indent) { try { auto node = static_cast(handle); @@ -335,7 +348,7 @@ extern "C" { } // Advanced version with all available options - bool yaml_write_file_advanced(YAMLNodeHandle handle, const char* filename, + YAML_API bool yaml_write_file_advanced(YAMLNodeHandle handle, const char* filename, int indent, bool flow_maps, bool flow_seqs, @@ -392,7 +405,7 @@ extern "C" { } // === UTILITY === - char* yaml_to_string(YAMLNodeHandle handle) { + YAML_API char* yaml_to_string(YAMLNodeHandle handle) { try { YAML::Emitter out; out << *static_cast(handle); @@ -406,11 +419,11 @@ extern "C" { } // Helper to free strings allocated by this library - void yaml_free_string(char* str) { + YAML_API void yaml_free_string(char* str) { delete[] str; } - void yaml_free_keys(char** keys, int count) { + YAML_API void yaml_free_keys(char** keys, int count) { for (int i = 0; i < count; i++) { delete[] keys[i]; } @@ -418,12 +431,12 @@ extern "C" { } - YAMLNodeHandle yaml_clone(YAMLNodeHandle handle) { + YAML_API YAMLNodeHandle yaml_clone(YAMLNodeHandle handle) { return new YAML::Node(YAML::Clone(*static_cast(handle))); } // C interface for expand - handles the map internally - YAMLNodeHandle yaml_expand(YAMLNodeHandle handle) { + YAML_API YAMLNodeHandle yaml_expand(YAMLNodeHandle handle) { auto node = static_cast(handle); std::map seen; YAML::Node result = expand_internal(*node, &seen);