1
0
Fork
You've already forked ParsePatch.cpp
0
A C++ port of Mozilla's rust-parsepatch patch & diff files parser library.
C++ 92.2%
CMake 7.8%
Find a file
2023年10月15日 18:34:01 +03:00
.reuse Initial commit. 2023年10月15日 18:34:01 +03:00
cmake Initial commit. 2023年10月15日 18:34:01 +03:00
include Initial commit. 2023年10月15日 18:34:01 +03:00
LICENSES Initial commit. 2023年10月15日 18:34:01 +03:00
src Initial commit. 2023年10月15日 18:34:01 +03:00
tests Initial commit. 2023年10月15日 18:34:01 +03:00
.clang-format Initial commit. 2023年10月15日 18:34:01 +03:00
.gitignore Initial commit. 2023年10月15日 18:34:01 +03:00
.gitmodules Initial commit. 2023年10月15日 18:34:01 +03:00
build.ninja Initial commit. 2023年10月15日 18:34:01 +03:00
CMakeLists.txt Initial commit. 2023年10月15日 18:34:01 +03:00
Doxyfile Initial commit. 2023年10月15日 18:34:01 +03:00
LICENSE.md Initial commit. 2023年10月15日 18:34:01 +03:00
ReadMe.md Initial commit. 2023年10月15日 18:34:01 +03:00

ParsePatch.cpp

Libraries.io Status

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:

  1. Instead of extensive using of templates we use abstract interfaces.
  2. 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.
  3. Rust enumerations are translated into C++ classes with the first member conveying the code, and the rest containing the value matching the semantics.
  4. So by_path and ParsepatchErrorCode::IOError are removed - user owns the memory and manages it himself. He can mmap a file, then the string_views will be within the map. Or he can read the file into a memory buffer. by_path assummes that the library owns memory, not the user. It is not flexible.
  5. fmt is replaced by the operator<< functions allowing output to the standard lib.
  6. We use parsepatch namespace.
  7. Some static functions moved from the class into ScannerUtils namespace.
  8. parse_numbers returns Result<NumbersT>. NumbersT is a struct with semantic names for each component, not a tuple.
  9. Parsing is done not by calling a static method, but by creating an object and reusing it.
  10. Debug output can be enabled by assigning a pointer to a stream to tracing variable.
  11. JSON-based tester was refatored. JSON structs have been separated from the Patch and Diff event listeners.
  12. Testing is done using my fileTestSuite framework. Tests are moved into the separate repository.

How to use

  1. You need a compiler supporting C++20 and std::expected. If you don't have std::expected, you can install https://github.com/TartanLlama/expected or https://github.com/martinmoene/expected-lite or https://github.com/RishabhRD/expected .
  2. Build and install into the system using CMake. CPack can be used to build native the packages.
  3. 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
  1. #include <ParsePatch.hpp>
  2. Subclass Diff and Patch and 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.

  1. Basic tests testing low-level blocks. For them you need https://github.com/google/googletest installed in the system.
  2. 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-runner is the runner glue executable.
  • libTestAbsBackend_GTest.so is the TestAbs backend using GoogleTest. Installed as a part of TestAbs (dependency of fileTestSuite), can be replaced by backends to other testing frameworks, depending on your needs.
  • libFileTestSuite_runner.so is the tester library for TestAbs, part of fileTestSuite.c, converts files into test cases.
  • ../tests/json/testDataset - path to testing dataset following the fileTestSuite spec. Fetched as a submodule.