diff --git a/CMakeLists.txt b/CMakeLists.txt index 09796a9..524c8bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,66 +29,11 @@ add_subdirectory(tests) file(COPY ${CMAKE_SOURCE_DIR}/lattice_files/ DESTINATION ${CMAKE_BINARY_DIR}/lattice_files/) -# if(APPLE) -# # Check for package managers -# execute_process(COMMAND which brew OUTPUT_VARIABLE HOMEBREW_EXISTS OUTPUT_STRIP_TRAILING_WHITESPACE) -# execute_process(COMMAND which port OUTPUT_VARIABLE MACPORTS_EXISTS OUTPUT_STRIP_TRAILING_WHITESPACE) -# execute_process(COMMAND which conda OUTPUT_VARIABLE CONDA_EXISTS OUTPUT_STRIP_TRAILING_WHITESPACE) - -# # Error if both Homebrew and MacPorts exist -# if(HOMEBREW_EXISTS AND MACPORTS_EXISTS) -# message(FATAL_ERROR -# "Both Homebrew and MacPorts detected. This can cause conflicts.\n" -# "Please use only one package manager:\n" -# " - Homebrew found at: ${HOMEBREW_EXISTS}\n" -# " - MacPorts found at: ${MACPORTS_EXISTS}\n" -# "Consider uninstalling one to avoid library conflicts." -# ) -# endif() - -# # Set RPATH based on which package manager is found -# set(BASE_RPATH "@executable_path/../lib;@loader_path") - -# if(HOMEBREW_EXISTS) -# message(STATUS "Using Homebrew package manager") -# # Check if Apple Silicon or Intel -# execute_process( -# COMMAND uname -m -# OUTPUT_VARIABLE ARCH -# OUTPUT_STRIP_TRAILING_WHITESPACE -# ) -# if(ARCH STREQUAL "arm64") -# set(CMAKE_INSTALL_RPATH "${BASE_RPATH};/opt/homebrew/lib") -# list(APPEND CMAKE_PREFIX_PATH "/opt/homebrew") -# else() -# set(CMAKE_INSTALL_RPATH "${BASE_RPATH};/usr/local/lib") -# list(APPEND CMAKE_PREFIX_PATH "/usr/local") -# endif() -# elseif(MACPORTS_EXISTS) -# message(STATUS "Using MacPorts package manager") -# set(CMAKE_INSTALL_RPATH "${BASE_RPATH};/opt/local/lib") -# list(APPEND CMAKE_PREFIX_PATH "/opt/local") -# elseif(CONDA_EXISTS) -# message(STATUS "Using Conda package manager") -# # Get conda prefix -# execute_process( -# COMMAND conda info --base -# OUTPUT_VARIABLE CONDA_PREFIX -# OUTPUT_STRIP_TRAILING_WHITESPACE -# ) -# set(CMAKE_INSTALL_RPATH "${BASE_RPATH};${CONDA_PREFIX}/lib") -# list(APPEND CMAKE_PREFIX_PATH "${CONDA_PREFIX}") -# else() -# message(STATUS "No package manager detected, using default paths") -# set(CMAKE_INSTALL_RPATH "${BASE_RPATH};/usr/local/lib") -# endif() - -# set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) -# message(STATUS "RPATH set to: ${CMAKE_INSTALL_RPATH}") -# endif() - add_library(yaml_c_wrapper SHARED src/yaml_c_wrapper.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) +add_executable(example_read_write examples/example_read_write.cpp) +target_link_libraries(example_read_write yaml_c_wrapper yaml-cpp) + +add_executable(get_lattices src/get_lattices.cpp) +target_link_libraries(get_lattices yaml_c_wrapper yaml-cpp) \ No newline at end of file diff --git a/README.md b/README.md index 2062938..4c9b5ee 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ include inherits repeat +YAML::Nodes are values that act like pointers, so editing a node will cause the tree the node is +contained in to reflect the changes. + ## Usage In pals-cpp, run diff --git a/examples/example_read_write.cpp b/examples/example_read_write.cpp new file mode 100644 index 0000000..9813a03 --- /dev/null +++ b/examples/example_read_write.cpp @@ -0,0 +1,57 @@ +#include +#include "../src/yaml_c_wrapper.h" +#include + +int main(int argc, char* argv[]) { + // reading a lattice from a yaml file + YAMLNodeHandle handle = parse_file("../lattice_files/ex.pals.yaml"); + std::cout << "Output of example_read_write.cpp" << std::endl; + // printing to terminal + std::cout << yaml_to_string(handle) << std::endl << std::endl; + + // type checking + // prints "handle is of type sequence: 1", 1 meaning true + std::cout << "handle is of type sequence: " << (is_sequence(handle)) + << "\n"; + + // accessing sequence + YAMLNodeHandle node = 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(get_key(node, "thingB")) << "\n"; + + // creating a new node that's a map + YAMLNodeHandle map = create_map(); + set_value_int(map, "apples", 5); + + // creating a new node that's a sequence + YAMLNodeHandle sequence = create_sequence(); + push_string(sequence, "magnet1"); + push_string(sequence, ""); + YAMLNodeHandle scalar = create_scalar(); + set_scalar_string(scalar, "magnet2"); + set_at_index(sequence, 1, scalar); + // give sequence a name by putting it in a map: + YAMLNodeHandle magnets = create_map(); + set_value_node(magnets, "magnets", sequence); + + // adding new nodes to lattice + push_node(handle, map); + push_node(handle, magnets); + + // getting expanded lattice + struct lattices lat = get_lattices("ex.pals.yaml", "lat1"); + YAMLNodeHandle expanded = lat.expanded; + + // writing modified lattice file to expand.pals.yaml + write_file(handle, "../lattice_files/expand.pals.yaml"); + return 0; +} diff --git a/lattice_files/ex.pals.yaml b/lattice_files/ex.pals.yaml index 644df78..d892512 100644 --- a/lattice_files/ex.pals.yaml +++ b/lattice_files/ex.pals.yaml @@ -1,5 +1,13 @@ - thingB: kind: Sextupole +- lat1: + kind: Lattice + branches: + - inj_line +- lat2: + kind: Lattice + branches: + - inj_line - inj_line: kind: BeamLine multipass: true @@ -20,4 +28,6 @@ line: - a - b - - c \ No newline at end of file + - c +- use: "lat2" +- use: "lat1" diff --git a/lattice_files/include.pals.yaml b/lattice_files/include.pals.yaml index b9317a2..d2af9d3 100644 --- a/lattice_files/include.pals.yaml +++ b/lattice_files/include.pals.yaml @@ -1,4 +1,5 @@ - line: - first: 1 - second: 2 - - third: 3 \ No newline at end of file + - third: 3 + - include: "include2.pals.yaml" diff --git a/lattice_files/include2.pals.yaml b/lattice_files/include2.pals.yaml new file mode 100644 index 0000000..2a2119c --- /dev/null +++ b/lattice_files/include2.pals.yaml @@ -0,0 +1,4 @@ +- line: + - fourth: 4 + - fifth: 5 + - sixth: 6 \ No newline at end of file diff --git a/src/get_lattices.cpp b/src/get_lattices.cpp new file mode 100644 index 0000000..ff2d4c8 --- /dev/null +++ b/src/get_lattices.cpp @@ -0,0 +1,30 @@ +#include +#include "../src/yaml_c_wrapper.h" +#include + +int main(int argc, char* argv[]) { + std::string file_name = "ex.pals.yaml"; + const char* lattice_name = ""; + if (argc >= 1) { + file_name = argv[0]; + } + if (argc >= 2) { + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-lat") == 0) { + lattice_name = argv[i+1]; + } + } + } + + struct lattices lat = get_lattices("ex.pals.yaml", lattice_name); + std::cout << "Printing original lattice information: " << std::endl; + std::cout << yaml_to_string(lat.original) << std::endl << "\n\n"; + + // put separating lines here + std::cout << "Printing included lattice information: " << std::endl; + std::cout << yaml_to_string(lat.included) << std::endl << "\n\n"; + + std::cout << "Printing expanded lattice information: " << std::endl; + std::cout << yaml_to_string(lat.expanded) << std::endl; + return 0; +} \ No newline at end of file diff --git a/src/yaml_c_wrapper.cpp b/src/yaml_c_wrapper.cpp index 35f310a..d5a3ca2 100644 --- a/src/yaml_c_wrapper.cpp +++ b/src/yaml_c_wrapper.cpp @@ -1,8 +1,10 @@ #include + #include #include #include #include +#include #if defined(_WIN32) #define YAML_API extern "C" __declspec(dllexport) @@ -10,120 +12,360 @@ #define YAML_API extern "C" __attribute__((visibility("default"))) #endif -// ======= LATTICE EXPANSION UTILS +// TODO: add absolute file paths +// for every element, add a field that points to the parent /* -Inserts the elements in `line` into `seq` at `index` a `repeat` number of times. -The value at index will be rewritten by the first inserted element. For example, -if seq = [1,2,3,4,5], line = [a,b], index = 2, repeat = 3, calling the function -will output [1,2,a,b,a,b,a,b,4,5]. +`original` is a map containing the base lattice as well as any lattices included +in the base lattice. They can be accessed using original[filename]. +`included` is the base lattice but with all included files substituted in. +`expanded` is the base lattice after lattice expansion has been performed. */ -YAML::Node repeat(YAML::Node line, YAML::Node seq, int index, int repeat) { - YAML::Node exp = YAML::Node(YAML::NodeType::Sequence); - for (int i = 0; i < index; i++) { - exp.push_back(YAML::Clone(seq[i])); - } - for (int i = 0; i < repeat; i++) { - for (int j = 0; j < line.size(); j++) { - exp.push_back(YAML::Clone(line[j])); +struct lattices_int { + YAML::Node original; + YAML::Node included; + YAML::Node expanded; +}; + +template +std::vector search(YAML::Node root_node, Condition condition) { + std::vector matches; + + if (condition(root_node)) matches.push_back(root_node); + + std::vector child_matches; + if (root_node.IsMap()) { + for (auto ele : root_node) { + child_matches = search(ele.second, condition); + matches.insert(matches.end(), child_matches.begin(), + child_matches.end()); + } + } else if (root_node.IsSequence()) { + for (int i = 0; i < root_node.size(); i++) { + child_matches = search(root_node[i], condition); + matches.insert(matches.end(), child_matches.begin(), + child_matches.end()); } } - for (int i = index + 1; i < seq.size(); i++) { - exp.push_back(YAML::Clone(seq[i])); + return matches; +} + +auto is_kind = [](YAML::Node node, std::string kind_type_string) { + if (node.IsMap()) { + for (auto ele : node) { + if (ele.second.IsMap() && + ele.second["kind"].as("") == kind_type_string) { + return true; + } + } } - return exp; + return false; +}; + +std::vector search_kind(YAML::Node root, + std::string kind_type_string) { + auto condition_wrapper = [kind_type_string](const YAML::Node& node) { + return is_kind(node, kind_type_string); + }; + return search(root, condition_wrapper); } -// recursively loops through the node to record all the elements and their -// corresponding parameters -void get_dict_helper(YAML::Node node, std::map* seen) { +/* +Recursively loops through the node to record all the lattices and beamlines and +their corresponding parameters. +*/ +void get_dict_helper(YAML::Node node, + std::map* element_map) { if (node.IsSequence()) { - for (int i = 0; i < node.size(); i++) { - get_dict_helper(node[i], seen); + for (size_t i = 0; i < node.size(); i++) { + YAML::Node child = node[i]; + get_dict_helper(child, element_map); } } else if (node.IsMap()) { for (auto ele : node) { - // exclude key words from being stored - if (ele.first.as() == "include" || - ele.first.as() == "inherit" || - (ele.second.IsMap() && ele.second["repeat"])) { - continue; + if (ele.second.IsMap() && ele.second["kind"]) { + element_map->insert({ele.first.as(), ele.second}); + } else { + get_dict_helper(ele.second, element_map); } - seen->insert( - {ele.first.as(), YAML::Clone(ele.second)}); - get_dict_helper(ele.second, seen); } } } +/* +Constructs the map from names to lattice elements. The values in the map +are references to lattice elements with a given name, and modifying them +will directly modifty the lattice. Elements in values are stored in the order +that they appear in the lattice file. Use YAML::Clone if only the information +is required. +*/ std::map* get_dict(YAML::Node root) { - std::map* seen = + std::map* element_map = new std::map(); - ; - get_dict_helper(root, seen); - return seen; + get_dict_helper(root, element_map); + return element_map; +} + +/* +Adds the file contained in `filename` to `original`, which should be +lat.original. The key is the filename and the value is the contents of the file. +*/ +void add_to_original(YAML::Node original, std::string filename) { + if (!original[filename]) { + YAML::Node node = YAML::Node(YAML::NodeType::Map); + node["path"] = ""; + node["info"] = YAML::LoadFile("../lattice_files/" + filename); + original[filename] = node; + } } -// === EXPAND === +/* +Constructs the original lattice. +*/ +YAML::Node original_lattice(std::string filename) { + YAML::Node original = YAML::Node(YAML::NodeType::Map); + + std::vector files_to_process; + files_to_process.push_back(filename); + + auto find_includes = [](const YAML::Node& node) { + return node.IsMap() && node["include"]; + }; + + while (!files_to_process.empty()) { + std::string current_file = files_to_process.back(); + files_to_process.pop_back(); + + if (original[current_file]) { + continue; + } + + add_to_original(original, current_file); + YAML::Node loaded_content = original[current_file]["info"]; + std::vector includes_found = + search(loaded_content, find_includes); + for (const auto& inc_node : includes_found) { + std::string inc_fn = inc_node["include"].as(); + if (inc_fn.size() >= 5 && + inc_fn.substr(inc_fn.size() - 5) == ".yaml") { + files_to_process.push_back(inc_fn); + } + } + } + return original; +} + +/* +Constructs the included lattice. +*/ +YAML::Node included_lattice(std::string filename) { + YAML::Node included = YAML::LoadFile("../lattice_files/" + filename); + std::vector include_files = + search(included, + [](YAML::Node node) { return node.IsMap() && node["include"]; }); + for (int i = 0; i < include_files.size(); i++) { + std::string inc_fn = include_files[i]["include"].as(); + if (inc_fn.size() >= 5 && inc_fn.substr(inc_fn.size() - 5) == ".yaml") { + YAML::Node node(YAML::NodeType::Sequence); + YAML::Node content = included_lattice(inc_fn); + YAML::Node file(YAML::NodeType::Map); + file["file"] = inc_fn; + + node.push_back(file); + node.push_back(content[0]); + + include_files[i].remove("include"); + include_files[i]["included"] = node; + } + } + return included; +} + +/* +Returns a new node with the elements in `line` inserted into `seq` at `index` +a `repeat` number of times. The value at index will be rewritten by the first +inserted element. For example, if seq = [1,2,3,4,5], line = [a,b], index = 2, +repeat = 3, calling the function will output [1,2,a,b,a,b,a,b,4,5]. +*/ +YAML::Node repeat(YAML::Node target_element, YAML::Node seq, int index, + int repeat_count) { + YAML::Node exp = YAML::Node(YAML::NodeType::Sequence); + for (int i = 0; i < index; i++) { + exp.push_back(YAML::Clone(seq[i])); + } + + YAML::Node inner_content = target_element; + if (inner_content.IsMap() && inner_content["line"]) { + inner_content = inner_content["line"]; + } + + for (int i = 0; i < repeat_count; i++) { + if (inner_content.IsSequence()) { + for (std::size_t j = 0; j < inner_content.size(); j++) { + exp.push_back(YAML::Clone(inner_content[j])); + } + } else { + exp.push_back(YAML::Clone(inner_content)); + } + } + + for (std::size_t i = index + 1; i < seq.size(); i++) { + exp.push_back(YAML::Clone(seq[i])); + } + return exp; +} + +/* +Performs lattice expansion on the provided `node`. +*/ YAML::Node expand_internal(YAML::Node node, - std::map* seen) { - if (node.IsSequence()) { - bool modified = true; - while (modified) { - modified = false; - for (int i = 0; i < node.size(); i++) { - if (node[i].IsMap()) { - for (auto ele : node[i]) { - if (ele.second.IsMap() && ele.second["repeat"]) { - YAML::Node line = - (*seen)[ele.first.as()]["line"]; - node = repeat(line, node, i, - ele.second["repeat"].as()); - modified = true; - break; + std::map* elements_map) { + if (node.IsScalar() && elements_map->count(node.as())) { + std::string element_name = node.as(); + YAML::Node wrapped_node = YAML::Node(YAML::NodeType::Map); + + wrapped_node[element_name] = expand_internal( + YAML::Clone(elements_map->at(element_name)), elements_map); + return wrapped_node; + } else if (node.IsSequence()) { + for (std::size_t i = 0; i < node.size(); i++) { + if (node[i].IsMap()) { + for (auto ele : node[i]) { + if (ele.second.IsMap() && ele.second["repeat"]) { + std::string target_name = ele.first.as(); + if (elements_map->count(target_name)) { + YAML::Node target_node = + YAML::Clone(elements_map->at(target_name)); + YAML::Node repeated_seq = + repeat(target_node, node, i, + ele.second["repeat"].as()); + return expand_internal(repeated_seq, elements_map); } } - if (modified) break; } } } - for (int i = 0; i < node.size(); i++) { - node[i] = expand_internal(node[i], seen); + YAML::Node new_seq = YAML::Node(YAML::NodeType::Sequence); + for (std::size_t i = 0; i < node.size(); i++) { + new_seq.push_back(expand_internal(node[i], elements_map)); } - return node; + return new_seq; } 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 filename = ele.second.as(); - YAML::Node seq = YAML::Node(YAML::NodeType::Sequence); - YAML::Node file = YAML::Node(YAML::NodeType::Map); - file["file"] = filename; - seq.push_back(file); - seq.push_back( - YAML::LoadFile("../lattice_files/" + filename)[0]); - - ele.first = "included"; - ele.second = seq; - break; - } else if (ele.first.as() == "inherit") { - YAML::Node parent = (*seen)[ele.second.as()]; - for (auto ele : parent) { - node[ele.first.as()] = ele.second; + YAML::Node new_map = YAML::Clone(node); + + if (new_map["inherit"]) { + std::string parent_name = new_map["inherit"].as(); + new_map.remove("inherit"); + new_map["inherited"] = parent_name; + + if (elements_map->count(parent_name)) { + YAML::Node parent = elements_map->at(parent_name); + for (auto elep : parent) { + std::string key = elep.first.as(); + if (!new_map[key]) { + new_map[key] = YAML::Clone(elep.second); + } } - ele.first = "inherited"; } - node[ele.first.as()] = - expand_internal(ele.second, seen); } - return node; + + YAML::Node final_map = YAML::Node(YAML::NodeType::Map); + for (auto ele : new_map) { + final_map[ele.first.as()] = + expand_internal(ele.second, elements_map); + } + return final_map; + } + + return YAML::Clone(node); +} + +/* +Performs lattice expansion with the following rules: +1. If name is specified, the lattice in `root` with the given name will be +expanded. +2. If no name is specified, the lattice that appears latest in `root` will be +expanded. +*/ +void find_and_replace(std::string name, YAML::Node root, + std::map* elements_map) { + if (name != "") { + for (std::size_t i = 0; i < root.size(); i++) { + if (root[i].IsMap() && root[i][name]) { + root[i][name] = expand_internal(root[i][name], elements_map); + return; + } + } } else { - return node; + for (int i = root.size() - 1; i >= 0; i--) { + if (root[i].IsMap() && root[i]["use"]) { + std::string target = root[i]["use"].as(); + + for (std::size_t j = 0; j < root.size(); j++) { + if (root[j].IsMap() && root[j][target]) { + root[j][target] = + expand_internal(root[j][target], elements_map); + return; + } + } + } + } + for (int i = root.size() - 1; i >= 0; i--) { + if (is_kind(root[i], "Lattice")) { + root[i] = expand_internal(root[i], elements_map); + return; + } + } } } +/* +Constructs the expanded lattice. Expanding has the following priority: +1. If a lattice name is supplied through lattice_name, that lattice will be +expanded. +2. If no lattice_name is supplied, the lattice specified by the last use +statement will be expanded. +3. If no lattice_name is supplied and no use statements are present, the lattice +that occurs latest in the file will be expanded. +*/ +YAML::Node expanded_lattice(std::string filename, std::string lattice_name) { + YAML::Node root = YAML::LoadFile("../lattice_files/" + filename); + root = included_lattice(filename); + std::map* elements_map = get_dict(root); + + find_and_replace(lattice_name, root, elements_map); + return root; +} + +struct lattices_int get_lattices_int(const std::string& filename, + const std::string& lattice_name = "") { + struct lattices_int lat; + lat.original = original_lattice(filename); + lat.included = included_lattice(filename); + lat.expanded = expanded_lattice(filename, lattice_name); + return lat; +} + extern "C" { typedef void* YAMLNodeHandle; +struct lattices { + YAMLNodeHandle original; + YAMLNodeHandle included; + YAMLNodeHandle expanded; +}; + +YAML_API struct lattices get_lattices(const char* filename, + const char* lattice_name) { + struct lattices lat; + lat.original = static_cast( + new YAML::Node(original_lattice(std::string(filename)))); + lat.included = static_cast( + new YAML::Node(included_lattice(std::string(filename)))); + lat.expanded = static_cast(new YAML::Node( + expanded_lattice(std::string(filename), std::string(lattice_name)))); + return lat; +} + // === CREATION/DELETION === YAML_API YAMLNodeHandle create_node() { return new YAML::Node(); } @@ -149,23 +391,6 @@ YAML_API void delete_node(YAMLNodeHandle handle) { delete static_cast(handle); } -// === PARSING === -YAML_API YAMLNodeHandle parse_string(const char* yaml_str) { - try { - return new YAML::Node(YAML::Load(yaml_str)); - } catch (...) { - return nullptr; - } -} - -YAML_API YAMLNodeHandle parse_file(const char* filename) { - try { - return new YAML::Node(YAML::LoadFile(filename)); - } catch (...) { - return nullptr; - } -} - // === TYPE CHECKS === YAML_API bool is_scalar(YAMLNodeHandle handle) { return static_cast(handle)->IsScalar(); @@ -211,6 +436,23 @@ YAML_API int size(YAMLNodeHandle handle) { return static_cast(handle)->size(); } +// === PARSING === +YAML_API YAMLNodeHandle parse_string(const char* yaml_str) { + try { + return new YAML::Node(YAML::Load(yaml_str)); + } catch (...) { + return nullptr; + } +} + +YAML_API YAMLNodeHandle parse_file(const char* filename) { + try { + return new YAML::Node(YAML::LoadFile(filename)); + } catch (...) { + return nullptr; + } +} + YAML_API char** get_keys(YAMLNodeHandle handle, int* out_count) { auto node = static_cast(handle); if (!node->IsMap()) { @@ -533,12 +775,4 @@ YAML_API void yaml_free_keys(char** keys, int count) { YAML_API YAMLNodeHandle yaml_clone(YAMLNodeHandle handle) { return new YAML::Node(YAML::Clone(*static_cast(handle))); } - -// C interface for expand - handles the map internally -YAML_API YAMLNodeHandle lattice_expand(YAMLNodeHandle handle) { - auto node = static_cast(handle); - std::map* seen = get_dict(*node); - YAML::Node result = expand_internal(*node, seen); - return new YAML::Node(result); -} } \ No newline at end of file diff --git a/src/yaml_c_wrapper.h b/src/yaml_c_wrapper.h index 40e7318..7f58e38 100644 --- a/src/yaml_c_wrapper.h +++ b/src/yaml_c_wrapper.h @@ -8,6 +8,13 @@ extern "C" { #endif typedef void* YAMLNodeHandle; +struct lattices { + YAMLNodeHandle original; + YAMLNodeHandle included; + YAMLNodeHandle expanded; + }; + +struct lattices get_lattices(const char* filename, const char* lattice_name); // === CREATION === YAMLNodeHandle create_node(void); @@ -66,7 +73,6 @@ void push_node(YAMLNodeHandle handle, YAMLNodeHandle value); char* yaml_to_string(YAMLNodeHandle handle); char* yaml_emit(YAMLNodeHandle handle, int indent); YAMLNodeHandle yaml_clone(YAMLNodeHandle handle); -YAMLNodeHandle lattice_expand(YAMLNodeHandle handle); bool write_file(YAMLNodeHandle handle, const char* filename); bool write_file_formatted(YAMLNodeHandle handle, const char* filename, diff --git a/tests/test_yaml_c_wrapper.cpp b/tests/test_yaml_c_wrapper.cpp index 2b8b669..a2ced7e 100644 --- a/tests/test_yaml_c_wrapper.cpp +++ b/tests/test_yaml_c_wrapper.cpp @@ -598,81 +598,6 @@ TEST_CASE("YAML nodes can be cloned", "[clone]") { } } -// =========================================== -// TEST SUITE: ex.pals.yaml Structure Tests -// =========================================== - -TEST_CASE("ex.pals.yaml has expected structure", "[ex.pals.yaml][structure]") { - YAMLNodeHandle root = parse_file("../lattice_files/ex.pals.yaml"); - REQUIRE(root != nullptr); - - SECTION("Root is a sequence") { - REQUIRE(is_sequence(root)); - REQUIRE(size(root) >= 2); - } - - SECTION("First element has thingB") { - YAMLNodeHandle first = get_index(root, 0); - REQUIRE(first != nullptr); - REQUIRE(is_map(first)); - REQUIRE(has_key(first, "thingB")); - - YAMLNodeHandle thingB = get_key(first, "thingB"); - REQUIRE(is_map(thingB)); - REQUIRE(has_key(thingB, "kind")); - - YAMLNodeHandle kind = get_key(thingB, "kind"); - char* kind_str = as_string(kind); - REQUIRE(std::string(kind_str) == "Sextupole"); - - yaml_free_string(kind_str); - delete_node(kind); - delete_node(thingB); - delete_node(first); - } - - SECTION("Second element has inj_line") { - YAMLNodeHandle second = get_index(root, 1); - REQUIRE(second != nullptr); - REQUIRE(is_map(second)); - REQUIRE(has_key(second, "inj_line")); - - YAMLNodeHandle inj_line = get_key(second, "inj_line"); - REQUIRE(is_map(inj_line)); - REQUIRE(has_key(inj_line, "kind")); - REQUIRE(has_key(inj_line, "multipass")); - REQUIRE(has_key(inj_line, "line")); - - YAMLNodeHandle kind = get_key(inj_line, "kind"); - char* kind_str = as_string(kind); - REQUIRE(std::string(kind_str) == "BeamLine"); - - YAMLNodeHandle multipass = get_key(inj_line, "multipass"); - REQUIRE(as_bool(multipass) == true); - - yaml_free_string(kind_str); - delete_node(kind); - delete_node(multipass); - delete_node(inj_line); - delete_node(second); - } - - SECTION("inj_line has line sequence") { - YAMLNodeHandle second = get_index(root, 1); - YAMLNodeHandle inj_line = get_key(second, "inj_line"); - YAMLNodeHandle line = get_key(inj_line, "line"); - - REQUIRE(is_sequence(line)); - REQUIRE(size(line) >= 3); - - delete_node(line); - delete_node(inj_line); - delete_node(second); - } - - delete_node(root); -} - // =========================================== // TEST SUITE: Memory Safety // ===========================================