Compare commits

..
188 Commits
Author SHA1 Message Date
rzh789ABC 356643ba26 Fix bug on tags starting with "!!" (#1427)
* Fix bug on tags starting with "!!"

* Add test for emitting SecondaryTag

* Fix bug when calling SetTag with named tag handles.

* Add test for SetTag

* move SetTag tests from emitter_test.cpp to load_node_test.cpp

* keep emitter_test.cpp unchanged

* keep emitter_test.cpp unchanged

log: improved parsing/emitting of local tags "!!"
2026-07-13 13:15:33 +02:00
raphaelroshan 156e6e22d1 fix: allow '~' in emitted anchor and alias names (#1461)
IsAnchorChar rejected 0x7E ('~') via an off-by-one (< 0x7E), even though
'~' is a valid ns-char and the parser's anchor rule already accepts it.
As a result the emitter could not round-trip its own valid anchor names,
failing with INVALID_ANCHOR. DEL (0x7F) and C1 controls stay excluded.

log: allow `~` in emitted anchor an alias names
2026-07-13 12:59:58 +02:00
rzh789ABC 881f6108e5 feat: add thread-safe contains() function for Node. (#1457)
* feat: add thread-safe contains() function for Node

* remove thread-unsafe EnsureNodeExists in Node::contains().

log: add Node::contains for thread safe testing of existence of children
2026-07-11 08:27:17 +02:00
NathanandBryan Nathan 3caebe2189 fix: emit uint8_t as an integer (#1459)
* Emit eight-bit integer types as numbers

* Rename uint8_t regression test

---------

Co-authored-by: Bryan Nathan <bryan@users.noreply.github.com>

log: behavior change: uint8_t are now emitted as integers
2026-07-11 08:24:00 +02:00
Simon Gene Gottlieb 3a1c96f218 doc: stop directing users to stackoverflow (#1454)
log: README - remove stackoverflow link
2026-07-07 14:21:46 +02:00
rzh789ABC fdca1e8268 feat: support line wrapping for Binary in literal syntax (#1455)
* Support line wrapping for literal binary emitting.

* Add test for literal binary wrapping

* fix code style and maintainability

log: Support for line wrapping for binary literal syntax
2026-07-07 14:21:06 +02:00
rzh789ABC ee52744a31 feat/fix: support literal and single-quoted style for YAML::Binary emitting (#1447)
* Support single-quoted and literal style for binary emitting.

* Add test for binary emitting styles.

* Add Utils::ComputeBinaryFormat and non-trivial comments.

log: support literal and single-quoted style for YAML::Binary emitting
2026-07-03 09:39:34 +02:00
Charlie Tonneslan 29a6f43950 emit secondary tag handles (e.g. !!str) on Node::SetTag (#1437)
When a node's tag started with "!!" — the YAML secondary tag handle,
as in "!!str" or "!!int" — EmitFromEvents stripped a single '!' and
emitted the rest as a LocalTag. The remaining string ("!str") then
failed the LocalTag character regex on the inner '!' and the emitter
bailed out with INVALID_TAG, truncating output after "!".

Reproduction from #1373:

    YAML::Node root;
    YAML::Node s{"hello"};
    s.SetTag("!!str");
    root["some_string"] = s;
    root["some_int"] = 2;
    std::cout << root;  // -> "some_string: !"

Recognize the "!!" prefix in EmitProps and route it through
SecondaryTag with the rest of the tag content. After this:

    some_string: !!str hello
    some_int: 2

Added two regression tests under NodeTest covering both the secondary
("!!") and primary ("!") handle paths.

Closes #1373.

Signed-off-by: Charlie Tonneslan <cst0520@gmail.com>

log: capability to emit secondary handles (e.g. !!str)
2026-07-02 11:20:01 +02:00
Mike Kruskal 1bff0699f8 Add explicit -fexceptions copts to Bazel config (#1449)
This allows users to build with -fno-exceptions, and smoothly turns exceptions into crashes at the boundary.

log: bazel support for '-fno-exceptions'
2026-07-02 11:03:32 +02:00
Eyüp Can Akman ddd9da99af Support the conversion for std::unordered_set (#1438)
fixes #1322

log: add converter for std::unordered_set
2026-07-02 11:00:24 +02:00
raphaelroshan 847020a9cd convert: parse YAML 1.2 octal scalars (0o prefix) as integers (#1251) (#1451)
log: recognizes `0o` and `0O` as prefix for octal values.
2026-07-02 10:58:21 +02:00
dependabot[bot] eadeac64e1 build(deps): bump actions/checkout in the github-actions group (#1453) 2026-07-01 12:16:17 -05:00
Jesse Beder 2decf96e91 Add rules about AI usage in contributions. 2026-05-26 11:27:43 -05:00
Christoph Grüninger 4861d04953 [ci] Update GitHub Action checkout to version 6 (#1434)
Fixes deprecation warning for Node20.js

log: Fixes deprecation warning for Node20.js
2026-04-20 20:00:39 +02:00
fb9107556b Fix MSVC narrowing-conversion warnings (C4244/C4267) under /W3 (#1431)
Add explicit casts to silence 8 warnings triggered by MSVC /W3:

fptostring.cpp:
- Add static_cast<int>(precision) where public API (size_t) calls
  internal template (int)
- Add static_cast<int>(...) for pointer-arithmetic result stored in int

dragonbox.h:
- Add static_cast<uint_least32_t>(n) in umul64() calls inside
  if-constexpr branches guarded by is_same<UInt, uint_least32_t> to
  silence MSVC warnings on discarded branches when UInt=uint_least64_t
- Change trailing-zero counter 's' from size_t to DecimalExponentType
  in both remove_trailing_zeros specializations to match exponent type

Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

log: fix MSVC narrowing conversion warnings
2026-04-20 17:33:35 +02:00
Simon Gene Gottlieb 1b60fae7c3 feat: option for strict flag usage (#1430)
When compiling yaml-cpp as a root project flags like -Wall -pedantic or
-pedantic-error are being set. Some compilers report false positives
and/or are not aware of certain flags.
While having a strict compile policy is nice but hinders people who are
using rare compiler or compiler configurations or sometimes just new
compiler.

The current workaround is to edit the CMakeLists.txt file and edit out
those flags.

This patch provides a new CMake option "YAML_CPP_USE_STRICT_FLAGS".
The default value is set to ON if its the
root project, otherwise OFF. This allows a user to call `cmake
-DYAML_CPP_USE_STRICT_FLAGS=OFF .." to deactivate any strict flag
settings.

log: feat: option for strict flag usage
2026-04-20 16:29:25 +02:00
Knightly f407cc9188 fix: Visual Studio warnings for narrowing conversion (#1433)
log: fix MSVC narrowing conversion warnings
2026-04-20 16:26:21 +02:00
Christoph Grüninger c237bb9de7 [cmake] Require CMake 3.15 or newer (#1358)
* [cmake] Require CMake 3.15 or newer

* [test] Update Google-test to 1.16

* [ci] Add workflow to configure with CMake 3.15

Ensure that oldest supportest version of CMake can configure project
Copy quick_cmake from CLIUtils/CLI11

log: requires cmake 3.15 as a minimum
2026-04-20 16:12:42 +02:00
Simon Gene Gottlieb 55a0a28d88 feat: CI tests windows-11-arm platform for bazel (#1419)
log: add CI on windows-11-arm platform for bazel
2026-04-20 15:52:18 +02:00
Christoph Grüninger 932b732d6f [ci] Test for compatibility with C++23
C++ 11 because it is the oldest supported by the project.
C++ 20 because it is GCC default in current compiler versions.
C++ 23 because its the newest with wide compiler support.

log: CI testing for c++23
2026-04-20 14:24:31 +02:00
Simon Gene Gottlieb 992d9c4f67 feat: literal string output 'chomping indicator'
log: fix literal string outputs 'chomping indicator' if required
2026-04-08 13:09:15 +02:00
Simon Gene Gottlieb b9fd92b5e9 test, fix: correct the unit test
The unit test only tested for the '|' literal indicator.
But in some cases it should have been '|-'. If a string does not end
with an '\n' it has to use '|-' to indicate that the trailing new line
is not part of the string.

Additionally, I also added a explicit test for '|+'.
2026-04-08 13:09:15 +02:00
mosfet80 1870e4be3a Update CXX requirement
googletest 1.13 requires at least C++14

log: fix tests using c++ version from googletest
2026-03-27 16:47:52 +01:00
Vadim D 0b7ce1d47c Cloning a node preserves marks
\#log: behaviour change: cloning a node preserves markings
2026-03-25 19:30:13 +01:00
Simon Gene Gottlieb 8a666a0c1e fix:hanlde <next line> '\N' correctly 2026-03-16 23:32:29 +01:00
Simon Gene Gottlieb aba9ed6b65 test: demonstrate that encoding fails
The 'Next Line' (NEL) has to be encoded utf8 0xC2 0x85.
This fixes the test (which now fails).
2026-03-16 23:32:29 +01:00
Simon Gene Gottlieb c6b7004299 fix: enables floats as keys
Previously, floats are converted to integer. In some cases this causes
the node to be converted to a sequence instead of a map.
This commit fixes this, by only treating integral values as integral
values.
2026-03-16 23:32:10 +01:00
Simon Gene Gottlieb 98684b3ec6 test: floats as keys for maps
This tests the usage of a float as a key.
Because of a bug, this will fail and will be converted to a sequence.
2026-03-16 23:32:10 +01:00
Simon Gene Gottlieb 79d822b6fb fix: accepted by vs16.11 2026-03-16 23:31:37 +01:00
Simon Gene Gottlieb 850ff086d7 Revert "fix yaml-cpp build with Visual Studio Code 2019"
This reverts commit 4d076581be.
2026-03-16 22:46:40 +01:00
Tim Schneider 4d076581be fix yaml-cpp build with Visual Studio Code 2019
fix issue #1357
2026-03-16 16:59:14 +01:00
PhilipDeegan 6424876d63 werror ununused param 2026-03-12 17:02:42 +01:00
Daniel Brondani 6f3b99c9bb Validate mapping key uniqueness 2026-03-12 15:32:49 +01:00
Simon Gene Gottlieb 5b04bd307e doc: minor bug in comment 2026-03-11 16:34:47 +01:00
Simon Gene Gottlieb ee8d9ed284 partial revert: remove windows-11-arm for bazel builds
The current bazel build (9.0.1) fails for windows arm 11.
2026-03-11 16:24:08 +01:00
Jeremy Nimmer 7f7b3257de Add missing istream and ostream headers 2026-03-11 15:30:59 +01:00
David Schneller 8bcadb1509 Do not pass warning printing flags to NVHPC 2026-03-10 18:14:16 +01:00
MUGUNDAN 5ce97d992c Add support for building and testing yaml-cpp on Windows ARM64 2026-03-10 18:03:50 +01:00
Vyacheslav Napadovsky 461a2aff85 replace std::shared_ptr<T>(new T) with std::make_shared<T> (#1355) 2026-03-10 17:58:48 +01:00
Dahan Gongandgongdahan 05c050c6c1 fix: invalidate iterator->first on dtor to expose use-after-free (#1409)
Co-authored-by: gongdahan <gongdahan@meituan.com>
2026-02-27 21:28:32 -06:00
Simon Gene Gottlieb dc413bdb16 feat: Emitter has option to produce string with trailing '.0' for floating point value (#1407)
This adds a new function Emitter::SetShowTrailingZero(bool).
By setting this, floating point values like '0' or '5' will get an extra
'.0' attached to force others to parse them as floats.

Example:
```
YAML::Emitter emitter;
emitter.SetShowTrailingZero(true);
emitter << ....
```

Fix #226 #412 #1016

Co-Author: Romain Reignier <romain.reignier@exail.com>
2026-02-24 09:02:19 -06:00
Simon Gene Gottlieb 97d150e98b Feat/fix faulty string (#1406) 2026-02-18 14:45:23 -06:00
Simon Gene Gottlieb 44d54544b1 fix: handle escaped underscore \_ correctly 2026-02-17 16:19:43 -06:00
Simon Gene Gottlieb 3e53605a31 test: fixes test for NBSP (non-break space)
This fixes the example "Example 5.13 Escaped Characters" from the YAML
specification.

The example demands that `\_` is being translated to unicode `\u00a0`.
The unicode codepoint `\u00A0` encoded for utf-8 in hex is `\xC2\xA0`.

Fixing this test case will cause the unit test to not pass, since the
codepoint `\u00A0` is not handled correctly.
(Failing unittest is expected).
2026-02-17 16:19:43 -06:00
Simon Gene Gottlieb f25f110e33 fix: change abort when no parsing progress is made
Previously, no parsing progress (detecting infinite loops) was detected by an empty Node.
This falsely triggers an abort, if an empty YAML document is being parsed.

Instead, we detect if progress in the parsing stream is made, by
comparing token positions. As long as new tokens are being
parsed (detected by position change), we assume we are not in an
infinite loop.
2026-02-17 08:58:37 -06:00
Simon Gene Gottlieb f3f123cea0 test: add case demonstrating bug 2026-02-17 08:58:37 -06:00
Alexey Sokolov 495cde635d Support newer CMake in test too 2026-02-11 12:22:05 -06:00
Simon Gene Gottlieb ebb85dd462 fix: floating point conversion on x86 (32bit) 2026-02-11 11:14:57 -06:00
Jeremy NimmerandSean Curtis 80ea0028c7 Fix DecodeBase64 to reject truncated input
If the input doesn't have the proper number of encoding characters
(a multiple of 4), return an empty result.

Co-Authored-By: Sean Curtis <sean.curtis@tri.global>
2026-02-10 13:49:45 -06:00
Kamil 2e6383d272 Update README.md 2026-02-07 21:23:53 -06:00
Jesse Beder 56e3bb550c Update project version to 0.9.0 2026-02-04 14:26:25 -06:00
dependabot[bot] f0329d0efd build(deps): bump actions/checkout in the github-actions group
Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout).


Updates `actions/checkout` from 6.0.1 to 6.0.2
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-01 10:53:39 -06:00
Henner Zeller 89ff142b99 Add IWYU export pragmas.
If a project is using the facade-header yaml-cpp/yaml.h it might
get `misc-include-cleaner` warnings from the `clangd` language server
and `clang-tidy` that this header is not providing directly the symbols used.

The annotation with IWYU pragmas fixes that and tells the tools that it should consider
all the includes as if they directly provided the symbol

Documentation clangd and clang-tidy
https://clang.llvm.org/extra/clang-tidy/checks/misc/include-cleaner.html points to
https://clangd.llvm.org/design/include-cleaner#iwyu-pragmas

This has been first implemented and docuemnted in the include-what-you-use project
https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/IWYUPragmas.md#iwyu-pragma-begin_exportsend_exports

Signed-off-by: Henner Zeller <h.zeller@acm.org>
2026-01-01 10:15:23 -06:00
Alexander Hans 3738976bdc fix(bazel): add missing load statements
Bazel 9 drops builtin `cc_*` rules, they need to be loaded explicitly now.
2026-01-01 10:14:47 -06:00
dependabot[bot] 5cf25533e3 build(deps): bump actions/checkout in the github-actions group
Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout).


Updates `actions/checkout` from 5.0.1 to 6.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v5.0.1...v6.0.1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-01 10:14:17 -06:00
Simon Gene Gottlieb c7aa78d294 fix: overflow buffer with large precision values
Issue #1385 demonstrates how a large 'precision' value can cause buffer
overflows. Originally, the buffer was designed to fit any scientific
notation. But the precision changes at which point large floating point
numbers are displayed in scientific notation or default notation.
In case of the default notation many extra zeros have to be printed,
this was not reflected in the output_buffer and an overflow could
occur.

This PR computes the number of zero that do not fit into the static
buffer and appends them at the end of the function triggering potential
a second dynamic allocation. (The first allocation is the std::string
allocation).
2025-12-28 17:33:09 -06:00
Simon Gene Gottlieb a2826e8983 fix: unittests sets locale before testing
the convert_with_stringstream seems to be missing a
.imbue() call to set the locale independent of the global state.
Not setting this, can in some settings lead to errors, see Issue #1366.
2025-12-28 17:32:43 -06:00
dependabot[bot] bbf8bdb087 Bump actions/checkout from 5 to 6 in the github-actions group
Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout).


Updates `actions/checkout` from 5 to 6
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-01 12:20:21 -06:00
dependabot[bot] a83cd31548 Bump actions/checkout from 4 to 5 in the github-actions group
Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout).


Updates `actions/checkout` from 4 to 5
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-01 16:57:22 -05:00
zhaoshihan 65c1c270db Fix warning -Wconstexpr-not-const 2025-09-27 10:31:12 -05:00
Michael Müller 4fe2fb83fe Use std::locale::classic() instead of creating new C locales on demand. 2025-09-17 15:21:50 -05:00
Onyad aa8d4e4750 up 2025-09-04 14:42:16 -05:00
Christoph Grüninger 2f86d13775 Update googletest to 1.13
Fix issue with CMake 4.0
2025-04-29 16:53:58 -05:00
Christoph Grüninger c9371de783 [cmake] Require minimum CMake version 3.5
Soon CMake 4.0 will be released. It requires that projects
set a minimum required CMake version of 3.5. There is a
workaround with an additional flag, but it would is better
to increase the minimum required version.
2025-04-29 16:53:58 -05:00
Salim B 28f93bdec6 docs: Fix link in README 2025-03-13 14:45:33 -05:00
Patrick Diehl 39f737443b Update README.md
Bump the release note to the latest version
2025-01-24 16:01:30 -06:00
Jeremy Nimmer 73ef0060aa Avoid including <iostream> in library code
Including iostream means introducing the static (global) constructors
and destructors for std::cin, std::cerr, and std::cout. That extra
init and fini code is undesirable when those streams are not actually
used.

Instead, we'll use the narrower includes for exactly what's needed,
i.e., <istream> or <ostream>.
2024-12-30 11:27:02 -06:00
Daniel Levin 7470c2d871 emitter: Support std::string_view
Accept Emitter::operator<<(std::string_view).

ABI remains C++11 compatible by exposing new method
Emitter::Write(const char*, size_t).

All affected calls optimized to pass std::string values as pointer + size
tuple into appropriate routines.
2024-12-22 16:22:38 -06:00
Jesse Beder 8a9a7b74ef Update CONTRIBUTING.md
Add some details about testing.
2024-12-22 16:16:07 -06:00
Jesse Beder d45c4fba3e Update README.md 2024-12-18 11:43:01 -06:00
Jesse Beder 61db89741d Exclude ubuntu/C++ 11/googletest system from the test matrix since it doesn't compile. 2024-12-17 15:59:47 -06:00
Jesse Beder 7def2046ff Fix bazel build, and commit module lock file.
Including:
- Remove WORKSPACE and upgrade to MODULE.bazel.
- The integration tests were not included since the directory was misspelled.
- Their header files were not accessible.
2024-12-17 14:49:17 -06:00
IMaloney 1da813f56a ensuring local tags are retained after loading a node + test 2024-12-17 09:20:46 -06:00
Phil Miller f878043f12 Don't install embedded copy of GTest
Goole Test itself documents the `INSTALL_GTEST` option as something that projects embedding it should set to `OFF`. Leaving it on means that projects downstream from libraries that embed it are likely to encounter conflicting copies. This is particularly annoying because GTest does not maintain anything like a stable API, and so causes builds to fail if include paths pick up an inappropriately installed copy ahead of the one that the code wanted.

Fixes #488
2024-12-17 09:12:49 -06:00
Simon Gene Gottlieb 9ce5a25188 fix: spell fix 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb ebfbf27115 patch: added more defensive programming techniques 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb 06ffaf3104 remove reduntant license information 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb 0b945415fd fix: add missing include 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb 82f3c04081 fix: add YAML_CPP_API for windows-shared library builds 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb d8de96524c patch: move dragonbox.h from 'include' folder to 'src' folder 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb 5d9e4b6251 patch: split fp_to_string.h into fptostring.h and fptostring.cpp 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb 28c0a1bc25 doc: add a little more information to dragonbox file 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb 72865f7d32 fix: remove trailing return types 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb f4bca79dc4 fix: fp_to_string uses now 2 spaces 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb d4e00bd473 fix: rename fp_to_string to FpToString to match coding style 2024-11-07 15:14:36 -06:00
Simon Gene Gottlieb bd070a7b76 fix: prettier floating point numbers
Add dragonbox to compute the required precision to print floating point
numbers. This avoids uglification of floating point numbers that
happen by default via std::stringstream.

Numbers like 34.34 used to be converted to '34.340000000000003' as strings.
With this version they will be converted to the string '34.34'.

This fixes issue https://github.com/jbeder/yaml-cpp/issues/1289
2024-11-07 15:14:36 -06:00
Reini Urban 3d2888cc8a missing keys should throw InvalidNode, not BadConversion
Fixes GH #1274
2024-11-01 10:25:39 -05:00
Federico Di Pierro c2bec4c755 chore(test): moved infiniteloop test to load_node_test suite.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-29 22:21:05 -05:00
Federico Di Pierro 29c59c01d4 new(test): added a test to avoid future issues with LoadAll().
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-29 22:21:05 -05:00
Federico Di Pierro bc67157109 fix(src): avoid possible infinite loop in LoadAll().
Leave at first empty root.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-29 22:21:05 -05:00
Federico Di Pierro da82fd982c chore(test/integration): refactor some test cases to their own test.
Plus, check that the content is what we actually expect.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-09-13 10:18:41 +02:00
Federico Di Pierro 1f2b841949 fix(src,include,test): fixed multiple cases where a bad yaml was accepted.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-09-13 10:18:41 +02:00
Orgad Shaneh 47cd2725d6 Remove build debug messages
They were commented out before 0733aeb45, but when that commit
was reverted in 2b65c65e1 they were recovered uncommented.
2024-08-27 12:23:42 -05:00
Orgad Shaneh 850ec4f39e Fix reference types in iterators
Amends 26faac387c.
2024-08-27 11:12:58 -05:00
Simon Gene Gottlieb 84459a7f98 fix: missing token enum name 2024-08-22 07:55:33 -05:00
Simon Gene Gottlieb ee9c4d19be fix: parse files with '\r' symbols as line ending correctly 2024-08-22 07:53:52 -05:00
Cristian Le b38ac5b55f Use FetchContent_MakeAvailable 2024-08-21 12:44:27 -05:00
Christopher Fore 7b469b4220 emitterutils: Explicitly include <cstdint>
GCC 15 will no longer include it by default, resulting in build
failures in projects that do not explicitly include it.

Error:
src/emitterutils.cpp:221:11: error: 'uint16_t' was not declared in this scope
  221 | std::pair<uint16_t, uint16_t> EncodeUTF16SurrogatePair(int codePoint) {
      |           ^~~~~~~~
src/emitterutils.cpp:13:1: note: 'uint16_t' is defined in header '<cstdint>';
this is probably fixable by adding '#include <cstdint>'
   12 | #include "yaml-cpp/null.h"
  +++ |+#include <cstdint>
   13 | #include "yaml-cpp/ostream_wrapper.h"

Tests pass.

Closes: #1307
See-also: https://gcc.gnu.org/pipermail/gcc-cvs/2024-August/407124.html
See-also: https://bugs.gentoo.org/937412
Signed-off-by: Christopher Fore <csfore@posteo.net>
2024-08-18 15:19:15 -05:00
Simon Gene Gottlieb 8fbf344aee doc, fix: invalid liquid '{{...}}' tags
jekyll/liquid got hung up on `{{"Daniel", 26}, {"Jesse", 24}}`.

The reason is that `{{...}}` are used as variables that are replaced by
there values. In this case we have a YAML object that looks the same.
This issue can be fixed by surrounding the block into `{% raw %}...{%
endraw %}` tags.
2024-08-06 10:40:52 -05:00
NameSirius 06c3d1db51 fix compile warning(Pull requests #1305)(Issues #1306) 2024-08-06 10:39:36 -05:00
Jesse Beder 04dddd6999 Revert "Fix compile warning with -Wshadow"
This reverts commit 1f5e971f77.

See #1306; the previous commit caused an error with -Wpedantic:

yaml-cpp/include/yaml-cpp/emitterstyle.h:13:2: error: extra ‘;’ [-Wpedantic]

Since the original commit was to resolve warnings, reverting and the OP can produce a new one that fixes this issue.
2024-08-05 15:50:36 -05:00
NameSirius 1f5e971f77 Fix compile warning with -Wshadow 2024-08-05 09:50:21 -05:00
Josiah VanderZee b11eaf1631 Run format target from project root
The CMake format target does not use the correct .clang-format file in
out-of-source builds. This instructs CMake to use the project root as
the working directory for running the clang-format command so that it
finds the .clang-format file.
2024-08-02 07:20:10 -05:00
Josiah VanderZee 9f7babc3ff Use c-strings to constant initialize token array
Since `std::string` has to be dynamically constructed and destructed,
it could be accessed before initialization or after destruction in a
multithreaded context. By using constant c-strings instead, we guarantee
that the array will be valid for the whole lifetime of the program. The
use of `constexpr` also enforces this requirement.

I have run clang-format on the file to format my changes according to
CONTRIBUTING.md.
2024-08-01 22:54:57 -05:00
Simon Gene Gottlieb b95aa146ec fix: use C locale by default 2024-07-17 13:39:30 -05:00
Frank Osterfeld 1d8ca1f35e Avoid static reference to temporary
These caused issues when used in a wasm project.
2024-05-02 09:29:05 -05:00
Humberto Dias 76dc671573 Add option YAML_ENABLE_PIC=ON 2024-02-22 12:12:48 -06:00
Humberto Dias 5c1bbbd276 Skip Position Independent Code for PSP/PS3 2024-02-22 12:12:48 -06:00
dependabot[bot] 4afd53b0d3 Bump the github-actions group with 1 update
Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout).

- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v2...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-28 15:49:18 -06:00
Jason Beach 96f5c887f3 assign fallback value 2024-01-26 13:28:55 -06:00
Alejandro-FA c67d701ad8 Fix indentation of empty sequences and add test 2024-01-26 12:30:06 -06:00
Trompettesib 9eb1142900 Fix GIT_TAG field in cmake integration example 2024-01-04 09:40:42 -06:00
Alexandre TISSOT c28295bda4 Add CMake integration example 2024-01-04 09:40:42 -06:00
Levi Armstrong 94710bb221 Add default destructor to EmitFromEvents 2023-12-28 10:44:52 -06:00
Diogo Teles Sant'Anna c7639e81d5 ci: configure dependabot to montly update GHAs
Signed-off-by: Diogo Teles Sant'Anna <diogoteles@google.com>
2023-12-14 09:13:33 -06:00
Diogo Teles Sant'Anna f30582fb09 ci: hash-pin sensitive workflow dependency
Signed-off-by: Diogo Teles Sant'Anna <diogoteles@google.com>
2023-12-14 09:13:33 -06:00
Alex Thiessen eaf7205372 README.md: Describe building with debug libstdc++ mode 2023-11-27 14:29:13 -06:00
Alex Thiessen 1c5a38eef3 workflows/build.yml: Use debug std C++ library on Ubuntu
Protect from regressions due to use of undefined or
implementation-specific behavior when using `std::` containers and smart
pointers.

This only has effect on platforms with the GNU standard C++ library.

Refer to https://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html.
2023-11-27 14:29:13 -06:00
Levi Armstrong 51adc5f739 Update yaml-cpp-config.cmake.in 2023-11-06 19:25:04 -06:00
Levi Armstrong 30e6933279 Fix yaml-cpp-config.cmake.in 2023-11-06 19:25:04 -06:00
Gianfranco Costamagna db03655d58 Make sure CXX_STANDARD can be overridden from outside (#1239) 2023-10-23 07:20:22 -05:00
Gianfranco Costamagna 145eec5f3e Add CMake option YAML_USE_SYSTEM_GTEST to use system googletest if available. (#1035)
There is no need to use the embedded gtest code copy in Linux systems, if they already provide the googletest framework system-wide.
Search for it, and fallback to the embedded one if the system one is not detected.

This patch has been also contributed by Simon Quigley <tsimonq2@debian.org>
2023-10-22 00:06:39 -05:00
Ezekiel Warren f791b955d8 remove unncessary continue-on-error (#1234) 2023-10-12 19:27:47 -04:00
Ezekiel Warren 4fc5ec36bc automatically create bzlmod archive for release (#1230) 2023-10-12 11:52:22 -04:00
Pete Lewis 8106fcf1e5 Resolve warnings about unreferenced parameter 'style' in NullEventHandlers (#1193) 2023-10-12 11:49:34 -04:00
Pierre WendlingandJesse Beder c26e047223 CMake: Fixes for generated config (#1212)
* CMake: Add option to set the package install dir.

* CMake: Fix generated config.

- `YAML_CPP_SHARED_LIBS_BUILT` should not be set with a `PATH_VAR` as it
would always evaluate to true.
- `YAML_CPP_LIBRARIES` should used the exported target name including
the namespace, but `check_required_components` shouldn't.
- Use `CMAKE_CURRENT_LIST_DIR` to find the target file, instead of a
`PATH_VAR`. Package managers such as vcpkg move CMake configs after
installing.

* CI: Test the generated CMake package.

* CMake: Create add a deprecated yaml-cpp target.

This target is meant to provide compatibility with versions prior to
0.8.0.

* CMake: mark the yaml-cpp target as IMPORTED.

---------

Co-authored-by: Jesse Beder <jbeder+github@gmail.com>
2023-10-12 11:48:16 -04:00
ac144ed46c Hide uninstall target unless YAML_CPP_INSTALL is set, and allow it to be disabled by YAML_CPP_DISABLE_UNINSTALL
add_custom_target uninstall causes a clash with the same target in rtmidi (https://github.com/thestk/rtmidi).
"add_custom_target cannot create target "uninstall" because another target with the same name already exists.  The existing target is a custom target created in source directory"

Adds new option YAML_CPP_DISABLE_UNINSTALL 

fixes #1151

---------

Co-authored-by: Megamouse <studienricky89@googlemail.de>
Co-authored-by: Jesse Beder <jbeder+github@gmail.com>
2023-10-11 00:02:33 -04:00
Alfi Maulana 4c061a5058 Disable format target when not building as the main project (#1231) 2023-10-10 23:40:09 -04:00
Paul Jurczak 37f1b8b8c9 Update How-To-Emit-YAML.md (#976) 2023-09-21 15:38:56 -05:00
FireWolf d046eea331 node/convert: Enable the template specialization for std::string_view properly when the library is compiled by MSVC on Windows. (#1227) 2023-09-17 11:58:31 -04:00
Daniel Stonier 9f31491b0f bzlmodded (#1224) 2023-09-17 11:57:52 -04:00
Kefu Chai 016b2e7769 CI: test with supported C++ standards (#1226)
* CI: test with supported C++ standards

let's test with the supported standards for better coverage.
C++23 standard was just out, but the support on the toolchain is
not quite ready yet. so let's leave it for a future change.

Signed-off-by: Kefu Chai <tchaikov@gmail.com>

* CI: drop redundant Build step

"Build Tests" is strictly a superset of "Build". in addition to
the library, the former builds the tests also. both these
steps share the same set of command line arguments. by removing
"Build" step, we don't lose anything regarding the test coverage
and information for further investigation if the build fails.

Signed-off-by: Kefu Chai <tchaikov@gmail.com>

---------

Signed-off-by: Kefu Chai <tchaikov@gmail.com>
2023-09-10 08:38:51 -04:00
Kefu Chai 2383e6d0f2 Revert "node/convert: relax the check for string_view (#1222)" (#1225)
This reverts commit 6262201182.

in 62622011, we wanted address the needs to use the `string_view`
converter in C++98, but that requirement was based on wrong
preconditions. `std::string_view` was introduced in C++17, and
popular standard libraries like libstdc++ and libc++ both provide
`std::string_view` when the source is built with C++17.

furthermore 62622011 is buggy. because it uses `<version>` to tell
the feature set provided by the standard library. but `<version>`
is a part of C++20. so this defeats the purpose of the change of
62622011.

Fixes #1223
2023-09-10 08:28:52 -04:00
Kefu Chai 6262201182 node/convert: relax the check for string_view (#1222) 2023-09-06 07:57:12 -05:00
Gianfranco Costamagna fcbb8193b9 Fix testsuite with gcc-13 (#1216)
cd /<<PKGBUILDDIR>>/build-static/test && /usr/bin/c++ -DYAML_CPP_STATIC_DEFINE -I/<<PKGBUILDDIR>>/test/integration -I/<<PKGBUILDDIR>>/test -I/<<PKGBUILDDIR>>/src -I/<<PKGBUILDDIR>>/include -isystem /usr/src/googletest/googlemock/include -isystem /usr/src/googletest/googlemock -isystem /usr/src/googletest/googletest/include -isystem /usr/src/googletest/googletest -g -O2 -ffile-prefix-map=/<<PKGBUILDDIR>>=. -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -fdebug-prefix-map=/<<PKGBUILDDIR>>=/usr/src/yaml-cpp-0.8.0+dfsg-1~build1 -Wdate-time -D_FORTIFY_SOURCE=2 -std=gnu++14 -Wno-variadic-macros -Wno-sign-compare -DGTEST_HAS_PTHREAD=1 -MD -MT test/CMakeFiles/yaml-cpp-tests.dir/binary_test.cpp.o -MF CMakeFiles/yaml-cpp-tests.dir/binary_test.cpp.o.d -o CMakeFiles/yaml-cpp-tests.dir/binary_test.cpp.o -c /<<PKGBUILDDIR>>/test/binary_test.cpp
/<<PKGBUILDDIR>>/test/binary_test.cpp: In member function ‘virtual void BinaryTest_DecodingNoCrashOnNegative_Test::TestBody()’:
/<<PKGBUILDDIR>>/test/binary_test.cpp:11:38: error: narrowing conversion of ‘-58’ from ‘int’ to ‘char’ [-Wnarrowing]
   11 |   std::string input{-58, -1, -99, 109};
      |                                      ^
2023-08-19 15:36:16 -04:00
Craig Scott c268020048 Specify CMake policy range to avoid deprecation warning (#1211) 2023-08-16 17:54:05 -05:00
Jesse Beder f732014112 Bump version to 0.8.0. 2023-08-10 14:27:56 -05:00
Diogo Teles Sant'Anna f6c8b17c3a Create Security-Policy (#1189) 2023-08-10 15:02:27 -04:00
Kefu Chai 35b4498026 node/convert: support conversion for std::string_view (#1148) 2023-07-24 14:51:05 -05:00
Ryan b8882652fc Add namespace for the exported targets (#1196)
This matches the name for the ALIAS targets, and fixes #1025.
2023-06-28 11:37:09 -05:00
Jesse Beder 0e6e28d1a3 Revert "Move CTest to test entry (#1181)" (#1182)
This reverts commit 74f63c1181.
2023-03-22 19:14:49 -05:00
Jelin 74f63c1181 Move CTest to test entry (#1181) 2023-03-21 11:24:19 -05:00
Matthijs van der Burgh 987a604256 Delete .travis.yml (#1177) 2023-03-04 16:18:51 -06:00
Matthijs van der Burgh 55a8037daa (appveyor) remove, because testing windows in GH actions (#1176) 2023-03-04 14:07:09 -06:00
Matthijs van der Burgh 3ff7ab07ac Make sure tests are run in CI (#1170)
* Test(CMake) set NAME and COMMAND in add_test

* (CMake) add enable_testing()

* (CMake) move cmake_dependent_option up, before using them

* (CMake) use YAML_CPP_MAIN_PROJECT in cmake_dependent_option

* (CMake) log values regarding tests

* (CMake) always find CTest, but don't enable tests

* (CMAKE)(temp) fix logging

* (actions) set YAML_CPP_BUILD_TESTS for tests

* (actions) provide YAML_CPP_BUILD_TESTS to ctest

* (actions) set -DYAML_CPP_BUILD_TESTS at build

* (actions) don't fail false

* (actions) build tests in Test step

* (actions) run tests verbose

* (CMake) remove temp logging

* (actions) split building from running tests

* (actions) ctest Debug

* (actions) ctest Debug

* Remove enable_testing
2023-03-04 14:06:01 -06:00
Diogo Teles Sant'Anna d7f672d141 CI: define read-only permission for GitHub Workflow (#1175)
It secures the repo against erroneous or malicious actions from external jobs you call from your workflow. It's specially important for the case they get compromised, for example.
2023-03-03 23:33:51 -06:00
Matthijs van der Burgh bdc5582b35 Add tests for iterator and const_iterator on sequence (#1169) 2023-03-01 19:27:51 -06:00
James Brown 1b50109f7b Include property nodes in the long key check (#1140) 2022-10-04 18:51:53 -05:00
sfalmo 4ae4cb7309 Support conversion for std::valarray (#956) 2022-09-20 00:31:51 -05:00
Derzsi Dániel 97ebcf035a Export library directory and shared libs to CMake config (#1113)
This pull request adds two new exported variables to the CMake config:

YAML_CPP_LIBRARY_DIR - points to the directory containing the built library files
YAML_CPP_SHARED_LIBS_BUILT - boolean value, lets users know whether shared libraries were built or not
2022-09-20 00:26:59 -05:00
stephematician 85ad599d79 Basic update to CMakeLists.txt to address #1116 (#1117)
Add definitions to static yaml-cpp target (fixes #1116)

Also updates CONTRIBUTING instructions for tests
2022-09-20 00:24:35 -05:00
Baruch c86a9e424c Minimize warnings when not the top-level project (#1124)
Minimize warnings when not the top-level project

Should fix #970 and #764 when trying to add yaml-cpp to other project
2022-09-20 00:22:11 -05:00
Timo Gurr 255bf1f9bc Install pkgconfig and cmake files into arch-dependent locations (#1055) 2022-09-20 00:17:13 -05:00
rdzehtsiarandRoman Degtyar 763b7d6c70 Fix compilation errors in build for Oracle Solaris OS (#1133)
On Oracle Solaris the following statement is declared in file /usr/include/sys/regset.h:
#define SS 18 /* only stored on a privilege transition */

Because of this template type name SS is substituted by numeric literal, which results in a compilation error:
error: expected nested-name-specifier before numeric constant

Fixed by renaming template type names.

Co-authored-by: Roman Degtyar <Roman.Degtyar@veeam.com>
2022-09-20 00:04:18 -05:00
Skywol e87ed7e5b1 Add the "make uninstall" target (#1130) 2022-09-20 00:03:40 -05:00
Igor [hyperxor] c73ee34704 Small perfomance optimization in Directives and Tag methods (#1112) 2022-05-31 18:05:22 -05:00
Igor [hyperxor] 190ad502b5 Remove redundant include (#1110) 2022-05-21 07:20:18 -05:00
Dr. Andre Vehreschild 420c982310 Improve bazel build for Windows. (#1100)
Windows builds need some defines being set to use the static linking.

Also add bazel builds and test to Github-CI.
2022-04-27 09:10:13 -05:00
Dr. Andre Vehreschild 13626af92a Fix escaping anchors in keys (#1101) 2022-04-21 08:19:51 -05:00
Dr. Andre Vehreschild 4c982d59dc Improve build and fix single cr on windows (#1099) 2022-04-19 12:39:55 -05:00
SpaceIm 7d06655611 Allow yaml-cpp to be installed from another project (#1007)
Changes YAML_CPP_INSTALL from a cmake_dependent_option to an option.

Fixes #756, #847, and #1011.
2022-04-03 16:57:28 -05:00
xiaozhuai, Weihang Ding 0e6e98e8fb Extend options that disable testing and formatting to looking for dependencies also. (#1039)
The option `YAML_CPP_BUILD_TESTS` currently enables or disables building of tests; but unconditionally the CMake file includes CTest; this PR makes that conditional on the option.

Also, there is no option for enabling formatting, but it does check whether it can find the `clang-format` executable; this PR adds an option (default to true) that skips even looking for the executable if disabled.
2022-03-31 22:36:43 -05:00
Felix Schwitzer 4aad2b1666 Fix CMake export files (#1077)
After configuring the file `yaml-cpp-config.cmake.in`, the result ends up with
empty variables.  (see also the discussion in #774).

Rework this file and the call to `configure_package_config_file` according the
cmake documentation
(https://cmake.org/cmake/help/v3.22/module/CMakePackageConfigHelpers.html?highlight=configure_package_config#command:configure_package_config_file)
to overcome this issue and allow a simple `find_package` after install.

As there was some discussion about the place where to install the
`yaml-cpp-config.cmake` file, e.g. #1055, factor out the install location into
an extra variable to make it easier changing this location in the future.

Also untabify CMakeLists.txt in some places to align with the other code parts in this file.
2022-03-31 22:26:47 -05:00
Dr. Andre Vehreschild a6db7e32ac Fix single cr not recognized (#1094)
Complies with YAML Standard [5.4](https://yaml.org/spec/1.2.2/#54-line-break-characters) [25] instead of matching `\r` only in combination with `\n`.
2022-03-31 22:16:35 -05:00
Michael Martz 669af4eb55 Make YAML_MSVC_SHARED_RT depend on "CMAKE_SYSTEM_NAME MATCHES Windows" instead of "MSVC".
Fixes issue #1053.
2022-03-31 22:13:19 -05:00
Akash Patel edadfecdc6 Update gtest to 1.11.0 (#1086)
Properly resolves #1083, #996.
2022-02-17 12:08:56 -06:00
Sam4uk 26e3b70407 Update old style cast from (T) to static_cast<T>. 2022-02-08 16:06:36 -06:00
Christian Rauch cdf89fa352 set POSITION_INDEPENDENT_CODE if BUILD_SHARED_LIBS=OFF (#1076) 2022-01-27 17:03:10 -06:00
TheVice f8e1a7be3b Add MinGW to build pipeline
Also refactor the build action to use a matrix.
2022-01-27 17:00:08 -06:00
Chen bce601f2bf Support the conversion for std::unordered_map (#932) 2022-01-05 18:12:40 -06:00
TheVice d8d9419092 Fix shared library tests for Windows (#1074)
Add copying of shared library to the output directory with a test binary.

[binary] removed using of non unsigned char as argument at
'std::isspace' function that was provokes undefined behavior.

[.github/workflows/build.yml] enabled run of test at the
'windows-latest' environment.
2021-12-15 13:38:09 -06:00
Jesse Beder 974349d015 Fix typo in README about building shared libraries. 2021-12-10 08:54:35 -06:00
Jesse Beder 5057a53293 Fix github actions badge. 2021-11-22 22:44:31 -06:00
Jesse Beder 634578e477 Add github actions badge to README
This replaces the old Travis CI badge that didn't mean anything.
2021-11-22 22:42:51 -06:00
Pavel Karelin 2b65c65e1b Partially revert commit 0733aeb4 to make dll.h a non-generated file (#1064)
Partial revert of "Revert "Revert "Hide most of non-public symbols by default (#984)" (#1038)" (#1045)"

This reverts commit 0733aeb451.
2021-11-22 22:40:08 -06:00
Ryan Burns 328d2d85e8 Fix .pc paths for absolute GNUInstallDirs (#1058)
GNUInstallDirs provided may be absolute paths, in which case appending
to the install prefix is not correct. We can instead use the provided
CMAKE_INSTALL_FULL_* variables, which are precomputed absolute paths.

https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html
2021-11-02 21:34:46 -05:00
PhilipDeegan 4564d9a131 github actions for mac/linux/windows (#1056) 2021-10-31 11:59:40 -05:00
Robert Sebastian Herlim 2f8997565b Use static_cast<unsigned char> on DecodeBase64 to prevent SEGV on negative values (#1051) 2021-10-20 10:18:08 -05:00
Michał Janiszewski 1713859b05 Remove unused code from parse util (#1048) 2021-10-13 15:56:11 -05:00
João Marcos Bezerra 393a02a225 README.md revision (#732) 2021-10-09 22:02:35 -05:00
Pino Toscano 0733aeb451 Revert "Revert "Hide most of non-public symbols by default (#984)" (#1038)" (#1045) 2021-10-09 21:48:05 -05:00
Jesse Beder 0d9dbcfe8c Revert "Hide most of non-public symbols by default (#984)" (#1038)
This reverts commit da1c8d360e. and fixes #1036.
2021-09-28 08:41:55 -05:00
Pino Toscano da1c8d360e Hide most of non-public symbols by default (#984)
* Export YAML::detail::node::m_amount

The internal header node/detail/node.h is included by public headers;
YAML::detail::node is implemented in the header itself, and thus it gets
inlined... except for its static m_amount class member, which is
instantiated in the library only. Right now all the symbols of yaml-cpp
are exported (nothing is hidden), so the linker will find node::m_amount
in the yaml-cpp library.

As solution/workaround, explicitly export YAML::detail::node::m_amount.

* CMake: use GenerateExportHeader

Make use of the GenerateExportHeader CMake module to generate the dll.h
header with export macros.

While the produced dll.h is different, the result should be the same,
i.e. nothing changes for yaml-cpp or its users.

* CMake: hide all the symbols by default

Hide all the symbols that are not explicitly exported with YAML_CPP_API.
This way the ABI will be way smaller, and only actually exposing the
public classes/functions.
2021-09-25 12:10:58 -05:00
jwindgassen 6308112e54 Added UE-Wrapper link to Readme (#1024) 2021-08-30 06:11:08 -05:00
Snow Pettersen db6deedcd3 Include name of anchor in invalid anchor error (#1015) 2021-07-23 14:52:21 -05:00
mjvankampen 79aa6d53e5 Add assert to enable compilation with libcxx + gcc (#947) 2021-07-15 16:09:05 -05:00
jbeach ef0bba178d Bump minimum cmake versions in gtest to eliminate cmake deprecation warnings. (#1012) 2021-07-15 16:08:00 -05:00
JBPennington b591d8ae2a Update node impl.h for GCC unused variable warning (#981)
Removed the variable name in the defaulted function to make GCC happy.
2021-07-10 11:07:12 -05:00
411 changed files with 49050 additions and 48802 deletions
+1
View File
@@ -0,0 +1 @@
test/googletest-1.16.0
+1 -1
View File
@@ -8,7 +8,7 @@ EXAMPLE_PATH =
# One or more directories and files to exclude from documentation generation.
# Use relative paths with respect to the repository root directory.
EXCLUDE = test/gtest-1.8.0/
EXCLUDE = test/googletest-1.16.0/
# One or more wildcard patterns to exclude files and directories from document
# generation.
+25
View File
@@ -0,0 +1,25 @@
name: Quick CMake config
description: "Runs CMake 3.14+ (if already setup)"
inputs:
args:
description: "Other arguments"
required: false
default: ""
cmake-version:
description: "The CMake version to run"
required: true
runs:
using: composite
steps:
- name: CMake ${{ inputs.cmake-version }}
uses: jwlawson/actions-setup-cmake@v2.2
with:
cmake-version: "${{ inputs.cmake-version }}"
- run: |
mkdir -p build-tmp
touch build-tmp/tmp
rm -r build-tmp/*
(cd build-tmp && cmake .. ${{ inputs.args }})
rm -r build-tmp
shell: bash
+11
View File
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
groups:
github-actions:
patterns:
- "*"
+161
View File
@@ -0,0 +1,161 @@
name: Github PR
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
permissions: read-all
defaults:
run:
shell: bash
jobs:
cmake-build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest, windows-11-arm]
cxx_standard: [11, 20, 23]
build: [static, shared]
googletest: [build, system]
generator: ["Default Generator", "MinGW Makefiles"]
exclude:
- os: ubuntu-latest
cxx_standard: 11
googletest: system
- os: macos-latest
build: shared
- os: macos-latest
generator: "MinGW Makefiles"
- os: ubuntu-latest
generator: "MinGW Makefiles"
- os: macos-latest
googletest: system
- os: windows-latest
googletest: system
- os: windows-11-arm
googletest: system
env:
YAML_BUILD_SHARED_LIBS: ${{ matrix.build == 'shared' && 'ON' || 'OFF' }}
YAML_USE_SYSTEM_GTEST: ${{ matrix.googletest == 'system' && 'ON' || 'OFF' }}
CMAKE_GENERATOR: >-
${{format(matrix.generator != 'Default Generator' && '-G "{0}"' || '', matrix.generator)}}
CMAKE_INSTALL_PREFIX: "${{ github.workspace }}/install-prefix"
CMAKE_BUILD_TYPE: Debug
CMAKE_CXX_FLAGS_DEBUG: ${{ matrix.googletest == 'build' && '-g -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC' || '-g' }}
runs-on: ${{ matrix.os }}
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
if: matrix.os == 'ubuntu-latest'
with:
packages: googletest libgmock-dev libgtest-dev
version: 1.0
- uses: actions/checkout@v7
- name: Configure
run: |
cmake \
${{ env.CMAKE_GENERATOR }} \
-S "${{ github.workspace }}" \
-B build \
-D CMAKE_CXX_STANDARD=${{ matrix.cxx_standard }} \
-D CMAKE_INSTALL_PREFIX="${{ env.CMAKE_INSTALL_PREFIX }}" \
-D CMAKE_BUILD_TYPE=${{ env.CMAKE_BUILD_TYPE }} \
-D CMAKE_CXX_FLAGS_DEBUG="${{ env.CMAKE_CXX_FLAGS_DEBUG }}" \
-D YAML_BUILD_SHARED_LIBS=${{ env.YAML_BUILD_SHARED_LIBS }} \
-D YAML_USE_SYSTEM_GTEST=${{ env.YAML_USE_SYSTEM_GTEST }} \
-D YAML_CPP_BUILD_TESTS=ON
- name: Build
run: |
cmake \
--build build \
--config ${{ env.CMAKE_BUILD_TYPE }} \
--verbose \
--parallel
- name: Run Tests
shell: bash
run: |
ctest \
--test-dir build \
--build-config ${{ env.CMAKE_BUILD_TYPE }} \
--output-on-failure \
--verbose
- name: Install
run: cmake --install build --config ${{ env.CMAKE_BUILD_TYPE }}
- name: Configure CMake package test
run: |
cmake \
${{ env.CMAKE_GENERATOR }} \
-S "${{ github.workspace }}/test/cmake" \
-B consumer-build \
-D CMAKE_BUILD_TYPE=${{ env.CMAKE_BUILD_TYPE }} \
-D CMAKE_PREFIX_PATH="${{ env.CMAKE_INSTALL_PREFIX }}"
- name: Build CMake package test
run: |
cmake \
--build consumer-build \
--config ${{ env.CMAKE_BUILD_TYPE }} \
--verbose
cmake-config-oldest-cmake:
name: CMake version range config check (Ubuntu 24.04)
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
- name: Check CMake 3.15
uses: ./.github/actions/quick_cmake
with:
cmake-version: "3.15"
if: success() || failure()
- name: Check CMake 4.3
uses: ./.github/actions/quick_cmake
with:
cmake-version: "4.3"
if: success() || failure()
bazel-build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest, windows-11-arm]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- name: Build
run: |
cd "${{ github.workspace }}"
bazel build :all
- name: Test
run: |
cd "${{ github.workspace }}"
bazel test test
bzlmod-build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest, windows-11-arm]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- name: Build
shell: bash
run: |
cd "${{ github.workspace }}"
bazel build --enable_bzlmod :all
- name: Test
shell: bash
run: |
cd "${{ github.workspace }}"
bazel test --enable_bzlmod test
+19
View File
@@ -0,0 +1,19 @@
name: Bazel Release
on:
release:
types: [published]
jobs:
# A release archive is required for bzlmod
# See: https://blog.bazel.build/2023/02/15/github-archive-checksum.html
bazel-release-archive:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- run: git archive $GITHUB_REF -o "yaml-cpp-${GITHUB_REF:10}.tar.gz"
- run: gh release upload ${GITHUB_REF:10} "yaml-cpp-${GITHUB_REF:10}.tar.gz"
env:
GH_TOKEN: ${{ github.token }}
-37
View File
@@ -1,37 +0,0 @@
language: c++
matrix:
include:
- os: linux
compiler: gcc
- os: osx
compiler: clang
- os: osx
compiler: gcc
env:
- CTEST_OUTPUT_ON_FAILURE=1
before_script:
- mkdir build
- cd build
- cmake ..
- cd ..
script:
- cmake --build build
- cmake --build build --target test
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
packages:
- g++-4.9
- clang-3.9
update: true
homebrew:
packages:
- ccache
- gcc@4.9
- llvm@4
update: true
+18
View File
@@ -1,8 +1,24 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
yaml_cpp_defines = select({
# On Windows, ensure static linking is used.
"@platforms//os:windows": ["YAML_CPP_STATIC_DEFINE", "YAML_CPP_NO_CONTRIB"],
"//conditions:default": [],
})
yaml_copts = select({
"@platforms//os:windows": [],
"//conditions:default": [
"-fexceptions",
],
})
cc_library(
name = "yaml-cpp_internal",
visibility = ["//:__subpackages__"],
strip_include_prefix = "src",
hdrs = glob(["src/**/*.h"]),
copts = yaml_copts,
)
cc_library(
@@ -11,4 +27,6 @@ cc_library(
includes = ["include"],
hdrs = glob(["include/**/*.h"]),
srcs = glob(["src/**/*.cpp", "src/**/*.h"]),
defines = yaml_cpp_defines,
copts = yaml_copts,
)
+70 -51
View File
@@ -1,62 +1,62 @@
# 3.5 is actually available almost everywhere, but this a good minimum
cmake_minimum_required(VERSION 3.4)
cmake_minimum_required(VERSION 3.15..4.3)
# enable MSVC_RUNTIME_LIBRARY target property
# see https://cmake.org/cmake/help/latest/policy/CMP0091.html
if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
project(YAML_CPP VERSION 0.9.0 LANGUAGES CXX)
set(YAML_CPP_MAIN_PROJECT OFF)
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
set(YAML_CPP_MAIN_PROJECT ON)
endif()
project(YAML_CPP VERSION 0.7.0 LANGUAGES CXX)
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)
include(CheckCXXCompilerFlag)
include(GNUInstallDirs)
include(CTest)
find_program(YAML_CPP_CLANG_FORMAT_EXE NAMES clang-format)
option(YAML_CPP_BUILD_CONTRIB "Enable yaml-cpp contrib in library" ON)
option(YAML_CPP_BUILD_TOOLS "Enable parse tools" ON)
option(YAML_BUILD_SHARED_LIBS "Build yaml-cpp shared library" ${BUILD_SHARED_LIBS})
option(YAML_CPP_INSTALL "Enable generation of yaml-cpp install targets" ${YAML_CPP_MAIN_PROJECT})
option(YAML_CPP_FORMAT_SOURCE "Format source" ${YAML_CPP_MAIN_PROJECT})
option(YAML_CPP_DISABLE_UNINSTALL "Disable uninstallation of yaml-cpp" OFF)
option(YAML_USE_SYSTEM_GTEST "Use system googletest if found" OFF)
option(YAML_ENABLE_PIC "Use Position-Independent Code " ON)
option(YAML_CPP_USE_STRICT_FLAGS "Uses strict compilation flags e.g.: -Wall" ${YAML_CPP_MAIN_PROJECT})
cmake_dependent_option(YAML_CPP_BUILD_TESTS
"Enable yaml-cpp tests" ON
"BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
cmake_dependent_option(YAML_CPP_INSTALL
"Enable generation of yaml-cpp install targets" ON
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
"Enable yaml-cpp tests" OFF
"BUILD_TESTING;YAML_CPP_MAIN_PROJECT" OFF)
cmake_dependent_option(YAML_MSVC_SHARED_RT
"MSVC: Build yaml-cpp with shared runtime libs (/MD)" ON
"MSVC" OFF)
"CMAKE_SYSTEM_NAME MATCHES Windows" OFF)
set(YAML_CPP_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/yaml-cpp"
CACHE STRING "Path to install the CMake package to")
if (YAML_CPP_FORMAT_SOURCE)
find_program(YAML_CPP_CLANG_FORMAT_EXE NAMES clang-format)
endif()
set(yaml-cpp-type STATIC)
set(yaml-cpp-label-postfix "static")
if (YAML_BUILD_SHARED_LIBS)
set(yaml-cpp-type SHARED)
set(yaml-cpp-label-postfix "shared")
else()
set(yaml-cpp-type STATIC)
set(yaml-cpp-label-postfix "static")
endif()
set(build-shared $<BOOL:${YAML_BUILD_SHARED_LIBS}>)
set(build-windows-dll $<AND:$<BOOL:${CMAKE_HOST_WIN32}>,${build-shared}>)
set(not-msvc $<NOT:$<CXX_COMPILER_ID:MSVC>>)
set(msvc-shared_rt $<BOOL:${YAML_MSVC_SHARED_RT}>)
set(print-warnings $<NOT:$<OR:$<CXX_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:NVHPC>>>)
if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
set(CMAKE_MSVC_RUNTIME_LIBRARY
MultiThreaded$<$<CONFIG:Debug>:Debug>$<${msvc-shared_rt}:DLL>)
endif()
set(contrib-pattern "src/contrib/*.cpp")
set(src-pattern "src/*.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.12)
list(INSERT contrib-pattern 0 CONFIGURE_DEPENDS)
list(INSERT src-pattern 0 CONFIGURE_DEPENDS)
endif()
file(GLOB yaml-cpp-contrib-sources ${contrib-pattern})
file(GLOB yaml-cpp-sources ${src-pattern})
file(GLOB yaml-cpp-contrib-sources CONFIGURE_DEPENDS "src/contrib/*.cpp")
file(GLOB yaml-cpp-sources CONFIGURE_DEPENDS "src/*.cpp")
set(msvc-rt $<TARGET_PROPERTY:MSVC_RUNTIME_LIBRARY>)
@@ -66,8 +66,6 @@ set(msvc-rt-mt-static $<STREQUAL:${msvc-rt},MultiThreaded>)
set(msvc-rt-mtd-dll $<STREQUAL:${msvc-rt},MultiThreadedDebugDLL>)
set(msvc-rt-mt-dll $<STREQUAL:${msvc-rt},MultiThreadedDLL>)
set(backport-msvc-runtime $<VERSION_LESS:${CMAKE_VERSION},3.15>)
add_library(yaml-cpp ${yaml-cpp-type} "")
add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp)
@@ -78,6 +76,10 @@ set_property(TARGET yaml-cpp
PROPERTY
CXX_STANDARD_REQUIRED ON)
if (NOT YAML_BUILD_SHARED_LIBS)
set_property(TARGET yaml-cpp PROPERTY POSITION_INDEPENDENT_CODE ${YAML_ENABLE_PIC})
endif()
target_include_directories(yaml-cpp
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
@@ -91,16 +93,15 @@ if (NOT DEFINED CMAKE_CXX_STANDARD)
CXX_STANDARD 11)
endif()
if (YAML_CPP_USE_STRICT_FLAGS)
target_compile_options(yaml-cpp
PRIVATE
$<${print-warnings}:-Wall -Wextra -Wshadow -Weffc++ -Wno-long-long>
$<${print-warnings}:-pedantic -pedantic-errors>)
endif()
target_compile_options(yaml-cpp
PRIVATE
$<${not-msvc}:-Wall -Wextra -Wshadow -Weffc++ -Wno-long-long>
$<${not-msvc}:-pedantic -pedantic-errors>
$<$<AND:${backport-msvc-runtime},${msvc-rt-mtd-static}>:-MTd>
$<$<AND:${backport-msvc-runtime},${msvc-rt-mt-static}>:-MT>
$<$<AND:${backport-msvc-runtime},${msvc-rt-mtd-dll}>:-MDd>
$<$<AND:${backport-msvc-runtime},${msvc-rt-mt-dll}>:-MD>
# /wd4127 = disable warning C4127 "conditional expression is constant"
# http://msdn.microsoft.com/en-us/library/6t66728h.aspx
# /wd4355 = disable warning C4355 "'this' : used in base member initializer list
@@ -108,6 +109,8 @@ target_compile_options(yaml-cpp
$<$<CXX_COMPILER_ID:MSVC>:/W3 /wd4127 /wd4355>)
target_compile_definitions(yaml-cpp
PUBLIC
$<$<NOT:$<BOOL:${YAML_BUILD_SHARED_LIBS}>>:YAML_CPP_STATIC_DEFINE>
PRIVATE
$<${build-windows-dll}:${PROJECT_NAME}_DLL>
$<$<NOT:$<BOOL:${YAML_CPP_BUILD_CONTRIB}>>:YAML_CPP_NO_CONTRIB>)
@@ -127,10 +130,13 @@ set_target_properties(yaml-cpp PROPERTIES
PROJECT_LABEL "yaml-cpp ${yaml-cpp-label-postfix}"
DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}")
set(EXPORT_TARGETS yaml-cpp::yaml-cpp)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/yaml-cpp-config.cmake.in"
"${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/yaml-cpp")
INSTALL_DESTINATION "${YAML_CPP_INSTALL_CMAKEDIR}"
PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR)
unset(EXPORT_TARGETS)
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
@@ -139,36 +145,49 @@ write_basic_package_version_file(
configure_file(yaml-cpp.pc.in yaml-cpp.pc @ONLY)
if (YAML_CPP_INSTALL)
install(TARGETS yaml-cpp
install(TARGETS yaml-cpp
EXPORT yaml-cpp-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h")
FILES_MATCHING PATTERN "*.h")
install(EXPORT yaml-cpp-targets
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/yaml-cpp")
install(FILES
"${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake"
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/yaml-cpp")
NAMESPACE yaml-cpp::
DESTINATION "${YAML_CPP_INSTALL_CMAKEDIR}")
install(FILES
"${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake"
"${PROJECT_BINARY_DIR}/yaml-cpp-config-version.cmake"
DESTINATION "${YAML_CPP_INSTALL_CMAKEDIR}")
install(FILES "${PROJECT_BINARY_DIR}/yaml-cpp.pc"
DESTINATION ${CMAKE_INSTALL_DATADIR}/pkgconfig)
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()
if(YAML_CPP_BUILD_TESTS)
add_subdirectory(test)
add_subdirectory(test)
endif()
if(YAML_CPP_BUILD_TOOLS)
add_subdirectory(util)
add_subdirectory(util)
endif()
if (YAML_CPP_CLANG_FORMAT_EXE)
if (YAML_CPP_FORMAT_SOURCE AND YAML_CPP_CLANG_FORMAT_EXE)
add_custom_target(format
COMMAND clang-format --style=file -i $<TARGET_PROPERTY:yaml-cpp,SOURCES>
COMMAND_EXPAND_LISTS
COMMENT "Running clang-format"
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
VERBATIM)
endif()
# uninstall target
if(YAML_CPP_INSTALL AND NOT YAML_CPP_DISABLE_UNINSTALL AND NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
+11 -2
View File
@@ -17,10 +17,19 @@ Commit messages should be in the imperative mood, as described in the [Git contr
# Tests
Please verify the tests pass by running the target `tests/run_tests`.
Please verify the tests pass by configuring CMake with `-D YAML_CPP_BUILD_TESTS=ON` and running the target `test/yaml-cpp-tests`.
If you are adding functionality, add tests accordingly.
If you are adding functionality, add tests accordingly. Note that the "spec tests" are reserved for examples directly from the YAML spec, so if you have new examples, put them in other test files.
# Pull request process
Every pull request undergoes a code review. Unfortunately, github's code review process isn't great, but we'll manage. During the code review, if you make changes, add new commits to the pull request for each change. Once the code review is complete, rebase against the master branch and squash into a single commit.
# AI Usage
The following rules are in service of producing correct, maintainable code while not inundating the maintainers.
1. You (the author of the PR) are responsible for the PR, regardless of the tools you use to create it. Make sure you understand it thoroughly and agree with its contents before you submit a PR.
2. Corollary: AI is not a co-author, AI is a tool. If you wouldn't list Emacs as a co-author, don't list Claude either. (Maybe it will be someday, but not yet.)
3. Do not use AI to generate documentation. It's fine for code, but it's [painful](https://samkriss.substack.com/p/if-you-let-ai-do-your-writing-i-will) to read AI text.
4. No "low effort" AI PRs. Don't just paste an issue into Claude and ask it to fix it; don't just ask it for a vulnerability report. That's fine as a starting point, but if that's *all* you do, then you haven't provided any value; you've just added work for the maintainers, who could have easily pasted the issue into Claude themselves.
+14
View File
@@ -0,0 +1,14 @@
"""
yaml-cpp is a YAML parser and emitter in c++ matching the YAML specification.
"""
module(
name = "yaml-cpp",
compatibility_level = 1,
version = "0.8.0",
)
bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_cc", version = "0.2.14")
bazel_dep(name = "googletest", version = "1.17.0.bcr.2", dev_dependency = True)
+282
View File
@@ -0,0 +1,282 @@
{
"lockFileVersion": 24,
"registryFileHashes": {
"https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
"https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
"https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
"https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16",
"https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1",
"https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215",
"https://bcr.bazel.build/modules/abseil-cpp/20250512.1/source.json": "d725d73707d01bb46ab3ca59ba408b8e9bd336642ca77a2269d4bfb8bbfd413d",
"https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85",
"https://bcr.bazel.build/modules/apple_support/1.22.1/MODULE.bazel": "90bd1a660590f3ceffbdf524e37483094b29352d85317060b2327fff8f3f4458",
"https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442",
"https://bcr.bazel.build/modules/apple_support/1.23.1/source.json": "d888b44312eb0ad2c21a91d026753f330caa48a25c9b2102fae75eb2b0dcfdd2",
"https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
"https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
"https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d",
"https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d",
"https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a",
"https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58",
"https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b",
"https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65",
"https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d",
"https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87",
"https://bcr.bazel.build/modules/bazel_features/1.30.0/source.json": "b07e17f067fe4f69f90b03b36ef1e08fe0d1f3cac254c1241a1818773e3423bc",
"https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
"https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
"https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
"https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
"https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
"https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
"https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
"https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
"https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953",
"https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
"https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
"https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
"https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
"https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
"https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
"https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108",
"https://bcr.bazel.build/modules/googletest/1.17.0.bcr.2/MODULE.bazel": "827f54f492a3ce549c940106d73de332c2b30cebd0c20c0bc5d786aba7f116cb",
"https://bcr.bazel.build/modules/googletest/1.17.0.bcr.2/source.json": "3664514073a819992320ffbce5825e4238459df344d8b01748af2208f8d2e1eb",
"https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46",
"https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075",
"https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d",
"https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
"https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
"https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f",
"https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
"https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
"https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
"https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
"https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
"https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc",
"https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580",
"https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96",
"https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
"https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a",
"https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12",
"https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c",
"https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d",
"https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df",
"https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92",
"https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e",
"https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981",
"https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
"https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
"https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34",
"https://bcr.bazel.build/modules/pybind11_bazel/2.13.6/MODULE.bazel": "2d746fda559464b253b2b2e6073cb51643a2ac79009ca02100ebbc44b4548656",
"https://bcr.bazel.build/modules/pybind11_bazel/2.13.6/source.json": "6aa0703de8efb20cc897bbdbeb928582ee7beaf278bcd001ac253e1605bddfae",
"https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
"https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a",
"https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa",
"https://bcr.bazel.build/modules/re2/2025-08-12.bcr.1/MODULE.bazel": "e09b434b122bfb786a69179f9b325e35cb1856c3f56a7a81dd61609260ed46e1",
"https://bcr.bazel.build/modules/re2/2025-08-12.bcr.1/source.json": "a8ae7c09533bf67f9f6e5122d884d5741600b09d78dca6fc0f2f8d2ee0c2d957",
"https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
"https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e",
"https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
"https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002",
"https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191",
"https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac",
"https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc",
"https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87",
"https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a",
"https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
"https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f",
"https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
"https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
"https://bcr.bazel.build/modules/rules_cc/0.1.4/MODULE.bazel": "bb03a452a7527ac25a7518fb86a946ef63df860b9657d8323a0c50f8504fb0b9",
"https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8",
"https://bcr.bazel.build/modules/rules_cc/0.2.14/source.json": "55d0a4587c5592fad350f6e698530f4faf0e7dd15e69d43f8d87e220c78bea54",
"https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642",
"https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e",
"https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
"https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86",
"https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39",
"https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6",
"https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31",
"https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64",
"https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a",
"https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6",
"https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
"https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
"https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615",
"https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc",
"https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017",
"https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939",
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
"https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909",
"https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036",
"https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d",
"https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4",
"https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0",
"https://bcr.bazel.build/modules/rules_jvm_external/6.3/source.json": "6f5f5a5a4419ae4e37c35a5bb0a6ae657ed40b7abc5a5189111b47fcebe43197",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5",
"https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
"https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
"https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c",
"https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb",
"https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
"https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff",
"https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a",
"https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
"https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483",
"https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73",
"https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2",
"https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1",
"https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
"https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300",
"https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
"https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed",
"https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
"https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937",
"https://bcr.bazel.build/modules/rules_python/0.34.0/MODULE.bazel": "1d623d026e075b78c9fde483a889cda7996f5da4f36dffb24c246ab30f06513a",
"https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
"https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7",
"https://bcr.bazel.build/modules/rules_python/1.5.1/MODULE.bazel": "acfe65880942d44a69129d4c5c3122d57baaf3edf58ae5a6bd4edea114906bf5",
"https://bcr.bazel.build/modules/rules_python/1.5.1/source.json": "aa903e1bcbdfa1580f2b8e2d55100b7c18bc92d779ebb507fec896c75635f7bd",
"https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c",
"https://bcr.bazel.build/modules/rules_shell/0.2.0/source.json": "7f27af3c28037d9701487c4744b5448d26537cc66cdef0d8df7ae85411f8de95",
"https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
"https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
"https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef",
"https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c",
"https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7",
"https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5",
"https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216",
"https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
"https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9",
"https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca",
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806",
"https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198"
},
"selectedYankedVersions": {},
"moduleExtensions": {
"@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
"general": {
"bzlTransitiveDigest": "rL/34P1aFDq2GqVC2zCFgQ8nTuOC6ziogocpvG50Qz8=",
"usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {
"com_github_jetbrains_kotlin_git": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository",
"attributes": {
"urls": [
"https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip"
],
"sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88"
}
},
"com_github_jetbrains_kotlin": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository",
"attributes": {
"git_repository_name": "com_github_jetbrains_kotlin_git",
"compiler_version": "1.9.23"
}
},
"com_github_google_ksp": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository",
"attributes": {
"urls": [
"https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip"
],
"sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d",
"strip_version": "1.9.23-1.0.20"
}
},
"com_github_pinterest_ktlint": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985",
"urls": [
"https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint"
],
"executable": true
}
},
"rules_android": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
"strip_prefix": "rules_android-0.1.1",
"urls": [
"https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"
]
}
}
},
"recordedRepoMappingEntries": [
[
"rules_kotlin+",
"bazel_tools",
"bazel_tools"
]
]
}
},
"@@rules_python+//python/uv:uv.bzl%uv": {
"general": {
"bzlTransitiveDigest": "8vT1ddXtljNxYD0tJkksqzeKE6xqx4Ix+tXthAppjTI=",
"usagesDigest": "WYhzIw9khRBy34H1GxV5+fI1yi07O90NmCXosPUdHWQ=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {
"uv": {
"repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo",
"attributes": {
"toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'",
"toolchain_names": [
"none"
],
"toolchain_implementations": {
"none": "'@@rules_python+//python:none'"
},
"toolchain_compatible_with": {
"none": [
"@platforms//:incompatible"
]
},
"toolchain_target_settings": {}
}
}
},
"recordedRepoMappingEntries": [
[
"rules_python+",
"bazel_tools",
"bazel_tools"
],
[
"rules_python+",
"platforms",
"platforms"
]
]
}
}
},
"facts": {}
}
+48 -27
View File
@@ -1,54 +1,74 @@
# yaml-cpp [![Build Status](https://travis-ci.org/jbeder/yaml-cpp.svg?branch=master)](https://travis-ci.org/jbeder/yaml-cpp) [![Documentation](https://codedocs.xyz/jbeder/yaml-cpp.svg)](https://codedocs.xyz/jbeder/yaml-cpp/)
# yaml-cpp ![Build Status](https://github.com/jbeder/yaml-cpp/actions/workflows/build.yml/badge.svg) [![Documentation](https://codedocs.xyz/jbeder/yaml-cpp.svg)](https://codedocs.xyz/jbeder/yaml-cpp/)
yaml-cpp is a [YAML](http://www.yaml.org/) parser and emitter in C++ matching the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html).
`yaml-cpp` is a [YAML](http://www.yaml.org/) parser and emitter in C++ matching the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html).
To get a feel for how it can be used, see the [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) or [How to Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML). For the old API (version < 0.5.0), see [How To Parse A Document](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)).
## Usage
# Problems? #
See [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial) and [How to Emit YAML](https://github.com/jbeder/yaml-cpp/wiki/How-To-Emit-YAML) for reference. For the old API (until 0.5.0), see [How To Parse A Document](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)).
If you find a bug, post an [issue](https://github.com/jbeder/yaml-cpp/issues)! If you have questions about how to use yaml-cpp, please post it on http://stackoverflow.com and tag it [`yaml-cpp`](http://stackoverflow.com/questions/tagged/yaml-cpp).
## How to Build
# How to Build #
`yaml-cpp` uses [CMake](http://www.cmake.org) to support cross-platform building. Install [CMake](http://www.cmake.org) _(Resources -> Download)_ before proceeding. The basic steps to build are:
yaml-cpp uses [CMake](http://www.cmake.org) to support cross-platform building. The basic steps to build are:
**Note:** If you don't use the provided installer for your platform, make sure that you add `CMake`'s bin folder to your path.
1. Download and install [CMake](http://www.cmake.org) (Resources -> Download).
#### 1. Navigate into the source directory, create build folder and run `CMake`:
**Note:** If you don't use the provided installer for your platform, make sure that you add CMake's bin folder to your path.
2. Navigate into the source directory, and type:
```
```sh
mkdir build
cd build
cmake [-G generator] [-DYAML_BUILD_SHARED_LIBS=on|OFF] ..
```
3. Run CMake. The basic syntax is:
* The `generator` option is the build system you'd like to use. Run `cmake` without arguments to see a full list of available generators.
* On Windows, you might use "Visual Studio 12 2013" (VS 2013 32-bits), or "Visual Studio 14 2015 Win64" (VS 2015 64-bits).
* On OS X, you might use "Xcode".
* On a UNIX-like system, omit the option (for a Makefile).
```
cmake [-G generator] [-DYAML_BUILD_SHARED_LIBS=ON|OFF] ..
```
* `yaml-cpp` builds a static library by default, you may want to build a shared library by specifying `-DYAML_BUILD_SHARED_LIBS=ON`.
* The `generator` is whatever type of build system you'd like to use. To see a full list of generators on your platform, just run `cmake` (with no arguments). For example:
* On Windows, you might use "Visual Studio 12 2013" to generate a Visual Studio 2013 solution or "Visual Studio 14 2015 Win64" to generate a 64-bit Visual Studio 2015 solution.
* On OS X, you might use "Xcode" to generate an Xcode project
* On a UNIX-y system, simply omit the option to generate a makefile
* [Debug mode of the GNU standard C++
library](https://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html)
can be used when both `yaml-cpp` and client code is compiled with the
`_GLIBCXX_DEBUG` flag (e.g. by calling CMake with `-D
CMAKE_CXX_FLAGS_DEBUG='-g -D_GLIBCXX_DEBUG'` option).
* yaml-cpp defaults to building a static library, but you may build a shared library by specifying `-DYAML_BUILD_SHARED_LIBS=ON`.
Note that for `yaml-cpp` unit tests to run successfully, the _GoogleTest_
library also must be built with this flag, i.e. the system one cannot be
used (the _YAML_USE_SYSTEM_GTEST_ CMake option must be _OFF_, which is the
default).
* For more options on customizing the build, see the [CMakeLists.txt](https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt) file.
4. Build it!
#### 2. Build it!
* The command you'll need to run depends on the generator you chose earlier.
5. To clean up, just remove the `build` directory.
**Note:** To clean up, just remove the `build` directory.
# Recent Release #
## How to Integrate it within your project using CMake
[yaml-cpp 0.6.0](https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.6.0) has been released! This release requires C++11, and no longer depends on Boost.
You can use for example FetchContent :
```cmake
include(FetchContent)
FetchContent_Declare(
yaml-cpp
GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git
GIT_TAG <tag_name> # Can be a tag (yaml-cpp-x.x.x), a commit hash, or a branch name (master)
)
FetchContent_MakeAvailable(yaml-cpp)
target_link_libraries(YOUR_LIBRARY PUBLIC yaml-cpp::yaml-cpp) # The library or executable that require yaml-cpp library
```
## Recent Releases
[yaml-cpp 0.9.0](https://github.com/jbeder/yaml-cpp/releases/tag/yaml-cpp-0.9.0) released!
[yaml-cpp 0.3.0](https://github.com/jbeder/yaml-cpp/releases/tag/release-0.3.0) is still available if you want the old API.
**The old API will continue to be supported, and will still receive bugfixes!** The 0.3.x and 0.4.x versions will be old API releases, and 0.5.x and above will all be new API releases.
**The old API will stop receiving bugfixes in 2026.** The 0.3.x versions provide the old API, and 0.5.x and above all provide the new API.
# API Documentation
@@ -59,3 +79,4 @@ The autogenerated API reference is hosted on [CodeDocs](https://codedocs.xyz/jbe
The following projects are not officially supported:
- [Qt wrapper](https://gist.github.com/brcha/d392b2fe5f1e427cc8a6)
- [UnrealEngine Wrapper](https://github.com/jwindgassen/UnrealYAML)
+13
View File
@@ -0,0 +1,13 @@
# Security Policy
## Supported Versions
Security updates are applied only to the latest release.
## Reporting a Vulnerability
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
Please disclose it at [security advisory](https://github.com/jbeder/yaml-cpp/security/advisories/new).
This project is maintained by a team of volunteers on a reasonable-effort basis. As such, vulnerabilities will be disclosed in a best effort base.
-10
View File
@@ -1,10 +0,0 @@
workspace(name = "com_github_jbeder_yaml_cpp")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_google_googletest",
strip_prefix = "googletest-release-1.8.1",
url = "https://github.com/google/googletest/archive/release-1.8.1.tar.gz",
sha256 = "9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c",
)
-28
View File
@@ -1,28 +0,0 @@
version: 1.0.{build}
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_GENERATOR: Visual Studio 14 2015
CMAKE_PLATFORM: win32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_GENERATOR: Visual Studio 14 2015
CMAKE_PLATFORM: x64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017
CMAKE_PLATFORM: win32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017
CMAKE_PLATFORM: x64
before_build:
- cmd: mkdir build
- cmd: cd build
- cmd: cmake .. -G "%CMAKE_GENERATOR%" -DCMAKE_GENERATOR_PLATFORM=%CMAKE_PLATFORM%
- cmd: cd ..
build_script:
- cmake --build build
test_script:
- cmd: cd build
- ctest
+21
View File
@@ -0,0 +1,21 @@
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif()
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif()
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif()
endforeach()
+5 -9
View File
@@ -154,16 +154,11 @@ produces
# STL Containers, and Other Overloads #
We overload `operator <<` for `std::vector`, `std::list`, and `std::map`, so you can write stuff like:
{% raw %}
```cpp
std::vector <int> squares;
squares.push_back(1);
squares.push_back(4);
squares.push_back(9);
squares.push_back(16);
std::vector <int> squares = {1, 4, 9, 16};
std::map <std::string, int> ages;
ages["Daniel"] = 26;
ages["Jesse"] = 24;
std::map <std::string, int> ages = {{"Daniel", 26}, {"Jesse", 24}};
YAML::Emitter out;
out << YAML::BeginSeq;
@@ -171,6 +166,7 @@ out << YAML::Flow << squares;
out << ages;
out << YAML::EndSeq;
```
{% endraw %}
produces
@@ -227,4 +223,4 @@ assert(out.good());
out << YAML::Key;
assert(!out.good());
std::cout << "Emitter error: " << out.GetLastError() << "\n";
```
```
+52 -26
View File
@@ -1,33 +1,59 @@
#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
// Definition YAML_CPP_STATIC_DEFINE using to building YAML-CPP as static
// library (definition created by CMake or defined manually)
// Definition yaml_cpp_EXPORTS using to building YAML-CPP as dll/so library
// (definition created by CMake or defined manually)
#ifdef YAML_CPP_STATIC_DEFINE
# define YAML_CPP_API
# define YAML_CPP_NO_EXPORT
#else
# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
# ifndef YAML_CPP_API
# ifdef yaml_cpp_EXPORTS
/* We are building this library */
# define YAML_CPP_API __declspec(dllexport)
# else
/* We are using this library */
# define YAML_CPP_API __declspec(dllimport)
# endif
# endif
# ifndef YAML_CPP_NO_EXPORT
# define YAML_CPP_NO_EXPORT
# endif
# else /* No _MSC_VER */
# ifndef YAML_CPP_API
# ifdef yaml_cpp_EXPORTS
/* We are building this library */
# define YAML_CPP_API __attribute__((visibility("default")))
# else
/* We are using this library */
# define YAML_CPP_API __attribute__((visibility("default")))
# endif
# endif
# ifndef YAML_CPP_NO_EXPORT
# define YAML_CPP_NO_EXPORT __attribute__((visibility("hidden")))
# endif
# endif /* _MSC_VER */
#endif /* YAML_CPP_STATIC_DEFINE */
#ifndef YAML_CPP_DEPRECATED
# ifdef _MSC_VER
# define YAML_CPP_DEPRECATED __declspec(deprecated)
# else
# define YAML_CPP_DEPRECATED __attribute__ ((__deprecated__))
# endif
#endif
// The following ifdef block is the standard way of creating macros which make
// exporting from a DLL simpler. All files within this DLL are compiled with the
// yaml_cpp_EXPORTS symbol defined on the command line. This symbol should not
// be defined on any project that uses this DLL. This way any other project
// whose source files include this file see YAML_CPP_API functions as being
// imported from a DLL, whereas this DLL sees symbols defined with this macro as
// being exported.
#undef YAML_CPP_API
#ifndef YAML_CPP_DEPRECATED_EXPORT
# define YAML_CPP_DEPRECATED_EXPORT YAML_CPP_API YAML_CPP_DEPRECATED
#endif
#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined
// manually)
#ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake
// or defined manually)
// #pragma message( "Defining YAML_CPP_API for DLL export" )
#define YAML_CPP_API __declspec(dllexport)
#else // yaml_cpp_EXPORTS
// #pragma message( "Defining YAML_CPP_API for DLL import" )
#define YAML_CPP_API __declspec(dllimport)
#endif // yaml_cpp_EXPORTS
#else // YAML_CPP_DLL
#define YAML_CPP_API
#endif // YAML_CPP_DLL
#ifndef YAML_CPP_DEPRECATED_NO_EXPORT
# define YAML_CPP_DEPRECATED_NO_EXPORT YAML_CPP_NO_EXPORT YAML_CPP_DEPRECATED
#endif
#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#endif /* DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 */
+1
View File
@@ -23,6 +23,7 @@ class Emitter;
class EmitFromEvents : public EventHandler {
public:
EmitFromEvents(Emitter& emitter);
~EmitFromEvents() override = default;
void OnDocumentStart(const Mark& mark) override;
void OnDocumentEnd() override;
+34 -4
View File
@@ -9,18 +9,24 @@
#include <cmath>
#include <cstddef>
#include <cstring>
#include <limits>
#include <memory>
#include <sstream>
#include <string>
#include <type_traits>
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
#include <string_view>
#endif
#include "yaml-cpp/binary.h"
#include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterdef.h"
#include "yaml-cpp/emittermanip.h"
#include "yaml-cpp/null.h"
#include "yaml-cpp/ostream_wrapper.h"
#include "yaml-cpp/fptostring.h"
namespace YAML {
class Binary;
@@ -59,14 +65,17 @@ class YAML_CPP_API Emitter {
bool SetPostCommentIndent(std::size_t n);
bool SetFloatPrecision(std::size_t n);
bool SetDoublePrecision(std::size_t n);
bool SetShowTrailingZero(bool value);
void RestoreGlobalModifiedSettings();
// local setters
Emitter& SetLocalValue(EMITTER_MANIP value);
Emitter& SetLocalIndent(const _Indent& indent);
Emitter& SetLocalWrap(const _Wrap& wrap);
Emitter& SetLocalPrecision(const _Precision& precision);
// overloads of write
Emitter& Write(const char* str, std::size_t size);
Emitter& Write(const std::string& str);
Emitter& Write(bool b);
Emitter& Write(char ch);
@@ -88,6 +97,7 @@ class YAML_CPP_API Emitter {
void SetStreamablePrecision(std::stringstream&) {}
std::size_t GetFloatPrecision() const;
std::size_t GetDoublePrecision() const;
bool GetShowTrailingZero() const;
void PrepareIntegralStream(std::stringstream& stream) const;
void StartedScalar();
@@ -141,6 +151,7 @@ inline Emitter& Emitter::WriteIntegralType(T value) {
PrepareNode(EmitterNodeType::Scalar);
std::stringstream stream;
stream.imbue(std::locale::classic());
PrepareIntegralStream(stream);
stream << value;
m_stream << stream.str();
@@ -158,6 +169,7 @@ inline Emitter& Emitter::WriteStreamable(T value) {
PrepareNode(EmitterNodeType::Scalar);
std::stringstream stream;
stream.imbue(std::locale::classic());
SetStreamablePrecision<T>(stream);
bool special = false;
@@ -178,8 +190,17 @@ inline Emitter& Emitter::WriteStreamable(T value) {
}
if (!special) {
stream << value;
auto value_as_str = FpToString(value, static_cast<size_t>(stream.precision()));
if (GetShowTrailingZero()) {
bool isInScientificNotation = (value_as_str.find('e') != std::string::npos);
bool hasDot = (value_as_str.find('.') != std::string::npos);
if (!isInScientificNotation && !hasDot) {
value_as_str += ".0";
}
}
stream << value_as_str;
}
m_stream << stream.str();
StartedScalar();
@@ -198,8 +219,13 @@ inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) {
}
// overloads of insertion
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
inline Emitter& operator<<(Emitter& emitter, const std::string_view& v) {
return emitter.Write(v.data(), v.size());
}
#endif
inline Emitter& operator<<(Emitter& emitter, const std::string& v) {
return emitter.Write(v);
return emitter.Write(v.data(), v.size());
}
inline Emitter& operator<<(Emitter& emitter, bool v) {
return emitter.Write(v);
@@ -208,7 +234,7 @@ inline Emitter& operator<<(Emitter& emitter, char v) {
return emitter.Write(v);
}
inline Emitter& operator<<(Emitter& emitter, unsigned char v) {
return emitter.Write(static_cast<char>(v));
return emitter.WriteIntegralType(static_cast<unsigned int>(v));
}
inline Emitter& operator<<(Emitter& emitter, const _Alias& v) {
return emitter.Write(v);
@@ -230,7 +256,7 @@ inline Emitter& operator<<(Emitter& emitter, const Binary& b) {
}
inline Emitter& operator<<(Emitter& emitter, const char* v) {
return emitter.Write(std::string(v));
return emitter.Write(v, std::strlen(v));
}
inline Emitter& operator<<(Emitter& emitter, int v) {
@@ -273,6 +299,10 @@ inline Emitter& operator<<(Emitter& emitter, _Indent indent) {
return emitter.SetLocalIndent(indent);
}
inline Emitter& operator<<(Emitter& emitter, _Wrap wrap) {
return emitter.SetLocalWrap(wrap);
}
inline Emitter& operator<<(Emitter& emitter, _Precision precision) {
return emitter.SetLocalPrecision(precision);
}
+7
View File
@@ -76,6 +76,13 @@ struct _Indent {
inline _Indent Indent(int value) { return _Indent(value); }
struct _Wrap {
_Wrap(int value_) : value(value_) {}
int value;
};
inline _Wrap Wrap(int value) { return _Wrap(value); }
struct _Alias {
_Alias(const std::string& content_) : content(content_) {}
std::string content;
+4 -3
View File
@@ -8,9 +8,10 @@
#endif
namespace YAML {
struct EmitterStyle {
enum value { Default, Block, Flow };
};
namespace EmitterStyle {
enum value { Default, Block, Flow };
}
}
#endif // EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+30 -1
View File
@@ -48,6 +48,8 @@ const char* const UNKNOWN_TOKEN = "unknown token";
const char* const DOC_IN_SCALAR = "illegal document indicator in scalar";
const char* const EOF_IN_SCALAR = "illegal EOF in scalar";
const char* const CHAR_IN_SCALAR = "illegal character in scalar";
const char* const UNEXPECTED_SCALAR = "unexpected scalar";
const char* const UNEXPECTED_FLOW = "plain value cannot start with flow indicator character";
const char* const TAB_IN_INDENTATION =
"illegal tab when looking for indentation";
const char* const FLOW_END = "illegal flow end";
@@ -65,7 +67,7 @@ const char* const ZERO_INDENT_IN_BLOCK =
const char* const CHAR_IN_BLOCK = "unexpected character in block scalar";
const char* const AMBIGUOUS_ANCHOR =
"cannot assign the same alias to multiple nodes";
const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined";
const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined: ";
const char* const INVALID_NODE =
"invalid node; this may result from using a map iterator as a sequence "
@@ -87,6 +89,8 @@ const char* const INVALID_ANCHOR = "invalid anchor";
const char* const INVALID_ALIAS = "invalid alias";
const char* const INVALID_TAG = "invalid tag";
const char* const BAD_FILE = "bad file";
const char* const UNEXPECTED_TOKEN_AFTER_DOC = "unexpected token after end of document";
const char* const NON_UNIQUE_MAP_KEY = "map keys must be unique";
template <typename T>
inline const std::string KEY_NOT_FOUND_WITH_KEY(
@@ -298,6 +302,31 @@ class YAML_CPP_API BadFile : public Exception {
BadFile(const BadFile&) = default;
~BadFile() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API NonUniqueMapKey : public RepresentationException {
public:
template <typename Key>
NonUniqueMapKey(const Mark& mark_, const Key& /*key*/)
: RepresentationException(mark_, ErrorMsg::NON_UNIQUE_MAP_KEY) {}
NonUniqueMapKey(const NonUniqueMapKey&) = default;
~NonUniqueMapKey() YAML_CPP_NOEXCEPT override;
};
} // namespace YAML
#if defined(_MSC_VER)
#define YAML_ATTRIBUTE_NO_SANITIZE_ADDRESS __declspec(no_sanitize_address)
#elif defined(__has_cpp_attribute) && __has_cpp_attribute(gnu::no_sanitize)
#define YAML_ATTRIBUTE_NO_SANITIZE_ADDRESS [[gnu::no_sanitize("address")]]
#elif defined(__has_cpp_attribute) && __has_cpp_attribute(clang::no_sanitize)
#define YAML_ATTRIBUTE_NO_SANITIZE_ADDRESS [[clang::no_sanitize("address")]]
#elif defined(__has_attribute) && __has_attribute(no_sanitize)
#define YAML_ATTRIBUTE_NO_SANITIZE_ADDRESS \
__attribute__((no_sanitize("address")))
#elif defined(__has_attribute) && __has_attribute(no_sanitize_address)
#define YAML_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
#else
#define YAML_ATTRIBUTE_NO_SANITIZE_ADDRESS
#endif
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+15
View File
@@ -0,0 +1,15 @@
#ifndef YAML_H_FPTOSTRING
#define YAML_H_FPTOSTRING
#include "yaml-cpp/dll.h"
#include <string>
namespace YAML {
// "precision = 0" refers to shortest known unique representation of the value
YAML_CPP_API std::string FpToString(float v, size_t precision = 0);
YAML_CPP_API std::string FpToString(double v, size_t precision = 0);
YAML_CPP_API std::string FpToString(long double v, size_t precision = 0);
}
#endif
+119 -3
View File
@@ -12,16 +12,24 @@
#include <limits>
#include <list>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <type_traits>
#include <valarray>
#include <vector>
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
#include <string_view>
#endif
#include "yaml-cpp/binary.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/type.h"
#include "yaml-cpp/null.h"
#include "yaml-cpp/fptostring.h"
namespace YAML {
@@ -87,6 +95,20 @@ struct convert<char[N]> {
static Node encode(const char* rhs) { return Node(rhs); }
};
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
template <>
struct convert<std::string_view> {
static Node encode(std::string_view rhs) { return Node(std::string(rhs)); }
static bool decode(const Node& node, std::string_view& rhs) {
if (!node.IsScalar())
return false;
rhs = node.Scalar();
return true;
}
};
#endif
template <>
struct convert<_Null> {
static Node encode(const _Null& /* rhs */) { return Node(); }
@@ -109,7 +131,7 @@ inner_encode(const T& rhs, std::stringstream& stream){
stream << ".inf";
}
} else {
stream << rhs;
stream << FpToString(rhs, static_cast<size_t>(stream.precision()));
}
}
@@ -127,7 +149,7 @@ ConvertStreamTo(std::stringstream& stream, T& rhs) {
if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) {
if (num >= (std::numeric_limits<T>::min)() &&
num <= (std::numeric_limits<T>::max)()) {
rhs = (T)num;
rhs = static_cast<T>(num);
return true;
}
}
@@ -143,6 +165,15 @@ ConvertStreamTo(std::stringstream& stream, T& rhs) {
}
return false;
}
// Rewrite a valid YAML 1.2 octal scalar ("0o14") to the stream-parseable "014".
inline std::string NormalizeOctalPrefix(std::string s) {
if (s.size() > 2 && s[0] == '0' && (s[1] == 'o' || s[1] == 'O') &&
s.find_first_not_of("01234567", 2) == std::string::npos) {
s.erase(1, 1);
}
return s;
}
}
#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \
@@ -151,6 +182,7 @@ ConvertStreamTo(std::stringstream& stream, T& rhs) {
\
static Node encode(const type& rhs) { \
std::stringstream stream; \
stream.imbue(std::locale::classic()); \
stream.precision(std::numeric_limits<type>::max_digits10); \
conversion::inner_encode(rhs, stream); \
return Node(stream.str()); \
@@ -161,7 +193,8 @@ ConvertStreamTo(std::stringstream& stream, T& rhs) {
return false; \
} \
const std::string& input = node.Scalar(); \
std::stringstream stream(input); \
std::stringstream stream(conversion::NormalizeOctalPrefix(input)); \
stream.imbue(std::locale::classic()); \
stream.unsetf(std::ios::dec); \
if ((stream.peek() == '-') && std::is_unsigned<type>::value) { \
return false; \
@@ -251,6 +284,58 @@ struct convert<std::map<K, V, C, A>> {
}
};
// std::unordered_map
template <typename K, typename V, typename H, typename P, typename A>
struct convert<std::unordered_map<K, V, H, P, A>> {
static Node encode(const std::unordered_map<K, V, H, P, A>& rhs) {
Node node(NodeType::Map);
for (const auto& element : rhs)
node.force_insert(element.first, element.second);
return node;
}
static bool decode(const Node& node, std::unordered_map<K, V, H, P, A>& rhs) {
if (!node.IsMap())
return false;
rhs.clear();
for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs[element.first.template as<K>()] = element.second.template as<V>();
#else
rhs[element.first.as<K>()] = element.second.as<V>();
#endif
return true;
}
};
// std::unordered_set
template <typename T, typename H, typename P, typename A>
struct convert<std::unordered_set<T, H, P, A>> {
static Node encode(const std::unordered_set<T, H, P, A>& rhs) {
Node node(NodeType::Sequence);
for (const auto& element : rhs)
node.push_back(element);
return node;
}
static bool decode(const Node& node, std::unordered_set<T, H, P, A>& rhs) {
if (!node.IsSequence())
return false;
rhs.clear();
for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs.insert(element.template as<T>());
#else
rhs.insert(element.as<T>());
#endif
return true;
}
};
// std::vector
template <typename T, typename A>
struct convert<std::vector<T, A>> {
@@ -336,6 +421,37 @@ struct convert<std::array<T, N>> {
}
};
// std::valarray
template <typename T>
struct convert<std::valarray<T>> {
static Node encode(const std::valarray<T>& rhs) {
Node node(NodeType::Sequence);
for (const auto& element : rhs) {
node.push_back(element);
}
return node;
}
static bool decode(const Node& node, std::valarray<T>& rhs) {
if (!node.IsSequence()) {
return false;
}
rhs.resize(node.size());
for (auto i = 0u; i < node.size(); ++i) {
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs[i] = node[i].template as<T>();
#else
rhs[i] = node[i].as<T>();
#endif
}
return true;
}
};
// std::pair
template <typename T, typename U>
struct convert<std::pair<T, U>> {
+2 -2
View File
@@ -43,7 +43,7 @@ struct get_idx<Key,
};
template <typename Key>
struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value && std::is_integral<Key>::value>::type> {
static node* get(const std::vector<node*>& sequence, const Key& key,
shared_memory_holder pMemory) {
return key >= 0 ? get_idx<std::size_t>::get(
@@ -218,7 +218,7 @@ inline void node_data::force_insert(const Key& key, const Value& value,
node& k = convert_to_node(key, pMemory);
node& v = convert_to_node(value, pMemory);
insert_map_pair(k, v);
insert_map_pair(k, v, true);
}
template <typename T>
+11 -5
View File
@@ -30,8 +30,12 @@ class iterator_base {
struct proxy {
explicit proxy(const V& x) : m_ref(x) {}
V* operator->() { return std::addressof(m_ref); }
operator V*() { return std::addressof(m_ref); }
V* operator->() YAML_ATTRIBUTE_LIFETIME_BOUND {
return std::addressof(m_ref);
}
operator V*() YAML_ATTRIBUTE_LIFETIME_BOUND {
return std::addressof(m_ref);
}
V m_ref;
};
@@ -41,7 +45,7 @@ class iterator_base {
using value_type = V;
using difference_type = std::ptrdiff_t;
using pointer = V*;
using reference = V;
using reference = V&;
public:
iterator_base() : m_iterator(), m_pMemory() {}
@@ -75,7 +79,7 @@ class iterator_base {
return m_iterator != rhs.m_iterator;
}
value_type operator*() const {
value_type operator*() const YAML_ATTRIBUTE_LIFETIME_BOUND {
const typename base_type::value_type& v = *m_iterator;
if (v.pNode)
return value_type(Node(*v, m_pMemory));
@@ -84,7 +88,9 @@ class iterator_base {
return value_type();
}
proxy operator->() const { return proxy(**this); }
proxy operator->() const YAML_ATTRIBUTE_LIFETIME_BOUND {
return proxy(**this);
}
private:
base_type m_iterator;
+2 -1
View File
@@ -25,6 +25,7 @@ class YAML_CPP_API memory {
memory() : m_nodes{} {}
node& create_node();
void merge(const memory& rhs);
size_t size() const;
private:
using Nodes = std::set<shared_node>;
@@ -33,7 +34,7 @@ class YAML_CPP_API memory {
class YAML_CPP_API memory_holder {
public:
memory_holder() : m_pMemory(new memory) {}
memory_holder() : m_pMemory(std::make_shared<memory>()) {}
node& create_node() { return m_pMemory->create_node(); }
void merge(memory_holder& rhs);
+2 -2
View File
@@ -24,7 +24,7 @@ class node {
};
public:
node() : m_pRef(new node_ref), m_dependencies{}, m_index{} {}
node() : m_pRef(std::make_shared<node_ref>()), m_dependencies{}, m_index{} {}
node(const node&) = delete;
node& operator=(const node&) = delete;
@@ -169,7 +169,7 @@ class node {
using nodes = std::set<node*, less>;
nodes m_dependencies;
size_t m_index;
static std::atomic<size_t> m_amount;
static YAML_CPP_API std::atomic<size_t> m_amount;
};
} // namespace detail
} // namespace YAML
+1 -1
View File
@@ -90,7 +90,7 @@ class YAML_CPP_API node_data {
void reset_sequence();
void reset_map();
void insert_map_pair(node& key, node& value);
void insert_map_pair(node& key, node& value, bool force = false);
void convert_to_map(const shared_memory_holder& pMemory);
void convert_sequence_to_map(const shared_memory_holder& pMemory);
+7 -3
View File
@@ -58,8 +58,12 @@ class node_iterator_base {
struct proxy {
explicit proxy(const node_iterator_value<V>& x) : m_ref(x) {}
node_iterator_value<V>* operator->() { return std::addressof(m_ref); }
operator node_iterator_value<V>*() { return std::addressof(m_ref); }
node_iterator_value<V>* operator->() YAML_ATTRIBUTE_LIFETIME_BOUND {
return std::addressof(m_ref);
}
operator node_iterator_value<V>*() YAML_ATTRIBUTE_LIFETIME_BOUND {
return std::addressof(m_ref);
}
node_iterator_value<V> m_ref;
};
@@ -69,7 +73,7 @@ class node_iterator_base {
using value_type = node_iterator_value<V>;
using difference_type = std::ptrdiff_t;
using pointer = node_iterator_value<V>*;
using reference = node_iterator_value<V>;
using reference = node_iterator_value<V>&;
using SeqIter = typename node_iterator_type<V>::seq;
using MapIter = typename node_iterator_type<V>::map;
+1 -1
View File
@@ -16,7 +16,7 @@ namespace YAML {
namespace detail {
class node_ref {
public:
node_ref() : m_pData(new node_data) {}
node_ref() : m_pData(std::make_shared<node_data>()) {}
node_ref(const node_ref&) = delete;
node_ref& operator=(const node_ref&) = delete;
+30 -6
View File
@@ -22,7 +22,7 @@ inline Node::Node()
inline Node::Node(NodeType::value type)
: m_isValid(true),
m_invalidKey{},
m_pMemory(new detail::memory_holder),
m_pMemory(std::make_shared<detail::memory_holder>()),
m_pNode(&m_pMemory->create_node()) {
m_pNode->set_type(type);
}
@@ -31,7 +31,7 @@ template <typename T>
inline Node::Node(const T& rhs)
: m_isValid(true),
m_invalidKey{},
m_pMemory(new detail::memory_holder),
m_pMemory(std::make_shared<detail::memory_holder>()),
m_pNode(&m_pMemory->create_node()) {
Assign(rhs);
}
@@ -42,7 +42,7 @@ inline Node::Node(const detail::iterator_value& rhs)
m_pMemory(rhs.m_pMemory),
m_pNode(rhs.m_pNode) {}
inline Node::Node(const Node& rhs) = default;
inline Node::Node(const Node&) = default;
inline Node::Node(Zombie)
: m_isValid(false), m_invalidKey{}, m_pMemory{}, m_pNode(nullptr) {}
@@ -65,6 +65,12 @@ inline void Node::EnsureNodeExists() const {
}
}
inline void Node::Invalidate() {
m_isValid = false;
m_pNode = nullptr;
m_pMemory = nullptr;
}
inline bool Node::IsDefined() const {
if (!m_isValid) {
return false;
@@ -97,7 +103,7 @@ struct as_if {
if (!node.m_pNode)
return fallback;
T t;
T t = fallback;
if (convert<T>::decode(node, t))
return t;
return fallback;
@@ -124,8 +130,8 @@ struct as_if<T, void> {
const Node& node;
T operator()() const {
if (!node.m_pNode)
throw TypedBadConversion<T>(node.Mark());
if (!node.m_pNode) // no fallback
throw InvalidNode(node.m_invalidKey);
T t;
if (convert<T>::decode(node, t))
@@ -140,6 +146,8 @@ struct as_if<std::string, void> {
const Node& node;
std::string operator()() const {
if (node.Type() == NodeType::Undefined) // no fallback
throw InvalidNode(node.m_invalidKey);
if (node.Type() == NodeType::Null)
return "null";
if (node.Type() != NodeType::Scalar)
@@ -169,6 +177,14 @@ inline const std::string& Node::Scalar() const {
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar();
}
YAML_ATTRIBUTE_NO_SANITIZE_ADDRESS
inline const std::string& Node::UninstrumentedScalarForTesting() const {
if (m_isValid && m_pMemory != nullptr && m_pNode != nullptr)
throw InvalidNode("use-after-free");
else
throw BadDereference();
}
inline const std::string& Node::Tag() const {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
@@ -378,6 +394,14 @@ inline void Node::force_insert(const Key& key, const Value& value) {
m_pNode->force_insert(key, value, m_pMemory);
}
template <typename Key>
inline bool Node::contains(const Key& key) const {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
if (!m_pNode) return false;
return (static_cast<const detail::node*>(m_pNode))->get(key, m_pMemory) != nullptr;
}
// free functions
inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
} // namespace YAML
+8
View File
@@ -15,6 +15,9 @@
#include <utility>
#include <vector>
// Assert in place so gcc + libc++ combination properly builds
static_assert(std::is_constructible<YAML::Node, const YAML::Node&>::value, "Node must be copy constructable");
namespace YAML {
namespace detail {
struct iterator_value : public Node, std::pair<Node, Node> {
@@ -24,6 +27,11 @@ struct iterator_value : public Node, std::pair<Node, Node> {
std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {}
explicit iterator_value(const Node& key, const Node& value)
: Node(Node::ZombieNode), std::pair<Node, Node>(key, value) {}
~iterator_value() noexcept {
this->Node::Invalidate();
first.Invalidate();
second.Invalidate();
}
};
}
}
+5
View File
@@ -67,6 +67,7 @@ class YAML_CPP_API Node {
template <typename T, typename S>
T as(const S& fallback) const;
const std::string& Scalar() const;
const std::string& UninstrumentedScalarForTesting() const;
const std::string& Tag() const;
void SetTag(const std::string& tag);
@@ -113,6 +114,9 @@ class YAML_CPP_API Node {
template <typename Key, typename Value>
void force_insert(const Key& key, const Value& value);
template <typename Key>
bool contains(const Key& key) const;
private:
enum Zombie { ZombieNode };
explicit Node(Zombie);
@@ -120,6 +124,7 @@ class YAML_CPP_API Node {
explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
void EnsureNodeExists() const;
void Invalidate();
template <typename T>
void Assign(const T& rhs);
+12 -1
View File
@@ -7,7 +7,6 @@
#pragma once
#endif
#include "yaml-cpp/dll.h"
#include <memory>
namespace YAML {
@@ -26,4 +25,16 @@ using shared_memory = std::shared_ptr<memory>;
}
}
#if defined(__has_cpp_attribute) && __has_cpp_attribute(msvc::lifetimebound)
#define YAML_ATTRIBUTE_LIFETIME_BOUND [[msvc::lifetimebound]]
#elif defined(__has_cpp_attribute) && __has_cpp_attribute(gnu::lifetimebound)
#define YAML_ATTRIBUTE_LIFETIME_BOUND [[gnu::lifetimebound]]
#elif defined(__has_cpp_attribute) && __has_cpp_attribute(clang::lifetimebound)
#define YAML_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
#elif defined(__has_attribute) && __has_attribute(lifetimebound)
#define YAML_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
#else
#define YAML_ATTRIBUTE_LIFETIME_BOUND
#endif
#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+4 -3
View File
@@ -8,9 +8,10 @@
#endif
namespace YAML {
struct NodeType {
enum value { Undefined, Null, Scalar, Sequence, Map };
};
namespace NodeType {
enum value { Undefined, Null, Scalar, Sequence, Map };
}
}
#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+2 -2
View File
@@ -8,7 +8,7 @@
#endif
#include "yaml-cpp/dll.h"
#include <string>
#include <cstddef>
namespace YAML {
class Node;
@@ -18,7 +18,7 @@ inline bool operator==(const _Null&, const _Null&) { return true; }
inline bool operator!=(const _Null&, const _Null&) { return false; }
YAML_CPP_API bool IsNull(const Node& node); // old API only
YAML_CPP_API bool IsNullString(const std::string& str);
YAML_CPP_API bool IsNullString(const char* str, std::size_t size);
extern YAML_CPP_API _Null Null;
}
+1
View File
@@ -7,6 +7,7 @@
#pragma once
#endif
#include <ostream>
#include <string>
#include <vector>
+2 -1
View File
@@ -7,8 +7,9 @@
#pragma once
#endif
#include <ios>
#include <istream>
#include <memory>
#include <ostream>
#include "yaml-cpp/dll.h"
+3 -2
View File
@@ -107,9 +107,9 @@ struct disable_if : public disable_if_c<Cond::value, T> {};
template <typename S, typename T>
struct is_streamable {
template <typename SS, typename TT>
template <typename StreamT, typename ValueT>
static auto test(int)
-> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
-> decltype(std::declval<StreamT&>() << std::declval<ValueT>(), std::true_type());
template <typename, typename>
static auto test(...) -> std::false_type;
@@ -121,6 +121,7 @@ template<typename Key, bool Streamable>
struct streamable_to_string {
static std::string impl(const Key& key) {
std::stringstream ss;
ss.imbue(std::locale::classic());
ss << key;
return ss.str();
}
+4
View File
@@ -7,6 +7,8 @@
#pragma once
#endif
// IWYU pragma: begin_exports
#include "yaml-cpp/parser.h"
#include "yaml-cpp/emitter.h"
#include "yaml-cpp/emitterstyle.h"
@@ -21,4 +23,6 @@
#include "yaml-cpp/node/parse.h"
#include "yaml-cpp/node/emit.h"
// IWYU pragma: end_exports
#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+12 -5
View File
@@ -74,24 +74,31 @@ std::vector<unsigned char> DecodeBase64(const std::string &input) {
unsigned char *out = &ret[0];
unsigned value = 0;
for (std::size_t i = 0, cnt = 0; i < input.size(); i++) {
if (std::isspace(input[i])) {
std::size_t cnt = 0;
for (std::size_t i = 0; i < input.size(); i++) {
if (std::isspace(static_cast<unsigned char>(input[i]))) {
// skip newlines
continue;
}
unsigned char d = decoding[static_cast<unsigned>(input[i])];
unsigned char d = decoding[static_cast<unsigned char>(input[i])];
if (d == 255)
return ret_type();
value = (value << 6) | d;
if (cnt % 4 == 3) {
if (cnt == 3) {
*out++ = value >> 16;
if (i > 0 && input[i - 1] != '=')
*out++ = value >> 8;
if (input[i] != '=')
*out++ = value;
cnt = 0;
} else {
++cnt;
}
++cnt;
}
if (cnt != 0) {
// An invalid number of characters were encountered.
return ret_type();
}
ret.resize(out - &ret[0]);
File diff suppressed because it is too large Load Diff
-1
View File
@@ -13,7 +13,6 @@
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/contrib/anchordict.h"
#include "yaml-cpp/contrib/graphbuilder.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
+1 -1
View File
@@ -3,7 +3,7 @@
namespace YAML {
Directives::Directives() : version{true, 1, 2}, tags{} {}
const std::string Directives::TranslateTagHandle(
std::string Directives::TranslateTagHandle(
const std::string& handle) const {
auto it = tags.find(handle);
if (it == tags.end()) {
+1 -1
View File
@@ -19,7 +19,7 @@ struct Version {
struct Directives {
Directives();
const std::string TranslateTagHandle(const std::string& handle) const;
std::string TranslateTagHandle(const std::string& handle) const;
Version version;
std::map<std::string, std::string> tags;
+22 -2
View File
@@ -116,8 +116,28 @@ void EmitFromEvents::BeginNode() {
}
void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) {
if (!tag.empty() && tag != "?" && tag != "!")
m_emitter << VerbatimTag(tag);
if (!tag.empty() && tag != "?" && tag != "!"){
if (tag.size() >= 2 && tag[0] == '!' && tag[1] == '!') {
// Tags like "!!str" use the secondary tag handle; emit them through
// SecondaryTag so the rendered output keeps both bangs instead of
// failing the LocalTag regex check on the inner '!'. See #1373.
m_emitter << SecondaryTag(std::string(tag.begin()+2, tag.end()));
} else if (tag[0] == '!') {
auto prefix_end = tag.begin() + 1;
while (prefix_end != tag.end() && *prefix_end != '!') {
++prefix_end;
}
if (prefix_end == tag.end()) {
m_emitter << LocalTag(std::string(tag.begin() + 1, tag.end()));
}
else {
m_emitter << LocalTag(std::string(tag.begin() + 1, prefix_end),
std::string(prefix_end + 1, tag.end()));
}
} else {
m_emitter << VerbatimTag(tag);
}
}
if (anchor)
m_emitter << Anchor(ToString(anchor));
}
+57 -13
View File
@@ -90,6 +90,10 @@ bool Emitter::SetDoublePrecision(std::size_t n) {
return m_pState->SetDoublePrecision(n, FmtScope::Global);
}
bool Emitter::SetShowTrailingZero(bool value) {
return m_pState->SetShowTrailingZero(value, FmtScope::Global);
}
void Emitter::RestoreGlobalModifiedSettings() {
m_pState->RestoreGlobalModifiedSettings();
}
@@ -141,6 +145,11 @@ Emitter& Emitter::SetLocalIndent(const _Indent& indent) {
return *this;
}
Emitter& Emitter::SetLocalWrap(const _Wrap& wrap) {
m_pState->SetWrap(wrap.value, FmtScope::Local);
return *this;
}
Emitter& Emitter::SetLocalPrecision(const _Precision& precision) {
if (precision.floatPrecision >= 0)
m_pState->SetFloatPrecision(precision.floatPrecision, FmtScope::Local);
@@ -213,7 +222,8 @@ void Emitter::EmitEndSeq() {
if (m_pState->CurGroupFlowType() == FlowType::Flow) {
if (m_stream.comment())
m_stream << "\n";
m_stream << IndentTo(m_pState->CurIndent());
if (originalType == FlowType::Block || m_pState->HasBegunNode())
m_stream << IndentTo(m_pState->CurIndent());
if (originalType == FlowType::Block) {
m_stream << "[";
} else {
@@ -533,7 +543,8 @@ void Emitter::BlockMapPrepareNode(EmitterNodeType::value child) {
if (m_pState->GetMapKeyFormat() == LongKey)
m_pState->SetLongKey();
if (child == EmitterNodeType::BlockSeq ||
child == EmitterNodeType::BlockMap)
child == EmitterNodeType::BlockMap ||
child == EmitterNodeType::Property)
m_pState->SetLongKey();
if (m_pState->CurGroupLongKey())
@@ -714,33 +725,33 @@ StringEscaping::value GetStringEscapingStyle(const EMITTER_MANIP emitterManip) {
}
}
Emitter& Emitter::Write(const std::string& str) {
Emitter& Emitter::Write(const char* str, std::size_t size) {
if (!good())
return *this;
StringEscaping::value stringEscaping = GetStringEscapingStyle(m_pState->GetOutputCharset());
const StringFormat::value strFormat =
Utils::ComputeStringFormat(str, m_pState->GetStringFormat(),
Utils::ComputeStringFormat(str, size, m_pState->GetStringFormat(),
m_pState->CurGroupFlowType(), stringEscaping == StringEscaping::NonAscii);
if (strFormat == StringFormat::Literal || str.size() > 1024)
if (strFormat == StringFormat::Literal || size > 1024)
m_pState->SetMapKeyFormat(YAML::LongKey, FmtScope::Local);
PrepareNode(EmitterNodeType::Scalar);
switch (strFormat) {
case StringFormat::Plain:
m_stream << str;
m_stream.write(str, size);
break;
case StringFormat::SingleQuoted:
Utils::WriteSingleQuotedString(m_stream, str);
Utils::WriteSingleQuotedString(m_stream, str, size);
break;
case StringFormat::DoubleQuoted:
Utils::WriteDoubleQuotedString(m_stream, str, stringEscaping);
Utils::WriteDoubleQuotedString(m_stream, str, size, stringEscaping);
break;
case StringFormat::Literal:
Utils::WriteLiteralString(m_stream, str,
Utils::WriteLiteralString(m_stream, str, size,
m_pState->CurIndent() + m_pState->GetIndent());
break;
}
@@ -750,6 +761,10 @@ Emitter& Emitter::Write(const std::string& str) {
return *this;
}
Emitter& Emitter::Write(const std::string& str) {
return Write(str.data(), str.size());
}
std::size_t Emitter::GetFloatPrecision() const {
return m_pState->GetFloatPrecision();
}
@@ -758,6 +773,10 @@ std::size_t Emitter::GetDoublePrecision() const {
return m_pState->GetDoublePrecision();
}
bool Emitter::GetShowTrailingZero() const {
return m_pState->GetShowTrailingZero();
}
const char* Emitter::ComputeFullBoolName(bool b) const {
const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool
? YesNoBool
@@ -863,7 +882,7 @@ Emitter& Emitter::Write(const _Alias& alias) {
PrepareNode(EmitterNodeType::Scalar);
if (!Utils::WriteAlias(m_stream, alias.content)) {
if (!Utils::WriteAlias(m_stream, alias.content.data(), alias.content.size())) {
m_pState->SetError(ErrorMsg::INVALID_ALIAS);
return *this;
}
@@ -886,7 +905,7 @@ Emitter& Emitter::Write(const _Anchor& anchor) {
PrepareNode(EmitterNodeType::Property);
if (!Utils::WriteAnchor(m_stream, anchor.content)) {
if (!Utils::WriteAnchor(m_stream, anchor.content.data(), anchor.content.size())) {
m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
return *this;
}
@@ -935,7 +954,7 @@ Emitter& Emitter::Write(const _Comment& comment) {
if (m_stream.col() > 0)
m_stream << Indentation(m_pState->GetPreCommentIndent());
Utils::WriteComment(m_stream, comment.content,
Utils::WriteComment(m_stream, comment.content.data(), comment.content.size(),
m_pState->GetPostCommentIndent());
m_pState->SetNonContent();
@@ -962,8 +981,33 @@ Emitter& Emitter::Write(const Binary& binary) {
if (!good())
return *this;
const StringFormat::value strFormat =
Utils::ComputeBinaryFormat(binary, m_pState->GetStringFormat(),
m_pState->CurGroupFlowType());
if (strFormat == StringFormat::Literal)
m_pState->SetMapKeyFormat(YAML::LongKey, FmtScope::Local);
PrepareNode(EmitterNodeType::Scalar);
Utils::WriteBinary(m_stream, binary);
switch (strFormat) {
case StringFormat::SingleQuoted:
Utils::WriteSingleQuotedBinary(m_stream, binary);
break;
// For a long period of time, this function outputed the DoubleQuoted form
// regardless of the options. In order not to change the default behavior,
// when strFormat is Plain, it is still treated as DoubleQuoted.
case StringFormat::Plain:
case StringFormat::DoubleQuoted:
Utils::WriteBinary(m_stream, binary);
break;
case StringFormat::Literal:
Utils::WriteLiteralBinary(m_stream, binary,
m_pState->CurIndent() + m_pState->GetIndent(),
m_pState->GetWrap());
break;
}
StartedScalar();
return *this;
+12
View File
@@ -18,11 +18,13 @@ EmitterState::EmitterState()
m_indent(2),
m_preCommentIndent(2),
m_postCommentIndent(1),
m_wrap(80),
m_seqFmt(Block),
m_mapFmt(Block),
m_mapKeyFmt(Auto),
m_floatPrecision(std::numeric_limits<float>::max_digits10),
m_doublePrecision(std::numeric_limits<double>::max_digits10),
m_showTrailingZero(false),
//
m_modifiedSettings{},
m_globalModifiedSettings{},
@@ -351,6 +353,11 @@ bool EmitterState::SetPostCommentIndent(std::size_t value,
return true;
}
bool EmitterState::SetWrap(std::size_t value, FmtScope::value scope) {
_Set(m_wrap, value, scope);
return true;
}
bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
FmtScope::value scope) {
switch (value) {
@@ -397,4 +404,9 @@ bool EmitterState::SetDoublePrecision(std::size_t value,
_Set(m_doublePrecision, value, scope);
return true;
}
bool EmitterState::SetShowTrailingZero(bool value, FmtScope::value scope) {
_Set(m_showTrailingZero, value, scope);
return true;
}
} // namespace YAML
+7
View File
@@ -108,6 +108,9 @@ class EmitterState {
bool SetPostCommentIndent(std::size_t value, FmtScope::value scope);
std::size_t GetPostCommentIndent() const { return m_postCommentIndent.get(); }
bool SetWrap(std::size_t value, FmtScope::value scope);
std::size_t GetWrap() const { return m_wrap.get(); }
bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
FmtScope::value scope);
EMITTER_MANIP GetFlowType(GroupType::value groupType) const;
@@ -119,6 +122,8 @@ class EmitterState {
std::size_t GetFloatPrecision() const { return m_floatPrecision.get(); }
bool SetDoublePrecision(std::size_t value, FmtScope::value scope);
std::size_t GetDoublePrecision() const { return m_doublePrecision.get(); }
bool SetShowTrailingZero(bool value, FmtScope::value scope);
bool GetShowTrailingZero() const { return m_showTrailingZero.get(); }
private:
template <typename T>
@@ -141,11 +146,13 @@ class EmitterState {
Setting<EMITTER_MANIP> m_intFmt;
Setting<std::size_t> m_indent;
Setting<std::size_t> m_preCommentIndent, m_postCommentIndent;
Setting<std::size_t> m_wrap; // applied to literal binary
Setting<EMITTER_MANIP> m_seqFmt;
Setting<EMITTER_MANIP> m_mapFmt;
Setting<EMITTER_MANIP> m_mapKeyFmt;
Setting<std::size_t> m_floatPrecision;
Setting<std::size_t> m_doublePrecision;
Setting<bool> m_showTrailingZero;
SettingChanges m_modifiedSettings;
SettingChanges m_globalModifiedSettings;
+118 -43
View File
@@ -1,4 +1,5 @@
#include <algorithm>
#include <cstdint>
#include <iomanip>
#include <sstream>
@@ -38,7 +39,7 @@ bool IsAnchorChar(int ch) { // test for ns-anchor-char
return false;
}
if (ch < 0x7E) {
if (ch <= 0x7E) {
return true;
}
@@ -88,8 +89,8 @@ int Utf8BytesIndicated(char ch) {
bool IsTrailingByte(char ch) { return (ch & 0xC0) == 0x80; }
bool GetNextCodePointAndAdvance(int& codePoint,
std::string::const_iterator& first,
std::string::const_iterator last) {
const char*& first,
const char* last) {
if (first == last)
return false;
@@ -152,39 +153,39 @@ void WriteCodePoint(ostream_wrapper& out, int codePoint) {
}
}
bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
bool IsValidPlainScalar(const char* str, std::size_t size, FlowType::value flowType,
bool allowOnlyAscii) {
// check against null
if (IsNullString(str)) {
if (IsNullString(str, size)) {
return false;
}
// check the start
const RegEx& start = (flowType == FlowType::Flow ? Exp::PlainScalarInFlow()
: Exp::PlainScalar());
if (!start.Matches(str)) {
if (!start.Matches(StringCharSource(str, size))) {
return false;
}
// and check the end for plain whitespace (which can't be faithfully kept in a
// plain scalar)
if (!str.empty() && *str.rbegin() == ' ') {
if (size != 0 && str[size - 1] == ' ') {
return false;
}
// then check until something is disallowed
static const RegEx& disallowed_flow =
static const RegEx disallowed_flow =
Exp::EndScalarInFlow() | (Exp::BlankOrBreak() + Exp::Comment()) |
Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
Exp::Tab();
static const RegEx& disallowed_block =
Exp::Tab() | Exp::Ampersand();
static const RegEx disallowed_block =
Exp::EndScalar() | (Exp::BlankOrBreak() + Exp::Comment()) |
Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
Exp::Tab();
Exp::Tab() | Exp::Ampersand();
const RegEx& disallowed =
flowType == FlowType::Flow ? disallowed_flow : disallowed_block;
StringCharSource buffer(str.c_str(), str.size());
StringCharSource buffer(str, size);
while (buffer) {
if (disallowed.Matches(buffer)) {
return false;
@@ -198,22 +199,22 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
return true;
}
bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) {
bool IsValidSingleQuotedScalar(const char* str, std::size_t size, bool escapeNonAscii) {
// TODO: check for non-printable characters?
return std::none_of(str.begin(), str.end(), [=](char ch) {
return std::none_of(str, str + size, [=](char ch) {
return (escapeNonAscii && (0x80 <= static_cast<unsigned char>(ch))) ||
(ch == '\n');
});
}
bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType,
bool IsValidLiteralScalar(const char* str, std::size_t size, FlowType::value flowType,
bool escapeNonAscii) {
if (flowType == FlowType::Flow) {
return false;
}
// TODO: check for non-printable characters?
return std::none_of(str.begin(), str.end(), [=](char ch) {
return std::none_of(str, str + size, [=](char ch) {
return (escapeNonAscii && (0x80 <= static_cast<unsigned char>(ch)));
});
}
@@ -253,10 +254,10 @@ void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint, StringE
out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF];
}
bool WriteAliasName(ostream_wrapper& out, const std::string& str) {
bool WriteAliasName(ostream_wrapper& out, const char* str, std::size_t size) {
int codePoint;
for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
for (const char* i = str;
GetNextCodePointAndAdvance(codePoint, i, str + size);) {
if (!IsAnchorChar(codePoint)) {
return false;
}
@@ -267,25 +268,25 @@ bool WriteAliasName(ostream_wrapper& out, const std::string& str) {
}
} // namespace
StringFormat::value ComputeStringFormat(const std::string& str,
StringFormat::value ComputeStringFormat(const char* str, std::size_t size,
EMITTER_MANIP strFormat,
FlowType::value flowType,
bool escapeNonAscii) {
switch (strFormat) {
case Auto:
if (IsValidPlainScalar(str, flowType, escapeNonAscii)) {
if (IsValidPlainScalar(str, size, flowType, escapeNonAscii)) {
return StringFormat::Plain;
}
return StringFormat::DoubleQuoted;
case SingleQuoted:
if (IsValidSingleQuotedScalar(str, escapeNonAscii)) {
if (IsValidSingleQuotedScalar(str, size, escapeNonAscii)) {
return StringFormat::SingleQuoted;
}
return StringFormat::DoubleQuoted;
case DoubleQuoted:
return StringFormat::DoubleQuoted;
case Literal:
if (IsValidLiteralScalar(str, flowType, escapeNonAscii)) {
if (IsValidLiteralScalar(str, size, flowType, escapeNonAscii)) {
return StringFormat::Literal;
}
return StringFormat::DoubleQuoted;
@@ -296,11 +297,38 @@ StringFormat::value ComputeStringFormat(const std::string& str,
return StringFormat::DoubleQuoted;
}
bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) {
StringFormat::value ComputeBinaryFormat(const Binary &bin,
EMITTER_MANIP strFormat,
FlowType::value flowType) {
// Equivalent to calling ComputeStringFormat with the base64
// encoded form of 'bin'.
switch (strFormat) {
case Auto:
if (bin.size() > 0u) {
return StringFormat::Plain;
}
return StringFormat::DoubleQuoted;
case SingleQuoted:
return StringFormat::SingleQuoted;
case DoubleQuoted:
return StringFormat::DoubleQuoted;
case Literal:
if (flowType == FlowType::Flow) {
return StringFormat::DoubleQuoted;
}
return StringFormat::Literal;
default:
break;
}
return StringFormat::DoubleQuoted;
}
bool WriteSingleQuotedString(ostream_wrapper& out, const char* str, std::size_t size) {
out << "'";
int codePoint;
for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
for (const char* i = str;
GetNextCodePointAndAdvance(codePoint, i, str + size);) {
if (codePoint == '\n') {
return false; // We can't handle a new line and the attendant indentation
// yet
@@ -316,12 +344,12 @@ bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) {
return true;
}
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
bool WriteDoubleQuotedString(ostream_wrapper& out, const char* str, std::size_t size,
StringEscaping::value stringEscaping) {
out << "\"";
int codePoint;
for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
for (const char* i = str;
GetNextCodePointAndAdvance(codePoint, i, str + size);) {
switch (codePoint) {
case '\"':
out << "\\\"";
@@ -363,12 +391,33 @@ bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
return true;
}
bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
bool WriteLiteralString(ostream_wrapper& out, const char* str, std::size_t size,
std::size_t indent) {
out << "|\n";
// depending on the numbers of new lines at the end of the string
// we need to use 'clip (-)', 'strip (default)' or 'keep' (+) annotation.
// if there is no newline at the end, we need 'clip'
// if there is single new line at the end, we need 'strip'
// otherwise 'keep'
//
// see YAML spec 1.2 chapter '8.1.1.2 Block Chomping Indicator' for more information
// https://yaml.org/spec/1.2.2/#8112-block-chomping-indicator
// The chomping depends on the number of new lines.
// The output following this 'WriteLiteralString' call will add an additional '\n',
// because of this we need to remove one in the case of 'strip' and 'keep'.
if (size == 0 || str[size-1] != '\n') { // clip
out << "|-\n";
} else if (size == 1 || str[size-2] != '\n') { // strip
out << "|\n";
size -= 1;
} else { // 'keep'
out << "|+\n";
size -= 1;
}
int codePoint;
for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
for (const char* i = str;
GetNextCodePointAndAdvance(codePoint, i, str + size);) {
if (codePoint == '\n') {
out << "\n";
} else {
@@ -406,14 +455,14 @@ bool WriteChar(ostream_wrapper& out, char ch, StringEscaping::value stringEscapi
return true;
}
bool WriteComment(ostream_wrapper& out, const std::string& str,
bool WriteComment(ostream_wrapper& out, const char* str, std::size_t size,
std::size_t postCommentIndent) {
const std::size_t curIndent = out.col();
out << "#" << Indentation(postCommentIndent);
out.set_comment();
int codePoint;
for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());) {
for (const char* i = str;
GetNextCodePointAndAdvance(codePoint, i, str + size);) {
if (codePoint == '\n') {
out << "\n"
<< IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
@@ -425,14 +474,14 @@ bool WriteComment(ostream_wrapper& out, const std::string& str,
return true;
}
bool WriteAlias(ostream_wrapper& out, const std::string& str) {
bool WriteAlias(ostream_wrapper& out, const char* str, std::size_t size) {
out << "*";
return WriteAliasName(out, str);
return WriteAliasName(out, str, size);
}
bool WriteAnchor(ostream_wrapper& out, const std::string& str) {
bool WriteAnchor(ostream_wrapper& out, const char* str, std::size_t size) {
out << "&";
return WriteAliasName(out, str);
return WriteAliasName(out, str, size);
}
bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) {
@@ -489,9 +538,35 @@ bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
}
bool WriteBinary(ostream_wrapper& out, const Binary& binary) {
WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()),
StringEscaping::None);
return true;
std::string encoded = EncodeBase64(binary.data(), binary.size());
return WriteDoubleQuotedString(out, encoded.data(), encoded.size(),
StringEscaping::None);
}
bool WriteLiteralBinary(ostream_wrapper& out, const Binary& binary, std::size_t indent, std::size_t wrap) {
std::string encoded = EncodeBase64(binary.data(), binary.size());
std::string wrapped = "";
if (wrap) {
if (wrap <= indent) return false;
wrap -= indent;
std::size_t point = wrap;
for (std::size_t i = 0; i < encoded.size(); i++) {
if (i == point) {
wrapped += '\n';
point += wrap;
}
wrapped += encoded[i];
}
}
else
wrapped = encoded;
return WriteLiteralString(out, wrapped.data(), wrapped.size(), indent);
}
bool WriteSingleQuotedBinary(ostream_wrapper& out, const Binary& binary) {
std::string encoded = EncodeBase64(binary.data(), binary.size());
return WriteSingleQuotedString(out, encoded.data(), encoded.size());
}
} // namespace Utils
} // namespace YAML
+12 -7
View File
@@ -29,26 +29,31 @@ struct StringEscaping {
};
namespace Utils {
StringFormat::value ComputeStringFormat(const std::string& str,
StringFormat::value ComputeStringFormat(const char* str, std::size_t size,
EMITTER_MANIP strFormat,
FlowType::value flowType,
bool escapeNonAscii);
StringFormat::value ComputeBinaryFormat(const Binary &bin,
EMITTER_MANIP strFormat,
FlowType::value flowType);
bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str);
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
bool WriteSingleQuotedString(ostream_wrapper& out, const char* str, std::size_t size);
bool WriteDoubleQuotedString(ostream_wrapper& out, const char* str, std::size_t size,
StringEscaping::value stringEscaping);
bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
bool WriteLiteralString(ostream_wrapper& out, const char* str, std::size_t size,
std::size_t indent);
bool WriteChar(ostream_wrapper& out, char ch,
StringEscaping::value stringEscapingStyle);
bool WriteComment(ostream_wrapper& out, const std::string& str,
bool WriteComment(ostream_wrapper& out, const char* str, std::size_t size,
std::size_t postCommentIndent);
bool WriteAlias(ostream_wrapper& out, const std::string& str);
bool WriteAnchor(ostream_wrapper& out, const std::string& str);
bool WriteAlias(ostream_wrapper& out, const char* str, std::size_t size);
bool WriteAnchor(ostream_wrapper& out, const char* str, std::size_t size);
bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim);
bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
const std::string& tag);
bool WriteBinary(ostream_wrapper& out, const Binary& binary);
bool WriteSingleQuotedBinary(ostream_wrapper& out, const Binary& binary);
bool WriteLiteralBinary(ostream_wrapper& out, const Binary& binary, std::size_t indent, std::size_t wrap);
}
}
+1
View File
@@ -17,4 +17,5 @@ BadPushback::~BadPushback() YAML_CPP_NOEXCEPT = default;
BadInsert::~BadInsert() YAML_CPP_NOEXCEPT = default;
EmitterException::~EmitterException() YAML_CPP_NOEXCEPT = default;
BadFile::~BadFile() YAML_CPP_NOEXCEPT = default;
NonUniqueMapKey::~NonUniqueMapKey() YAML_CPP_NOEXCEPT = default;
} // namespace YAML
+4 -4
View File
@@ -115,13 +115,13 @@ std::string Escape(Stream& in) {
case '/':
return "/";
case 'N':
return "\x85";
return "\xC2\x85"; // NEL (U+0085)
case '_':
return "\xA0";
return "\xC2\xA0"; // NBSP (U+00A0)
case 'L':
return "\xE2\x80\xA8"; // LS (#x2028)
return "\xE2\x80\xA8"; // LS (U+2028)
case 'P':
return "\xE2\x80\xA9"; // PS (#x2029)
return "\xE2\x80\xA9"; // PS (U+2029)
case 'x':
return Escape(in, 2);
case 'u':
+5 -1
View File
@@ -37,7 +37,7 @@ inline const RegEx& Blank() {
return e;
}
inline const RegEx& Break() {
static const RegEx e = RegEx('\n') | RegEx("\r\n");
static const RegEx e = RegEx('\n') | RegEx("\r\n") | RegEx('\r');
return e;
}
inline const RegEx& BlankOrBreak() {
@@ -117,6 +117,10 @@ inline const RegEx& ValueInJSONFlow() {
static const RegEx e = RegEx(':');
return e;
}
inline const RegEx& Ampersand() {
static const RegEx e = RegEx('&');
return e;
}
inline const RegEx Comment() {
static const RegEx e = RegEx('#');
return e;
+256
View File
@@ -0,0 +1,256 @@
#include "yaml-cpp/fptostring.h"
#include "contrib/dragonbox.h"
#include <array>
#include <cassert>
#include <cmath>
#include <limits>
#include <sstream>
#include <tuple>
namespace YAML {
namespace detail {
namespace fp_formatting {
/**
* Converts a integer into its ASCII digits.
*
* @param begin/end - a buffer, must be at least 20bytes long.
* @param value - input value.
* @param width - minimum number of digits, fill with '0' to the left. Must be equal or smaller than the buffer size.
* @return - number of digits filled into the buffer (or -1 if preconditions are not meet)
*
* Example:
* std::array<char, 20> buffer;
* auto ct = ConvertToChars(buffer.begin(), buffer.end(), 23, 3);
* assert(ct = 3);
* assert(buffer[0] == '0');
* assert(buffer[1] == '2');
* assert(buffer[2] == '3');
*/
int ConvertToChars(char* begin, char* end, uint64_t value, int width=1) {
// precondition of this function (will trigger in debug build)
assert(width >= 1);
assert(end >= begin); // end must be after begin
assert(end-begin >= width); // Buffer must be large enough
assert(end-begin >= 20); // 2^64 has 20digits, so at least 20 digits must be available
// defensive programming, abort if precondition are not met (will trigger in release build)
if (width < 1) {
return -1;
}
if (end < begin) {
return -1;
}
if (end-begin < width) {
return -1;
}
if (end-begin < 20) {
return -1;
}
// count number of digits, and fill digits array accordingly
int digits_ct{};
while (value > 0) {
char c = value % 10 + '0';
value = value / 10;
digits_ct += 1;
*(end-digits_ct) = c;
}
while(digits_ct < width) {
assert(digits_ct < 64);
digits_ct += 1;
*(end-digits_ct) = '0';
}
// move data to the front of the array
std::memmove(begin, end-digits_ct, digits_ct);
return digits_ct;
}
/**
* Converts a float or double to a string.
*
* converts a value 'v' to a string. Uses dragonbox for formatting.
*/
template <typename T>
std::string FpToString(T v, int precision = 0) {
// hard coded constant, at which exponent should switch to a scientific notation
int const lowerExponentThreshold = -5;
int const upperExponentThreshold = (precision==0)?6:precision;
if (precision == 0) {
precision = 6;
}
// dragonbox/to_decimal does not handle value 0, inf, NaN
if (v == 0 || std::isinf(v) || std::isnan(v)) {
std::stringstream ss;
ss.imbue(std::locale::classic());
ss << v;
return ss.str();
}
auto r = jkj::dragonbox::to_decimal(v);
auto digits = std::array<char, 20>{}; // max digits of size_t is 20.
auto digits_ct = ConvertToChars(digits.data(), digits.data() + digits.size(), r.significand);
// defensive programming, ConvertToChars arguments are invalid
if (digits_ct == -1) {
std::stringstream ss;
ss.imbue(std::locale::classic());
ss << v;
return ss.str();
}
// check if requested precision is lower than
// required digits for exact representation
if (digits_ct > precision) {
auto diff = digits_ct - precision;
r.exponent += diff;
digits_ct = precision;
// round numbers if required
if (digits[digits_ct] >= '5') {
int i{digits_ct-1};
digits[i] += 1;
while (digits[i] == '9'+1) {
digits_ct -= 1;
r.exponent += 1;
if (i > 0) {
digits[i-1] += 1;
i -= 1;
} else {
digits_ct = 1;
digits[0] = '1';
break;
}
}
}
}
// Case 1 - scientific notation: max digits of size_t plus sign, a dot and 2 letters for 'e+' or 'e-' and 4 letters for the exponent
// Case 2 - default notation: require up to precision number of digits and one for a potential sign
std::array<char, 28> output_buffer;
auto output_ptr = &output_buffer[0];
// Helper variable that in Case 2 counts the overflowing number of zeros that do not fit into the buffer.
int overflow_zeros = 0;
// print '-' symbol for negative numbers
if (r.is_negative) {
*(output_ptr++) = '-';
}
// exponent if only a single non-zero digit is before the decimal point
int const exponent = r.exponent + digits_ct - 1;
// case 1: scientific notation
if (exponent >= upperExponentThreshold || exponent <= lowerExponentThreshold) {
// print first digit
*(output_ptr++) = digits[0];
// print digits after decimal point
if (digits_ct > 1) {
*(output_ptr++) = '.';
// print significant numbers after decimal point
for (int i{1}; i < digits_ct; ++i) {
*(output_ptr++) = digits[i];
}
}
*(output_ptr++) = 'e';
*(output_ptr++) = (exponent>=0)?'+':'-';
auto exp_digits = std::array<char, 20>{};
auto exp_digits_ct = ConvertToChars(exp_digits.data(), exp_digits.data() + exp_digits.size(), std::abs(exponent), /*.precision=*/ 2);
// defensive programming, ConvertToChars arguments are invalid
if (exp_digits_ct == -1) {
std::stringstream ss;
ss.imbue(std::locale::classic());
ss << v;
return ss.str();
}
for (int i{0}; i < exp_digits_ct; ++i) {
*(output_ptr++) = exp_digits[i];
}
// case 2: default notation
} else {
auto const digits_end = digits.begin() + digits_ct;
auto digits_iter = digits.begin();
// print digits before point
int const before_decimal_digits = digits_ct + r.exponent;
if (before_decimal_digits > 0) {
// print non-zero digits before point
for (int i{0}; i < std::min(before_decimal_digits, digits_ct); ++i) {
*(output_ptr++) = *(digits_iter++);
}
// number of digits that have to be zero
int const zero_digits_ct = before_decimal_digits - digits_ct;
// space left in the output_buffer (-1 because we need it for null-termination)
int const buffer_empty_space = static_cast<int>(
output_buffer.data() + output_buffer.size() - output_ptr - 1);
// print all zeros not fitting into the buffer at the end of the function
overflow_zeros = std::max(0, zero_digits_ct - buffer_empty_space);
// print trailing zeros before point
for (int i{0}; i < zero_digits_ct - overflow_zeros; ++i) {
*(output_ptr++) = '0';
}
// print 0 before point if none where printed before
} else {
*(output_ptr++) = '0';
}
if (digits_iter != digits_end) {
*(output_ptr++) = '.';
// print 0 after decimal point, to fill until first digits
int const after_decimal_zeros = -digits_ct - r.exponent;
for (int i{0}; i < after_decimal_zeros; ++i) {
*(output_ptr++) = '0';
}
// print significant numbers after decimal point
for (;digits_iter < digits_end; ++digits_iter) {
*(output_ptr++) = *digits_iter;
}
}
}
*output_ptr = '\0';
auto ret_value = std::string{&output_buffer[0], output_ptr};
ret_value.resize(ret_value.size() + overflow_zeros, '0');
return ret_value;
}
}
}
std::string FpToString(float v, size_t precision) {
return detail::fp_formatting::FpToString(v, static_cast<int>(precision));
}
std::string FpToString(double v, size_t precision) {
return detail::fp_formatting::FpToString(v, static_cast<int>(precision));
}
/**
* dragonbox only works for floats/doubles not long double
*/
std::string FpToString(long double v, size_t precision) {
std::stringstream ss;
ss.imbue(std::locale::classic());
if (precision == 0) {
precision = std::numeric_limits<long double>::max_digits10;
}
ss.precision(precision);
ss << v;
return ss.str();
}
}
-1
View File
@@ -7,7 +7,6 @@
#pragma once
#endif
#include <iostream>
#include <cstddef>
#include "yaml-cpp/ostream_wrapper.h"
+9 -1
View File
@@ -9,12 +9,16 @@ void memory_holder::merge(memory_holder& rhs) {
if (m_pMemory == rhs.m_pMemory)
return;
if (m_pMemory->size() < rhs.m_pMemory->size()) {
std::swap(m_pMemory, rhs.m_pMemory);
}
m_pMemory->merge(*rhs.m_pMemory);
rhs.m_pMemory = m_pMemory;
}
node& memory::create_node() {
shared_node pNode(new node);
shared_node pNode(std::make_shared<node>());
m_nodes.insert(pNode);
return *pNode;
}
@@ -22,5 +26,9 @@ node& memory::create_node() {
void memory::merge(const memory& rhs) {
m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
}
size_t memory::size() const {
return m_nodes.size();
}
} // namespace detail
} // namespace YAML
+8 -2
View File
@@ -13,7 +13,7 @@
namespace YAML {
namespace detail {
std::atomic<size_t> node::m_amount{0};
YAML_CPP_API std::atomic<size_t> node::m_amount{0};
const std::string& node_data::empty_scalar() {
static const std::string svalue;
@@ -279,7 +279,12 @@ void node_data::reset_map() {
m_undefinedPairs.clear();
}
void node_data::insert_map_pair(node& key, node& value) {
void node_data::insert_map_pair(node& key, node& value, bool force) {
if (!force && !key.scalar().empty())
for (const auto& mapEntry : m_map)
if (mapEntry.first->scalar() == key.scalar())
throw NonUniqueMapKey(m_mark, key);
m_map.emplace_back(&key, &value);
if (!key.is_defined() || !value.is_defined())
@@ -310,6 +315,7 @@ void node_data::convert_sequence_to_map(const shared_memory_holder& pMemory) {
reset_map();
for (std::size_t i = 0; i < m_sequence.size(); i++) {
std::stringstream stream;
stream.imbue(std::locale::classic());
stream << i;
node& key = pMemory->create_node();
+1 -1
View File
@@ -10,7 +10,7 @@ namespace YAML {
struct Mark;
NodeBuilder::NodeBuilder()
: m_pMemory(new detail::memory_holder),
: m_pMemory(std::make_shared<detail::memory_holder>()),
m_pRoot(nullptr),
m_stack{},
m_anchors{},
+4 -4
View File
@@ -69,19 +69,19 @@ void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
case NodeType::Undefined:
break;
case NodeType::Null:
handler.OnNull(Mark(), anchor);
handler.OnNull(node.mark(), anchor);
break;
case NodeType::Scalar:
handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
handler.OnScalar(node.mark(), node.tag(), anchor, node.scalar());
break;
case NodeType::Sequence:
handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style());
handler.OnSequenceStart(node.mark(), node.tag(), anchor, node.style());
for (auto element : node)
Emit(*element, handler, am);
handler.OnSequenceEnd();
break;
case NodeType::Map:
handler.OnMapStart(Mark(), node.tag(), anchor, node.style());
handler.OnMapStart(node.mark(), node.tag(), anchor, node.style());
for (auto element : node) {
Emit(*element.first, handler, am);
Emit(*element.second, handler, am);
+10 -3
View File
@@ -1,10 +1,17 @@
#include "yaml-cpp/null.h"
#include <cstring>
namespace YAML {
_Null Null;
bool IsNullString(const std::string& str) {
return str.empty() || str == "~" || str == "null" || str == "Null" ||
str == "NULL";
template <std::size_t N>
static bool same(const char* str, std::size_t size, const char (&literal)[N]) {
constexpr int literalSize = N - 1; // minus null terminator
return size == literalSize && std::strncmp(str, literal, literalSize) == 0;
}
bool IsNullString(const char* str, std::size_t size) {
return size == 0 || same(str, size, "~") || same(str, size, "null") ||
same(str, size, "Null") || same(str, size, "NULL");
}
} // namespace YAML
+1 -1
View File
@@ -2,7 +2,7 @@
#include <algorithm>
#include <cstring>
#include <iostream>
#include <ostream>
namespace YAML {
ostream_wrapper::ostream_wrapper()
+17 -1
View File
@@ -33,9 +33,24 @@ bool Parser::HandleNextDocument(EventHandler& eventHandler) {
return false;
}
auto oldPos = m_pScanner->peek().mark.pos;
SingleDocParser sdp(*m_pScanner, *m_pDirectives);
sdp.HandleDocument(eventHandler);
return true;
// checks if progress was made
// 1. if scanner has no more tokens, progress was made
if (m_pScanner->empty()) {
return true;
}
// 2. if token position has changed, progress was made
auto newPos = m_pScanner->peek().mark.pos;
if (newPos != oldPos) {
return true;
}
// No progress was made, no further processing
return false;
}
void Parser::ParseDirectives() {
@@ -77,6 +92,7 @@ void Parser::HandleYamlDirective(const Token& token) {
}
std::stringstream str(token.params[0]);
str.imbue(std::locale::classic());
str >> m_pDirectives->version.major;
str.get();
str >> m_pDirectives->version.minor;
+4
View File
@@ -27,6 +27,10 @@ inline bool RegEx::Matches(const Stream& in) const { return Match(in) >= 0; }
template <typename Source>
inline bool RegEx::Matches(const Source& source) const {
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201103L) || __cplusplus >= 201103L)
static_assert(!std::is_same<Source, const char*>::value,
#endif
"Must use StringCharSource instead of plain C-string");
return Match(source) >= 0;
}
+24
View File
@@ -13,6 +13,7 @@ Scanner::Scanner(std::istream& in)
m_startedStream(false),
m_endedStream(false),
m_simpleKeyAllowed(false),
m_scalarValueAllowed(false),
m_canBeJSONFlow(false),
m_simpleKeys{},
m_indents{},
@@ -127,6 +128,17 @@ void Scanner::ScanNextToken() {
}
if (INPUT.peek() == Keys::FlowEntry) {
// values starting with `,` are not allowed.
// eg: reject `,foo`
if (INPUT.column() == 0) {
throw ParserException(INPUT.mark(), ErrorMsg::UNEXPECTED_FLOW);
}
// if we already parsed a quoted scalar value and we are not in a flow,
// then `,` is not a valid character.
// eg: reject `"foo",`
if (!m_scalarValueAllowed) {
throw ParserException(INPUT.mark(), ErrorMsg::UNEXPECTED_SCALAR);
}
return ScanFlowEntry();
}
@@ -159,6 +171,13 @@ void Scanner::ScanNextToken() {
return ScanBlockScalar();
}
// if we already parsed a quoted scalar value in this line,
// another scalar value is an error.
// eg: reject `"foo" "bar"`
if (!m_scalarValueAllowed) {
throw ParserException(INPUT.mark(), ErrorMsg::UNEXPECTED_SCALAR);
}
if (INPUT.peek() == '\'' || INPUT.peek() == '\"') {
return ScanQuotedScalar();
}
@@ -203,6 +222,9 @@ void Scanner::ScanToNextToken() {
// oh yeah, and let's get rid of that simple key
InvalidateSimpleKey();
// new line - we accept a scalar value now
m_scalarValueAllowed = true;
// new line - we may be able to accept a simple key now
if (InBlockContext()) {
m_simpleKeyAllowed = true;
@@ -245,6 +267,7 @@ const RegEx& Scanner::GetValueRegex() const {
void Scanner::StartStream() {
m_startedStream = true;
m_simpleKeyAllowed = true;
m_scalarValueAllowed = true;
std::unique_ptr<IndentMarker> pIndent(
new IndentMarker(-1, IndentMarker::NONE));
m_indentRefs.push_back(std::move(pIndent));
@@ -261,6 +284,7 @@ void Scanner::EndStream() {
PopAllSimpleKeys();
m_simpleKeyAllowed = false;
m_scalarValueAllowed = false;
m_endedStream = true;
}
+1 -2
View File
@@ -9,9 +9,7 @@
#include <cstddef>
#include <ios>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
@@ -179,6 +177,7 @@ class Scanner {
// state info
bool m_startedStream, m_endedStream;
bool m_simpleKeyAllowed;
bool m_scalarValueAllowed;
bool m_canBeJSONFlow;
std::stack<SimpleKey> m_simpleKeys;
std::stack<IndentMarker *> m_indents;
+7
View File
@@ -211,6 +211,9 @@ void Scanner::ScanValue() {
m_simpleKeyAllowed = InBlockContext();
}
// we are parsing a `key: value` pair; scalars are always allowed
m_scalarValueAllowed = true;
// eat
Mark mark = INPUT.mark();
INPUT.eat(1);
@@ -360,6 +363,10 @@ void Scanner::ScanQuotedScalar() {
// and scan
scalar = ScanScalar(INPUT, params);
m_simpleKeyAllowed = false;
// we just scanned a quoted scalar;
// we can only have another scalar in this line
// if we are in a flow, eg: `[ "foo", "bar" ]` is ok, but `"foo", "bar"` isn't.
m_scalarValueAllowed = InFlowContext();
m_canBeJSONFlow = true;
Token token(Token::NON_PLAIN_SCALAR, mark);
+14 -7
View File
@@ -1,4 +1,3 @@
#include <algorithm>
#include <cstdio>
#include <sstream>
@@ -42,8 +41,13 @@ void SingleDocParser::HandleDocument(EventHandler& eventHandler) {
eventHandler.OnDocumentEnd();
// check if any tokens left after the text
if (!m_scanner.empty() && m_scanner.peek().type != Token::DOC_END
&& m_scanner.peek().type != Token::DOC_START)
throw ParserException(m_scanner.mark(), ErrorMsg::UNEXPECTED_TOKEN_AFTER_DOC);
// and finally eat any doc ends we see
while (!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END)
if (!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END)
m_scanner.pop();
}
@@ -93,9 +97,9 @@ void SingleDocParser::HandleNode(EventHandler& eventHandler) {
// add non-specific tags
if (tag.empty())
tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
if (token.type == Token::PLAIN_SCALAR
&& tag.compare("?") == 0 && IsNullString(token.value)) {
if (token.type == Token::PLAIN_SCALAR
&& tag.compare("?") == 0 && IsNullString(token.value.data(), token.value.size())) {
eventHandler.OnNull(mark, anchor);
m_scanner.pop();
return;
@@ -424,8 +428,11 @@ anchor_t SingleDocParser::RegisterAnchor(const std::string& name) {
anchor_t SingleDocParser::LookupAnchor(const Mark& mark,
const std::string& name) const {
auto it = m_anchors.find(name);
if (it == m_anchors.end())
throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR);
if (it == m_anchors.end()) {
std::stringstream ss;
ss << ErrorMsg::UNKNOWN_ANCHOR << name;
throw ParserException(mark, ss.str());
}
return it->second;
}
+19 -2
View File
@@ -1,4 +1,4 @@
#include <iostream>
#include <istream>
#include "stream.h"
@@ -262,7 +262,24 @@ char Stream::get() {
AdvanceCurrent();
m_mark.column++;
if (ch == '\n') {
// if line ending symbol is unknown, set it to the first
// encountered line ending.
// if line ending '\r' set ending symbol to '\r'
// other wise set it to '\n'
if (!m_lineEndingSymbol) {
if (ch == '\n') { // line ending is '\n'
m_lineEndingSymbol = '\n';
} else if (ch == '\r') {
auto ch2 = peek();
if (ch2 == '\n') { // line ending is '\r\n'
m_lineEndingSymbol = '\n';
} else { // line ending is '\r'
m_lineEndingSymbol = '\r';
}
}
}
if (ch == m_lineEndingSymbol) {
m_mark.column = 0;
m_mark.line++;
}
+2 -1
View File
@@ -11,7 +11,7 @@
#include <cstddef>
#include <deque>
#include <ios>
#include <iostream>
#include <istream>
#include <set>
#include <string>
@@ -53,6 +53,7 @@ class Stream {
Mark m_mark;
CharacterSet m_charSet;
char m_lineEndingSymbol{}; // 0 means it is not determined yet, must be '\n' or '\r'
mutable std::deque<char> m_readahead;
unsigned char* const m_pPrefetched;
mutable size_t m_nPrefetchedAvailable;
+1 -1
View File
@@ -29,7 +29,7 @@ Tag::Tag(const Token& token)
}
}
const std::string Tag::Translate(const Directives& directives) {
std::string Tag::Translate(const Directives& directives) {
switch (type) {
case VERBATIM:
return value;
+1 -1
View File
@@ -23,7 +23,7 @@ struct Tag {
};
Tag(const Token& token);
const std::string Translate(const Directives& directives);
std::string Translate(const Directives& directives);
TYPE type;
std::string handle, value;
+4 -3
View File
@@ -8,17 +8,18 @@
#endif
#include "yaml-cpp/mark.h"
#include <iostream>
#include <ostream>
#include <string>
#include <vector>
namespace YAML {
const std::string TokenNames[] = {
constexpr const char* TokenNames[] = {
"DIRECTIVE", "DOC_START", "DOC_END", "BLOCK_SEQ_START",
"BLOCK_MAP_START", "BLOCK_SEQ_END", "BLOCK_MAP_END", "BLOCK_ENTRY",
"FLOW_SEQ_START", "FLOW_MAP_START", "FLOW_SEQ_END", "FLOW_MAP_END",
"FLOW_MAP_COMPACT", "FLOW_ENTRY", "KEY", "VALUE",
"ANCHOR", "ALIAS", "TAG", "SCALAR"};
"ANCHOR", "ALIAS", "TAG", "SCALAR",
"NON_PLAIN_SCALAR"};
struct Token {
// enums
+19 -3
View File
@@ -1,14 +1,30 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
package(default_visibility = ["//test:__subpackages__"])
cc_library(
name = "mock_event_handler",
hdrs = ["mock_event_handler.h"],
strip_include_prefix = "//test",
)
cc_library(
name = "specexamples",
hdrs = ["specexamples.h"],
strip_include_prefix = "//test",
)
cc_test(
name = "test",
srcs = glob([
"*.cpp",
"*.h",
"integrations/*.cpp",
"node/*.cpp",
]),
deps = [
":mock_event_handler",
":specexamples",
"//:yaml-cpp",
"//:yaml-cpp_internal",
"@com_google_googletest//:gtest_main",
"@googletest//:gtest_main",
],
)
+25 -18
View File
@@ -2,23 +2,22 @@ find_package(Threads REQUIRED)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
set(BUILD_MOCK ON CACHE BOOL "" FORCE)
set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE)
add_subdirectory(
"${CMAKE_CURRENT_SOURCE_DIR}/gtest-1.10.0"
"${CMAKE_CURRENT_BINARY_DIR}/prefix")
include_directories(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/gtest-1.10.0/googletest/include")
set(test-new-api-pattern "new-api/*.cpp")
set(test-source-pattern "*.cpp" "integration/*.cpp" "node/*.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.11)
list(INSERT test-new-api-pattern 0 CONFIGURE_DEPENDS)
list(INSERT test-source-pattern 0 CONFIGURE_DEPENDS)
if(YAML_USE_SYSTEM_GTEST)
find_package(GTest)
if (NOT GTEST_FOUND)
message(FATAL_ERROR "system googletest was requested but not found")
endif()
else()
add_subdirectory(
"${CMAKE_CURRENT_SOURCE_DIR}/googletest-1.16.0"
"${CMAKE_CURRENT_BINARY_DIR}/prefix")
include_directories(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/googletest-1.16.0/googletest/include")
endif()
file(GLOB test-new-api-sources ${test-new-api-pattern})
file(GLOB test-sources ${test-source-pattern})
file(GLOB test-new-api-sources CONFIGURE_DEPENDS "new-api/*.cpp")
file(GLOB test-sources CONFIGURE_DEPENDS "*.cpp" "integration/*.cpp" "node/*.cpp")
add_executable(yaml-cpp-tests "")
target_sources(yaml-cpp-tests
@@ -33,12 +32,13 @@ target_include_directories(yaml-cpp-tests
target_compile_options(yaml-cpp-tests
PRIVATE
$<$<CXX_COMPILER_ID:Clang>:-Wno-c99-extensions -Wno-variadic-macros -Wno-sign-compare>
$<$<CXX_COMPILER_ID:GNU>:-Wno-variadic-macros -Wno-sign-compare>)
$<$<CXX_COMPILER_ID:GNU>:-Wno-variadic-macros -Wno-sign-compare -Wno-narrowing>)
target_link_libraries(yaml-cpp-tests
PRIVATE
Threads::Threads
yaml-cpp
gmock)
yaml-cpp::yaml-cpp
GTest::gtest
GTest::gmock)
set_property(TARGET yaml-cpp-tests PROPERTY CXX_STANDARD_REQUIRED ON)
if (NOT DEFINED CMAKE_CXX_STANDARD)
@@ -46,4 +46,11 @@ if (NOT DEFINED CMAKE_CXX_STANDARD)
endif()
add_test(yaml-cpp::test yaml-cpp-tests)
add_test(NAME yaml-cpp::test COMMAND yaml-cpp-tests)
if (build-windows-dll)
add_custom_command(
TARGET yaml-cpp-tests
POST_BUILD COMMAND ${CMAKE_COMMAND} -E
copy_if_different "$<TARGET_FILE:yaml-cpp>" "$<TARGET_FILE_DIR:yaml-cpp-tests>")
endif()
+20
View File
@@ -0,0 +1,20 @@
#include "gtest/gtest.h"
#include <yaml-cpp/binary.h>
TEST(BinaryTest, DecodingSimple) {
std::string input{90, 71, 86, 104, 90, 71, 74, 108, 90, 87, 89, 61};
const std::vector<unsigned char> &result = YAML::DecodeBase64(input);
EXPECT_EQ(std::string(result.begin(), result.end()), "deadbeef");
}
TEST(BinaryTest, DecodingNoCrashOnNegative) {
std::string input{-58, -1, -99, 109};
const std::vector<unsigned char> &result = YAML::DecodeBase64(input);
EXPECT_TRUE(result.empty());
}
TEST(BinaryTest, DecodingTooShort) {
std::string input{90, 71, 86, 104, 90, 71, 74, 108, 90, 87, 89};
const std::vector<unsigned char> &result = YAML::DecodeBase64(input);
EXPECT_TRUE(result.empty());
}
+21
View File
@@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.5...3.30)
project(yaml-cpp-consumer LANGUAGES CXX)
find_package(yaml-cpp CONFIG REQUIRED)
get_target_property(LIBRARY_TYPE yaml-cpp::yaml-cpp TYPE)
if(LIBRARY_TYPE STREQUAL "SHARED_LIBRARY")
if(NOT YAML_CPP_SHARED_LIBS_BUILT)
message(FATAL_ERROR "Library type (${LIBRARY_TYPE}) contradicts config: ${YAML_CPP_SHARED_LIBS_BUILT}")
endif()
else()
if(YAML_CPP_SHARED_LIBS_BUILT)
message(FATAL_ERROR "Library type (${LIBRARY_TYPE}) contradicts config: ${YAML_CPP_SHARED_LIBS_BUILT}")
endif()
endif()
add_executable(main main.cpp)
if (NOT DEFINED CMAKE_CXX_STANDARD)
set_target_properties(main PROPERTIES CXX_STANDARD 11)
endif()
target_link_libraries(main PRIVATE ${YAML_CPP_LIBRARIES})
+3
View File
@@ -0,0 +1,3 @@
#include "yaml-cpp/yaml.h"
int main(int, char**) { YAML::Parser foo{}; }
+249
View File
@@ -0,0 +1,249 @@
#include "yaml-cpp/fptostring.h"
#include "gtest/gtest.h"
#include <iomanip>
namespace YAML {
namespace {
/**
* Helper function, that converts double to string as std::stringstream would do
*/
template <typename T>
static std::string convert_with_stringstream(T v, size_t precision = 0) {
std::stringstream ss;
ss.imbue(std::locale::classic());
if (precision > 0) {
ss << std::setprecision(precision);
}
ss << v;
return ss.str();
}
// Caution: Test involving 'convert_with_stringstream' are based on std::stringstream
// having certain printing behavior, if these changes, the unit test might fail.
// This is not a fault of FpToString just a weakness of the way these
// tests are constructed
TEST(FpToStringTest, conversion_double) {
// Issue motivating FpToString function,
// https://github.com/jbeder/yaml-cpp/issues/1289
// Original problem at hand:
EXPECT_EQ("34.34", FpToString(34.34));
EXPECT_EQ("56.56", FpToString(56.56));
EXPECT_EQ("12.12", FpToString(12.12));
EXPECT_EQ("78.78", FpToString(78.78));
// Special challenge with rounding
// https://github.com/jbeder/yaml-cpp/issues/1289#issuecomment-2211705536
EXPECT_EQ("1.54743e+26", FpToString(1.5474250491e+26f));
EXPECT_EQ(convert_with_stringstream(1.5474250491e+26f), FpToString(1.5474250491e+26f));
EXPECT_EQ("1.5474251e+26", FpToString(1.5474250491e+26f, 8));
// prints the same way as std::stringstream
EXPECT_EQ(convert_with_stringstream(1.), FpToString(1.));
EXPECT_EQ(convert_with_stringstream(1e0), FpToString(1e0));
EXPECT_EQ(convert_with_stringstream(1e1), FpToString(1e1));
EXPECT_EQ(convert_with_stringstream(1e2), FpToString(1e2));
EXPECT_EQ(convert_with_stringstream(1e3), FpToString(1e3));
EXPECT_EQ(convert_with_stringstream(1e4), FpToString(1e4));
EXPECT_EQ(convert_with_stringstream(1e5), FpToString(1e5));
EXPECT_EQ(convert_with_stringstream(1e6), FpToString(1e6));
EXPECT_EQ(convert_with_stringstream(1e7), FpToString(1e7));
EXPECT_EQ(convert_with_stringstream(1e8), FpToString(1e8));
EXPECT_EQ(convert_with_stringstream(1e9), FpToString(1e9));
// Print by default values below 1e6 without scientific notation
EXPECT_EQ("1", FpToString(1.));
EXPECT_EQ("1", FpToString(1e0));
EXPECT_EQ("10", FpToString(1e1));
EXPECT_EQ("100", FpToString(1e2));
EXPECT_EQ("1000", FpToString(1e3));
EXPECT_EQ("10000", FpToString(1e4));
EXPECT_EQ("100000", FpToString(1e5));
EXPECT_EQ("1e+06", FpToString(1e6));
EXPECT_EQ("1e+07", FpToString(1e7));
EXPECT_EQ("1e+08", FpToString(1e8));
EXPECT_EQ("1e+09", FpToString(1e9));
// prints the same way as std::stringstream
EXPECT_EQ(convert_with_stringstream(1.), FpToString(1.));
EXPECT_EQ(convert_with_stringstream(1e-0), FpToString(1e-0));
EXPECT_EQ(convert_with_stringstream(1e-1), FpToString(1e-1));
EXPECT_EQ(convert_with_stringstream(1e-2), FpToString(1e-2));
EXPECT_EQ(convert_with_stringstream(1e-3), FpToString(1e-3));
EXPECT_EQ(convert_with_stringstream(1e-4), FpToString(1e-4));
EXPECT_EQ(convert_with_stringstream(1e-5), FpToString(1e-5));
EXPECT_EQ(convert_with_stringstream(1e-6), FpToString(1e-6));
EXPECT_EQ(convert_with_stringstream(1e-7), FpToString(1e-7));
EXPECT_EQ(convert_with_stringstream(1e-8), FpToString(1e-8));
EXPECT_EQ(convert_with_stringstream(1e-9), FpToString(1e-9));
// Print by default values above 1e-5 without scientific notation
EXPECT_EQ("1", FpToString(1.));
EXPECT_EQ("1", FpToString(1e-0));
EXPECT_EQ("0.1", FpToString(1e-1));
EXPECT_EQ("0.01", FpToString(1e-2));
EXPECT_EQ("0.001", FpToString(1e-3));
EXPECT_EQ("0.0001", FpToString(1e-4));
EXPECT_EQ("1e-05", FpToString(1e-5));
EXPECT_EQ("1e-06", FpToString(1e-6));
EXPECT_EQ("1e-07", FpToString(1e-7));
EXPECT_EQ("1e-08", FpToString(1e-8));
EXPECT_EQ("1e-09", FpToString(1e-9));
// changing precision has the same effect as std::stringstream
EXPECT_EQ(convert_with_stringstream(123., 1), FpToString(123., 1));
EXPECT_EQ(convert_with_stringstream(1234567., 7), FpToString(1234567., 7));
EXPECT_EQ(convert_with_stringstream(12345.67, 7), FpToString(12345.67, 7));
EXPECT_EQ(convert_with_stringstream(1234567e-9, 7), FpToString(1234567e-9, 7));
EXPECT_EQ(convert_with_stringstream(1234567e-9, 1), FpToString(1234567e-9, 1));
// known example that is difficult to round
EXPECT_EQ("1", FpToString(0.9999, 2));
EXPECT_EQ("-1", FpToString(-0.9999, 2));
// some more random tests
EXPECT_EQ("1.25", FpToString(1.25));
EXPECT_EQ("34.34", FpToString(34.34));
EXPECT_EQ("1e+20", FpToString(1e+20));
EXPECT_EQ("1.1e+20", FpToString(1.1e+20));
EXPECT_EQ("1e-20", FpToString(1e-20));
EXPECT_EQ("1.1e-20", FpToString(1.1e-20));
EXPECT_EQ("1e-20", FpToString(0.1e-19));
EXPECT_EQ("1.1e-20", FpToString(0.11e-19));
EXPECT_EQ("19", FpToString(18.9, 2));
EXPECT_EQ("20", FpToString(19.9, 2));
EXPECT_EQ("2e+01", FpToString(19.9, 1));
EXPECT_EQ("1.2e-05", FpToString(1.234e-5, 2));
EXPECT_EQ("1.3e-05", FpToString(1.299e-5, 2));
EXPECT_EQ("-1", FpToString(-1.));
EXPECT_EQ("-1.25", FpToString(-1.25));
EXPECT_EQ("-34.34", FpToString(-34.34));
EXPECT_EQ("-1e+20", FpToString(-1e+20));
EXPECT_EQ("-1.1e+20", FpToString(-1.1e+20));
EXPECT_EQ("-1e-20", FpToString(-1e-20));
EXPECT_EQ("-1.1e-20", FpToString(-1.1e-20));
EXPECT_EQ("-1e-20", FpToString(-0.1e-19));
EXPECT_EQ("-1.1e-20", FpToString(-0.11e-19));
EXPECT_EQ("-19", FpToString(-18.9, 2));
EXPECT_EQ("-20", FpToString(-19.9, 2));
EXPECT_EQ("-2e+01", FpToString(-19.9, 1));
EXPECT_EQ("-1.2e-05", FpToString(-1.234e-5, 2));
EXPECT_EQ("-1.3e-05", FpToString(-1.299e-5, 2));
}
TEST(FpToStringTest, conversion_float) {
// Issue motivating FpToString function,
// https://github.com/jbeder/yaml-cpp/issues/1289
// Original problem at hand:
EXPECT_EQ("34.34", FpToString(34.34f));
EXPECT_EQ("56.56", FpToString(56.56f));
EXPECT_EQ("12.12", FpToString(12.12f));
EXPECT_EQ("78.78", FpToString(78.78f));
// prints the same way as std::stringstream
EXPECT_EQ(convert_with_stringstream(1.f), FpToString(1.f));
EXPECT_EQ(convert_with_stringstream(1e0f), FpToString(1e0f));
EXPECT_EQ(convert_with_stringstream(1e1f), FpToString(1e1f));
EXPECT_EQ(convert_with_stringstream(1e2f), FpToString(1e2f));
EXPECT_EQ(convert_with_stringstream(1e3f), FpToString(1e3f));
EXPECT_EQ(convert_with_stringstream(1e4f), FpToString(1e4f));
EXPECT_EQ(convert_with_stringstream(1e5f), FpToString(1e5f));
EXPECT_EQ(convert_with_stringstream(1e6f), FpToString(1e6f));
EXPECT_EQ(convert_with_stringstream(1e7f), FpToString(1e7f));
EXPECT_EQ(convert_with_stringstream(1e8f), FpToString(1e8f));
EXPECT_EQ(convert_with_stringstream(1e9f), FpToString(1e9f));
// Print by default values below 1e6 without scientific notation
EXPECT_EQ("1", FpToString(1.f));
EXPECT_EQ("1", FpToString(1e0f));
EXPECT_EQ("10", FpToString(1e1f));
EXPECT_EQ("100", FpToString(1e2f));
EXPECT_EQ("1000", FpToString(1e3f));
EXPECT_EQ("10000", FpToString(1e4f));
EXPECT_EQ("100000", FpToString(1e5f));
EXPECT_EQ("1e+06", FpToString(1e6f));
EXPECT_EQ("1e+07", FpToString(1e7f));
EXPECT_EQ("1e+08", FpToString(1e8f));
EXPECT_EQ("1e+09", FpToString(1e9f));
// prints the same way as std::stringstream
EXPECT_EQ(convert_with_stringstream(1.f), FpToString(1.f));
EXPECT_EQ(convert_with_stringstream(1e-0f), FpToString(1e-0f));
EXPECT_EQ(convert_with_stringstream(1e-1f), FpToString(1e-1f));
EXPECT_EQ(convert_with_stringstream(1e-2f), FpToString(1e-2f));
EXPECT_EQ(convert_with_stringstream(1e-3f), FpToString(1e-3f));
EXPECT_EQ(convert_with_stringstream(1e-4f), FpToString(1e-4f));
EXPECT_EQ(convert_with_stringstream(1e-5f), FpToString(1e-5f));
EXPECT_EQ(convert_with_stringstream(1e-6f), FpToString(1e-6f));
EXPECT_EQ(convert_with_stringstream(1e-7f), FpToString(1e-7f));
EXPECT_EQ(convert_with_stringstream(1e-8f), FpToString(1e-8f));
EXPECT_EQ(convert_with_stringstream(1e-9f), FpToString(1e-9f));
// Print by default values above 1e-5 without scientific notation
EXPECT_EQ("1", FpToString(1.f));
EXPECT_EQ("1", FpToString(1e-0f));
EXPECT_EQ("0.1", FpToString(1e-1f));
EXPECT_EQ("0.01", FpToString(1e-2f));
EXPECT_EQ("0.001", FpToString(1e-3f));
EXPECT_EQ("0.0001", FpToString(1e-4f));
EXPECT_EQ("1e-05", FpToString(1e-5f));
EXPECT_EQ("1e-06", FpToString(1e-6f));
EXPECT_EQ("1e-07", FpToString(1e-7f));
EXPECT_EQ("1e-08", FpToString(1e-8f));
EXPECT_EQ("1e-09", FpToString(1e-9f));
// changing precision has the same effect as std::stringstream
EXPECT_EQ(convert_with_stringstream(123.f, 1), FpToString(123.f, 1));
EXPECT_EQ(convert_with_stringstream(1234567.f, 7), FpToString(1234567.f, 7));
EXPECT_EQ(convert_with_stringstream(12345.67f, 7), FpToString(12345.67f, 7));
EXPECT_EQ(convert_with_stringstream(1234567e-9f, 7), FpToString(1234567e-9f, 7));
EXPECT_EQ(convert_with_stringstream(1234567e-9f, 1), FpToString(1234567e-9f, 1));
// known example that is difficult to round
EXPECT_EQ("1", FpToString(0.9999f, 2));
EXPECT_EQ("-1", FpToString(-0.9999f, 2));
// some more random tests
EXPECT_EQ("1.25", FpToString(1.25f));
EXPECT_EQ("34.34", FpToString(34.34f));
EXPECT_EQ("1e+20", FpToString(1e+20f));
EXPECT_EQ("1.1e+20", FpToString(1.1e+20f));
EXPECT_EQ("1e-20", FpToString(1e-20f));
EXPECT_EQ("1.1e-20", FpToString(1.1e-20f));
EXPECT_EQ("1e-20", FpToString(0.1e-19f));
EXPECT_EQ("1.1e-20", FpToString(0.11e-19f));
EXPECT_EQ("19", FpToString(18.9f, 2));
EXPECT_EQ("20", FpToString(19.9f, 2));
EXPECT_EQ("2e+01", FpToString(19.9f, 1));
EXPECT_EQ("1.2e-05", FpToString(1.234e-5f, 2));
EXPECT_EQ("1.3e-05", FpToString(1.299e-5f, 2));
EXPECT_EQ("-1", FpToString(-1.f));
EXPECT_EQ("-1.25", FpToString(-1.25f));
EXPECT_EQ("-34.34", FpToString(-34.34f));
EXPECT_EQ("-1e+20", FpToString(-1e+20f));
EXPECT_EQ("-1.1e+20", FpToString(-1.1e+20f));
EXPECT_EQ("-1e-20", FpToString(-1e-20f));
EXPECT_EQ("-1.1e-20", FpToString(-1.1e-20f));
EXPECT_EQ("-1e-20", FpToString(-0.1e-19f));
EXPECT_EQ("-1.1e-20", FpToString(-0.11e-19f));
EXPECT_EQ("-19", FpToString(-18.9f, 2));
EXPECT_EQ("-20", FpToString(-19.9f, 2));
EXPECT_EQ("-2e+01", FpToString(-19.9f, 1));
EXPECT_EQ("-1.2e-05", FpToString(-1.234e-5f, 2));
EXPECT_EQ("-1.3e-05", FpToString(-1.299e-5f, 2));
}
TEST(FpToStringTest, vulnerability_stack_buffer_overflow) {
EXPECT_EQ(FpToString(1.0e100, 200), "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
}
} // namespace
} // namespace YAML
@@ -8,6 +8,7 @@ bazel-genfiles
bazel-googletest
bazel-out
bazel-testlogs
MODULE.bazel.lock
# python
*.pyc
@@ -24,6 +25,10 @@ Win32-Release/
x64-Debug/
x64-Release/
# VSCode files
.cache/
cmake-variants.yaml
# Ignore autoconf / automake files
Makefile.in
aclocal.m4
@@ -30,15 +30,44 @@
#
# Bazel Build for Google C++ Testing Framework(Google Test)
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
exports_files(["LICENSE"])
config_setting(
name = "qnx",
constraint_values = ["@platforms//os:qnx"],
)
config_setting(
name = "windows",
constraint_values = ["@bazel_tools//platforms:windows"],
constraint_values = ["@platforms//os:windows"],
)
config_setting(
name = "freebsd",
constraint_values = ["@platforms//os:freebsd"],
)
config_setting(
name = "openbsd",
constraint_values = ["@platforms//os:openbsd"],
)
# NOTE: Fuchsia is not an officially supported platform.
config_setting(
name = "fuchsia",
constraint_values = ["@platforms//os:fuchsia"],
)
config_setting(
name = "msvc_compiler",
flag_values = {
"@bazel_tools//tools/cpp:compiler": "msvc-cl",
},
visibility = [":__subpackages__"],
)
config_setting(
@@ -76,6 +105,7 @@ cc_library(
"googlemock/include/gmock/*.h",
]),
copts = select({
":qnx": [],
":windows": [],
"//conditions:default": ["-pthread"],
}),
@@ -94,17 +124,44 @@ cc_library(
"googletest/include",
],
linkopts = select({
":qnx": ["-lregex"],
":windows": [],
":freebsd": [
"-lm",
"-pthread",
],
":openbsd": [
"-lm",
"-pthread",
],
"//conditions:default": ["-pthread"],
}),
deps = select({
":has_absl": [
"@com_google_absl//absl/debugging:failure_signal_handler",
"@com_google_absl//absl/debugging:stacktrace",
"@com_google_absl//absl/debugging:symbolize",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/types:optional",
"@com_google_absl//absl/types:variant",
"@abseil-cpp//absl/container:flat_hash_set",
"@abseil-cpp//absl/debugging:failure_signal_handler",
"@abseil-cpp//absl/debugging:stacktrace",
"@abseil-cpp//absl/debugging:symbolize",
"@abseil-cpp//absl/flags:flag",
"@abseil-cpp//absl/flags:parse",
"@abseil-cpp//absl/flags:reflection",
"@abseil-cpp//absl/flags:usage",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/types:any",
"@abseil-cpp//absl/types:optional",
"@abseil-cpp//absl/types:variant",
"@re2//:re2",
],
"//conditions:default": [],
}) + select({
# `gtest-death-test.cc` has `EXPECT_DEATH` that spawns a process,
# expects it to crash and inspects its logs with the given matcher,
# so that's why these libraries are needed.
# Otherwise, builds targeting Fuchsia would fail to compile.
":fuchsia": [
"@fuchsia_sdk//pkg/fdio",
"@fuchsia_sdk//pkg/syslog",
"@fuchsia_sdk//pkg/zx",
],
"//conditions:default": [],
}),
@@ -1,23 +1,13 @@
# Note: CMake support is community-based. The maintainers do not use CMake
# internally.
cmake_minimum_required(VERSION 2.8.8)
if (POLICY CMP0048)
cmake_policy(SET CMP0048 NEW)
endif (POLICY CMP0048)
cmake_minimum_required(VERSION 3.13)
project(googletest-distribution)
set(GOOGLETEST_VERSION 1.10.0)
set(GOOGLETEST_VERSION 1.16.0)
if (CMAKE_VERSION VERSION_LESS "3.1")
add_definitions(-std=c++11)
else()
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT CYGWIN)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
enable_testing()
@@ -25,9 +15,19 @@ enable_testing()
include(CMakeDependentOption)
include(GNUInstallDirs)
#Note that googlemock target already builds googletest
# Note that googlemock target already builds googletest.
option(BUILD_GMOCK "Builds the googlemock subproject" ON)
option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON)
option(GTEST_HAS_ABSL "Use Abseil and RE2. Requires Abseil and RE2 to be separately added to the build." OFF)
if(GTEST_HAS_ABSL)
if(NOT TARGET absl::base)
find_package(absl REQUIRED)
endif()
if(NOT TARGET re2::re2)
find_package(re2 REQUIRED)
endif()
endif()
if(BUILD_GMOCK)
add_subdirectory( googlemock )
@@ -21,14 +21,14 @@ accept your pull requests.
## Are you a Googler?
If you are a Googler, please make an attempt to submit an internal change rather
than a GitHub Pull Request. If you are not able to submit an internal change a
If you are a Googler, please make an attempt to submit an internal contribution
rather than a GitHub Pull Request. If you are not able to submit internally, a
PR is acceptable as an alternative.
## Contributing A Patch
1. Submit an issue describing your proposed change to the
[issue tracker](https://github.com/google/googletest).
[issue tracker](https://github.com/google/googletest/issues).
2. Please don't mix more than one logical change per submittal, because it
makes the history hard to follow. If you want to make a change that doesn't
have a corresponding issue in the issue tracker, please create one.
@@ -36,7 +36,8 @@ PR is acceptable as an alternative.
This ensures that work isn't being duplicated and communicating your plan
early also generally leads to better patches.
4. If your proposed change is accepted, and you haven't already done so, sign a
Contributor License Agreement (see details above).
Contributor License Agreement
([see details above](#contributor-license-agreements)).
5. Fork the desired repo, develop and test your code changes.
6. Ensure that your code adheres to the existing style in the sample to which
you are contributing.
@@ -46,11 +47,11 @@ PR is acceptable as an alternative.
## The Google Test and Google Mock Communities
The Google Test community exists primarily through the
[discussion group](http://groups.google.com/group/googletestframework) and the
[discussion group](https://groups.google.com/group/googletestframework) and the
GitHub repository. Likewise, the Google Mock community exists primarily through
their own [discussion group](http://groups.google.com/group/googlemock). You are
definitely encouraged to contribute to the discussion and you can also help us
to keep the effectiveness of the group high by following and promoting the
their own [discussion group](https://groups.google.com/group/googlemock). You
are definitely encouraged to contribute to the discussion and you can also help
us to keep the effectiveness of the group high by following and promoting the
guidelines listed here.
### Please Be Friendly
@@ -79,17 +80,17 @@ fairly rigid coding style, as defined by the
[google-styleguide](https://github.com/google/styleguide) project. All patches
will be expected to conform to the style outlined
[here](https://google.github.io/styleguide/cppguide.html). Use
[.clang-format](https://github.com/google/googletest/blob/master/.clang-format)
to check your formatting
[.clang-format](https://github.com/google/googletest/blob/main/.clang-format) to
check your formatting.
## Requirements for Contributors
If you plan to contribute a patch, you need to build Google Test, Google Mock,
and their own tests from a git checkout, which has further requirements:
* [Python](https://www.python.org/) v2.3 or newer (for running some of the
* [Python](https://www.python.org/) v3.6 or newer (for running some of the
tests and re-generating certain source files from templates)
* [CMake](https://cmake.org/) v2.6.4 or newer
* [CMake](https://cmake.org/) v2.8.12 or newer
## Developing Google Test and Google Mock
@@ -101,42 +102,40 @@ To make sure your changes work as intended and don't break existing
functionality, you'll want to compile and run Google Test and GoogleMock's own
tests. For that you can use CMake:
mkdir mybuild
cd mybuild
cmake -Dgtest_build_tests=ON -Dgmock_build_tests=ON ${GTEST_REPO_DIR}
```
mkdir mybuild
cd mybuild
cmake -Dgtest_build_tests=ON -Dgmock_build_tests=ON ${GTEST_REPO_DIR}
```
To choose between building only Google Test or Google Mock, you may modify your
cmake command to be one of each
cmake -Dgtest_build_tests=ON ${GTEST_DIR} # sets up Google Test tests
cmake -Dgmock_build_tests=ON ${GMOCK_DIR} # sets up Google Mock tests
```
cmake -Dgtest_build_tests=ON ${GTEST_DIR} # sets up Google Test tests
cmake -Dgmock_build_tests=ON ${GMOCK_DIR} # sets up Google Mock tests
```
Make sure you have Python installed, as some of Google Test's tests are written
in Python. If the cmake command complains about not being able to find Python
(`Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE)`), try telling it
explicitly where your Python executable can be found:
cmake -DPYTHON_EXECUTABLE=path/to/python ...
```
cmake -DPYTHON_EXECUTABLE=path/to/python ...
```
Next, you can build Google Test and / or Google Mock and all desired tests. On
\*nix, this is usually done by
make
```
make
```
To run the tests, do
make test
```
make test
```
All tests should pass.
### Regenerating Source Files
Some of Google Test's source files are generated from templates (not in the C++
sense) using a script. For example, the file
include/gtest/internal/gtest-type-util.h.pump is used to generate
gtest-type-util.h in the same directory.
You don't need to worry about regenerating the source files unless you need to
modify them. You would then modify the corresponding `.pump` files and run the
'[pump.py](googletest/scripts/pump.py)' generator script. See the
[Pump Manual](googletest/docs/pump_manual.md).
@@ -5,33 +5,62 @@
Ajay Joshi <jaj@google.com>
Balázs Dán <balazs.dan@gmail.com>
Benoit Sigoure <tsuna@google.com>
Bharat Mediratta <bharat@menalto.com>
Bogdan Piloca <boo@google.com>
Chandler Carruth <chandlerc@google.com>
Chris Prince <cprince@google.com>
Chris Taylor <taylorc@google.com>
Dan Egnor <egnor@google.com>
Dave MacLachlan <dmaclach@gmail.com>
David Anderson <danderson@google.com>
Dean Sturtevant
Eric Roman <eroman@chromium.org>
Gene Volovich <gv@cite.com>
Hady Zalek <hady.zalek@gmail.com>
Hal Burch <gmock@hburch.com>
Jeffrey Yasskin <jyasskin@google.com>
Jim Keller <jimkeller@google.com>
Joe Walnes <joe@truemesh.com>
Jon Wray <jwray@google.com>
Jói Sigurðsson <joi@google.com>
Keir Mierle <mierle@gmail.com>
Keith Ray <keith.ray@gmail.com>
Kenton Varda <kenton@google.com>
Kostya Serebryany <kcc@google.com>
Krystian Kuzniarek <krystian.kuzniarek@gmail.com>
Lev Makhlis
Manuel Klimek <klimek@google.com>
Mario Tanev <radix@google.com>
Mark Paskin
Markus Heule <markus.heule@gmail.com>
Martijn Vels <mvels@google.com>
Matthew Simmons <simmonmt@acm.org>
Mika Raento <mikie@iki.fi>
Mike Bland <mbland@google.com>
Miklós Fazekas <mfazekas@szemafor.com>
Neal Norwitz <nnorwitz@gmail.com>
Nermin Ozkiranartli <nermin@google.com>
Owen Carlsen <ocarlsen@google.com>
Paneendra Ba <paneendra@google.com>
Pasi Valminen <pasi.valminen@gmail.com>
Patrick Hanna <phanna@google.com>
Patrick Riley <pfr@google.com>
Paul Menage <menage@google.com>
Peter Kaminski <piotrk@google.com>
Piotr Kaminski <piotrk@google.com>
Preston Jackson <preston.a.jackson@gmail.com>
Rainer Klaffenboeck <rainer.klaffenboeck@dynatrace.com>
Russ Cox <rsc@google.com>
Russ Rufer <russ@pentad.com>
Sean Mcafee <eefacm@gmail.com>
Sigurður Ásgeirsson <siggi@google.com>
Soyeon Kim <sxshx818@naver.com>
Sverre Sundsdal <sundsdal@gmail.com>
Szymon Sobik <sobik.szymon@gmail.com>
Takeshi Yoshino <tyoshino@google.com>
Tracy Bialik <tracy@pentad.com>
Vadim Berman <vadimb@google.com>
Vlad Losev <vladl@google.com>
Wolfgang Klier <wklier@google.com>
Zhanyong Wan <wan@google.com>
@@ -1,5 +1,4 @@
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# Copyright 2024 Google Inc.
# All Rights Reserved.
#
#
@@ -29,21 +28,49 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -eu
# https://bazel.build/external/overview#bzlmod
if [ "${TRAVIS_OS_NAME}" != linux ]; then
echo "Not a Linux build; skipping installation"
exit 0
fi
module(
name = "googletest",
version = "1.16.0",
compatibility_level = 1,
)
# Only direct dependencies need to be listed below.
# Please keep the versions in sync with the versions in the WORKSPACE file.
if [ "${TRAVIS_SUDO}" = "true" ]; then
echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | \
sudo tee /etc/apt/sources.list.d/bazel.list
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update && sudo apt-get install -y bazel gcc-4.9 g++-4.9 clang-3.9
elif [ "${CXX}" = "clang++" ]; then
# Use ccache, assuming $HOME/bin is in the path, which is true in the Travis build environment.
ln -sf /usr/bin/ccache $HOME/bin/${CXX};
ln -sf /usr/bin/ccache $HOME/bin/${CC};
fi
bazel_dep(
name = "abseil-cpp",
version = "20250127.0",
)
bazel_dep(
name = "platforms",
version = "0.0.10",
)
bazel_dep(
name = "re2",
version = "2024-07-02",
)
bazel_dep(
name = "rules_python",
version = "1.1.0",
dev_dependency = True,
)
# https://rules-python.readthedocs.io/en/stable/toolchains.html#library-modules-with-dev-only-python-usage
python = use_extension(
"@rules_python//python/extensions:python.bzl",
"python",
dev_dependency = True,
)
python.toolchain(
ignore_root_user_error = True,
is_default = True,
python_version = "3.12",
)
# See fake_fuchsia_sdk.bzl for instructions on how to override this with a real SDK, if needed.
fuchsia_sdk = use_extension("//:fake_fuchsia_sdk.bzl", "fuchsia_sdk")
fuchsia_sdk.create_fake()
use_repo(fuchsia_sdk, "fuchsia_sdk")
+142
View File
@@ -0,0 +1,142 @@
# GoogleTest
### Announcements
#### Live at Head
GoogleTest now follows the
[Abseil Live at Head philosophy](https://abseil.io/about/philosophy#upgrade-support).
We recommend
[updating to the latest commit in the `main` branch as often as possible](https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#what-is-live-at-head-and-how-do-i-do-it).
We do publish occasional semantic versions, tagged with
`v${major}.${minor}.${patch}` (e.g. `v1.16.0`).
#### Documentation Updates
Our documentation is now live on GitHub Pages at
https://google.github.io/googletest/. We recommend browsing the documentation on
GitHub Pages rather than directly in the repository.
#### Release 1.16.0
[Release 1.16.0](https://github.com/google/googletest/releases/tag/v1.16.0) is
now available.
The 1.16.x branch requires at least C++14.
#### Continuous Integration
We use Google's internal systems for continuous integration.
#### Coming Soon
* We are planning to take a dependency on
[Abseil](https://github.com/abseil/abseil-cpp).
## Welcome to **GoogleTest**, Google's C++ test framework!
This repository is a merger of the formerly separate GoogleTest and GoogleMock
projects. These were so closely related that it makes sense to maintain and
release them together.
### Getting Started
See the [GoogleTest User's Guide](https://google.github.io/googletest/) for
documentation. We recommend starting with the
[GoogleTest Primer](https://google.github.io/googletest/primer.html).
More information about building GoogleTest can be found at
[googletest/README.md](googletest/README.md).
## Features
* xUnit test framework: \
Googletest is based on the [xUnit](https://en.wikipedia.org/wiki/XUnit)
testing framework, a popular architecture for unit testing
* Test discovery: \
Googletest automatically discovers and runs your tests, eliminating the need
to manually register your tests
* Rich set of assertions: \
Googletest provides a variety of assertions, such as equality, inequality,
exceptions, and more, making it easy to test your code
* User-defined assertions: \
You can define your own assertions with Googletest, making it simple to
write tests that are specific to your code
* Death tests: \
Googletest supports death tests, which verify that your code exits in a
certain way, making it useful for testing error-handling code
* Fatal and non-fatal failures: \
You can specify whether a test failure should be treated as fatal or
non-fatal with Googletest, allowing tests to continue running even if a
failure occurs
* Value-parameterized tests: \
Googletest supports value-parameterized tests, which run multiple times with
different input values, making it useful for testing functions that take
different inputs
* Type-parameterized tests: \
Googletest also supports type-parameterized tests, which run with different
data types, making it useful for testing functions that work with different
data types
* Various options for running tests: \
Googletest provides many options for running tests including running
individual tests, running tests in a specific order and running tests in
parallel
## Supported Platforms
GoogleTest follows Google's
[Foundational C++ Support Policy](https://opensource.google/documentation/policies/cplusplus-support).
See
[this table](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md)
for a list of currently supported versions of compilers, platforms, and build
tools.
## Who Is Using GoogleTest?
In addition to many internal projects at Google, GoogleTest is also used by the
following notable projects:
* The [Chromium projects](https://www.chromium.org/) (behind the Chrome
browser and Chrome OS).
* The [LLVM](https://llvm.org/) compiler.
* [Protocol Buffers](https://github.com/google/protobuf), Google's data
interchange format.
* The [OpenCV](https://opencv.org/) computer vision library.
## Related Open Source Projects
[GTest Runner](https://github.com/nholthaus/gtest-runner) is a Qt5 based
automated test-runner and Graphical User Interface with powerful features for
Windows and Linux platforms.
[GoogleTest UI](https://github.com/ospector/gtest-gbar) is a test runner that
runs your test binary, allows you to track its progress via a progress bar, and
displays a list of test failures. Clicking on one shows failure text. GoogleTest
UI is written in C#.
[GTest TAP Listener](https://github.com/kinow/gtest-tap-listener) is an event
listener for GoogleTest that implements the
[TAP protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol) for test
result output. If your test runner understands TAP, you may find it useful.
[gtest-parallel](https://github.com/google/gtest-parallel) is a test runner that
runs tests from your binary in parallel to provide significant speed-up.
[GoogleTest Adapter](https://marketplace.visualstudio.com/items?itemName=DavidSchuldenfrei.gtest-adapter)
is a VS Code extension allowing to view GoogleTest in a tree view and run/debug
your tests.
[C++ TestMate](https://github.com/matepek/vscode-catch2-test-adapter) is a VS
Code extension allowing to view GoogleTest in a tree view and run/debug your
tests.
[Cornichon](https://pypi.org/project/cornichon/) is a small Gherkin DSL parser
that generates stub code for GoogleTest.
## Contributing Changes
Please read
[`CONTRIBUTING.md`](https://github.com/google/googletest/blob/main/CONTRIBUTING.md)
for details on how to contribute to this project.
Happy testing!
@@ -1,5 +1,4 @@
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# Copyright 2024 Google Inc.
# All Rights Reserved.
#
#
@@ -29,12 +28,34 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -eu
workspace(name = "googletest")
if [ "${TRAVIS_OS_NAME}" != "osx" ]; then
echo "Not a macOS build; skipping installation"
exit 0
fi
load("//:googletest_deps.bzl", "googletest_deps")
googletest_deps()
brew update
brew install ccache gcc@4.9
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_python",
sha256 = "9c6e26911a79fbf510a8f06d8eedb40f412023cf7fa6d1461def27116bff022c",
strip_prefix = "rules_python-1.1.0",
url = "https://github.com/bazelbuild/rules_python/releases/download/1.1.0/rules_python-1.1.0.tar.gz",
)
# https://github.com/bazelbuild/rules_python/releases/tag/1.1.0
load("@rules_python//python:repositories.bzl", "py_repositories")
py_repositories()
http_archive(
name = "bazel_skylib",
sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94",
urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz"],
)
http_archive(
name = "platforms",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.10/platforms-0.0.10.tar.gz",
"https://github.com/bazelbuild/platforms/releases/download/0.0.10/platforms-0.0.10.tar.gz",
],
sha256 = "218efe8ee736d26a3572663b374a253c012b716d8af0c07e842e82f238a0a7ee",
)
@@ -1,5 +1,4 @@
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# Copyright 2024 Google Inc.
# All Rights Reserved.
#
#
@@ -29,9 +28,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -e
bazel version
bazel build --curses=no //...:all
bazel test --curses=no //...:all
bazel test --curses=no //...:all --define absl=1
# https://bazel.build/external/migration#workspace.bzlmod
#
# This file is intentionally empty. When bzlmod is enabled and this
# file exists, the content of WORKSPACE is ignored. This prevents
# bzlmod builds from unintentionally depending on the WORKSPACE file.
@@ -0,0 +1,139 @@
#!/bin/bash
#
# Copyright 2020, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -euox pipefail
readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20241218"
readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20250205"
if [[ -z ${GTEST_ROOT:-} ]]; then
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
fi
if [[ -z ${STD:-} ]]; then
STD="c++14 c++17 c++20"
fi
# Test the CMake build
for cc in /usr/local/bin/gcc /opt/llvm/clang/bin/clang; do
for cmake_off_on in OFF ON; do
time docker run \
--volume="${GTEST_ROOT}:/src:ro" \
--tmpfs="/build:exec" \
--workdir="/build" \
--rm \
--env="CC=${cc}" \
--env=CXXFLAGS="-Werror -Wdeprecated" \
${LINUX_LATEST_CONTAINER} \
/bin/bash -c "
cmake /src \
-DCMAKE_CXX_STANDARD=14 \
-Dgtest_build_samples=ON \
-Dgtest_build_tests=ON \
-Dgmock_build_tests=ON \
-Dcxx_no_exception=${cmake_off_on} \
-Dcxx_no_rtti=${cmake_off_on} && \
make -j$(nproc) && \
ctest -j$(nproc) --output-on-failure"
done
done
# Do one test with an older version of GCC
# TODO(googletest-team): This currently uses Bazel 5. When upgrading to a
# version of Bazel that supports Bzlmod, add --enable_bzlmod=false to keep test
# coverage for the old WORKSPACE dependency management.
time docker run \
--volume="${GTEST_ROOT}:/src:ro" \
--workdir="/src" \
--rm \
--env="CC=/usr/local/bin/gcc" \
--env="BAZEL_CXXOPTS=-std=c++14" \
${LINUX_GCC_FLOOR_CONTAINER} \
/usr/local/bin/bazel test ... \
--copt="-Wall" \
--copt="-Werror" \
--copt="-Wuninitialized" \
--copt="-Wundef" \
--copt="-Wno-error=pragmas" \
--features=external_include_paths \
--keep_going \
--show_timestamps \
--test_output=errors
# Test GCC
for std in ${STD}; do
for absl in 0 1; do
time docker run \
--volume="${GTEST_ROOT}:/src:ro" \
--workdir="/src" \
--rm \
--env="CC=/usr/local/bin/gcc" \
--env="BAZEL_CXXOPTS=-std=${std}" \
${LINUX_LATEST_CONTAINER} \
/usr/local/bin/bazel test ... \
--copt="-Wall" \
--copt="-Werror" \
--copt="-Wuninitialized" \
--copt="-Wundef" \
--define="absl=${absl}" \
--enable_bzlmod=true \
--features=external_include_paths \
--keep_going \
--show_timestamps \
--test_output=errors
done
done
# Test Clang
for std in ${STD}; do
for absl in 0 1; do
time docker run \
--volume="${GTEST_ROOT}:/src:ro" \
--workdir="/src" \
--rm \
--env="CC=/opt/llvm/clang/bin/clang" \
--env="BAZEL_CXXOPTS=-std=${std}" \
${LINUX_LATEST_CONTAINER} \
/usr/local/bin/bazel test ... \
--copt="--gcc-toolchain=/usr/local" \
--copt="-Wall" \
--copt="-Werror" \
--copt="-Wuninitialized" \
--copt="-Wundef" \
--define="absl=${absl}" \
--enable_bzlmod=true \
--features=external_include_paths \
--keep_going \
--linkopt="--gcc-toolchain=/usr/local" \
--show_timestamps \
--test_output=errors
done
done
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Copyright 2017 Google Inc.
# All Rights Reserved.
#!/bin/bash
#
# Copyright 2020, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@@ -29,20 +29,49 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This file is typically sourced by another script.
# if possible, ask for the precise number of processors,
# otherwise take 2 processors as reasonable default; see
# https://docs.travis-ci.com/user/speeding-up-the-build/#Makefile-optimization
if [ -x /usr/bin/getconf ]; then
NPROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN)
else
NPROCESSORS=2
set -euox pipefail
if [[ -z ${GTEST_ROOT:-} ]]; then
GTEST_ROOT="$(realpath $(dirname ${0})/..)"
fi
# as of 2017-09-04 Travis CI reports 32 processors, but GCC build
# crashes if parallelized too much (maybe memory consumption problem),
# so limit to 4 processors for the time being.
if [ $NPROCESSORS -gt 4 ] ; then
echo "$0:Note: Limiting processors to use by make from $NPROCESSORS to 4."
NPROCESSORS=4
# Test the CMake build
for cmake_off_on in OFF ON; do
BUILD_DIR=$(mktemp -d build_dir.XXXXXXXX)
cd ${BUILD_DIR}
time cmake ${GTEST_ROOT} \
-DCMAKE_CXX_STANDARD=14 \
-Dgtest_build_samples=ON \
-Dgtest_build_tests=ON \
-Dgmock_build_tests=ON \
-Dcxx_no_exception=${cmake_off_on} \
-Dcxx_no_rtti=${cmake_off_on}
time make
time ctest -j$(nproc) --output-on-failure
done
# Test the Bazel build
# If we are running on Kokoro, check for a versioned Bazel binary.
KOKORO_GFILE_BAZEL_BIN="bazel-7.0.0-darwin-x86_64"
if [[ ${KOKORO_GFILE_DIR:-} ]] && [[ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]]; then
BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
chmod +x ${BAZEL_BIN}
else
BAZEL_BIN="bazel"
fi
cd ${GTEST_ROOT}
for absl in 0 1; do
${BAZEL_BIN} test ... \
--copt="-Wall" \
--copt="-Werror" \
--copt="-Wundef" \
--cxxopt="-std=c++14" \
--define="absl=${absl}" \
--enable_bzlmod=true \
--features=external_include_paths \
--keep_going \
--show_timestamps \
--test_output=errors
done
@@ -0,0 +1,63 @@
SETLOCAL ENABLEDELAYEDEXPANSION
SET BAZEL_EXE=%KOKORO_GFILE_DIR%\bazel-7.0.0-windows-x86_64.exe
SET PATH=C:\Python34;%PATH%
SET BAZEL_PYTHON=C:\python34\python.exe
SET BAZEL_SH=C:\tools\msys64\usr\bin\bash.exe
SET CMAKE_BIN="cmake.exe"
SET CTEST_BIN="ctest.exe"
SET CTEST_OUTPUT_ON_FAILURE=1
SET CMAKE_BUILD_PARALLEL_LEVEL=16
SET CTEST_PARALLEL_LEVEL=16
IF EXIST git\googletest (
CD git\googletest
) ELSE IF EXIST github\googletest (
CD github\googletest
)
IF %errorlevel% neq 0 EXIT /B 1
:: ----------------------------------------------------------------------------
:: CMake
MKDIR cmake_msvc2022
CD cmake_msvc2022
%CMAKE_BIN% .. ^
-G "Visual Studio 17 2022" ^
-DPYTHON_EXECUTABLE:FILEPATH=c:\python37\python.exe ^
-DPYTHON_INCLUDE_DIR:PATH=c:\python37\include ^
-DPYTHON_LIBRARY:FILEPATH=c:\python37\lib\site-packages\pip ^
-Dgtest_build_samples=ON ^
-Dgtest_build_tests=ON ^
-Dgmock_build_tests=ON
IF %errorlevel% neq 0 EXIT /B 1
%CMAKE_BIN% --build . --target ALL_BUILD --config Debug -- -maxcpucount
IF %errorlevel% neq 0 EXIT /B 1
%CTEST_BIN% -C Debug --timeout 600
IF %errorlevel% neq 0 EXIT /B 1
CD ..
RMDIR /S /Q cmake_msvc2022
:: ----------------------------------------------------------------------------
:: Bazel
:: The default home directory on Kokoro is a long path which causes errors
:: because of Windows limitations on path length.
:: --output_user_root=C:\tmp causes Bazel to use a shorter path.
SET BAZEL_VS=C:\Program Files\Microsoft Visual Studio\2022\Community
%BAZEL_EXE% ^
--output_user_root=C:\tmp ^
test ... ^
--compilation_mode=dbg ^
--copt=/std:c++14 ^
--copt=/WX ^
--enable_bzlmod=true ^
--keep_going ^
--test_output=errors ^
--test_tag_filters=-no_test_msvc2017
IF %errorlevel% neq 0 EXIT /B 1
+1
View File
@@ -0,0 +1 @@
title: GoogleTest
@@ -0,0 +1,43 @@
nav:
- section: "Get Started"
items:
- title: "Supported Platforms"
url: "/platforms.html"
- title: "Quickstart: Bazel"
url: "/quickstart-bazel.html"
- title: "Quickstart: CMake"
url: "/quickstart-cmake.html"
- section: "Guides"
items:
- title: "GoogleTest Primer"
url: "/primer.html"
- title: "Advanced Topics"
url: "/advanced.html"
- title: "Mocking for Dummies"
url: "/gmock_for_dummies.html"
- title: "Mocking Cookbook"
url: "/gmock_cook_book.html"
- title: "Mocking Cheat Sheet"
url: "/gmock_cheat_sheet.html"
- section: "References"
items:
- title: "Testing Reference"
url: "/reference/testing.html"
- title: "Mocking Reference"
url: "/reference/mocking.html"
- title: "Assertions"
url: "/reference/assertions.html"
- title: "Matchers"
url: "/reference/matchers.html"
- title: "Actions"
url: "/reference/actions.html"
- title: "Testing FAQ"
url: "/faq.html"
- title: "Mocking FAQ"
url: "/gmock_faq.html"
- title: "Code Samples"
url: "/samples.html"
- title: "Using pkg-config"
url: "/pkgconfig.html"
- title: "Community Documentation"
url: "/community_created_documentation.html"
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="{{ site.lang | default: "en-US" }}">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% seo %}
<link rel="stylesheet" href="{{ "/assets/css/style.css?v=" | append: site.github.build_revision | relative_url }}">
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-197576187-1', { 'storage': 'none' });
ga('set', 'referrer', document.referrer.split('?')[0]);
ga('set', 'location', window.location.href.split('?')[0]);
ga('set', 'anonymizeIp', true);
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
</head>
<body>
<div class="sidebar">
<div class="header">
<h1><a href="{{ "/" | relative_url }}">{{ site.title | default: "Documentation" }}</a></h1>
</div>
<input type="checkbox" id="nav-toggle" class="nav-toggle">
<label for="nav-toggle" class="expander">
<span class="arrow"></span>
</label>
<nav>
{% for item in site.data.navigation.nav %}
<h2>{{ item.section }}</h2>
<ul>
{% for subitem in item.items %}
<a href="{{subitem.url | relative_url }}">
<li class="{% if subitem.url == page.url %}active{% endif %}">
{{ subitem.title }}
</li>
</a>
{% endfor %}
</ul>
{% endfor %}
</nav>
</div>
<div class="main markdown-body">
<div class="main-inner">
{{ content }}
</div>
<div class="footer">
GoogleTest &middot;
<a href="https://github.com/google/googletest">GitHub Repository</a> &middot;
<a href="https://github.com/google/googletest/blob/main/LICENSE">License</a> &middot;
<a href="https://policies.google.com/privacy">Privacy Policy</a>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/4.1.0/anchor.min.js" integrity="sha256-lZaRhKri35AyJSypXXs4o6OPFTbTmUoltBbDCbdzegg=" crossorigin="anonymous"></script>
<script>anchors.add('.main h2, .main h3, .main h4, .main h5, .main h6');</script>
</body>
</html>
+200
View File
@@ -0,0 +1,200 @@
// Styles for GoogleTest docs website on GitHub Pages.
// Color variables are defined in
// https://github.com/pages-themes/primer/tree/master/_sass/primer-support/lib/variables
$sidebar-width: 260px;
body {
display: flex;
margin: 0;
}
.sidebar {
background: $black;
color: $text-white;
flex-shrink: 0;
height: 100vh;
overflow: auto;
position: sticky;
top: 0;
width: $sidebar-width;
}
.sidebar h1 {
font-size: 1.5em;
}
.sidebar h2 {
color: $gray-light;
font-size: 0.8em;
font-weight: normal;
margin-bottom: 0.8em;
padding-left: 2.5em;
text-transform: uppercase;
}
.sidebar .header {
background: $black;
padding: 2em;
position: sticky;
top: 0;
width: 100%;
}
.sidebar .header a {
color: $text-white;
text-decoration: none;
}
.sidebar .nav-toggle {
display: none;
}
.sidebar .expander {
cursor: pointer;
display: none;
height: 3em;
position: absolute;
right: 1em;
top: 1.5em;
width: 3em;
}
.sidebar .expander .arrow {
border: solid $white;
border-width: 0 3px 3px 0;
display: block;
height: 0.7em;
margin: 1em auto;
transform: rotate(45deg);
transition: transform 0.5s;
width: 0.7em;
}
.sidebar nav {
width: 100%;
}
.sidebar nav ul {
list-style-type: none;
margin-bottom: 1em;
padding: 0;
&:last-child {
margin-bottom: 2em;
}
a {
text-decoration: none;
}
li {
color: $text-white;
padding-left: 2em;
text-decoration: none;
}
li.active {
background: $border-gray-darker;
font-weight: bold;
}
li:hover {
background: $border-gray-darker;
}
}
.main {
background-color: $bg-gray;
width: calc(100% - #{$sidebar-width});
}
.main .main-inner {
background-color: $white;
padding: 2em;
}
.main .footer {
margin: 0;
padding: 2em;
}
.main table th {
text-align: left;
}
.main .callout {
border-left: 0.25em solid $white;
padding: 1em;
a {
text-decoration: underline;
}
&.important {
background-color: $bg-yellow-light;
border-color: $bg-yellow;
color: $black;
}
&.note {
background-color: $bg-blue-light;
border-color: $text-blue;
color: $text-blue;
}
&.tip {
background-color: $green-000;
border-color: $green-700;
color: $green-700;
}
&.warning {
background-color: $red-000;
border-color: $text-red;
color: $text-red;
}
}
.main .good pre {
background-color: $bg-green-light;
}
.main .bad pre {
background-color: $red-000;
}
@media all and (max-width: 768px) {
body {
flex-direction: column;
}
.sidebar {
height: auto;
position: relative;
width: 100%;
}
.sidebar .expander {
display: block;
}
.sidebar nav {
height: 0;
overflow: hidden;
}
.sidebar .nav-toggle:checked {
& ~ nav {
height: auto;
}
& + .expander .arrow {
transform: rotate(-135deg);
}
}
.main {
width: 100%;
}
}

Some files were not shown because too many files have changed in this diff Show More