A C++ port of Mozilla's
rust-parsepatch patch & diff files parser library.
| .reuse | Initial commit. | |
| cmake | Initial commit. | |
| include | Initial commit. | |
| LICENSES | Initial commit. | |
| src | Initial commit. | |
| tests | Initial commit. | |
| .clang-format | Initial commit. | |
| .gitignore | Initial commit. | |
| .gitmodules | Initial commit. | |
| build.ninja | Initial commit. | |
| CMakeLists.txt | Initial commit. | |
| Doxyfile | Initial commit. | |
| LICENSE.md | Initial commit. | |
| ReadMe.md | Initial commit. | |
ParsePatch.cpp
A C++ port of https://github.com/mozilla/rust-parsepatch MPL-2.0-licensed patch file parsing library. API is not yet stable, minor changes can happen.
Corresponds to b3dbb48ecc73de3fecea20c7e8848a3fc2239772 commit of the original library.
Goals:
- API similar to the one of the Rust library.
- But when needed, it can differ.
- Speed and efficiency.
- Safety.
- Usage as a shared lib.
- Packaging.
Differences:
- Instead of extensive using of templates we use abstract interfaces.
- Instead of buffers we use
string_views. Everything is pointers into the original buffer. If one wants the data to outlive them, he must convert them into allocated buffers. - Rust enumerations are translated into C++ classes with the first member conveying the code, and the rest containing the value matching the semantics.
- So
by_pathandParsepatchErrorCode::IOErrorare removed - user owns the memory and manages it himself. He can mmap a file, then thestring_views will be within the map. Or he can read the file into a memory buffer.by_pathassummes that the library owns memory, not the user. It is not flexible. fmtis replaced by theoperator<<functions allowing output to the standard lib.- We use
parsepatchnamespace. - Some static functions moved from the class into
ScannerUtilsnamespace. parse_numbersreturnsResult<NumbersT>.NumbersTis a struct with semantic names for each component, not a tuple.- Parsing is done not by calling a static method, but by creating an object and reusing it.
- Debug output can be enabled by assigning a pointer to a stream to
tracingvariable. - JSON-based tester was refatored. JSON structs have been separated from the
PatchandDiffevent listeners. - Testing is done using my
fileTestSuiteframework. Tests are moved into the separate repository.
How to use
- You need a compiler supporting C++20 and
std::expected. If you don't havestd::expected, you can install https://github.com/TartanLlama/expected or https://github.com/martinmoene/expected-lite or https://github.com/RishabhRD/expected . - Build and install into the system using CMake. CPack can be used to build native the packages.
- Import into your CMake project:
find_package(ParsePatch)target_link_libraries("${PROJECT_NAME}" PRIVATE ParsePatch::libParsePatch)Or you can use pkg-config
pkg-config --libs ParsePatch
#include <ParsePatch.hpp>- Subclass
DiffandPatchand implement the event listener callbacks.
struct DiffImpl: public ParsePatch::Diff {
virtual void set_info(const std::string_view old_name, const std::string_view new_name, ParsePatch::FileOp op, std::optional<std::vector<ParsePatch::BinaryHunk>> binary_sizes, std::optional<FileMode> file_mode) override {
...
}
virtual void add_line(uint32_t old_line, uint32_t new_line, std::string_view &&line) override {}
virtual void new_hunk() override {}
virtual void close() override {}
};
struct PatchImpl: public ParsePatch::Patch {
DiffImpl diff{};
virtual ParsePatch::Diff* new_diff() override {
return &diff;
}
virtual void close() override {}
};
Testing
There are 2 kinds of tests.
- Basic tests testing low-level blocks. For them you need https://github.com/google/googletest installed in the system.
- Testing against the dataset of etalon parses serialized into JSON. For them you need https://github.com/nlohmann/json and https://codeberg.org/fileTestSuite/fileTestSuite.c and their dependencies installed and the submodules populated.
Testing against JSON dataset can be done for example using
testabs-runner /usr/lib/x86_64-linux-gnu/libTestAbsBackend_GTest.so /usr/lib/x86_64-linux-gnu/libFileTestSuite_runner.so ./tests/json/libjson_tests.so ../tests/json/testDataset
where:
testabs-runneris the runner glue executable.libTestAbsBackend_GTest.sois the TestAbs backend using GoogleTest. Installed as a part ofTestAbs(dependency offileTestSuite), can be replaced by backends to other testing frameworks, depending on your needs.libFileTestSuite_runner.sois the tester library for TestAbs, part offileTestSuite.c, converts files into test cases.../tests/json/testDataset- path to testing dataset following thefileTestSuitespec. Fetched as a submodule.