diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f53cc9..25f3db7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,5 +38,5 @@ target_link_libraries(yaml_c_wrapper PUBLIC ryml) add_executable(example_rw examples/example_rw.cpp) target_link_libraries(example_rw yaml_c_wrapper ryml) -add_executable(get_lattices src/get_lattices.cpp) -target_link_libraries(get_lattices yaml_c_wrapper ryml) \ No newline at end of file +add_executable(print_lattices examples/print_lattices.cpp) +target_link_libraries(print_lattices yaml_c_wrapper ryml) \ No newline at end of file diff --git a/README.md b/README.md index f0a1ef7..ff0da88 100644 --- a/README.md +++ b/README.md @@ -16,35 +16,31 @@ cmake -S . -B build cmake --build build ``` -This builds `libyaml_c_wrapper.dylib`, a shared object library that can interface with other languages. +This builds `libyaml_c_wrapper.dylib`, a shared object library that can interface with other languages. Make sure to rebuild after making any changes to files, and before running tests. All lattice files should go in `lattice_files/`. -It also builds an executable at build/example_rw containing examples for how -to use the library to read lattice files, perform basic manipulations, and write -to the lattice back to a file. To see the output, navigate to the build directory and run +### Example 1 +`examples/example_rw.cpp` contains examples for how to use the library API to read lattice files, perform basic manipulations (adding and removing elements, renaming, etc.), print to console, and write the lattice back to a file. The example uses `ex.pals.yaml` and writes to `expand.pals.yaml`. To see the consle output, navigate to the build directory and run ```console ./example_rw ``` -The program `get_lattices` will create a struct containing three lattices: +### Example 2 +The program `examples/print_lattices` performs lattice expansion on a user-specified lattice. The first argument is the file name where the lattice is defined. It also takes an option argument using `-lat lattice_name` to specify a specific lattice to expand, otherwise it will choose a default (the lattice in the last `use` statement, or the last lattice in the file if none is present). The program will create and print a struct containing three lattices: - `original` is a map containing the base lattice as well as any lattices included in the base lattice. - `included` is the base lattice but with all included files substituted in. - `expanded` is the base lattice after lattice expansion has been performed. -Specify the lattice file with the first argument to the function. On default, -the lattice specified by the last `use` statement will be used, and if no `use` -statement exists, the lattice lattice in the file will be used. An optional flag -`-lat lattice_name` can be used to specify the lattice to expand, which has greatest -priority. For example, in the build directory, run +To see the console output, in the build directory, run ```console -./get_lattices ex.pals.yaml -lat lat2 +./print_lattices ex.pals.yaml -lat lat2 ``` ## Developer Notes `YAMLTreeHandle` wraps `ryml::Tree` into C objects so they can be part of a shared object library to interface with other languages. `ryml::Tree`s are stored in memory simply as arrays. `ryml::NodeRef` acts as a simple wrapper around nodes, which are just indices in the tree array. Trees are obtained by parsing C++ std::string, and values are simply pointers to locations in the string. Therefore, the string must be kept in memory as long as the tree is in use. -Most of the relevant ryml code for reference is contained in /build/_deps/rapidyaml-src/src/c4/yml/tree.hpp +Most of the relevant ryml code for reference is contained in `/build/_deps/rapidyaml-src/src/c4/yml/tree.hpp`. Documentation generated by Doxygen. Run in the root directory @@ -64,5 +60,4 @@ ctest --test-dir build -R "Test Name" ``` ## To Do -Update test cases Search by kind \ No newline at end of file diff --git a/examples/example_rw.cpp b/examples/example_rw.cpp index 341e0a2..d44512e 100644 --- a/examples/example_rw.cpp +++ b/examples/example_rw.cpp @@ -3,54 +3,58 @@ #include "../src/yaml_c_wrapper.h" int main(int argc, char* argv[]) { + std::cout << "============ Printing Developer Information ============" << std::endl; + std::string text = "Use the function 'parse_file(filename)' to read a lattice file. For example,\n\n" + "YAMLTreeHandle tree = parse_file(\"../lattice_files/ex.pals.yaml\")\n" + "reads the file 'ex.pals.yaml' into a tree named 'tree'.\n\n"; // reading a lattice from a yaml file + std::cout << text; YAMLTreeHandle tree = parse_file("../lattice_files/ex.pals.yaml"); - std::cout << "Output of example_read_write.cpp" << std::endl; // printing to terminal - std::cout << node_to_string(tree, get_root(tree)) << std::endl << std::endl; + std::cout << "To print a tree to console, use the 'tree_to_string(tree_name)' function.\n"; + std::cout << tree_to_string(tree) << std::endl << std::endl; // type checking - // prints "handle is of type sequence: 1", 1 meaning true - std::cout << "handle is of type sequence: " + std::cout << "The root node of 'ex.pals.yaml' is a sequence, so is_sequence(tree, get_root(tree)) = " << is_sequence(tree, get_root(tree)) << "\n"; // accessing sequence - YAMLNodeId node = get_child_by_index(tree, get_root(tree), 0); - /* prints - the first element is: - thingB: - kind: Sextupole - */ - std::cout << "the first element is: \n" - << node_to_string(tree, node) << "\n"; + std::cout << "Elements in a sequence may be accessed by their index.\n"; + YAMLNodeId seq1 = get_child_by_index(tree, get_root(tree), 0); + std::cout << "The first element of 'tree' is: \n" + << node_to_string(tree, seq1) << "\n"; // accessing map - // prints "the value at key 'thingB' is: kind: Sextupole" - std::cout << "\nthe value at key 'thingB' is: " - << node_to_string(tree, get_child_by_key(tree, node, "thingB")) - << "\n"; + std::cout << "Elements in a map may be accessed by their key.\n"; + YAMLNodeId map1 = get_child_by_key(tree, get_child_by_index(tree, seq1, 0), "kind"); + std::cout << "The element 'thingB' has:\n " + << node_to_string(tree, map1) << "\n"; // add a new sequence element to the root containing new_map: {apples: 5} + std::cout << "Adding a new element '-apples: 5' to root.\n"; YAMLNodeId new_map_entry = add_map(tree, get_root(tree), NULL, END); YAMLNodeId map = add_map(tree, new_map_entry, "new_map", END); add_scalar(tree, map, "apples", "5", END); - // add a new sequence element to the root containing magnets: {magnet_list: - // [...]} + // add a new sequence element to the root containing magnets + std::cout << "Adding a new element\n" + << " - magnet_list:\n" + << " - magnet1\n" + << " - magnet2\n" + << "to root.\n\n"; YAMLNodeId magnets_entry = add_map(tree, get_root(tree), NULL, END); - YAMLNodeId magnets = add_map(tree, magnets_entry, "magnets", END); - YAMLNodeId sequence = add_sequence(tree, magnets, "magnet_list", END); + YAMLNodeId sequence = add_sequence(tree, magnets_entry, "magnet_list", END); add_scalar(tree, sequence, NULL, "magnet1", END); add_scalar(tree, sequence, NULL, "magnet2", 1); + + // writing trees to files + std::cout << "Use 'write_file(tree, filename)' to write the edited tree to a file.\n"; + write_file(tree, "../lattice_files/expand.pals.yaml"); + std::cout << "Wrote tree to 'expand.pals.yaml`\n\n\n\n"; - // print tree after modifications — if new nodes don't appear here the issue - // is in add_*, if they do appear but not in the file the issue is in - // write_file - std::cout << "\nTree after modifications:\n"; - std::cout << node_to_string(tree, get_root(tree)) << std::endl; + std::cout << "========== Printing Final Modified Tree ==========\n"; + std::cout << tree_to_string(tree) << std::endl; - bool ok = write_file(tree, "../lattice_files/expand.pals.yaml"); - std::cout << "write_file returned: " << ok << std::endl; return 0; } \ No newline at end of file diff --git a/src/get_lattices.cpp b/examples/print_lattices.cpp similarity index 56% rename from src/get_lattices.cpp rename to examples/print_lattices.cpp index 120a9d2..1a4b1fb 100644 --- a/src/get_lattices.cpp +++ b/examples/print_lattices.cpp @@ -1,11 +1,12 @@ #include +#include #include #include #include "../src/yaml_c_wrapper.h" int main(int argc, char* argv[]) { - const char* file_name = "../lattice_files/ex.pals.yaml"; + const char* file_name = nullptr; const char* lattice_name = ""; for (int i = 1; i < argc; i++) { @@ -21,17 +22,22 @@ int main(int argc, char* argv[]) { } } - struct lattices lat = get_lattices(file_name, lattice_name); - - std::cout << "Printing original lattice: " << std::endl; + if (!file_name) { + std::cerr << "Usage: " << argv[0] << " [-lat ]" << std::endl; + return 1; + } + + std::string file_path = std::string("../lattice_files/") + file_name; + + struct lattices lat = get_lattices(file_path.c_str(), lattice_name); + + std::cout << "========== Printing original lattice ==========" << std::endl; std::cout << tree_to_string(lat.original) << std::endl << "\n\n"; - std::cout << "Printing included lattice: " << std::endl; + std::cout << "========== Printing included lattice ==========" << std::endl; std::cout << tree_to_string(lat.included) << std::endl << "\n\n"; - std::cout << "Printing expanded lattice: " << std::endl; + std::cout << "========== Printing expanded lattice ==========" << std::endl; std::cout << tree_to_string(lat.expanded) << std::endl; - - write_file(lat.expanded, "../lattice_files/expand.pals.yaml"); return 0; } \ No newline at end of file