mirror of
https://github.com/biojppm/rapidyaml.git
synced 2026-01-18 13:31:19 +01:00
Update samples
This commit is contained in:
159
samples/quickstart-ints.cpp
Normal file
159
samples/quickstart-ints.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
// This file shows a quick example of parsing YAML to an int events
|
||||
// buffer. Since this functionality is meant to implement in other
|
||||
// programming languages, the code is kept very simple, and using only
|
||||
// C-like idioms.
|
||||
|
||||
// ryml can be used as a single header, or as a simple library:
|
||||
#if defined(RYML_SINGLE_HEADER) // using the single header directly in the executable
|
||||
#define RYML_SINGLE_HDR_DEFINE_NOW
|
||||
#ifndef RYML_SINGLE_HEADER_INTS
|
||||
#include <ryml_all.hpp>
|
||||
#else
|
||||
#include <ryml_ints.hpp>
|
||||
#endif
|
||||
#elif defined(RYML_SINGLE_HEADER_LIB) // using the single header from a library
|
||||
#ifndef RYML_SINGLE_HEADER_INTS
|
||||
#include <ryml_all.hpp>
|
||||
#else
|
||||
#include <ryml_ints.hpp>
|
||||
#endif
|
||||
#else
|
||||
#include <c4/yml/parse_engine.def.hpp>
|
||||
#endif
|
||||
|
||||
#ifndef RYML_SINGLE_HEADER_INTS
|
||||
#include <c4/yml/extra/event_handler_ints.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
// NOLINTBEGIN(hicpp-signed-bitwise)
|
||||
|
||||
int main(int, const char *[])
|
||||
{
|
||||
using namespace c4::yml::extra::ievt;
|
||||
auto PSTR_ = c4::yml::extra::ievt::PSTR; // PSTR does not work in windows
|
||||
// YAML code to be parsed in place
|
||||
char yaml[] = "do: a deer, a female deer\n"
|
||||
"re: a drop of golden sun\n"
|
||||
"mi: a name I call myself\n"
|
||||
"fa: a long long way to run\n";
|
||||
// these are the event values we expect
|
||||
const int expected_events[] = {
|
||||
BSTR,
|
||||
BDOC,
|
||||
VAL_|BMAP|BLCK,
|
||||
//
|
||||
KEY_|SCLR|PLAI, 0, 2, // "do"
|
||||
VAL_|SCLR|PLAI|PSTR_, 4, 21, // "a deer, a female deer"
|
||||
//
|
||||
KEY_|SCLR|PLAI|PSTR_, 26, 2, // "re"
|
||||
VAL_|SCLR|PLAI|PSTR_, 30, 20, // "a drop of golden sun"
|
||||
//
|
||||
KEY_|SCLR|PLAI|PSTR_, 51, 2, // "mi"
|
||||
VAL_|SCLR|PLAI|PSTR_, 55, 20, // "a name I call myself"
|
||||
//
|
||||
KEY_|SCLR|PLAI|PSTR_, 76, 2, // "fa"
|
||||
VAL_|SCLR|PLAI|PSTR_, 80, 22, // "a long long way to run"
|
||||
//
|
||||
EMAP|PSTR_,
|
||||
EDOC,
|
||||
ESTR,
|
||||
};
|
||||
|
||||
/* the output should be this:
|
||||
*
|
||||
* success! YAML requires event size 30, estimated=49
|
||||
* pos=0 event[0]: 0x1
|
||||
* pos=1 event[1]: 0x4
|
||||
* pos=2 event[2]: 0x110010
|
||||
* pos=3 event[3]: 0x80500 str=(0,2) 'do'
|
||||
* pos=6 event[4]: 0x900500 str=(4,21) 'a deer, a female deer'
|
||||
* pos=9 event[5]: 0x880500 str=(26,2) 're'
|
||||
* pos=12 event[6]: 0x900500 str=(30,20) 'a drop of golden sun'
|
||||
* pos=15 event[7]: 0x880500 str=(51,2) 'mi'
|
||||
* pos=18 event[8]: 0x900500 str=(55,20) 'a name I call myself'
|
||||
* pos=21 event[9]: 0x880500 str=(76,2) 'fa'
|
||||
* pos=24 event[10]: 0x900500 str=(80,22) 'a long long way to run'
|
||||
* pos=27 event[11]: 0x800020
|
||||
* pos=28 event[12]: 0x8
|
||||
* pos=29 event[13]: 0x2
|
||||
*/
|
||||
|
||||
// buffer to where we will write the events
|
||||
constexpr const int events_size = 100;
|
||||
int events[events_size] = {};
|
||||
static_assert(events_size >= sizeof(expected_events)/sizeof(expected_events[0]), "buffer too small");
|
||||
// buffer for placing any scalars/tags that cannot be filtered
|
||||
// in-place
|
||||
char arena[100] = {};
|
||||
|
||||
|
||||
// ensure the estimation will succeed vs required size
|
||||
int estimated_size = c4::yml::extra::estimate_events_ints_size(yaml);
|
||||
if (estimated_size > events_size)
|
||||
{
|
||||
printf("the estimated size (%d) will not fit the events array (%d)\n", estimated_size, events_size); // LCOV_EXCL_LINE
|
||||
return 1; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
// parse now. the parse should succeed (because the YAML above is
|
||||
// legit), but if there were would be a parse error, we would get
|
||||
// the default behavior which is abort on error, since we did not
|
||||
// set up the error callbacks
|
||||
c4::yml::extra::EventHandlerInts handler;
|
||||
c4::yml::ParseEngine<c4::yml::extra::EventHandlerInts> parser(&handler);
|
||||
handler.reset(yaml, arena, events, estimated_size); // note we pass the estimated size!
|
||||
parser.parse_in_place_ev("filename", yaml);
|
||||
|
||||
// the YAML was successfully parsed, but it may happen that it
|
||||
// requires more events than may fit in the buffer. so we need to
|
||||
// check that it actually fits (this is mandatory):
|
||||
if(!handler.fits_buffers())
|
||||
{
|
||||
printf("error: buffers too small: required_evt=%d actual_evt=%d\n required_arena=%zu actual_arena=%zu\n", // LCOV_EXCL_LINE
|
||||
handler.required_size_events(), estimated_size, handler.required_size_arena(), c4::to_csubstr(arena).len); // LCOV_EXCL_LINE
|
||||
// WATCHOUT: if you want to retry the parse, you need to set
|
||||
// up the source buffer again, because it is invalidated from
|
||||
// being parsed in place. refer to the doxygen documentation
|
||||
// for more details.
|
||||
return 1; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
// done!
|
||||
printf("success! YAML requires event size %d, estimated=%d (required_arena=%zu actual=%zu)\n", // LCOV_EXCL_LINE
|
||||
handler.required_size_events(), estimated_size, handler.required_size_arena(), c4::to_csubstr(arena).len); // LCOV_EXCL_LINE
|
||||
|
||||
// ensure the result is as expected
|
||||
bool compare = true;
|
||||
|
||||
// example iterating through the events array: compare and print
|
||||
// the result
|
||||
for (int pos = 0, evt = 0; pos < handler.required_size_events(); ++pos, ++evt)
|
||||
{
|
||||
bool status = (events[pos] == expected_events[pos]);
|
||||
printf("pos=%d\tevent[%d]:\t0x%x", pos, evt, events[pos]);
|
||||
if(events[pos] & WSTR) // the event has a string following it
|
||||
{
|
||||
int offset = events[pos + 1];
|
||||
int length = events[pos + 2];
|
||||
bool in_arena = (events[pos] & AREN);
|
||||
// WATCHOUT! the string is NOT ZERO TERMINATED!
|
||||
const char *ptr = in_arena ? arena : yaml;
|
||||
const char *str = ptr + offset;
|
||||
printf("\tstr=(%d,%d)\t'%.*s'", offset, length, length, str);
|
||||
status = status && (offset == expected_events[pos + 1]);
|
||||
status = status && (length == expected_events[pos + 2]);
|
||||
pos += 2; // advance the two ints from the string
|
||||
}
|
||||
if(!status)
|
||||
{
|
||||
printf(" ... fail!"); // LCOV_EXCL_LINE
|
||||
compare = false; // LCOV_EXCL_LINE
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return compare ? 0 : 1;
|
||||
}
|
||||
|
||||
// NOLINTEND(hicpp-signed-bitwise)
|
||||
@@ -129,6 +129,9 @@ C4_SUPPRESS_WARNING_GCC_CLANG_PUSH
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG("-Wcast-qual")
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG("-Wold-style-cast")
|
||||
C4_SUPPRESS_WARNING_GCC("-Wuseless-cast")
|
||||
#if __GNUC__ >= 6
|
||||
C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wnull-dereference")
|
||||
#endif
|
||||
|
||||
namespace sample {
|
||||
|
||||
|
||||
17
samples/singleheader-ints/CMakeLists.txt
Normal file
17
samples/singleheader-ints/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
|
||||
project(ryml-quickstart-ints LANGUAGES CXX)
|
||||
|
||||
# create a target to amalgamate ryml into a single header:
|
||||
include(amalgamate.cmake)
|
||||
amalgamate_ryml(SINGLE_HEADER_DIR SINGLE_HEADER)
|
||||
|
||||
# now simply define the executable:
|
||||
add_executable(ryml-quickstart-ints ../quickstart-ints.cpp ${SINGLE_HEADER})
|
||||
target_compile_features(ryml-quickstart-ints PUBLIC cxx_std_11)
|
||||
target_compile_definitions(ryml-quickstart-ints PUBLIC -DRYML_SINGLE_HEADER)
|
||||
target_compile_definitions(ryml-quickstart-ints PUBLIC -DRYML_SINGLE_HEADER_INTS)
|
||||
target_include_directories(ryml-quickstart-ints PUBLIC "${SINGLE_HEADER_DIR}")
|
||||
|
||||
add_custom_target(run ryml-quickstart-ints
|
||||
COMMAND $<TARGET_FILE:ryml-quickstart-ints>
|
||||
DEPENDS ryml-quickstart-ints)
|
||||
18
samples/singleheader-ints/amalgamate.cmake
Normal file
18
samples/singleheader-ints/amalgamate.cmake
Normal file
@@ -0,0 +1,18 @@
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
|
||||
# amalgamate ryml to get the single header
|
||||
function(amalgamate_ryml header_dir header_file)
|
||||
set(rymldir "${CMAKE_CURRENT_LIST_DIR}/../..")
|
||||
set(singleheaderdir "${rymldir}/src_singleheader")
|
||||
set(singleheader "${singleheaderdir}/ryml_ints.hpp")
|
||||
set(amscript "${rymldir}/tools/amalgamate.py")
|
||||
file(GLOB_RECURSE srcfiles
|
||||
LIST_DIRECTORIES FALSE
|
||||
CONFIGURE_DEPENDS "${rymldir}/src" "${rymldir}/src_extra")
|
||||
add_custom_command(OUTPUT "${singleheader}"
|
||||
COMMAND "${Python3_EXECUTABLE}" "${amscript}" -e ints -- "${singleheader}"
|
||||
COMMENT "${Python3_EXECUTABLE} ${amscript} -e ints -- ${singleheader}"
|
||||
DEPENDS ${srcfiles} "${amscript}" "${rymldir}/ext/c4core/cmake/amalgamate_utils.py")
|
||||
set(${header_dir} "${singleheaderdir}" PARENT_SCOPE)
|
||||
set(${header_file} "${singleheader}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
10
samples/singleheader-ints/run.sh
Executable file
10
samples/singleheader-ints/run.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# take the build type from the command line, or default to release
|
||||
cfg=${1:-Release}
|
||||
# make sure to run from where this file is
|
||||
cd $(dirname $0)
|
||||
# configure the sample
|
||||
cmake -S . -B ./build/$cfg -DCMAKE_BUILD_TYPE=$cfg
|
||||
# build and run the sample
|
||||
cmake --build ./build/$cfg --config $cfg --target run
|
||||
27
samples/singleheaderlib-ints/CMakeLists.txt
Normal file
27
samples/singleheaderlib-ints/CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
|
||||
project(ryml-quickstart-ints LANGUAGES CXX)
|
||||
|
||||
# create a target to amalgamate ryml into a single header:
|
||||
include(../singleheader-ints/amalgamate.cmake)
|
||||
amalgamate_ryml(SINGLE_HEADER_DIR SINGLE_HEADER)
|
||||
|
||||
# add a library using the amalgamated header
|
||||
add_library(ryml lib.cpp ${SINGLE_HEADER})
|
||||
target_compile_features(ryml PUBLIC cxx_std_11)
|
||||
target_include_directories(ryml PUBLIC "${SINGLE_HEADER_DIR}")
|
||||
|
||||
# now simply define the executable:
|
||||
add_executable(ryml-quickstart-ints ../quickstart-ints.cpp)
|
||||
target_link_libraries(ryml-quickstart-ints PRIVATE ryml)
|
||||
target_compile_definitions(ryml-quickstart-ints PUBLIC -DRYML_SINGLE_HEADER_LIB)
|
||||
target_compile_definitions(ryml-quickstart-ints PUBLIC -DRYML_SINGLE_HEADER_INTS)
|
||||
|
||||
# adjustments for shared library
|
||||
if(BUILD_SHARED_LIBS)
|
||||
# RYML_SHARED should be propagated to targets consuming ryml
|
||||
target_compile_definitions(ryml PUBLIC -DRYML_SHARED)
|
||||
endif()
|
||||
|
||||
add_custom_target(run ryml-quickstart-ints
|
||||
COMMAND $<TARGET_FILE:ryml-quickstart-ints>
|
||||
DEPENDS ryml-quickstart-ints)
|
||||
2
samples/singleheaderlib-ints/lib.cpp
Normal file
2
samples/singleheaderlib-ints/lib.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#define RYML_SINGLE_HDR_DEFINE_NOW
|
||||
#include <ryml_ints.hpp>
|
||||
10
samples/singleheaderlib-ints/run_shared.sh
Executable file
10
samples/singleheaderlib-ints/run_shared.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# take the build type from the command line, or default to release
|
||||
cfg=${1:-Release}
|
||||
# make sure to run from where this file is
|
||||
cd $(dirname $0)
|
||||
# configure the sample
|
||||
cmake -S . -B ./build/$cfg-shared -DCMAKE_BUILD_TYPE=$cfg -DBUILD_SHARED_LIBS=ON
|
||||
# build and run the sample
|
||||
cmake --build ./build/$cfg-shared --config $cfg --target run
|
||||
10
samples/singleheaderlib-ints/run_static.sh
Executable file
10
samples/singleheaderlib-ints/run_static.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# take the build type from the command line, or default to release
|
||||
cfg=${1:-Release}
|
||||
# make sure to run from where this file is
|
||||
cd $(dirname $0)
|
||||
# configure the sample
|
||||
cmake -S . -B ./build/$cfg-static -DCMAKE_BUILD_TYPE=$cfg -DBUILD_SHARED_LIBS=OFF
|
||||
# build and run the sample
|
||||
cmake --build ./build/$cfg-static --config $cfg --target run
|
||||
@@ -19,6 +19,7 @@ class Event(Enum):
|
||||
testsuite = "testsuite"
|
||||
ints = "ints"
|
||||
ints_utils = "ints_utils"
|
||||
ints_to_testsuite = "ints_to_testsuite"
|
||||
all = "all"
|
||||
none = "none"
|
||||
def __str__(self):
|
||||
@@ -33,6 +34,7 @@ event_doc = {
|
||||
Event.testsuite: "enable the (extra) YAML test suite event handler",
|
||||
Event.ints: "enable the (extra) integer-based event handler",
|
||||
Event.ints_utils: "enable the (extra) integer-based event handler utils",
|
||||
Event.ints_to_testsuite: "enable the (extra) integer events conversion to testsuite events",
|
||||
Event.all: "enable all event handlers",
|
||||
Event.none: "disable all event handlers",
|
||||
}
|
||||
@@ -138,7 +140,8 @@ INSTRUCTIONS:
|
||||
"src/c4/yml/event_handler_stack.hpp",
|
||||
am.onlyif(has_evt(Event.tree), "src/c4/yml/event_handler_tree.hpp"),
|
||||
am.onlyif(has_evt(Event.ints), "src_extra/c4/yml/extra/event_handler_ints.hpp"),
|
||||
am.onlyif(has_evt(Event.ints_utils), "src_extra/c4/yml/extra/event_handler_ints_utils.hpp"),
|
||||
am.onlyif(has_evt(Event.ints_utils), "src_extra/c4/yml/extra/ints_utils.hpp"),
|
||||
am.onlyif(has_evt(Event.ints_to_testsuite), "src_extra/c4/yml/extra/ints_to_testsuite.hpp"),
|
||||
am.onlyif(has_evt(Event.testsuite), "src_extra/c4/yml/extra/string.hpp"),
|
||||
am.onlyif(has_evt(Event.testsuite), "src_extra/c4/yml/extra/event_handler_testsuite.hpp"),
|
||||
am.onlyif(has_evt(Event.ints_utils, Event.testsuite), "src_extra/c4/yml/extra/scalar.hpp"),
|
||||
@@ -158,8 +161,8 @@ INSTRUCTIONS:
|
||||
am.onlyif(has_evt(Event.tree), "src/c4/yml/tree.cpp"),
|
||||
am.onlyif(has_evt(Event.ints), "src_extra/c4/yml/extra/event_handler_ints.cpp"),
|
||||
am.onlyif(has_evt(Event.ints_utils, Event.testsuite), "src_extra/c4/yml/extra/scalar.cpp"),
|
||||
am.onlyif(has_evt(Event.ints_utils), "src_extra/c4/yml/extra/event_handler_ints_utils.cpp"),
|
||||
am.onlyif(has_evt(Event.testsuite), "src_extra/c4/yml/extra/event_handler_testsuite.cpp"),
|
||||
am.onlyif(has_evt(Event.ints_utils), "src_extra/c4/yml/extra/ints_utils.cpp"),
|
||||
am.onlyif(has_evt(Event.ints_to_testsuite), "src_extra/c4/yml/extra/ints_to_testsuite.cpp"),
|
||||
am.onlyif(has_evt(Event.tree), "src/c4/yml/reference_resolver.cpp"),
|
||||
am.onlyif(has_evt(Event.tree), "src/c4/yml/parse.cpp"),
|
||||
am.onlyif(has_evt(Event.tree), "src/c4/yml/node.cpp"),
|
||||
|
||||
Reference in New Issue
Block a user