Compare commits

..

436 Commits

Author SHA1 Message Date
beder 8d2c2ae3fb Closed branch new-api (since we're going to make it a separate repository).
The new API will now be found in the repository yaml-cpp.new-api
2012-05-19 15:03:29 -05:00
beder 39171cf060 Fixed explicitly qualifying iterator type for gcc 2012-05-14 22:18:46 -05:00
beder b20e0a5e54 Switched all new API runtime_error exceptions to exceptions that derive from YAML::Exception 2012-05-14 22:12:31 -05:00
beder cfb7d46246 Added test for BOOST_FOREACH on a map 2012-05-08 12:30:02 -05:00
beder adc0e7e7e9 Tweaked node iterator tests 2012-05-08 12:27:04 -05:00
beder bd9103f44a Added node iterator tests 2012-05-08 12:23:37 -05:00
beder 485afcb633 Added proper typedefs for BOOST_FOREACH to work 2012-05-08 12:20:28 -05:00
beder b1a1f8ce2d Patched signed -> unsigned warning (issue 98) 2012-02-14 10:11:44 -06:00
beder d50fbf59d7 Fixed warning about binary's shadowing members functions 2012-01-25 17:40:16 -06:00
beder 8d0ee05dbe Renamed append -> push_back (to play nice with STL algorithms 2012-01-21 12:11:40 -06:00
beder 5647711578 Added != for Binary 2012-01-21 02:02:24 -06:00
beder 2731f862a5 Added convert<> specialization for Binary 2012-01-21 01:54:54 -06:00
beder e17734de33 Renamed the base64 methods, and switched the EncodeBase64 one to return a string (to make it easy to use elsewhere) 2012-01-21 01:33:49 -06:00
beder b66197bdf4 Refactored the base64 binary to its own space with a unified class that (will) be used for parsing (in addition to emitting) 2012-01-21 01:18:37 -06:00
beder 41a7f7a026 Moved including boost headers to after the project's headers 2012-01-21 00:22:34 -06:00
beder 8d658bbf61 Patched for issue 142 for MSVC 2012-01-21 00:15:01 -06:00
beder b0b0c191b9 Flattened the src directory, and added back yaml.h (since it used to be generated) 2012-01-21 00:06:32 -06:00
beder 90f48fd035 Began new-api branch, and removed all traces of the old api from this branch 2012-01-20 23:36:08 -06:00
beder 9403ac04fa Fixed hex and oct emitting (it now adds the 0x or 0 prefix) 2012-01-13 00:00:11 -06:00
beder b266447d2e Added test for new API octal/hex conversion 2012-01-12 23:55:15 -06:00
beder 88540cc96a Fixed double -> int conversion (now throws) for old API 2012-01-12 23:52:51 -06:00
beder 60fa4d7f63 Updated new API conversion to handle nan/inf and to throw when the conversion didn't use the entire string (e.g., parsing 1.2 as an integer) 2012-01-12 23:49:05 -06:00
beder 924bb8b00e Added default parameters for the as<> function (new API) 2012-01-12 01:03:31 -06:00
beder f3446cbcea Added LoadFile and LoadAllFromFile (new API) 2012-01-11 21:31:01 -06:00
beder 2dbcc58912 Fixed bug in parsing escaped newline (it was being clipped like a regular newline) 2012-01-11 17:55:27 -06:00
beder 29859af6c0 Removed some extra stuff in the comment/newline in flow map tests, which really should be illegal (since implicit keys can't span multiple lines). It would be impossible to fix if we keep the immediate-output we're doing now - the only way to prevent it would be to hold on to a key's text until we got to the value token to make sure it could be an implicit key 2012-01-11 17:06:27 -06:00
beder e4838f0933 Fixed signed/unsigned mismatch with the new precision code 2012-01-11 16:50:06 -06:00
beder 8123b27c09 Added parsing emitter tests with the new API, two fail 2012-01-11 16:41:13 -06:00
beder 2d166d1733 Disallowed a plain scalar with just a dash 2012-01-11 16:39:24 -06:00
beder 8f948b8f37 Added float/double precision setters 2012-01-11 14:34:04 -06:00
beder 537063f907 Added explicit conversion from an iterator value to a Node. This conversion was always allowed (since the iterator value is derived from Node, but since Node has a templated constructor, that would take precedence over the derived-to-base conversion. This didn't seem to be a problem in gcc or clang, but MSVC seems to have trouble. (new API) 2012-01-11 13:58:18 -06:00
beder d2f5a6086a Added boost find/includes to the new API CMake instructions 2012-01-11 13:19:31 -06:00
beder c82122ba36 Fixed compiler error in iterator_base friend forward declaration in node on clang (and I hope MSVC), plus warnings on clang 2012-01-07 01:42:21 -06:00
beder 569a0461f2 Fixed assignment with an empty node (new API) - a segfault that only showed up in debuggable 2011-12-20 22:19:54 -06:00
beder 66980da9d2 Added overload for emitting unsigned char 2011-11-14 17:00:28 -06:00
beder c6e5ad350b Added single character emitting 2011-11-14 16:23:14 -06:00
beder fe5fcbb84e Added missing includes (iostream) for the tests 2011-11-13 16:12:39 -06:00
beder c4b3b5e52e Added (unspecified-type) bool conversions for Node (new API) 2011-11-13 16:05:42 -06:00
beder 50b6a02907 Set the default operator >> to not compile unless there is a scalar conversion, so it doesn't interfere with user-defined types 2011-11-01 17:19:03 -05:00
beder a853a7a14d Fixed emitter bug with colon at the end of a scalar in a flow collection 2011-10-31 19:16:17 -05:00
beder e4e410af5b Switched the utf bom checking to putback in the stream (instead of keeping a secondary buffer), which fixes a bug when there's only one ascii character 2011-10-20 22:29:41 -05:00
beder df9bcd5f12 Fixed typo in computing private headers (no effect on the build, just for the project files) 2011-10-20 21:50:47 -05:00
beder a6961e8dae Added parser test for single char input (that fails) 2011-10-20 13:53:27 -05:00
beder b204169c65 Fixed broken includes when using the old api 2011-10-18 15:13:10 -05:00
beder b9a708d5b3 Fixed installation (we now install the whole include header tree) 2011-10-18 14:55:31 -05:00
beder 692347fd97 Added a .hgignore file that ignores the generated yaml.h 2011-10-18 14:48:07 -05:00
beder 488c3d6cef Fixed the #ifdefs for the api stuff 2011-10-18 14:47:35 -05:00
beder 075f8449f8 Couldn't get the copy command to work for yaml.h, so switched to configure_file 2011-10-18 14:43:48 -05:00
beder 482c0afe2f Split the yaml.h file into new/old API, which we'll then copy to yaml.h at build time (so the right one gets installed) 2011-10-18 00:16:51 -05:00
beder 3663d5f24b Merged with the main branch, which just updated version count to 0.2.7 2011-09-18 00:26:18 -05:00
beder 0db8182839 Updated old api spectests with common spec examples 2011-09-17 23:57:40 -05:00
beder 0c50a9d861 Set the default build to the old API, and removed the duplicate spec test implementation for the old api 2011-09-17 23:46:48 -05:00
beder 4260b3460f Moved conversion.cpp to the old api, where it belongs 2011-09-14 01:49:06 -05:00
beder 36086448d2 Added bool conversions 2011-09-14 01:48:36 -05:00
beder f21c96188d Added tag release-0.2.7 for changeset d0bed6918076 2011-09-14 01:23:25 -05:00
beder 138b2f4733 Bumped version to 0.2.7 2011-09-14 01:23:15 -05:00
beder 4e6418ff12 Added Dump() 2011-09-13 14:49:00 -05:00
beder 0a1022a526 Added tags to Node emitter output 2011-09-13 14:47:33 -05:00
beder 2798b20b31 Finished adding old spec tests 2011-09-13 14:31:00 -05:00
beder 183ba98d03 Switched YAML::Parse to YAML::Load, and added LoadAll 2011-09-13 14:24:47 -05:00
beder d899562ba1 Added 7.x and 8.x tests with tags - all that's left is multiple docs in stream 2011-09-13 14:20:32 -05:00
beder de3377459a Added 6.x tests with tags 2011-09-13 14:18:00 -05:00
beder c314860e00 Added IsNull, IsScalar, IsSequence, IsMap functions, so you don't have to query Type() 2011-09-13 14:10:27 -05:00
beder d2a10e3d53 Copied 2.x tests with tags 2011-09-13 14:07:22 -05:00
beder 8dcd96dbd2 Added tags to Node 2011-09-13 14:00:47 -05:00
beder 535f81a387 Added a convert<> specialization for YAML::_Null (so you can say node[YAML::Null]) 2011-09-13 02:03:56 -05:00
beder e61826e5a2 Copied over the 8.x tests that don't have tags 2011-09-13 01:56:44 -05:00
beder 367d2f9112 Copied over the 7.x tests that don't have tags 2011-09-13 01:46:42 -05:00
beder 4e90ee6201 Copied over the 6.x tests that don't have tags 2011-09-13 01:36:27 -05:00
beder cec996ef81 Copied over the 5.x tests 2011-09-13 01:28:32 -05:00
beder ef892a15b7 Copied over all the 2.x tests that are (a) single doc and (b) don't have tags 2011-09-13 01:23:30 -05:00
beder 7f283a3a38 Factored out spec examples, and sketched skeleton for spec tests for new API 2011-09-12 22:55:37 -05:00
beder 2b6f31dd0d Added temp variable tests 2011-09-12 22:09:16 -05:00
beder 78ebd14551 Switched Node::operator=(const Node&) to *not* force itself to create its node first (since we're just assigning them) 2011-09-12 22:05:43 -05:00
beder 04152dae8f Switched the node_ref to *always* create its data (since now the Node itself doesn't always create itself) 2011-09-12 22:03:11 -05:00
beder 14955a2a63 Set the pimpl node in Node to be optional, so we don't create unnecessary guys every time you call Node tmp = foo[value]; 2011-09-12 21:59:47 -05:00
beder a2aa5a2f75 Fixed NodeBuilder bug when an alias was in a map - we weren't pushing that guy as a key 2011-09-12 14:24:27 -05:00
beder b8cc21eb3c Fixed new API node key/value insertion in NodeBuilder (it was using the wrong condition on when it had added a key already) 2011-09-12 13:25:41 -05:00
beder ad95934844 Added failing self-reference tests 2011-09-12 12:48:51 -05:00
beder 95f763f466 Added two alias tests 2011-09-12 12:42:23 -05:00
beder f38e38df09 Implemented std::map decode (and fixed bug in the Node iterator - the reference_type should be just a plain value, since it's created on-the-fly) 2011-09-12 00:29:39 -05:00
beder cf240daf63 Added reading/writing std::list 2011-09-11 23:18:19 -05:00
beder 2a71e8868b Added reading/writing std::vector 2011-09-11 23:14:52 -05:00
beder cf5695e320 Removed the (unimplemented) operator <, and added operator == (in place of is()) for nodes 2011-09-11 22:56:04 -05:00
beder 30ce282198 Added mutable operator[] for integral types (you can only grow the sequence if you specify the *next* element) 2011-09-11 22:51:49 -05:00
beder 4dd9f036d3 Implemented operator[] specialization, but only const (should the sequence be mutable?) 2011-09-11 21:51:04 -05:00
beder e8210b476c Started specialization for operator[] for integers 2011-09-11 21:32:47 -05:00
beder d8955fc52c Set the map iterator to filter over undefined items 2011-09-11 19:44:27 -05:00
beder d4e5a3ea93 Added failing map iterator count test 2011-09-11 17:36:08 -05:00
beder c8fc3c9592 Implemented the map size computation 2011-09-11 17:16:26 -05:00
beder 9c6bd61398 Switched the implementation of maps from list<pair> to map (but just pointer comparison) 2011-09-11 16:56:38 -05:00
beder ad28ffc6f8 Added computing and caching the sequence size 2011-09-11 16:21:36 -05:00
beder 73a47d1c1c Added some small map tests 2011-09-11 16:02:31 -05:00
beder bb1a816a3a Added dependency management (to cause nodes to become defined if their children do) 2011-09-11 15:59:53 -05:00
beder a9914342e0 Added a few simple node tests, and the sequence one doesn't pass (let's work now) 2011-09-10 23:31:12 -05:00
beder 10d712d060 Started Node tests (for the new API Node) 2011-09-10 23:22:30 -05:00
beder 4bbe984bdc Fixed up the old API stuff, and removed the util/value (since it's no longer needed) 2011-09-10 23:11:28 -05:00
beder fb538c9490 Set up util/parse for the new API 2011-09-10 23:03:02 -05:00
beder 2851f5f8c9 Fixed minor things that used the old API, compiles/links/runs\! 2011-09-10 22:59:27 -05:00
beder 24c55b434a Added stubs for spec and parser tests with the new API 2011-09-10 18:05:35 -05:00
beder 7cdf684ae6 Moved old api tests to subfolder 2011-09-10 18:02:07 -05:00
beder e905b74232 Major switch from Value -> Node. The library compiles with the new API, but tests are still oldies, and don't compile 2011-09-10 17:57:23 -05:00
beder 8fd372b0db Start of moving Value -> Node and Node -> old API Node (with a #define toggle) 2011-09-10 17:18:15 -05:00
beder 33a71151ca Added helper emitter functions, but we have a problem: YAML::Value is already a manipulator 2011-09-10 16:50:44 -05:00
beder 59ce694ca3 Implemented value events emitter 2011-09-10 16:23:18 -05:00
beder b3086ac260 Fixed node iterator 2011-09-10 14:36:10 -05:00
beder c12a03473e New iterators work\! 2011-09-10 14:16:50 -05:00
beder 89f87d855d Updated the node/value classes with the new iterators, they compile until we try to instantiate anything 2011-09-10 14:11:42 -05:00
beder 81243c87d4 Finished the main iterator stuff, now have to hook it to the nodes/values 2011-09-10 14:06:49 -05:00
beder f809206baa Halfway towards factoring out a node_iterator, and then building iterator on top of it 2011-09-10 13:20:22 -05:00
beder dcf9309ea8 Started emitting events for Values 2011-09-10 12:42:42 -05:00
beder b8e9b52af7 Implemented sugar Parse() functions 2011-09-09 23:40:19 -05:00
beder 8185fa48f1 Implemented (untested) the value builder 2011-09-09 23:28:21 -05:00
beder 91a3f020ff Map iterator works\! 2011-09-09 19:25:11 -05:00
beder f0ae0254d4 Sequence iterator works\! 2011-09-09 19:22:17 -05:00
beder b35a332fdd Switched iterators to typedef's, with a bit of finagling so we can forward-declare them 2011-09-09 19:07:37 -05:00
beder f60fb95ab6 Base iterator stuff compiles :) 2011-09-09 18:46:37 -05:00
beder 9de9ac7e7e Started writing new iterators 2011-09-09 16:17:59 -05:00
beder 603c726811 Made the 'data' member optional in node_ref - it's only created on-demand, so we don't waste extra memory every time we do Value tmp = v; 2011-09-09 14:26:55 -05:00
beder 8e52497d96 Switched value = otherValue to assign the actual nodes after setting the reference (so that tmp = foo['bar']; tmp = other; is the same as foo['bar'] = other;) 2011-09-09 14:02:18 -05:00
beder 7a1e47e03f Added append() 2011-09-09 02:51:35 -05:00
beder 255a392eb9 Switched operator[] access to node reference equality, not node equality 2011-09-09 02:39:36 -05:00
beder e32b3cd93f Switched memory to using shared nodes, and node_data to keep only naked node pointers, not shared nodes (to break the cycle, and we don't need weak pointers because their memory is guaranteed to exist, via 'memory') 2011-09-09 02:29:17 -05:00
beder 37cd3bd53c Added half of the std::map conversion (we don't have reading from Values yet) 2011-09-08 02:10:04 -05:00
beder c080478444 Added back the streamable conversions 2011-09-08 02:05:03 -05:00
beder bb2eafc387 Switched convert to a templated struct that can be specialized (so we can partially specialize it) 2011-09-08 02:02:15 -05:00
beder 21fbb461c0 Added streamable conversions 2011-09-08 00:48:40 -05:00
beder 3b0cc619b2 Implemented conversion for std::string, including a bypass-accessor to the scalar value 2011-09-07 15:49:01 -05:00
beder a9c7f8cc5a Set the 'memory' to only store node_refs, not nodes 2011-09-07 14:56:04 -05:00
beder 82fa4e71db Implemented is() 2011-09-07 14:46:25 -05:00
beder 980fb59d4b Added (another) layer - now 'node_ref' is between node and node_data, and it decrees whether nodes are identical 2011-09-07 14:44:18 -05:00
beder 75f3a36547 Implemented map get(), and it would work (I think) if we implemented convert() for strings 2011-09-07 03:36:50 -05:00
beder 2d75a631e2 Set up map searching by templated key 2011-09-07 03:21:24 -05:00
beder 7a3f425720 Reorganized so that we don't have cyclic include problems 2011-09-07 02:59:58 -05:00
beder 6fa53f9714 Implemented map access by already-existing node 2011-09-07 02:39:59 -05:00
beder a07642f156 Started implementing node_data 2011-09-07 00:45:28 -05:00
beder 555cfae28d Compiles/links assignment to string 2011-09-07 00:20:23 -05:00
beder 74ffe6a61b Value stuff compiles/links with lots of placeholder functions 2011-09-07 00:12:24 -05:00
beder 57617cc5cc Sketched more of the implementation 2011-09-06 23:11:38 -05:00
beder 40605b78c7 Moved the value header to its own subfolder 2011-09-06 16:06:46 -05:00
beder 1d7e6a6589 Sketched out interface for YAML::Value 2011-09-06 01:43:15 -05:00
beder d6811c42a8 Merged from trunk 2011-09-06 01:10:27 -05:00
beder ae14042031 Added notes about the two failing tests - that they're (I think) bugs in the YAML spec 2011-09-06 01:05:14 -05:00
beder 126dfdb155 Switched YAML::Binary interface to use unsigned chars, not chars 2011-09-06 00:39:31 -05:00
beder a8fdb1718d Added overload for operator [] for char * (non-const version) 2011-09-06 00:32:53 -05:00
beder ec3a9ecbf0 Fixed empty string emitter bug (it now with auto-quote it 2011-09-06 00:24:10 -05:00
beder ced351dec8 Switched the 'pragma once' to only happen on MSVC, or gcc >= 3.4 (it was causing trouble on the sun compiler) 2011-09-06 00:16:03 -05:00
beder f56d453050 Added api sketch 2011-09-04 19:50:08 -05:00
beder 44bee0b8ad Added .hgeol for native eols 2011-08-24 02:59:58 -05:00
convert-repo 301db885ea update tags 2011-08-24 13:44:56 +00:00
jbeder b5eaeac0b0 Removed ATOMIC_TYPE, an old enum that wasn't used any more 2011-08-22 21:37:51 +00:00
jbeder 088401fa88 Added test for anchor/alias in flow 2011-08-04 21:50:04 +00:00
jbeder a1fc9d8d88 Forced a newline after any comments 2011-08-04 21:47:57 +00:00
jbeder dae85e28e2 Included <cstddef> for NULL 2011-08-04 18:47:37 +00:00
jbeder 7f9aa35edb Fixed negative infinity parsing 2011-07-10 18:29:44 +00:00
jbeder 9ec2b96b19 Added parsing .inf and .nan (and friend) 2011-07-10 16:27:40 +00:00
jbeder ede50424ef Fixed includedir for the .pc.cmake file 2011-05-29 02:17:49 +00:00
jbeder ee446d00ea Added emitting std::set (and refactored the stl emitters a bit) 2011-05-18 21:07:25 +00:00
jbeder f7bee99fa3 Added include <cstdlib> for using 'NULL' (apparently gcc 4.6 is more strict) 2011-05-03 21:55:49 +00:00
jbeder 2402c4d7e9 Set version to 0.2.6 2011-03-30 01:33:02 +00:00
jbeder 95d05dcfa5 Switched project label to use 'nicer' suffix (e.g., md instead of /MD) 2011-03-21 23:03:01 +00:00
jbeder e468dd7d38 Added eol-style=native prop to missing files 2011-03-17 02:06:10 +00:00
jbeder e1f27488d1 Fixed mixed line endings 2011-03-17 02:04:34 +00:00
jbeder 509ba0d640 Marked Parser, Emitter, Node, Iterator, Mark, and Null for exporting to a DLL. It appears to work properly, although VS gives me lots of warning C4251 since I didn't export all data members of each of the above classes.
It seems that it's not necessary to export those members (as long as you can't access them), and most of them are STL instances, which apparently cause lots of problems for DLLs. (For example, you simply can't export instances of std::map; see http://support.microsoft.com/kb/168958.)
2011-03-16 02:31:30 +00:00
jbeder 4941d8ff75 Set eol-style to native for all sources 2011-03-16 01:13:41 +00:00
jbeder d1221b4456 Added option to disable compilation of contrib code 2011-03-16 01:10:57 +00:00
jbeder 9d83747162 Removed comparison/implicit conversion operators for Node, and renamed Node::Read<T>() to Node::to<T>() 2011-03-15 05:49:56 +00:00
jbeder 2ad6f06df5 Added newline at the end 2011-03-10 00:23:15 +00:00
jbeder 0f0bd2bf2d Updated for error in spec test 2011-03-04 04:19:34 +00:00
jbeder ddfbad6c7f Added spec tests through chapter 8, all new ones pass except 8.21, which I think is wrong 2011-03-04 04:14:08 +00:00
jbeder 1132c8df21 Fixed folding bug (detecting indentation, example 8.2), and clipping/stripping empty strings (example 8.6) 2011-03-04 02:26:59 +00:00
jbeder cee0974abd Refactored parse.cpp so that VS doesn't complain, added MinSizeRel build setting, and fixed numbering in the spec tests 2011-03-03 20:01:32 +00:00
jbeder 5b1ca74376 Added explicit doc start/end tokens for the emitter, and set it so that if you try to write after you've already written a full doc, it writes a doc start and continues 2011-03-03 09:26:12 +00:00
jbeder 77d20873dc Removed the default --- at the start of all emitter output 2011-03-03 08:57:00 +00:00
jbeder f5b09d3ec6 Switched the scanner list of owned indent markers to a ptr_vector 2011-03-03 08:34:30 +00:00
jbeder 06eae35c31 Switched the emitter state's stack of groups to a ptr_stack 2011-03-03 08:11:14 +00:00
jbeder bbb19cf5c0 Added parsing of output to emitter tests 2011-03-03 08:04:30 +00:00
jbeder bf2bb91dc6 Compressed the sequence-of-maps emitting (got rid of the unnecessary newline) - issue 61 2011-03-03 03:37:54 +00:00
jbeder 9419d411f8 Set the precision of emitting float/double to 15 2011-03-03 02:38:35 +00:00
jbeder 6f7995d27e Merged r444:449 from the node refactoring branch to the trunk 2011-03-03 00:19:26 +00:00
jbeder e6c1007043 Tiny formatting change in CMake file 2011-03-02 21:09:38 +00:00
jbeder f1f983764f Removed the old, unsupported Visual Studio files (just build with CMake) 2011-03-02 21:03:03 +00:00
jbeder 152e48f0d0 Prettied up the bool formatting code 2011-03-02 20:59:39 +00:00
jbeder 396e3309de Refactored bool emitting to make it 1) correct for the short bool form and 2) not barf on early versions of VS 2011-03-02 20:55:05 +00:00
jbeder c6e085524a Included 'mark.h' in the graphbuilder so that its method for removing the unused param warning (casting to void) compiles on VS 2011-03-02 20:30:54 +00:00
jbeder 142a4bca9b Flipped the include guard and the pragma, and don't use the pragma for early versions of gcc (< 3.4) 2011-03-02 06:11:41 +00:00
jbeder f4d2f11d2c Small changes to eliminate compiler warnings for 'nite' in issue 83 2011-03-02 05:29:46 +00:00
jbeder fb3b491734 Moved the local structs from Emitter::Write(bool) to an anonymous namespace in the hopes that Visual Studio <= 2003 will be happy 2011-03-02 05:21:25 +00:00
jbeder 357cd1e122 Fixed 'long long' error in VS 2002, issue 90 2011-03-02 05:15:36 +00:00
jbeder 898d29d9b7 Merged the debuggable branch's CMakeLists.txt (and added a build for RelWithDebInfo) - note that the options are only for gcc 2011-03-02 05:02:01 +00:00
jbeder 7b6e87277d Merged contrib folders from the graphbuilder-api branch, including the recursive search in CMakeLists.txt 2011-03-02 04:48:04 +00:00
jbeder 0823af5369 Merged CMakeLists.txt from issue 87 - now it's cleaner, and supports Windows much better 2011-03-02 04:37:55 +00:00
jbeder 3192d29e66 Switched exception constants to const char * const (from const std::string) so we don't have to construct them all in every translation unit, and switched the exception class to derive from std::runtime_error (so it handles what() for us) 2011-03-02 04:12:57 +00:00
jbeder 3f6254822d Included cstddef to stream.h 2011-02-05 22:28:08 +00:00
jbeder 9e345650e1 Added Anchor() regex (so that we're not just using Alphanumeric to match anchors), but it's still not 100% right (it shouldn't allow non-printable characters, e.g.). Also fixed a test that was broken along these lines (if a colon immediately follows an anchor, it's part of the anchor) 2011-01-31 17:47:20 +00:00
jbeder 7fd040c311 Fixed emitting colon at end of scalar bug 2010-12-03 21:52:04 +00:00
jbeder 6f6e096316 Added long long types to the emitter 2010-11-15 01:46:33 +00:00
jbeder 6e06857bf9 Updated Visual Studio project file. 2010-11-09 19:59:25 +00:00
jbeder 8c913c8ce4 Refactored tags so we can emit secondary tags (and named local tags) 2010-10-28 23:06:16 +00:00
jbeder 24dc58b68d Implemented binary emitting without the binary tag 2010-10-28 21:53:54 +00:00
jbeder d6e56a0941 Refactored emitter so that it emits the : for an implicit key right away 2010-10-22 04:19:01 +00:00
jbeder cb8eee46f0 Added more tests for the newline, and disallowed newlines after implicit block keys 2010-10-22 03:53:33 +00:00
jbeder 59745a4cff Added YAML::Newline manipulator for the emitter 2010-10-21 22:02:29 +00:00
jbeder 7bad58ba47 Merged the extra tests from other-tags into the trunk (forgot last commit) 2010-10-19 06:51:54 +00:00
jbeder 973ce78fe1 Merged the other-tags branch into the trunk (this wasn't an rX:Y merge, since the branch wasn't branched directly from the head of the trunk) 2010-10-19 06:46:55 +00:00
jbeder 59d126f5b0 Updated CMake iPhone settings 2010-10-18 21:35:34 +00:00
jbeder 2d3722db85 Made emitter noncopyable, which should fix any auto_ptr warnings 2010-10-18 07:24:42 +00:00
jbeder 91944e4538 Fixed the rest of the includes to explicitly state yaml-cpp/ 2010-10-18 07:22:53 +00:00
jbeder 7e511c41ad Forgot to add the new header location to the project (not important for compiling, but it is for the various generators) 2010-10-18 07:09:07 +00:00
jbeder 2a256f2870 Moved all the includes to a subfolder yaml-cpp so they don't interfere with other libraries' includes 2010-10-18 07:05:53 +00:00
jbeder 12d2beda29 Merged r366:387 from the jbeder-event-api branch 2010-10-18 06:45:03 +00:00
jbeder 78db8b02c8 Fixed missing header 2010-05-01 20:05:15 +00:00
jbeder d99cb95d2d Tagged version 0.2.5 2010-03-15 19:25:02 +00:00
jbeder 11903da3fb Added overloads for parsing stl maps and vectors 2010-03-15 04:25:17 +00:00
jbeder e58f0f31b7 Set alias nodes to return the tag of their anchor 2010-03-15 04:10:36 +00:00
jbeder 8080400cb6 Disabled those warnings in the release version of the .svn too. 2010-03-03 05:33:07 +00:00
jbeder b869aab8e1 Updated to remove most of the warnings in Visual Studio. (There's still the one about all control paths returning a value left.) Fixed one warning (when an istream converts to void * to then convert to bool), and disabled three. 2010-03-03 05:30:06 +00:00
jbeder 3720ceb57b Added newline to install and license files 2009-12-21 20:35:27 +00:00
jbeder 6d37c370ba Added missing include 2009-12-02 05:59:18 +00:00
jbeder ac3d95f499 Added test for duplicate key 2009-12-02 01:29:16 +00:00
jbeder f4b81e7349 Fixed leak when adding duplicate keys (and actually changed the behavior - now we take the first instance, not the last) 2009-12-02 01:01:45 +00:00
jbeder 8f0f0d62a7 Refactored emitter operator << overloads to not template them, so it's easier to overload for pointer types 2009-11-17 20:21:22 +00:00
jbeder bbf510d6cc Refactored the traits a bit, and added displaying the key to string and numeric key not found errors 2009-11-12 17:00:12 +00:00
jbeder 7b33c7c4b4 Small bug from switching static initialized regexes to lazy ones 2009-11-12 05:45:47 +00:00
jbeder 63cc5adefd Replaced conversion macros with SFINAE 2009-11-10 21:23:52 +00:00
jbeder 71489e5abf Overloaded more integral types for emitting 2009-11-06 03:24:12 +00:00
jbeder 472bb80c9c Fixed the return value of the integral conversion functions, and also unset the dec flag so it reads other bases (just a temporary fix, since we're officially supposed to read binary too) 2009-11-06 03:13:54 +00:00
jbeder ca79c3da7f Switched the Exp:: regexes to functions that lazily evaluate their regexes 2009-11-04 22:56:59 +00:00
jbeder fea35e3e8f Fixed silly bug in node cloning 2009-10-30 20:29:14 +00:00
jbeder a55970c879 Added some block scalar tests (with errors) 2009-10-30 18:16:26 +00:00
jbeder 4dd1b19e51 Updated the Visual Studio solution for the new files/renaming. 2009-10-30 04:52:13 +00:00
jbeder b1f143cfaf Fixed bug with block maps with null value (the next key was being read as the value) 2009-10-30 01:06:19 +00:00
jbeder c3f222e4d9 Fixed the whitespace tracking when we escape a newline in a double-quoted string 2009-10-29 22:55:50 +00:00
jbeder e8beb6c98f Fixed mistake in test 2009-10-29 22:39:53 +00:00
jbeder 08ac48518f Refactored the compact map notation, which made it easy to implement explicit keys for compact maps 2009-10-29 22:09:50 +00:00
jbeder 7c4a8dad85 Added case for parsing a compact key: value pair in a flow sequence with a null key 2009-10-29 22:01:01 +00:00
jbeder 011a608b5a Implemented adjacent key:value pairs when the key is JSON-like 2009-10-29 21:05:48 +00:00
jbeder 72dceba671 Added test 2009-10-29 20:45:20 +00:00
jbeder 5618157a1e Added flow collection tests 2009-10-29 20:35:07 +00:00
jbeder 72413bafd4 Added ability to read compact maps in a flow sequence 2009-10-29 19:41:46 +00:00
jbeder cccbddb54c Merged r295:305 from the tags branch to the trunk 2009-10-29 15:48:06 +00:00
jbeder 4f74f805c2 Removed crt stuff (we can do memory leak checking in Linux easier) 2009-10-27 14:55:01 +00:00
jbeder 3d24383686 Removed unused test yaml file 2009-10-27 14:48:01 +00:00
jbeder 5986307b8e Now actually removed yaml-reader 2009-10-27 14:47:08 +00:00
jbeder d3b00fa6c5 Reverted yaml-reader name change 2009-10-27 14:45:14 +00:00
jbeder 50b026a3a9 Renamed yaml-reader test (try 2) 2009-10-27 14:39:48 +00:00
jbeder 7d5988401e Renamed yaml-reader test 2009-10-27 14:38:53 +00:00
jbeder 47628bf25e Tagged version 0.2.4 2009-10-25 20:27:31 +00:00
jbeder 52e3e0a4aa Updated the CMake globbing so it only compiles sources starting with a lowercase letter (apparently Mac OS auto-generates files looking like ._whatever and it was trying to compile those too) 2009-10-25 18:01:48 +00:00
jbeder 770466d5d4 Tagged version 0.2.3 2009-10-22 21:55:44 +00:00
jbeder 9ee348d62e Small refactoring 2009-10-22 21:51:32 +00:00
jbeder 2b2fca758c Switch to flow map when emitting an empty block map 2009-10-22 14:21:12 +00:00
jbeder 2022379cf4 Switch to flow sequence when emitting an empty sequence 2009-10-22 14:17:12 +00:00
jbeder 68df40c1dc Fixed bug in plain scalar folding 2009-10-20 14:47:16 +00:00
jbeder 0bf5b133e1 Added a bunch of tests, simplified the testing code 2009-10-20 14:43:24 +00:00
jbeder 9a28c9178e Merged r270:HEAD of the emitting-unicode branch 2009-10-19 23:31:11 +00:00
jbeder ae937a31d2 Fixed little bug in parser commit 2009-10-19 22:42:30 +00:00
jbeder afc7c1088d Added default constructor to Parser, and cleaned it up a bit 2009-10-19 22:40:46 +00:00
jbeder dd29c8181a Update CMakeLists.txt to append, not overwrite CMAKE_CXX_FLAGS 2009-10-19 22:32:26 +00:00
jbeder 06b8d4bacf Patched for optional building of tests and tools 2009-10-12 05:21:00 +00:00
jbeder 41a776b397 Refactored the UTF-8 emitting 2009-10-08 21:05:56 +00:00
jbeder 15d5b2b533 Fixed the emitter unicode output 2009-10-07 06:46:05 +00:00
jbeder fb443b3056 Updated signature of Parser::GetNextDocument (issue 45) 2009-09-29 18:25:11 +00:00
jbeder 60fce621e8 Modified old gcc version patch so it still uses the new Node::Read in Visual Studio. Also broke up the \uNNNN characters in the spec tests into \xNN-type strings. 2009-09-16 05:31:28 +00:00
jbeder a20141bca7 Patched for gcc version <= 3.3 (just fall back to original version of Node::Read) 2009-09-16 04:01:40 +00:00
jbeder d957634c25 Tagged version 0.2.2 2009-09-09 01:37:23 +00:00
jbeder 7b889b9f35 Cleaned up the read template overloads (per litb's update); it seems the old version didn't compile in VS2008. Also updated the VS project files. 2009-09-08 20:57:18 +00:00
jbeder 246d8993d2 More tests, found bug in implicit keys in flow sequence 2009-09-08 05:35:39 +00:00
jbeder e4540f2c2a Fixed flow folding, and made the separation slightly cleaner (but the whole scanscalar thing could use a major refactoring) 2009-09-08 05:24:06 +00:00
jbeder 1d52e03750 Tests through 6.29, skipping directives and tags 2009-09-08 04:16:45 +00:00
jbeder d38c4e6026 (Actually) fixed the folding newline bug, but it's a bit messy, and we don't accurately make the distinction between block folding and flow folding 2009-09-07 23:29:04 +00:00
jbeder afe01a86bd Fixed newlines in folded scalars bug 2009-09-07 22:48:32 +00:00
jbeder 994e6af8e0 Simplified testing output 2009-09-07 22:17:02 +00:00
jbeder d15ce26b58 Fixed bugs with tab as non-content whitespace 2009-09-07 17:12:45 +00:00
jbeder a725d4b190 Fixed bugs in escape characters (both parsing and emitting) 2009-09-07 16:31:23 +00:00
jbeder 315205298a Fixed error in test 2009-09-07 06:56:05 +00:00
jbeder e1a112a761 Fixed last newline of folded scalar bug 2009-09-07 06:54:38 +00:00
jbeder 21232e3bef Fixed bug in trailing newlines of plain scalars 2009-09-07 06:42:03 +00:00
jbeder 90be7e75c2 Added spec tests (minus tags, directives, and BOM) up through example 5.12 - this exposed an error in line folding 2009-09-07 06:35:37 +00:00
jbeder bdf6008dea Added spec tests through example 2.13 2009-09-06 22:17:53 +00:00
jbeder 21c87d4961 Tagged release 0.2.1 for patch with complex keys 2009-09-06 22:02:59 +00:00
jbeder e67e6e19f9 Fixed bug with complex keys (and simplified the parsing for flow maps) 2009-09-06 21:52:56 +00:00
jbeder fe47783b5f Refactored the operator >> and Node::Read default functions, as well as the conversion functions, to more easily read new types as keys (this uncovered an error, in example 2.11 of the spec) 2009-09-06 20:52:45 +00:00
jbeder dbcf401cbd Added spec tests through 2.10 2009-09-06 17:02:24 +00:00
jbeder 2fe7e8d525 Added templated casting to nodes, as well as operator == and != (for quick checks, especially to help in testing). Implemented size() on a map node to return the number of key/value pairs (as in std::map) 2009-09-06 15:54:11 +00:00
jbeder 44750974e7 Updated the CMake file for 0.2.0 release, and added install.txt 2009-09-05 23:05:39 +00:00
jbeder f21456972c Allowed solo entries in a flow map to be read as keys with null value 2009-09-05 22:42:01 +00:00
jbeder ba472cc9a3 Finished refactoring of simple keys so that they can refer to multiple tokens at a single level 2009-09-05 03:49:38 +00:00
jbeder a2f2ab8426 Refactored simple keys so that validating doesn't require popping indents, and so popping indents (and adding the end map) is independent of when we validate the simple key 2009-09-05 02:51:09 +00:00
jbeder 6594941d24 Moved token enums into Token scope 2009-09-05 02:28:11 +00:00
jbeder a926fefe0d Started implementing spec tests 2009-09-03 14:27:03 +00:00
jbeder f7a47e9f9f Fixed bug with omitted keys/values in a flow map 2009-09-02 21:39:57 +00:00
jbeder 2e859413e7 Added more explicit doc indicator tests 2009-08-26 16:23:58 +00:00
jbeder aadc5052bc Fixed bug with explicit doc start introduced in last commit 2009-08-26 16:15:27 +00:00
jbeder 3c35ab1e42 Added CMake option to build for the iphone 2009-08-24 23:43:53 +00:00
jbeder 4457b7dd5b Removed the implicit sequence code (since it's not used any more) 2009-08-24 22:58:47 +00:00
jbeder c7ed85a4ac Fixed bug in anchors with no content. This involved refactoring the 'implicit sequence' concept (where a map and a sequence start on the same indent, but we read the sequence as more indented since the '-' is visually an indent). 2009-08-24 22:56:54 +00:00
jbeder fc22d55b53 Added Node::Clone function 2009-08-24 20:10:42 +00:00
jbeder 8fcd09f30b Cleaned up 2009-08-24 18:23:20 +00:00
jbeder 2c4a7cf58c Removed the std::wstring conversion 2009-08-22 00:25:37 +00:00
jbeder 770d6de545 Converted indexing to std::size_t, and fixed the Node templated overloads to properly index any index type (determining what is an index type is a bit of a hack - it should be is_convertible<T, std::size_t> (I think), but I just explicitly wrote down a list) 2009-08-19 20:58:07 +00:00
jbeder c45372e2f3 Added 'yaml-cpp: ' to the exception messages 2009-08-19 05:09:12 +00:00
jbeder d1c888f57a Added templated Read() function that creates the output variable itself (so you don't need to have a temp variable) 2009-08-19 03:37:19 +00:00
jbeder c456eab7cd Fixed out-of-bounds memory access 2009-07-31 18:26:42 +00:00
jbeder 952f72233e Added IsNull function 2009-07-31 05:07:21 +00:00
jbeder cb2b5783fa Fixed null key/value bug, added tests 2009-07-30 06:49:09 +00:00
jbeder 49265fa12b Fixed empty scalar in sequence bug 2009-07-30 05:54:40 +00:00
jbeder c043b9c64b Added support for emitting and represeting null 2009-07-30 04:42:27 +00:00
jbeder a2bd317397 Added header file inclusion guards 2009-07-29 22:27:20 +00:00
jbeder 4725c4fabb Forgot to add mark.h 2009-07-27 04:14:19 +00:00
jbeder 7e26c711cf Collected pos, line, and column into a Mark struct 2009-07-27 02:56:18 +00:00
jbeder 25b5e9fec1 Fixed hex output in emitter (should be always two hex chars) 2009-07-26 07:57:22 +00:00
jbeder c4e1446dff Fixed bug in emitting null nodes 2009-07-26 07:42:50 +00:00
jbeder d0870b4112 Fixed the Exception::what() function 2009-07-26 01:37:21 +00:00
jbeder 27055f178f Fixed bug with simple keys that are quoted scalars 2009-07-25 18:58:41 +00:00
jbeder ab7c8b0df0 Fixed yaml-cpp.pc file (with prefix) 2009-07-25 18:03:58 +00:00
jbeder 94cb26ae59 Fixed location of yaml-cpp.pc file 2009-07-24 06:18:46 +00:00
jbeder e6a26ef104 Updated visual studio project, and fixed a VS warning 2009-07-20 20:18:59 +00:00
jbeder f8440aa0e5 Patched to read into std::wstring 2009-07-15 20:47:51 +00:00
jbeder fd5bf7c29a Cosmetic change to .pc.cmake file 2009-07-15 20:38:25 +00:00
jbeder 64a5687656 Added support for pkgconfig 2009-07-15 20:37:11 +00:00
jbeder ba787edee4 Added FindValue to more easily read optional keys in a map 2009-07-12 02:59:23 +00:00
jbeder a48191c970 Added emitting for a YAML::Node (instead of the ad-hoc std::ostream overload) so it'll actually emit valid YAML always 2009-07-10 23:39:14 +00:00
jbeder 689c5fa7b7 Added check for extra compiler flags if using gcc 2009-07-10 17:26:39 +00:00
jbeder 10b5961f3c Set up the parse utility program to read from standard input if no file is specified 2009-07-10 04:25:11 +00:00
jbeder 6752e25bcd (Finally) overrode Exception::what()\n 2009-07-10 04:17:30 +00:00
jbeder ae89793c28 Applied patch to build and version a shared library 2009-07-10 03:52:05 +00:00
jbeder 616eafc3c1 Fixed warnings to compile on gcc with -Wall -pedantic -Wextra 2009-07-10 03:30:04 +00:00
jbeder 907960850b Clarified some copy/assignment issues with the stream/streamcharsource. 2009-07-10 03:20:16 +00:00
jbeder 4ba713bf43 Updated the visual studio project with some of the utf changes 2009-07-10 03:15:08 +00:00
jbeder e7f1ca7fb1 Merged utf branch changes r178:187 into the trunk 2009-07-10 03:10:03 +00:00
jbeder aa959e6705 Fixed bug that didn't allow multiple docs in a stream (using only "---") 2009-06-25 03:05:09 +00:00
jbeder 8aefb675a2 Patched CMake file to allow flexibility in build (in particular to allow shared lib build) 2009-06-12 04:28:36 +00:00
jbeder ed8f016c1f Updated the nested RegEx classes so they don't need to also take an std::string 2009-06-01 03:42:16 +00:00
jbeder 6e1fc798e1 Updated yaml-reader CMake file 2009-05-31 06:39:08 +00:00
jbeder ec578d45f1 Switched from loading test files to testing specific parsing constructs. The tests don't fully cover the span (eventually I'll add more, maybe), but there's a bunch there.
More to the point, the yaml-reader program doesn't do any file IO, so it doesn't require a specific working directory.
2009-05-31 06:36:01 +00:00
jbeder f2ed49f720 Patch - added testing 2009-05-30 02:41:27 +00:00
jbeder f09e4497b6 Set eol-style to native on all of the new files 2009-05-30 02:29:47 +00:00
jbeder 2fdf2475bb Patched - removed unnecessary CMake statements 2009-05-29 22:58:14 +00:00
jbeder ade7e7cd18 Patched - install target 2009-05-29 22:55:59 +00:00
jbeder b444913576 Patch to simplify CMakeLists.txt files 2009-05-29 22:48:25 +00:00
jbeder c150e9945c Patch for gcc -Wall (order of initialization) 2009-05-29 22:36:52 +00:00
jbeder 51457eece9 Changed the way we read different types of scalars.
It's better organized now, I think - nodes only offer a single main way of getting the fundamental scalar (as a string), and now we can specialize a single template to read specific types.
2009-05-23 23:51:01 +00:00
jbeder 0c34137d84 Updated Visual Studio project for the emitter. 2009-05-23 22:58:05 +00:00
jbeder 947356a64a Changed output library directory to /lib (in the source directory) - this makes more sense 2009-05-23 17:11:19 +00:00
jbeder fcab73a9b6 Added emitter headers to yaml.h 2009-05-22 22:23:57 +00:00
jbeder 7dd29ee5db Replaced direct emitter writing with an accessor to a C-string 2009-05-22 22:21:01 +00:00
jbeder 3e41edd30e Restructured CMake file to include headers, and to be better organized 2009-05-22 22:11:21 +00:00
jbeder e6617e3273 Removed excessive stderr logging 2009-05-22 21:56:45 +00:00
jbeder cba20711b0 Merged emitter branch into trunk, changes r105:r151 2009-05-22 21:52:31 +00:00
jbeder 5abf31b991 Merged aliases branch into trunk, changes r100:150 2009-05-22 21:48:05 +00:00
jbeder 7297387015 Fixed several bugs from the new file i/o setup.
In particular:
1. Windows CR/LF weren't read properly (issue #11)
2. Scanning wasn't reading EOF properly
3. Documents may be empty (this was old, I think)
Also fixed some VS2008 warnings on /W4.
2009-02-07 07:57:13 +00:00
jbeder 855d0d60df Switched to reading the entire file into a buffer at the start.\nThis speeds it up a TON (like 100x). 2009-02-01 20:48:43 +00:00
jbeder e9512a5ac8 Included <cstdio> for gcc-4.4 (issue 9) 2009-01-27 21:08:40 +00:00
jbeder 4e2e644c35 Included <cstring> for strcmp 2009-01-27 20:16:30 +00:00
jbeder d44502c979 Applied patch for gcc -Wall 2009-01-15 17:12:13 +00:00
jbeder 6434b4f0c8 Re-added the throw() specification to ~Exception(), and also to ~TypedKeyNotFound(); I suppose this'll fix the gcc compiler error. 2009-01-01 23:59:37 +00:00
jbeder 4cebe50a9f Removed throw() specifier in Exception (I don't remember putting it in). This may solve a gcc error (I haven't tested it yet) or it may break it further. 2009-01-01 20:14:32 +00:00
jbeder 51ea36e444 Added a templated derived exception to KeyNotFound so that you can figure out *which* key wasn't found. 2009-01-01 02:40:18 +00:00
jbeder ad2b9fbaaf Fixed tag output bug 2008-11-20 04:12:31 +00:00
jbeder 4b45a7185a Replaced a pointer-centered try/catch block with std::auto_ptr 2008-11-20 03:41:40 +00:00
jbeder 27da48bac2 Added line/column data for nodes so they can give better invalid scalar exceptions. 2008-11-18 04:20:07 +00:00
jbeder 09d2858dc0 Added line/column data for nodes so they can give better invalid scalar exceptions. 2008-11-18 04:19:50 +00:00
jbeder d1ef1e8ef1 Added more natural ways to parse boolean values (based on the YAML spec).
(Thanks to Vadim Zeitlin)
2008-09-25 00:15:40 +00:00
jbeder bf01059c38 Added Read() functions for Node that return true/false, so we can easily check if a read is successful without throwing.
But we still have operator >> that throws on failure.
2008-09-24 23:29:00 +00:00
jbeder ecba08e240 Fixed infinite loop bug having to do with simple keys when we hit an unexpected EOF. 2008-09-24 22:45:04 +00:00
jbeder d51888bc7e Fixed a problem where you lose the exception type on rethrow. 2008-09-23 21:13:23 +00:00
jbeder 0b6edc6cfe Made Node non-copyable. 2008-09-19 02:44:49 +00:00
jbeder 1d92deff31 2008-09-11 03:49:52 +00:00
jbeder c44b8e601e 2008-09-11 03:48:04 +00:00
jbeder b43f827188 Set the eol style to native for all files. 2008-09-03 22:20:39 +00:00
jbeder 859ac5e520 Fixed some gcc warnings. 2008-09-03 22:19:27 +00:00
jbeder 7f2c3591e3 Unified line endings. 2008-09-03 22:17:17 +00:00
jbeder a57a5748f8 Added the license.txt file describing the MIT license. 2008-09-03 04:37:06 +00:00
jbeder aa25fadf94 Fixed struct vs. class disparity. 2008-08-07 03:37:16 +00:00
jbeder 2d93b6ce58 Added CMake scripts for other platforms\nFixed some bugs that gcc complained about\nFixed CR/LF vs LF bug 2008-08-07 03:30:56 +00:00
beder 2601f5fd49 2008-07-31 19:41:11 +00:00
beder 89ed418b83 Small changes in the iterator code.
Changed the public interface of Scanner to resemble an STL container.
2008-07-23 04:38:18 +00:00
beder 57255a9898 Switched the Iterator implementation to a dedicated helper class (to hide the specific implementation, since it's pretty messy and may change). 2008-07-21 02:54:39 +00:00
beder 557f81e622 Replaced the queue of Token pointers with values.
We were getting memory leaks (as told by the CRT detectors, which I also added), and there's really no reason (as long as we're careful) to use pointers there.
2008-07-20 05:02:01 +00:00
beder f4e522490f Moved the testing source to the yaml-reader folder. 2008-07-14 05:18:25 +00:00
beder 2ffc7dc6ac Set the yaml-reader project to link to the yamlcpp library. 2008-07-14 05:08:46 +00:00
beder 11eb40e636 Added a static library project 'yamlcpp' to the solution. 2008-07-14 05:03:38 +00:00
beder ef8e9415f8 Renamed the solution yamlcpp. 2008-07-14 04:51:47 +00:00
beder 4c1c0977ab 2008-07-14 04:37:58 +00:00
beder 516637fcdc Moved all code to src/ and include/ directories. 2008-07-14 04:33:30 +00:00
beder e6aeb45d09 Switched from moving the cursor forward (in Regex) to ignoring (this handles newlines properly).
Updated some of the character-in-scalar rules.
2008-07-10 00:23:25 +00:00
beder 0b2e0dd32b Centralized the error messages to one location. 2008-07-08 20:31:48 +00:00
beder 84bcdda342 Removed the (unused) 'required' flag from simple keys (the parser should take care of this, not the scanner). 2008-07-08 18:34:26 +00:00
beder 5d5651861d Added some exceptions for directives. 2008-07-08 06:06:24 +00:00
beder 2f5c19fa00 Combined the myriad ScannerExceptions and ParserExceptions to a single ParserException class that has a message and a line/column position in the file where the error occurred. 2008-07-08 05:48:38 +00:00
beder 1acc0e4982 Added a (recursive) ordering, so we have a canonical output that we can compare. 2008-07-06 00:06:36 +00:00
beder 3cad5a2ed0 Wrote some tests, but they don't work because it doesn't output maps in a canonical form. 2008-07-05 19:00:58 +00:00
beder ba97c9f719 Rewrote the output so that it emits correct YAML.
Fixed a bug in the last newline of a block folded scalar.
2008-07-05 05:28:23 +00:00
beder 5feaef3748 2008-07-04 22:57:52 +00:00
beder c4c873733b Removed the document class (since it's really just a root node, and that's it). 2008-07-04 22:56:43 +00:00
beder 99a9aaa591 Specialized the overloaded [] operator for int/unsigned, and added a size() function, so that you can iterate through a sequence node like a vector. 2008-07-02 21:41:54 +00:00
beder 620c322df5 Added some parser exceptions. 2008-07-02 05:00:32 +00:00
beder 807045bc14 Overloaded the iterator's -> operator. 2008-07-02 01:32:19 +00:00
beder b4b287c4e9 Added an iterator class that can iterate through both sequence and map nodes. 2008-07-02 01:22:39 +00:00
beder 81ff4946ae Fixed opening newline bug for block scalars. 2008-07-01 06:34:55 +00:00
beder 8eb50fe9d0 Tags, anchors, and aliases are all parsed now. 2008-07-01 06:28:10 +00:00
beder 104da5c244 Added parsing of anchors, aliases, and tags (still no semantics yet).
Fixed a silly bug in the simple key pushing (queues are FIFO!).
2008-07-01 01:17:10 +00:00
beder d41503da5a Finished parsing of basic data types (scalar, sequence, map). 2008-06-30 23:57:58 +00:00
beder 146122f455 Renamed the stream member functions get() and eat(). 2008-06-30 22:34:10 +00:00
beder 17533e22da Instead of deriving different tokens from a base Token class, we now use an enumerated TOKEN_TYPE to distinguish types. This is so we don't have to cast all the time when parsing the resulting token stream.
Also, removed start/end stream tokens.
2008-06-30 21:47:21 +00:00
beder 2a7e20a315 Started the parser. 2008-06-30 06:51:22 +00:00
beder 795df7224b Added a peek token command (for the parser to use). 2008-06-30 06:21:12 +00:00
beder a93584b065 Added directives and tags. 2008-06-30 04:22:41 +00:00
beder b58c0c94e4 Moved the three scalar token scanning functions back to scantoken.cpp, so scanscalar.cpp now only has the main scalar scanning function.
Renamed ScanScalarInfo to ScanScalarParams.
2008-06-30 01:38:32 +00:00
beder 67250833b8 Mostly finished refactoring the scalar scanning. 2008-06-30 01:31:23 +00:00
beder 4de9cb48a5 Moved scalar scanning-related parameters to a struct.
Renamed the valid/possible tokens to a single variable status with enums valid, invalid, and unverified.
2008-06-29 17:39:33 +00:00
beder 6efc5614ec Moved the input stream, together with line/column info, into its own class, which allowed some other stuff just to pass the stream, and not have to be a member of Scanner. 2008-06-29 06:32:13 +00:00
beder 8dfb5c0ea8 Refactored common scalar scanning code (from plain, quoted, and block) to one function. 2008-06-29 05:45:41 +00:00
beder 3c56fd49eb Moved the scalar-related functions to their own file. 2008-06-29 03:11:25 +00:00
beder 45dfc719e1 2008-06-29 00:33:34 +00:00
beder ab27b9781e Small refactoring. 2008-06-28 22:05:51 +00:00
beder 34cd7177cd 2008-06-28 20:09:49 +00:00
beder 566916ba19 Added folded and literal scalars. 2008-06-28 20:08:21 +00:00
beder 1a96548fa5 Fixed complex keys. 2008-06-28 17:32:10 +00:00
beder b1c60706d7 Moved the simple key validation to before each token scan (plus at newlines of scalars). 2008-06-28 16:46:37 +00:00
beder 70afd130ad Added simple keys.
There's a bug (and question): should we test simple keys' validity BEFORE stuff or AFTER stuff?
2008-06-28 06:36:59 +00:00
beder fb9176a054 Added quoted scalars (with escaping).
Refactored some common whitespace-parsing code in scanning both scalars.
Implemented the flow collection tokens.
2008-06-27 23:11:46 +00:00
beder ba132b01bc Small plain scalar scanning fixes. 2008-06-27 20:54:43 +00:00
beder 10c4a2687f Split off the specific regular expressions, and the specialized token-scanning functions, into their own files. 2008-06-27 19:13:03 +00:00
beder aad36b8c47 Added stream input to the regular expressions, greatly simplifying the usage (in particular, we no longer have to specify the number of characters to be checked). 2008-06-27 19:07:30 +00:00
beder bb4bc8c4ae Wrote a simplified regular expression parser to make life easier (it only does single matches; i.e., no one-or-more matches, etc.).
Fixed some of the whitespace/line break matching.
2008-06-27 08:20:41 +00:00
beder 20dba9cd75 The plain scalar scanner is almost done (and it scans a simple list correctly).
Also messed around with multiple character peeking on the input, and got something working.
2008-06-27 00:18:52 +00:00
beder c7274ff2e8 More simple scalar scanning. 2008-06-26 22:00:39 +00:00
beder 2040e4de8b Continued working on scanner.
We're now using exceptions for errors, and scanning/pushing tokens is exception-safe (using a set of "limbo tokens").
2008-06-26 19:30:11 +00:00
beder 4b33531240 Started the scanner. 2008-06-26 09:05:28 +00:00
beder e6977cbe4e Beginning of first attempt to parse.
Will be completely wiped, I think, in favor of a Scanner (to tokens), then Parser mechanism.
2008-06-26 06:49:50 +00:00
beder 2d0f324529 Preliminary setup - basic data structures are there. 2008-06-25 23:00:18 +00:00
beder ffaf6a19ca 2008-06-25 22:46:18 +00:00
beder 0134c553a5 2008-06-25 22:45:08 +00:00
beder f959a475b7 2008-06-25 22:44:44 +00:00
413 changed files with 13496 additions and 145123 deletions
-1
View File
@@ -1 +0,0 @@
test/googletest-1.13.0
-47
View File
@@ -1,47 +0,0 @@
---
# BasedOnStyle: Google
AccessModifierOffset: -1
ConstructorInitializerIndentWidth: 4
AlignEscapedNewlinesLeft: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakTemplateDeclarations: true
AlwaysBreakBeforeMultilineStrings: true
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
ColumnLimit: 80
ConstructorInitializerAllOnOneLineOrOnePerLine: true
DerivePointerBinding: true
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: true
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 60
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerBindsToType: true
SpacesBeforeTrailingComments: 2
Cpp11BracedListStyle: true
Standard: Cpp11
IndentWidth: 2
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Attach
IndentFunctionDeclarationAfterType: true
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpaceAfterControlStatementKeyword: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
...
-50
View File
@@ -1,50 +0,0 @@
# CodeDocs.xyz Configuration File
# Optional project name, if left empty the GitHub repository name will be used.
PROJECT_NAME =
# One or more directories and files that contain example code to be included.
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/googletest-1.13.0/
# One or more wildcard patterns to exclude files and directories from document
# generation.
EXCLUDE_PATTERNS =
# One or more symbols to exclude from document generation. Symbols can be
# namespaces, classes, or functions.
EXCLUDE_SYMBOLS =
# Override the default parser (language) used for each file extension.
EXTENSION_MAPPING =
# Set the wildcard patterns used to filter out the source-files.
# If left blank the default is:
# *.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl,
# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php,
# *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox, *.py,
# *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
FILE_PATTERNS =
# Hide undocumented class members.
HIDE_UNDOC_MEMBERS =
# Hide undocumented classes.
HIDE_UNDOC_CLASSES =
# Specify a markdown page whose contents should be used as the main page
# (index.html). This will override a page marked as \mainpage. For example, a
# README.md file usually serves as a useful main page.
USE_MDFILE_AS_MAINPAGE = README.md
# Specify external repository to link documentation with.
# This is similar to Doxygen's TAGFILES option, but will automatically link to
# tags of other repositories already using CodeDocs. List each repository to
# link with by giving its location in the form of owner/repository.
# For example:
# TAGLINKS = doxygen/doxygen CodeDocs/osg
# Note: these repositories must already be built on CodeDocs.
TAGLINKS =
-11
View File
@@ -1,11 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
groups:
github-actions:
patterns:
- "*"
-141
View File
@@ -1,141 +0,0 @@
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]
cxx_standard: [11, 17, 20]
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
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@v6.0.2
- 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
bazel-build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6.0.2
- 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]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6.0.2
- 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
@@ -1,19 +0,0 @@
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@0c366fd6a839edf440554fa01a7085ccba70ac98 # v4.1.1
- 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 }}
-3
View File
@@ -1,3 +0,0 @@
build/
/tags
/bazel-*
+4
View File
@@ -0,0 +1,4 @@
**.h = native
**.c = native
**.cpp = native
**.txt = native
+2
View File
@@ -0,0 +1,2 @@
syntax: glob
-23
View File
@@ -1,23 +0,0 @@
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": [],
})
cc_library(
name = "yaml-cpp_internal",
visibility = ["//:__subpackages__"],
strip_include_prefix = "src",
hdrs = glob(["src/**/*.h"]),
)
cc_library(
name = "yaml-cpp",
visibility = ["//visibility:public"],
includes = ["include"],
hdrs = glob(["include/**/*.h"]),
srcs = glob(["src/**/*.cpp", "src/**/*.h"]),
defines = yaml_cpp_defines,
)
+255 -183
View File
@@ -1,213 +1,285 @@
# 3.5 is actually available almost everywhere. ###
# 3.30 as the upper policy limit avoids CMake deprecation warnings. ### CMake settings
cmake_minimum_required(VERSION 3.5...3.30) ###
## Due to Mac OSX we need to keep compatibility with CMake 2.6
# enable MSVC_RUNTIME_LIBRARY target property # see http://www.cmake.org/Wiki/CMake_Policies
# see https://cmake.org/cmake/help/latest/policy/CMP0091.html cmake_minimum_required(VERSION 2.6)
if(POLICY CMP0091) # see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0012
cmake_policy(SET CMP0091 NEW) if(POLICY CMP0012)
cmake_policy(SET CMP0012 OLD)
endif()
# see http://www.cmake.org/cmake/help/cmake-2-8-docs.html#policy:CMP0015
if(POLICY CMP0015)
cmake_policy(SET CMP0015 OLD)
endif() endif()
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()
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(GNUInstallDirs)
include(CTest)
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)
cmake_dependent_option(YAML_CPP_BUILD_TESTS ###
"Enable yaml-cpp tests" OFF ### Project settings
"BUILD_TESTING;YAML_CPP_MAIN_PROJECT" OFF) ###
cmake_dependent_option(YAML_MSVC_SHARED_RT project(YAML_CPP)
"MSVC: Build yaml-cpp with shared runtime libs (/MD)" ON
"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()
if (YAML_BUILD_SHARED_LIBS) set(YAML_CPP_VERSION_MAJOR "0")
set(yaml-cpp-type SHARED) set(YAML_CPP_VERSION_MINOR "5")
set(yaml-cpp-label-postfix "shared") set(YAML_CPP_VERSION_PATCH "0")
set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
enable_testing()
###
### Project options
###
## Project stuff
option(YAML_CPP_BUILD_TOOLS "Enable testing and parse tools" ON)
option(YAML_CPP_BUILD_CONTRIB "Enable contrib stuff in library" ON)
## Build options
# --> General
# see http://www.cmake.org/cmake/help/cmake2.6docs.html#variable:BUILD_SHARED_LIBS
# http://www.cmake.org/cmake/help/cmake2.6docs.html#command:add_library
option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
# --> Apple
option(APPLE_UNIVERSAL_BIN "Apple: Build universal binary" OFF)
# --> Microsoft Visual C++
# see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx
# http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx
option(MSVC_SHARED_RT "MSVC: Build with shared runtime libs (/MD)" ON)
option(MSVC_STHREADED_RT "MSVC: Build with single-threaded static runtime libs (/ML until VS .NET 2003)" OFF)
###
### Sources, headers, directories and libs
###
set(header_directory "include/yaml-cpp/")
file(GLOB sources "src/[a-zA-Z]*.cpp")
file(GLOB_RECURSE public_headers "include/yaml-cpp/[a-zA-Z]*.h")
file(GLOB private_headers "src/[a-zA-Z]*.h")
if(YAML_CPP_BUILD_CONTRIB)
file(GLOB contrib_sources "src/contrib/[a-zA-Z]*.cpp")
file(GLOB contrib_public_headers "include/yaml-cpp/contrib/[a-zA-Z]*.h")
file(GLOB contrib_private_headers "src/contrib/[a-zA-Z]*.h")
else() else()
set(yaml-cpp-type STATIC) add_definitions(-DYAML_CPP_NO_CONTRIB)
set(yaml-cpp-label-postfix "static")
endif() endif()
set(build-shared $<BOOL:${YAML_BUILD_SHARED_LIBS}>) if(VERBOSE)
set(build-windows-dll $<AND:$<BOOL:${CMAKE_HOST_WIN32}>,${build-shared}>) message(STATUS "sources: ${sources}")
set(not-msvc $<NOT:$<CXX_COMPILER_ID:MSVC>>) message(STATUS "public_headers: ${public_headers}")
set(msvc-shared_rt $<BOOL:${YAML_MSVC_SHARED_RT}>) message(STATUS "private_headers: ${private_headers}")
message(STATUS "contrib_sources: ${contrib_sources}")
if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) message(STATUS "contrib_public_headers: ${contrib_public_headers}")
set(CMAKE_MSVC_RUNTIME_LIBRARY message(STATUS "contrib_private_headers: ${contrib_private_headers}")
MultiThreaded$<$<CONFIG:Debug>:Debug>$<${msvc-shared_rt}:DLL>)
endif() endif()
set(contrib-pattern "src/contrib/*.cpp") include_directories(${YAML_CPP_SOURCE_DIR}/src)
set(src-pattern "src/*.cpp") include_directories(${YAML_CPP_SOURCE_DIR}/include)
if (CMAKE_VERSION VERSION_GREATER 3.12)
list(INSERT contrib-pattern 0 CONFIGURE_DEPENDS) find_package(Boost REQUIRED)
list(INSERT src-pattern 0 CONFIGURE_DEPENDS) include_directories(${Boost_INCLUDE_DIRS})
###
### General compilation settings
###
if(BUILD_SHARED_LIBS)
set(LABEL_SUFFIX "shared")
else()
set(LABEL_SUFFIX "static")
endif() endif()
file(GLOB yaml-cpp-contrib-sources ${contrib-pattern}) if(APPLE)
file(GLOB yaml-cpp-sources ${src-pattern}) if(APPLE_UNIVERSAL_BIN)
set(CMAKE_OSX_ARCHITECTURES ppc;i386)
set(msvc-rt $<TARGET_PROPERTY:MSVC_RUNTIME_LIBRARY>) endif()
set(msvc-rt-mtd-static $<STREQUAL:${msvc-rt},MultiThreadedDebug>)
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)
set_property(TARGET yaml-cpp
PROPERTY
MSVC_RUNTIME_LIBRARY ${CMAKE_MSVC_RUNTIME_LIBRARY})
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() endif()
target_include_directories(yaml-cpp if(IPHONE)
PUBLIC set(CMAKE_OSX_SYSROOT "iphoneos4.2")
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> set(CMAKE_OSX_ARCHITECTURES "armv6;armv7")
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
if (NOT DEFINED CMAKE_CXX_STANDARD)
set_target_properties(yaml-cpp
PROPERTIES
CXX_STANDARD 11)
endif() endif()
if(YAML_CPP_MAIN_PROJECT) if(WIN32)
target_compile_options(yaml-cpp if(BUILD_SHARED_LIBS)
PRIVATE add_definitions(-D${PROJECT_NAME}_DLL) # use or build Windows DLL
$<${not-msvc}:-Wall -Wextra -Wshadow -Weffc++ -Wno-long-long> endif()
$<${not-msvc}:-pedantic -pedantic-errors>) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "C:/")
endif()
endif() endif()
target_compile_options(yaml-cpp # GCC specialities
PRIVATE if(CMAKE_COMPILER_IS_GNUCXX)
$<$<AND:${backport-msvc-runtime},${msvc-rt-mtd-static}>:-MTd> ### General stuff
$<$<AND:${backport-msvc-runtime},${msvc-rt-mt-static}>:-MT> if(WIN32)
$<$<AND:${backport-msvc-runtime},${msvc-rt-mtd-dll}>:-MDd> set(CMAKE_SHARED_LIBRARY_PREFIX "") # DLLs do not have a "lib" prefix
$<$<AND:${backport-msvc-runtime},${msvc-rt-mt-dll}>:-MD> set(CMAKE_IMPORT_LIBRARY_PREFIX "") # same for DLL import libs
set(CMAKE_LINK_DEF_FILE_FLAG "") # CMake workaround (2.8.3)
endif()
# /wd4127 = disable warning C4127 "conditional expression is constant" ### Project stuff
# http://msdn.microsoft.com/en-us/library/6t66728h.aspx if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
# /wd4355 = disable warning C4355 "'this' : used in base member initializer list set(CMAKE_BUILD_TYPE Release)
# http://msdn.microsoft.com/en-us/library/3c594ae3.aspx endif()
$<$<CXX_COMPILER_ID:MSVC>:/W3 /wd4127 /wd4355>) #
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
target_compile_definitions(yaml-cpp set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
PUBLIC set(CMAKE_CXX_FLAGS_DEBUG "-g")
$<$<NOT:$<BOOL:${YAML_BUILD_SHARED_LIBS}>>:YAML_CPP_STATIC_DEFINE> set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
PRIVATE #
$<${build-windows-dll}:${PROJECT_NAME}_DLL> set(GCC_EXTRA_OPTIONS "")
$<$<NOT:$<BOOL:${YAML_CPP_BUILD_CONTRIB}>>:YAML_CPP_NO_CONTRIB>) #
set(FLAG_TESTED "-Wextra")
target_sources(yaml-cpp check_cxx_compiler_flag(${FLAG_TESTED} FLAG_WEXTRA)
PRIVATE if(FLAG_WEXTRA)
$<$<BOOL:${YAML_CPP_BUILD_CONTRIB}>:${yaml-cpp-contrib-sources}> set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} ${FLAG_TESTED}")
${yaml-cpp-sources}) endif()
#
if (NOT DEFINED CMAKE_DEBUG_POSTFIX) set(CMAKE_CXX_FLAGS "-Wall ${GCC_EXTRA_OPTIONS} -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}")
set(CMAKE_DEBUG_POSTFIX "d") #
add_custom_target(debuggable $(MAKE) clean
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_SOURCE_DIR}
COMMENT "Adjusting settings for debug compilation"
VERBATIM)
add_custom_target(releasable $(MAKE) clean
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release ${CMAKE_SOURCE_DIR}
COMMENT "Adjusting settings for release compilation"
VERBATIM)
endif() endif()
# Microsoft VisualC++ specialities
if(MSVC)
### General stuff
# a) Change MSVC runtime library settings (/MD[d], /MT[d], /ML[d] (single-threaded until VS 2003))
# plus set lib suffix for later use and project label accordingly
# see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx
# http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx
set(LIB_RT_SUFFIX "md") # CMake defaults to /MD for MSVC
set(LIB_RT_OPTION "/MD")
#
if(NOT MSVC_SHARED_RT) # User wants to have static runtime libraries (/MT, /ML)
if(MSVC_STHREADED_RT) # User wants to have old single-threaded static runtime libraries
set(LIB_RT_SUFFIX "ml")
set(LIB_RT_OPTION "/ML")
if(NOT ${MSVC_VERSION} LESS 1400)
message(FATAL_ERROR "Single-threaded static runtime libraries (/ML) only available until VS .NET 2003 (7.1).")
endif()
else()
set(LIB_RT_SUFFIX "mt")
set(LIB_RT_OPTION "/MT")
endif()
# correct linker options
foreach(flag_var CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
foreach(config_name "" DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
set(var_name "${flag_var}")
if(NOT "${config_name}" STREQUAL "")
set(var_name "${var_name}_${config_name}")
endif()
string(REPLACE "/MD" "${LIB_RT_OPTION}" ${var_name} "${${var_name}}")
endforeach()
endforeach()
endif()
#
set(LABEL_SUFFIX "${LABEL_SUFFIX} ${LIB_RT_SUFFIX}")
# b) Change prefix for static libraries
set(CMAKE_STATIC_LIBRARY_PREFIX "lib") # to distinguish static libraries from DLL import libs
# c) Correct suffixes for static libraries
if(NOT BUILD_SHARED_LIBS)
### General stuff
set(LIB_TARGET_SUFFIX "${LIB_SUFFIX}${LIB_RT_SUFFIX}")
endif()
### Project stuff
# /W3 = set warning level; see http://msdn.microsoft.com/en-us/library/thxezb7y.aspx
# /wd4127 = disable warning C4127 "conditional expression is constant"; see http://msdn.microsoft.com/en-us/library/6t66728h.aspx
# /wd4355 = disable warning C4355 "'this' : used in base member initializer list"; http://msdn.microsoft.com/en-us/library/3c594ae3.aspx
set(CMAKE_CXX_FLAGS "/W3 /wd4127 /wd4355 /D_SCL_SECURE_NO_WARNINGS ${CMAKE_CXX_FLAGS}")
endif()
###
### General install settings
###
if(WIN32)
set(_library_dir bin) # .dll are in PATH, like executables
else()
set(_library_dir lib)
endif()
set(INCLUDE_INSTALL_ROOT_DIR include)
set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_ROOT_DIR}/yaml-cpp)
set(LIB_INSTALL_DIR "${_library_dir}${LIB_SUFFIX}")
set(_INSTALL_DESTINATIONS
RUNTIME DESTINATION bin
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
)
###
### Library
###
add_library(yaml-cpp
${sources}
${public_headers}
${private_headers}
${contrib_sources}
${contrib_public_headers}
${contrib_private_headers}
)
set_target_properties(yaml-cpp PROPERTIES set_target_properties(yaml-cpp PROPERTIES
VERSION "${PROJECT_VERSION}" VERSION "${YAML_CPP_VERSION}"
SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}" SOVERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}"
PROJECT_LABEL "yaml-cpp ${yaml-cpp-label-postfix}" PROJECT_LABEL "yaml-cpp ${LABEL_SUFFIX}"
DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}") )
set(EXPORT_TARGETS yaml-cpp::yaml-cpp) if(IPHONE)
configure_package_config_file( set_target_properties(yaml-cpp PROPERTIES
"${PROJECT_SOURCE_DIR}/yaml-cpp-config.cmake.in" XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "3.0"
"${PROJECT_BINARY_DIR}/yaml-cpp-config.cmake" )
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"
COMPATIBILITY AnyNewerVersion)
configure_file(yaml-cpp.pc.in yaml-cpp.pc @ONLY)
if (YAML_CPP_INSTALL)
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/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h")
install(EXPORT yaml-cpp-targets
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_LIBDIR}/pkgconfig)
endif() endif()
if(YAML_CPP_BUILD_TESTS) if(MSVC)
add_subdirectory(test) if(NOT BUILD_SHARED_LIBS)
# correct library names
set_target_properties(yaml-cpp PROPERTIES
DEBUG_POSTFIX "${LIB_TARGET_SUFFIX}d"
RELEASE_POSTFIX "${LIB_TARGET_SUFFIX}"
MINSIZEREL_POSTFIX "${LIB_TARGET_SUFFIX}"
RELWITHDEBINFO_POSTFIX "${LIB_TARGET_SUFFIX}"
)
endif()
endif() endif()
install(TARGETS yaml-cpp ${_INSTALL_DESTINATIONS})
install(
DIRECTORY ${header_directory}
DESTINATION ${INCLUDE_INSTALL_DIR}
FILES_MATCHING PATTERN "*.h"
)
if(UNIX)
set(PC_FILE ${CMAKE_BINARY_DIR}/yaml-cpp.pc)
configure_file("yaml-cpp.pc.cmake" ${PC_FILE} @ONLY)
install(FILES ${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
endif()
###
### Extras
###
if(YAML_CPP_BUILD_TOOLS) if(YAML_CPP_BUILD_TOOLS)
add_subdirectory(util) add_subdirectory(test)
endif() add_subdirectory(util)
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() endif()
-26
View File
@@ -1,26 +0,0 @@
# Style
This project is formatted with [clang-format][fmt] using the style file at the root of the repository. Please run clang-format before sending a pull request.
In general, try to follow the style of surrounding code. We mostly follow the [Google C++ style guide][cpp-style].
Commit messages should be in the imperative mood, as described in the [Git contributing file][git-contrib]:
> Describe your changes in imperative mood, e.g. "make xyzzy do frotz"
> instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy
> to do frotz", as if you are giving orders to the codebase to change
> its behaviour.
[fmt]: http://clang.llvm.org/docs/ClangFormat.html
[cpp-style]: https://google.github.io/styleguide/cppguide.html
[git-contrib]: http://git.kernel.org/cgit/git/git.git/tree/Documentation/SubmittingPatches?id=HEAD
# 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. 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.
-14
View File
@@ -1,14 +0,0 @@
"""
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
@@ -1,282 +0,0 @@
{
"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": {}
}
-86
View File
@@ -1,86 +0,0 @@
# 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).
## Usage
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)).
## Any Problems?
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
`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:
**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. Navigate into the source directory, create build folder and run `CMake`:
```sh
mkdir build
cd build
cmake [-G generator] [-DYAML_BUILD_SHARED_LIBS=on|OFF] ..
```
* 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).
* `yaml-cpp` builds a static library by default, you may want to build a shared library by specifying `-DYAML_BUILD_SHARED_LIBS=ON`.
* [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).
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.
#### 2. Build it!
* The command you'll need to run depends on the generator you chose earlier.
**Note:** To clean up, just remove the `build` directory.
## How to Integrate it within your project using CMake
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.8.0](https://github.com/jbeder/yaml-cpp/releases/tag/0.8.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 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
The autogenerated API reference is hosted on [CodeDocs](https://codedocs.xyz/jbeder/yaml-cpp/index.html)
# Third Party Integrations
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
@@ -1,13 +0,0 @@
# 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.
-21
View File
@@ -1,21 +0,0 @@
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()
-52
View File
@@ -1,52 +0,0 @@
# The following is a list of breaking changes to yaml-cpp, by version #
# New API #
## HEAD ##
* Throws an exception when trying to parse a negative number as an unsigned integer.
* Supports the `as<int8_t>`/`as<uint8_t>`, which throws an exception when the value exceeds the range of `int8_t`/`uint8_t`.
## 0.6.0 ##
* Requires C++11.
## 0.5.3 ##
_none_
## 0.5.2 ##
_none_
## 0.5.1 ##
* `Node::clear` was replaced by `Node::reset`, which takes an optional node, similar to smart pointers.
## 0.5.0 ##
Initial version of the new API.
# Old API #
## 0.3.0 ##
_none_
## 0.2.7 ##
* `YAML::Binary` now takes `const unsigned char *` for the binary data (instead of `const char *`).
## 0.2.6 ##
* `Node::GetType()` is now `Node::Type()`, and returns an enum `NodeType::value`, where:
> > ` struct NodeType { enum value { Null, Scalar, Sequence, Map }; }; `
* `Node::GetTag()` is now `Node::Tag()`
* `Node::Identity()` is removed, and `Node::IsAlias()` and `Node::IsReferenced()` have been merged into `Node::IsAliased()`. The reason: there's no reason to distinguish an alias node from its anchor - whichever happens to be emitted first will be the anchor, and the rest will be aliases.
* `Node::Read<T>` is now `Node::to<T>`. This wasn't a documented function, so it shouldn't break anything.
* `Node`'s comparison operators (for example, `operator == (const Node&, const T&)`) have all been removed. These weren't documented either (they were just used for the tests), so this shouldn't break anything either.
* The emitter no longer produces the document start by default - if you want it, you can supply it with the manipulator `YAML::BeginDoc`.
## 0.2.5 ##
This wiki was started with v0.2.5.
-226
View File
@@ -1,226 +0,0 @@
## Contents ##
# Basic Emitting #
The model for emitting YAML is `std::ostream` manipulators. A `YAML::Emitter` objects acts as an output stream, and its output can be retrieved through the `c_str()` function (as in `std::string`). For a simple example:
```cpp
#include "yaml-cpp/yaml.h"
int main()
{
YAML::Emitter out;
out << "Hello, World!";
std::cout << "Here's the output YAML:\n" << out.c_str(); // prints "Hello, World!"
return 0;
}
```
# Simple Lists and Maps #
A `YAML::Emitter` object acts as a state machine, and we use manipulators to move it between states. Here's a simple sequence:
```cpp
YAML::Emitter out;
out << YAML::BeginSeq;
out << "eggs";
out << "bread";
out << "milk";
out << YAML::EndSeq;
```
produces
```yaml
- eggs
- bread
- milk
```
A simple map:
```cpp
YAML::Emitter out;
out << YAML::BeginMap;
out << YAML::Key << "name";
out << YAML::Value << "Ryan Braun";
out << YAML::Key << "position";
out << YAML::Value << "LF";
out << YAML::EndMap;
```
produces
```yaml
name: Ryan Braun
position: LF
```
These elements can, of course, be nested:
```cpp
YAML::Emitter out;
out << YAML::BeginMap;
out << YAML::Key << "name";
out << YAML::Value << "Barack Obama";
out << YAML::Key << "children";
out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq;
out << YAML::EndMap;
```
produces
```yaml
name: Barack Obama
children:
- Sasha
- Malia
```
# Using Manipulators #
To deviate from standard formatting, you can use manipulators to modify the output format. For example,
```cpp
YAML::Emitter out;
out << YAML::Literal << "A\n B\n C";
```
produces
```yaml
|
A
B
C
```
and
```cpp
YAML::Emitter out;
out << YAML::Flow;
out << YAML::BeginSeq << 2 << 3 << 5 << 7 << 11 << YAML::EndSeq;
```
produces
```yaml
[2, 3, 5, 7, 11]
```
Comments act like manipulators:
```cpp
YAML::Emitter out;
out << YAML::BeginMap;
out << YAML::Key << "method";
out << YAML::Value << "least squares";
out << YAML::Comment("should we change this method?");
out << YAML::EndMap;
```
produces
```yaml
method: least squares # should we change this method?
```
And so do aliases/anchors:
```cpp
YAML::Emitter out;
out << YAML::BeginSeq;
out << YAML::Anchor("fred");
out << YAML::BeginMap;
out << YAML::Key << "name" << YAML::Value << "Fred";
out << YAML::Key << "age" << YAML::Value << "42";
out << YAML::EndMap;
out << YAML::Alias("fred");
out << YAML::EndSeq;
```
produces
```yaml
- &fred
name: Fred
age: 42
- *fred
```
# 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 = {1, 4, 9, 16};
std::map <std::string, int> ages = {{"Daniel", 26}, {"Jesse", 24}};
YAML::Emitter out;
out << YAML::BeginSeq;
out << YAML::Flow << squares;
out << ages;
out << YAML::EndSeq;
```
{% endraw %}
produces
```yaml
- [1, 4, 9, 16]
-
Daniel: 26
Jesse: 24
```
Of course, you can overload `operator <<` for your own types:
```cpp
struct Vec3 { int x; int y; int z; };
YAML::Emitter& operator << (YAML::Emitter& out, const Vec3& v) {
out << YAML::Flow;
out << YAML::BeginSeq << v.x << v.y << v.z << YAML::EndSeq;
return out;
}
```
and it'll play nicely with everything else.
# Using Existing Nodes #
We also overload `operator << ` for `YAML::Node`s in both APIs, so you can output existing Nodes. Of course, Nodes in the old API are read-only, so it's tricky to emit them if you want to modify them. So use the new API!
# Output Encoding #
The output is always UTF-8. By default, yaml-cpp will output as much as it can without escaping any characters. If you want to restrict the output to ASCII, use the manipulator `YAML::EscapeNonAscii`:
```cpp
emitter.SetOutputCharset(YAML::EscapeNonAscii);
```
# Lifetime of Manipulators #
Manipulators affect the **next** output item in the stream. If that item is a `BeginSeq` or `BeginMap`, the manipulator lasts until the corresponding `EndSeq` or `EndMap`. (However, within that sequence or map, you can override the manipulator locally, etc.; in effect, there's a "manipulator stack" behind the scenes.)
If you want to permanently change a setting, there are global setters corresponding to each manipulator, e.g.:
```cpp
YAML::Emitter out;
out.SetIndent(4);
out.SetMapStyle(YAML::Flow);
```
# When Something Goes Wrong #
If something goes wrong when you're emitting a document, it must be something like forgetting a `YAML::EndSeq`, or a misplaced `YAML::Key`. In this case, emitting silently fails (no more output is emitted) and an error flag is set. For example:
```cpp
YAML::Emitter out;
assert(out.good());
out << YAML::Key;
assert(!out.good());
std::cout << "Emitter error: " << out.GetLastError() << "\n";
```
-265
View File
@@ -1,265 +0,0 @@
_The following describes the old API. For the new API, see the [Tutorial](https://github.com/jbeder/yaml-cpp/wiki/Tutorial)._
## Contents ##
# Basic Parsing #
The parser accepts streams, not file names, so you need to first load the file. Since a YAML file can contain many documents, you can grab them one-by-one. A simple way to parse a YAML file might be:
```
#include <fstream>
#include "yaml-cpp/yaml.h"
int main()
{
std::ifstream fin("test.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
while(parser.GetNextDocument(doc)) {
// ...
}
return 0;
}
```
# Reading From the Document #
Suppose we have a document consisting only of a scalar. We can read that scalar like this:
```
YAML::Node doc; // let's say we've already parsed this document
std::string scalar;
doc >> scalar;
std::cout << "That scalar was: " << scalar << std::endl;
```
How about sequences? Let's say our document now consists only of a sequences of scalars. We can use an iterator:
```
YAML::Node doc; // already parsed
for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
std::string scalar;
*it >> scalar;
std::cout << "Found scalar: " << scalar << std::endl;
}
```
... or we can just loop through:
```
YAML::Node doc; // already parsed
for(unsigned i=0;i<doc.size();i++) {
std::string scalar;
doc[i] >> scalar;
std::cout << "Found scalar: " << scalar << std::endl;
}
```
And finally maps. For now, let's say our document is a map with all keys/values being scalars. Again, we can iterate:
```
YAML::Node doc; // already parsed
for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
std::string key, value;
it.first() >> key;
it.second() >> value;
std::cout << "Key: " << key << ", value: " << value << std::endl;
}
```
Note that dereferencing a map iterator is undefined; instead, use the `first` and `second` methods to get the key and value nodes, respectively.
Alternatively, we can pick off the values one-by-one, if we know the keys:
```
YAML::Node doc; // already parsed
std::string name;
doc["name"] >> name;
int age;
doc["age"] >> age;
std::cout << "Found entry with name '" << name << "' and age '" << age << "'\n";
```
One thing to be keep in mind: reading a map by key (as immediately above) requires looping through all entries until we find the right key, which is an O(n) operation. So if you're reading the entire map this way, it'll be O(n^2). For small n, this isn't a big deal, but I wouldn't recommend reading maps with a very large number of entries (>100, say) this way.
## Optional Keys ##
If you try to access a key that doesn't exist, `yaml-cpp` throws an exception (see [When Something Goes Wrong](https://github.com/jbeder/yaml-cpp/wiki/How-To-Parse-A-Document-(Old-API)#When_Something_Goes_Wrong). If you have optional keys, it's often easier to use `FindValue` instead of `operator[]`:
```
YAML::Node doc; // already parsed
if(const YAML::Node *pName = doc.FindValue("name")) {
std::string name;
*pName >> name;
std::cout << "Key 'name' exists, with value '" << name << "'\n";
} else {
std::cout << "Key 'name' doesn't exist\n";
}
```
# Getting More Complicated #
The above three methods can be combined to read from an arbitrary document. But we can make life a lot easier. Suppose we're reading 3-vectors (i.e., vectors with three components), so we've got a structure looking like this:
```
struct Vec3 {
float x, y, z;
};
```
We can read this in one operation by overloading the extraction (>>) operator:
```
void operator >> (const YAML::Node& node, Vec3& v)
{
node[0] >> v.x;
node[1] >> v.y;
node[2] >> v.z;
}
// now it's a piece of cake to read it
YAML::Node doc; // already parsed
Vec3 v;
doc >> v;
std::cout << "Here's the vector: (" << v.x << ", " << v.y << ", " << v.z << ")\n";
```
# A Complete Example #
Here's a complete example of how to parse a complex YAML file:
`monsters.yaml`
```
- name: Ogre
position: [0, 5, 0]
powers:
- name: Club
damage: 10
- name: Fist
damage: 8
- name: Dragon
position: [1, 0, 10]
powers:
- name: Fire Breath
damage: 25
- name: Claws
damage: 15
- name: Wizard
position: [5, -3, 0]
powers:
- name: Acid Rain
damage: 50
- name: Staff
damage: 3
```
`main.cpp`
```
#include "yaml-cpp/yaml.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
// our data types
struct Vec3 {
float x, y, z;
};
struct Power {
std::string name;
int damage;
};
struct Monster {
std::string name;
Vec3 position;
std::vector <Power> powers;
};
// now the extraction operators for these types
void operator >> (const YAML::Node& node, Vec3& v) {
node[0] >> v.x;
node[1] >> v.y;
node[2] >> v.z;
}
void operator >> (const YAML::Node& node, Power& power) {
node["name"] >> power.name;
node["damage"] >> power.damage;
}
void operator >> (const YAML::Node& node, Monster& monster) {
node["name"] >> monster.name;
node["position"] >> monster.position;
const YAML::Node& powers = node["powers"];
for(unsigned i=0;i<powers.size();i++) {
Power power;
powers[i] >> power;
monster.powers.push_back(power);
}
}
int main()
{
std::ifstream fin("monsters.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
parser.GetNextDocument(doc);
for(unsigned i=0;i<doc.size();i++) {
Monster monster;
doc[i] >> monster;
std::cout << monster.name << "\n";
}
return 0;
}
```
# When Something Goes Wrong #
... we throw an exception (all exceptions are derived from `YAML::Exception`). If there's a parsing exception (i.e., a malformed YAML document), we throw a `YAML::ParserException`:
```
try {
std::ifstream fin("test.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
parser.GetNextDocument(doc);
// do stuff
} catch(YAML::ParserException& e) {
std::cout << e.what() << "\n";
}
```
If you make a programming error (say, trying to read a scalar from a sequence node, or grabbing a key that doesn't exist), we throw some kind of `YAML::RepresentationException`. To prevent this, you can check what kind of node something is:
```
YAML::Node node;
YAML::NodeType::value type = node.Type(); // should be:
// YAML::NodeType::Null
// YAML::NodeType::Scalar
// YAML::NodeType::Sequence
// YAML::NodeType::Map
```
# Note about copying `YAML::Node` #
Currently `YAML::Node` is non-copyable, so you need to do something like
```
const YAML::Node& node = doc["whatever"];
```
This is intended behavior. If you want to copy a node, use the `Clone` function:
```
std::auto_ptr<YAML::Node> pCopy = myOtherNode.Clone();
```
The intent is that if you'd like to keep a `YAML::Node` around for longer than the document will stay in scope, you can clone it and store it as long as you like.
-18
View File
@@ -1,18 +0,0 @@
# Encodings and `yaml-cpp` #
`yaml-cpp` will parse any file as specified by the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html#id2570322). Internally, it stores all strings in UTF-8, and representation is done with UTF-8. This means that in
```
std::string str;
node >> str;
```
`str` will be UTF-8. Similarly, if you're accessing a map by string key, you need to pass the key in UTF-8. If your application uses a different encoding, you need to convert to and from UTF-8 to work with `yaml-cpp`. (It's possible we'll add some small conversion functions, but for now it's restricted.)
---
For convenience, Richard Weeks has kindly provided a google gadget that converts Unicode to a string literal. It's a Google Gadget, so unfortunately it does not work on GitHub. Patches welcome to port it to a usable format here:
```
<wiki:gadget url="http://hosting.gmodules.com/ig/gadgets/file/111180078345548400783/c-style-utf8-encoder.xml"/>
```
-201
View File
@@ -1,201 +0,0 @@
# Introduction #
A typical example, loading a configuration file, might look like this:
```cpp
YAML::Node config = YAML::LoadFile("config.yaml");
if (config["lastLogin"]) {
std::cout << "Last logged in: " << config["lastLogin"].as<DateTime>() << "\n";
}
const std::string username = config["username"].as<std::string>();
const std::string password = config["password"].as<std::string>();
login(username, password);
config["lastLogin"] = getCurrentDateTime();
std::ofstream fout("config.yaml");
fout << config;
```
# Basic Parsing and Node Editing #
All nodes in a YAML document (including the root) are represented by `YAML::Node`. You can check what kind it is:
```cpp
YAML::Node node = YAML::Load("[1, 2, 3]");
assert(node.Type() == YAML::NodeType::Sequence);
assert(node.IsSequence()); // a shortcut!
```
Collection nodes (sequences and maps) act somewhat like STL vectors and maps:
```cpp
YAML::Node primes = YAML::Load("[2, 3, 5, 7, 11]");
for (std::size_t i=0;i<primes.size();i++) {
std::cout << primes[i].as<int>() << "\n";
}
// or:
for (YAML::const_iterator it=primes.begin();it!=primes.end();++it) {
std::cout << it->as<int>() << "\n";
}
primes.push_back(13);
assert(primes.size() == 6);
```
and
```cpp
YAML::Node lineup = YAML::Load("{1B: Prince Fielder, 2B: Rickie Weeks, LF: Ryan Braun}");
for(YAML::const_iterator it=lineup.begin();it!=lineup.end();++it) {
std::cout << "Playing at " << it->first.as<std::string>() << " is " << it->second.as<std::string>() << "\n";
}
lineup["RF"] = "Corey Hart";
lineup["C"] = "Jonathan Lucroy";
assert(lineup.size() == 5);
```
Querying for keys does **not** create them automatically (this makes handling optional map entries very easy)
```cpp
YAML::Node node = YAML::Load("{name: Brewers, city: Milwaukee}");
if (node["name"]) {
std::cout << node["name"].as<std::string>() << "\n";
}
if (node["mascot"]) {
std::cout << node["mascot"].as<std::string>() << "\n";
}
assert(node.size() == 2); // the previous call didn't create a node
```
If you're not sure what kind of data you're getting, you can query the type of a node:
```cpp
switch (node.Type()) {
case Null: // ...
case Scalar: // ...
case Sequence: // ...
case Map: // ...
case Undefined: // ...
}
```
or ask directly whether it's a particular type, e.g.:
```cpp
if (node.IsSequence()) {
// ...
}
```
# Building Nodes #
You can build `YAML::Node` from scratch:
```cpp
YAML::Node node; // starts out as null
node["key"] = "value"; // it now is a map node
node["seq"].push_back("first element"); // node["seq"] automatically becomes a sequence
node["seq"].push_back("second element");
node["mirror"] = node["seq"][0]; // this creates an alias
node["seq"][0] = "1st element"; // this also changes node["mirror"]
node["mirror"] = "element #1"; // and this changes node["seq"][0] - they're really the "same" node
node["self"] = node; // you can even create self-aliases
node[node["mirror"]] = node["seq"]; // and strange loops :)
```
The above node is now:
```yaml
&1
key: value
&2 seq: [&3 "element #1", second element]
mirror: *3
self: *1
*3 : *2
```
# How Sequences Turn Into Maps #
Sequences can be turned into maps by asking for non-integer keys. For example,
```cpp
YAML::Node node = YAML::Load("[1, 2, 3]");
node[1] = 5; // still a sequence, [1, 5, 3]
node.push_back(-3) // still a sequence, [1, 5, 3, -3]
node["key"] = "value"; // now it's a map! {0: 1, 1: 5, 2: 3, 3: -3, key: value}
```
Indexing a sequence node by an index that's not in its range will _usually_ turn it into a map, but if the index is one past the end of the sequence, then the sequence will grow by one to accommodate it. (That's the **only** exception to this rule.) For example,
```cpp
YAML::Node node = YAML::Load("[1, 2, 3]");
node[3] = 4; // still a sequence, [1, 2, 3, 4]
node[10] = 10; // now it's a map! {0: 1, 1: 2, 2: 3, 3: 4, 10: 10}
```
# Converting To/From Native Data Types #
Yaml-cpp has built-in conversion to and from most built-in data types, as well as `std::vector`, `std::list`, and `std::map`. The following examples demonstrate when those conversions are used:
```cpp
YAML::Node node = YAML::Load("{pi: 3.14159, [0, 1]: integers}");
// this needs the conversion from Node to double
double pi = node["pi"].as<double>();
// this needs the conversion from double to Node
node["e"] = 2.71828;
// this needs the conversion from Node to std::vector<int> (*not* the other way around!)
std::vector<int> v;
v.push_back(0);
v.push_back(1);
std::string str = node[v].as<std::string>();
```
To use yaml-cpp with your own data types, you need to specialize the YAML::convert<> template class. For example, suppose you had a simple `Vec3` class:
```cpp
struct Vec3 { double x, y, z; /* etc - make sure you have overloaded operator== */ };
```
You could write
```cpp
namespace YAML {
template<>
struct convert<Vec3> {
static Node encode(const Vec3& rhs) {
Node node;
node.push_back(rhs.x);
node.push_back(rhs.y);
node.push_back(rhs.z);
return node;
}
static bool decode(const Node& node, Vec3& rhs) {
if(!node.IsSequence() || node.size() != 3) {
return false;
}
rhs.x = node[0].as<double>();
rhs.y = node[1].as<double>();
rhs.z = node[2].as<double>();
return true;
}
};
}
```
Then you could use `Vec3` wherever you could use any other type:
```cpp
YAML::Node node = YAML::Load("start: [1, 3, 0]");
Vec3 v = node["start"].as<Vec3>();
node["end"] = Vec3(2, -1, 0);
```
-1
View File
@@ -1 +0,0 @@
theme: jekyll-theme-slate
-1
View File
@@ -1 +0,0 @@
To learn how to use the library, see the [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)
+6 -7
View File
@@ -1,17 +1,16 @@
#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cstddef> #include <cstddef>
namespace YAML { namespace YAML
using anchor_t = std::size_t; {
const anchor_t NullAnchor = 0; typedef std::size_t anchor_t;
const anchor_t NullAnchor = 0;
} }
#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+52 -61
View File
@@ -1,71 +1,62 @@
#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <vector> #include <vector>
#include "yaml-cpp/dll.h" namespace YAML
{
std::string EncodeBase64(const unsigned char *data, std::size_t size);
std::vector<unsigned char> DecodeBase64(const std::string& input);
class Binary {
public:
Binary(): m_unownedData(0), m_unownedSize(0) {}
Binary(const unsigned char *data_, std::size_t size_): m_unownedData(data_), m_unownedSize(size_) {}
bool owned() const { return !m_unownedData; }
std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; }
const unsigned char *data() const { return owned() ? &m_data[0] : m_unownedData; }
void swap(std::vector<unsigned char>& rhs) {
if(m_unownedData) {
m_data.swap(rhs);
rhs.clear();
rhs.resize(m_unownedSize);
std::copy(m_unownedData, m_unownedData + m_unownedSize, &rhs[0]);
m_unownedData = 0;
m_unownedSize = 0;
} else {
m_data.swap(rhs);
}
}
bool operator == (const Binary& rhs) const {
const std::size_t s = size();
if(s != rhs.size())
return false;
const unsigned char *d1 = data();
const unsigned char *d2 = rhs.data();
for(std::size_t i=0;i<s;i++) {
if(*d1++ != *d2++)
return false;
}
return true;
}
bool operator != (const Binary& rhs) const {
return !(*this == rhs);
}
private:
std::vector<unsigned char> m_data;
const unsigned char *m_unownedData;
std::size_t m_unownedSize;
};
}
namespace YAML { #endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
YAML_CPP_API std::string EncodeBase64(const unsigned char *data,
std::size_t size);
YAML_CPP_API std::vector<unsigned char> DecodeBase64(const std::string &input);
class YAML_CPP_API Binary {
public:
Binary(const unsigned char *data_, std::size_t size_)
: m_data{}, m_unownedData(data_), m_unownedSize(size_) {}
Binary() : Binary(nullptr, 0) {}
Binary(const Binary &) = default;
Binary(Binary &&) = default;
Binary &operator=(const Binary &) = default;
Binary &operator=(Binary &&) = default;
bool owned() const { return !m_unownedData; }
std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; }
const unsigned char *data() const {
return owned() ? &m_data[0] : m_unownedData;
}
void swap(std::vector<unsigned char> &rhs) {
if (m_unownedData) {
m_data.swap(rhs);
rhs.clear();
rhs.resize(m_unownedSize);
std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin());
m_unownedData = nullptr;
m_unownedSize = 0;
} else {
m_data.swap(rhs);
}
}
bool operator==(const Binary &rhs) const {
const std::size_t s = size();
if (s != rhs.size())
return false;
const unsigned char *d1 = data();
const unsigned char *d2 = rhs.data();
for (std::size_t i = 0; i < s; i++) {
if (*d1++ != *d2++)
return false;
}
return true;
}
bool operator!=(const Binary &rhs) const { return !(*this == rhs); }
private:
std::vector<unsigned char> m_data;
const unsigned char *m_unownedData;
std::size_t m_unownedSize;
};
} // namespace YAML
#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+30 -28
View File
@@ -1,9 +1,7 @@
#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
@@ -11,30 +9,34 @@
#include "../anchor.h" #include "../anchor.h"
namespace YAML { namespace YAML
/** {
* An object that stores and retrieves values correlating to {@link anchor_t} /// AnchorDict
* values. /// . An object that stores and retrieves values correlating to anchor_t
* /// values.
* <p>Efficient implementation that can make assumptions about how /// . Efficient implementation that can make assumptions about how anchor_t
* {@code anchor_t} values are assigned by the {@link Parser} class. /// values are assigned by the Parser class.
*/ template <class T>
template <class T> class AnchorDict
class AnchorDict { {
public: public:
AnchorDict() : m_data{} {} void Register(anchor_t anchor, T value)
void Register(anchor_t anchor, T value) { {
if (anchor > m_data.size()) { if (anchor > m_data.size())
m_data.resize(anchor); {
m_data.resize(anchor);
}
m_data[anchor - 1] = value;
} }
m_data[anchor - 1] = value;
} T Get(anchor_t anchor) const
{
return m_data[anchor - 1];
}
private:
std::vector<T> m_data;
};
}
T Get(anchor_t anchor) const { return m_data[anchor - 1]; } #endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
private:
std::vector<T> m_data;
};
} // namespace YAML
#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+121 -137
View File
@@ -1,149 +1,133 @@
#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include <string> #include <string>
namespace YAML { namespace YAML
class Parser; {
class Parser;
// GraphBuilderInterface
// . Abstraction of node creation // GraphBuilderInterface
// . pParentNode is always nullptr or the return value of one of the NewXXX() // . Abstraction of node creation
// functions. // . pParentNode is always NULL or the return value of one of the NewXXX()
class GraphBuilderInterface { // functions.
public: class GraphBuilderInterface
virtual ~GraphBuilderInterface() = 0; {
public:
// Create and return a new node with a null value. // Create and return a new node with a null value.
virtual void *NewNull(const Mark &mark, void *pParentNode) = 0; virtual void *NewNull(const Mark& mark, void *pParentNode) = 0;
// Create and return a new node with the given tag and value. // Create and return a new node with the given tag and value.
virtual void *NewScalar(const Mark &mark, const std::string &tag, virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) = 0;
void *pParentNode, const std::string &value) = 0;
// Create and return a new sequence node
// Create and return a new sequence node virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) = 0;
virtual void *NewSequence(const Mark &mark, const std::string &tag, // Add pNode to pSequence. pNode was created with one of the NewXxx()
void *pParentNode) = 0; // functions and pSequence with NewSequence().
virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
// Add pNode to pSequence. pNode was created with one of the NewXxx() // Note that no moew entries will be added to pSequence
// functions and pSequence with NewSequence(). virtual void SequenceComplete(void *pSequence) {(void)pSequence;}
virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
// Create and return a new map node
// Note that no moew entries will be added to pSequence virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) = 0;
virtual void SequenceComplete(void *pSequence) { (void)pSequence; } // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode
// were created with one of the NewXxx() methods and pMap with NewMap().
// Create and return a new map node virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0;
virtual void *NewMap(const Mark &mark, const std::string &tag, // Note that no more assignments will be made in pMap
void *pParentNode) = 0; virtual void MapComplete(void *pMap) {(void)pMap;}
// Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode // Return the node that should be used in place of an alias referencing
// were created with one of the NewXxx() methods and pMap with NewMap(). // pNode (pNode by default)
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0; virtual void *AnchorReference(const Mark& mark, void *pNode) {(void)mark; return pNode;}
};
// Note that no more assignments will be made in pMap
virtual void MapComplete(void *pMap) { (void)pMap; } // Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines
// Node, Sequence, and Map types. Sequence and Map must derive from Node
// Return the node that should be used in place of an alias referencing // (unless Node is defined as void). Impl must also implement function with
// pNode (pNode by default) // all of the same names as the virtual functions in GraphBuilderInterface
virtual void *AnchorReference(const Mark &mark, void *pNode) { // -- including the ones with default implementations -- but with the
(void)mark; // prototypes changed to accept an explicit Node*, Sequence*, or Map* where
return pNode; // appropriate.
template <class Impl>
class GraphBuilder : public GraphBuilderInterface
{
public:
typedef typename Impl::Node Node;
typedef typename Impl::Sequence Sequence;
typedef typename Impl::Map Map;
GraphBuilder(Impl& impl) : m_impl(impl)
{
Map* pMap = NULL;
Sequence* pSeq = NULL;
Node* pNode = NULL;
// Type consistency checks
pNode = pMap;
pNode = pSeq;
}
GraphBuilderInterface& AsBuilderInterface() {return *this;}
virtual void *NewNull(const Mark& mark, void* pParentNode) {
return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode)));
}
virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) {
return CheckType<Node>(m_impl.NewScalar(mark, tag, AsNode(pParentNode), value));
}
virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) {
return CheckType<Sequence>(m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
}
virtual void AppendToSequence(void *pSequence, void *pNode) {
m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
}
virtual void SequenceComplete(void *pSequence) {
m_impl.SequenceComplete(AsSequence(pSequence));
}
virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) {
return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
}
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
}
virtual void MapComplete(void *pMap) {
m_impl.MapComplete(AsMap(pMap));
}
virtual void *AnchorReference(const Mark& mark, void *pNode) {
return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
}
private:
Impl& m_impl;
// Static check for pointer to T
template <class T, class U>
static T* CheckType(U* p) {return p;}
static Node *AsNode(void *pNode) {return static_cast<Node*>(pNode);}
static Sequence *AsSequence(void *pSeq) {return static_cast<Sequence*>(pSeq);}
static Map *AsMap(void *pMap) {return static_cast<Map*>(pMap);}
};
void *BuildGraphOfNextDocument(Parser& parser, GraphBuilderInterface& graphBuilder);
template <class Impl>
typename Impl::Node *BuildGraphOfNextDocument(Parser& parser, Impl& impl)
{
GraphBuilder<Impl> graphBuilder(impl);
return static_cast<typename Impl::Node *>(BuildGraphOfNextDocument(
parser, graphBuilder
));
} }
};
// Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines
// Node, Sequence, and Map types. Sequence and Map must derive from Node
// (unless Node is defined as void). Impl must also implement function with
// all of the same names as the virtual functions in GraphBuilderInterface
// -- including the ones with default implementations -- but with the
// prototypes changed to accept an explicit Node*, Sequence*, or Map* where
// appropriate.
template <class Impl>
class GraphBuilder : public GraphBuilderInterface {
public:
typedef typename Impl::Node Node;
typedef typename Impl::Sequence Sequence;
typedef typename Impl::Map Map;
GraphBuilder(Impl &impl) : m_impl(impl) {
Map *pMap = nullptr;
Sequence *pSeq = nullptr;
Node *pNode = nullptr;
// Type consistency checks
pNode = pMap;
pNode = pSeq;
}
GraphBuilderInterface &AsBuilderInterface() { return *this; }
virtual void *NewNull(const Mark &mark, void *pParentNode) {
return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode)));
}
virtual void *NewScalar(const Mark &mark, const std::string &tag,
void *pParentNode, const std::string &value) {
return CheckType<Node>(
m_impl.NewScalar(mark, tag, AsNode(pParentNode), value));
}
virtual void *NewSequence(const Mark &mark, const std::string &tag,
void *pParentNode) {
return CheckType<Sequence>(
m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
}
virtual void AppendToSequence(void *pSequence, void *pNode) {
m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
}
virtual void SequenceComplete(void *pSequence) {
m_impl.SequenceComplete(AsSequence(pSequence));
}
virtual void *NewMap(const Mark &mark, const std::string &tag,
void *pParentNode) {
return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
}
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
}
virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); }
virtual void *AnchorReference(const Mark &mark, void *pNode) {
return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
}
private:
Impl &m_impl;
// Static check for pointer to T
template <class T, class U>
static T *CheckType(U *p) {
return p;
}
static Node *AsNode(void *pNode) { return static_cast<Node *>(pNode); }
static Sequence *AsSequence(void *pSeq) {
return static_cast<Sequence *>(pSeq);
}
static Map *AsMap(void *pMap) { return static_cast<Map *>(pMap); }
};
void *BuildGraphOfNextDocument(Parser &parser,
GraphBuilderInterface &graphBuilder);
template <class Impl>
typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) {
GraphBuilder<Impl> graphBuilder(impl);
return static_cast<typename Impl::Node *>(
BuildGraphOfNextDocument(parser, graphBuilder));
}
} }
#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-77
View File
@@ -1,77 +0,0 @@
#ifndef DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000
#define DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include "exceptions.h"
namespace YAML {
/**
* @brief The DeepRecursion class
* An exception class which is thrown by DepthGuard. Ideally it should be
* a member of DepthGuard. However, DepthGuard is a templated class which means
* that any catch points would then need to know the template parameters. It is
* simpler for clients to not have to know at the catch point what was the
* maximum depth.
*/
class DeepRecursion : public ParserException {
public:
virtual ~DeepRecursion() = default;
DeepRecursion(int depth, const Mark& mark_, const std::string& msg_);
// Returns the recursion depth when the exception was thrown
int depth() const {
return m_depth;
}
private:
int m_depth = 0;
};
/**
* @brief The DepthGuard class
* DepthGuard takes a reference to an integer. It increments the integer upon
* construction of DepthGuard and decrements the integer upon destruction.
*
* If the integer would be incremented past max_depth, then an exception is
* thrown. This is ideally geared toward guarding against deep recursion.
*
* @param max_depth
* compile-time configurable maximum depth.
*/
template <int max_depth = 2000>
class DepthGuard final {
public:
DepthGuard(int & depth_, const Mark& mark_, const std::string& msg_) : m_depth(depth_) {
++m_depth;
if ( max_depth <= m_depth ) {
throw DeepRecursion{m_depth, mark_, msg_};
}
}
DepthGuard(const DepthGuard & copy_ctor) = delete;
DepthGuard(DepthGuard && move_ctor) = delete;
DepthGuard & operator=(const DepthGuard & copy_assign) = delete;
DepthGuard & operator=(DepthGuard && move_assign) = delete;
~DepthGuard() {
--m_depth;
}
int current_depth() const {
return m_depth;
}
private:
int & m_depth;
};
} // namespace YAML
#endif // DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000
+21 -52
View File
@@ -1,59 +1,28 @@
#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
// Definition YAML_CPP_STATIC_DEFINE using to building YAML-CPP as static #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
// library (definition created by CMake or defined manually) #pragma once
// 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 #endif
#ifndef YAML_CPP_DEPRECATED_EXPORT // The following ifdef block is the standard way of creating macros which make exporting
# define YAML_CPP_DEPRECATED_EXPORT YAML_CPP_API YAML_CPP_DEPRECATED // from a DLL simpler. All files within this DLL are compiled with the yaml_cpp_EXPORTS
#endif // 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_NO_EXPORT #ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined manually)
# define YAML_CPP_DEPRECATED_NO_EXPORT YAML_CPP_NO_EXPORT YAML_CPP_DEPRECATED #ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake or defined manually)
#endif // #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
#endif /* DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 */ #endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+35 -48
View File
@@ -1,58 +1,45 @@
#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/eventhandler.h"
#include <stack> #include <stack>
#include "yaml-cpp/anchor.h" namespace YAML
#include "yaml-cpp/emitterstyle.h" {
#include "yaml-cpp/eventhandler.h" class Emitter;
namespace YAML { class EmitFromEvents: public EventHandler
struct Mark; {
} // namespace YAML public:
EmitFromEvents(Emitter& emitter);
namespace YAML {
class Emitter; virtual void OnDocumentStart(const Mark& mark);
virtual void OnDocumentEnd();
class EmitFromEvents : public EventHandler {
public: virtual void OnNull(const Mark& mark, anchor_t anchor);
EmitFromEvents(Emitter& emitter); virtual void OnAlias(const Mark& mark, anchor_t anchor);
~EmitFromEvents() override = default; virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value);
void OnDocumentStart(const Mark& mark) override; virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor);
void OnDocumentEnd() override; virtual void OnSequenceEnd();
void OnNull(const Mark& mark, anchor_t anchor) override; virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor);
void OnAlias(const Mark& mark, anchor_t anchor) override; virtual void OnMapEnd();
void OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value) override; private:
void BeginNode();
void OnSequenceStart(const Mark& mark, const std::string& tag, void EmitProps(const std::string& tag, anchor_t anchor);
anchor_t anchor, EmitterStyle::value style) override;
void OnSequenceEnd() override; private:
Emitter& m_emitter;
void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) override; struct State { enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue }; };
void OnMapEnd() override; std::stack<State::value> m_stateStack;
};
private:
void BeginNode();
void EmitProps(const std::string& tag, anchor_t anchor);
private:
Emitter& m_emitter;
struct State {
enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue };
};
std::stack<State::value> m_stateStack;
};
} }
#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+167 -276
View File
@@ -1,295 +1,186 @@
#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#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/dll.h"
#include "yaml-cpp/emitterdef.h" #include "yaml-cpp/binary.h"
#include "yaml-cpp/emittermanip.h" #include "yaml-cpp/emittermanip.h"
#include "yaml-cpp/ostream.h"
#include "yaml-cpp/noncopyable.h"
#include "yaml-cpp/null.h" #include "yaml-cpp/null.h"
#include "yaml-cpp/ostream_wrapper.h" #include <memory>
#include "yaml-cpp/fptostring.h" #include <string>
#include <sstream>
namespace YAML { namespace YAML
class Binary; {
struct _Null; class EmitterState;
} // namespace YAML
class YAML_CPP_API Emitter: private noncopyable
{
public:
Emitter();
~Emitter();
// output
const char *c_str() const;
unsigned size() const;
// state checking
bool good() const;
const std::string GetLastError() const;
// global setters
bool SetOutputCharset(EMITTER_MANIP value);
bool SetStringFormat(EMITTER_MANIP value);
bool SetBoolFormat(EMITTER_MANIP value);
bool SetIntBase(EMITTER_MANIP value);
bool SetSeqFormat(EMITTER_MANIP value);
bool SetMapFormat(EMITTER_MANIP value);
bool SetIndent(unsigned n);
bool SetPreCommentIndent(unsigned n);
bool SetPostCommentIndent(unsigned n);
bool SetFloatPrecision(unsigned n);
bool SetDoublePrecision(unsigned n);
// local setters
Emitter& SetLocalValue(EMITTER_MANIP value);
Emitter& SetLocalIndent(const _Indent& indent);
Emitter& SetLocalPrecision(const _Precision& precision);
// overloads of write
Emitter& Write(const std::string& str);
Emitter& Write(bool b);
Emitter& Write(char ch);
Emitter& Write(const _Alias& alias);
Emitter& Write(const _Anchor& anchor);
Emitter& Write(const _Tag& tag);
Emitter& Write(const _Comment& comment);
Emitter& Write(const _Null& null);
Emitter& Write(const Binary& binary);
template <typename T>
Emitter& WriteIntegralType(T value);
template <typename T>
Emitter& WriteStreamable(T value);
namespace YAML { private:
class EmitterState; void PreWriteIntegralType(std::stringstream& str);
void PreWriteStreamable(std::stringstream& str);
void PostWriteIntegralType(const std::stringstream& str);
void PostWriteStreamable(const std::stringstream& str);
template<typename T> void SetStreamablePrecision(std::stringstream&) {}
unsigned GetFloatPrecision() const;
unsigned GetDoublePrecision() const;
private:
void PreAtomicWrite();
bool GotoNextPreAtomicState();
void PostAtomicWrite();
void EmitSeparationIfNecessary();
void EmitBeginDoc();
void EmitEndDoc();
void EmitBeginSeq();
void EmitEndSeq();
void EmitBeginMap();
void EmitEndMap();
void EmitKey();
void EmitValue();
void EmitNewline();
void EmitKindTag();
void EmitTag(bool verbatim, const _Tag& tag);
const char *ComputeFullBoolName(bool b) const;
bool CanEmitNewline() const;
private:
ostream m_stream;
std::auto_ptr <EmitterState> m_pState;
};
template <typename T>
inline Emitter& Emitter::WriteIntegralType(T value)
{
if(!good())
return *this;
std::stringstream str;
PreWriteIntegralType(str);
str << value;
PostWriteIntegralType(str);
return *this;
}
class YAML_CPP_API Emitter { template <typename T>
public: inline Emitter& Emitter::WriteStreamable(T value)
Emitter(); {
explicit Emitter(std::ostream& stream); if(!good())
Emitter(const Emitter&) = delete; return *this;
Emitter& operator=(const Emitter&) = delete;
~Emitter(); std::stringstream str;
PreWriteStreamable(str);
// output SetStreamablePrecision<T>(str);
const char* c_str() const; str << value;
std::size_t size() const; PostWriteStreamable(str);
return *this;
// state checking }
bool good() const;
const std::string GetLastError() const; template<>
inline void Emitter::SetStreamablePrecision<float>(std::stringstream& str)
// global setters {
bool SetOutputCharset(EMITTER_MANIP value); str.precision(GetFloatPrecision());
bool SetStringFormat(EMITTER_MANIP value);
bool SetBoolFormat(EMITTER_MANIP value);
bool SetNullFormat(EMITTER_MANIP value);
bool SetIntBase(EMITTER_MANIP value);
bool SetSeqFormat(EMITTER_MANIP value);
bool SetMapFormat(EMITTER_MANIP value);
bool SetIndent(std::size_t n);
bool SetPreCommentIndent(std::size_t n);
bool SetPostCommentIndent(std::size_t n);
bool SetFloatPrecision(std::size_t n);
bool SetDoublePrecision(std::size_t n);
void RestoreGlobalModifiedSettings();
// local setters
Emitter& SetLocalValue(EMITTER_MANIP value);
Emitter& SetLocalIndent(const _Indent& indent);
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);
Emitter& Write(const _Alias& alias);
Emitter& Write(const _Anchor& anchor);
Emitter& Write(const _Tag& tag);
Emitter& Write(const _Comment& comment);
Emitter& Write(const _Null& n);
Emitter& Write(const Binary& binary);
template <typename T>
Emitter& WriteIntegralType(T value);
template <typename T>
Emitter& WriteStreamable(T value);
private:
template <typename T>
void SetStreamablePrecision(std::stringstream&) {}
std::size_t GetFloatPrecision() const;
std::size_t GetDoublePrecision() const;
void PrepareIntegralStream(std::stringstream& stream) const;
void StartedScalar();
private:
void EmitBeginDoc();
void EmitEndDoc();
void EmitBeginSeq();
void EmitEndSeq();
void EmitBeginMap();
void EmitEndMap();
void EmitNewline();
void EmitKindTag();
void EmitTag(bool verbatim, const _Tag& tag);
void PrepareNode(EmitterNodeType::value child);
void PrepareTopNode(EmitterNodeType::value child);
void FlowSeqPrepareNode(EmitterNodeType::value child);
void BlockSeqPrepareNode(EmitterNodeType::value child);
void FlowMapPrepareNode(EmitterNodeType::value child);
void FlowMapPrepareLongKey(EmitterNodeType::value child);
void FlowMapPrepareLongKeyValue(EmitterNodeType::value child);
void FlowMapPrepareSimpleKey(EmitterNodeType::value child);
void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child);
void BlockMapPrepareNode(EmitterNodeType::value child);
void BlockMapPrepareLongKey(EmitterNodeType::value child);
void BlockMapPrepareLongKeyValue(EmitterNodeType::value child);
void BlockMapPrepareSimpleKey(EmitterNodeType::value child);
void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child);
void SpaceOrIndentTo(bool requireSpace, std::size_t indent);
const char* ComputeFullBoolName(bool b) const;
const char* ComputeNullName() const;
bool CanEmitNewline() const;
private:
std::unique_ptr<EmitterState> m_pState;
ostream_wrapper m_stream;
};
template <typename T>
inline Emitter& Emitter::WriteIntegralType(T value) {
if (!good())
return *this;
PrepareNode(EmitterNodeType::Scalar);
std::stringstream stream;
stream.imbue(std::locale::classic());
PrepareIntegralStream(stream);
stream << value;
m_stream << stream.str();
StartedScalar();
return *this;
}
template <typename T>
inline Emitter& Emitter::WriteStreamable(T value) {
if (!good())
return *this;
PrepareNode(EmitterNodeType::Scalar);
std::stringstream stream;
stream.imbue(std::locale::classic());
SetStreamablePrecision<T>(stream);
bool special = false;
if (std::is_floating_point<T>::value) {
if ((std::numeric_limits<T>::has_quiet_NaN ||
std::numeric_limits<T>::has_signaling_NaN) &&
std::isnan(value)) {
special = true;
stream << ".nan";
} else if (std::numeric_limits<T>::has_infinity && std::isinf(value)) {
special = true;
if (std::signbit(value)) {
stream << "-.inf";
} else {
stream << ".inf";
}
} }
}
if (!special) { template<>
stream << FpToString(value, stream.precision()); inline void Emitter::SetStreamablePrecision<double>(std::stringstream& str)
} {
m_stream << stream.str(); str.precision(GetDoublePrecision());
}
StartedScalar(); // overloads of insertion
inline Emitter& operator << (Emitter& emitter, const std::string& v) { return emitter.Write(v); }
inline Emitter& operator << (Emitter& emitter, bool v) { return emitter.Write(v); }
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)); }
inline Emitter& operator << (Emitter& emitter, const _Alias& v) { return emitter.Write(v); }
inline Emitter& operator << (Emitter& emitter, const _Anchor& v) { return emitter.Write(v); }
inline Emitter& operator << (Emitter& emitter, const _Tag& v) { return emitter.Write(v); }
inline Emitter& operator << (Emitter& emitter, const _Comment& v) { return emitter.Write(v); }
inline Emitter& operator << (Emitter& emitter, const _Null& v) { return emitter.Write(v); }
inline Emitter& operator << (Emitter& emitter, const Binary& b) { return emitter.Write(b); }
return *this; inline Emitter& operator << (Emitter& emitter, const char *v) { return emitter.Write(std::string(v)); }
inline Emitter& operator << (Emitter& emitter, int v) { return emitter.WriteIntegralType(v); }
inline Emitter& operator << (Emitter& emitter, unsigned int v) { return emitter.WriteIntegralType(v); }
inline Emitter& operator << (Emitter& emitter, short v) { return emitter.WriteIntegralType(v); }
inline Emitter& operator << (Emitter& emitter, unsigned short v) { return emitter.WriteIntegralType(v); }
inline Emitter& operator << (Emitter& emitter, long v) { return emitter.WriteIntegralType(v); }
inline Emitter& operator << (Emitter& emitter, unsigned long v) { return emitter.WriteIntegralType(v); }
inline Emitter& operator << (Emitter& emitter, long long v) { return emitter.WriteIntegralType(v); }
inline Emitter& operator << (Emitter& emitter, unsigned long long v) { return emitter.WriteIntegralType(v); }
inline Emitter& operator << (Emitter& emitter, float v) { return emitter.WriteStreamable(v); }
inline Emitter& operator << (Emitter& emitter, double v) { return emitter.WriteStreamable(v); }
inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) {
return emitter.SetLocalValue(value);
}
inline Emitter& operator << (Emitter& emitter, _Indent indent) {
return emitter.SetLocalIndent(indent);
}
inline Emitter& operator << (Emitter& emitter, _Precision precision) {
return emitter.SetLocalPrecision(precision);
}
} }
template <> #endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream) {
stream.precision(static_cast<std::streamsize>(GetFloatPrecision()));
}
template <>
inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) {
stream.precision(static_cast<std::streamsize>(GetDoublePrecision()));
}
// 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.data(), v.size());
}
inline Emitter& operator<<(Emitter& emitter, bool v) {
return emitter.Write(v);
}
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));
}
inline Emitter& operator<<(Emitter& emitter, const _Alias& v) {
return emitter.Write(v);
}
inline Emitter& operator<<(Emitter& emitter, const _Anchor& v) {
return emitter.Write(v);
}
inline Emitter& operator<<(Emitter& emitter, const _Tag& v) {
return emitter.Write(v);
}
inline Emitter& operator<<(Emitter& emitter, const _Comment& v) {
return emitter.Write(v);
}
inline Emitter& operator<<(Emitter& emitter, const _Null& v) {
return emitter.Write(v);
}
inline Emitter& operator<<(Emitter& emitter, const Binary& b) {
return emitter.Write(b);
}
inline Emitter& operator<<(Emitter& emitter, const char* v) {
return emitter.Write(v, std::strlen(v));
}
inline Emitter& operator<<(Emitter& emitter, int v) {
return emitter.WriteIntegralType(v);
}
inline Emitter& operator<<(Emitter& emitter, unsigned int v) {
return emitter.WriteIntegralType(v);
}
inline Emitter& operator<<(Emitter& emitter, short v) {
return emitter.WriteIntegralType(v);
}
inline Emitter& operator<<(Emitter& emitter, unsigned short v) {
return emitter.WriteIntegralType(v);
}
inline Emitter& operator<<(Emitter& emitter, long v) {
return emitter.WriteIntegralType(v);
}
inline Emitter& operator<<(Emitter& emitter, unsigned long v) {
return emitter.WriteIntegralType(v);
}
inline Emitter& operator<<(Emitter& emitter, long long v) {
return emitter.WriteIntegralType(v);
}
inline Emitter& operator<<(Emitter& emitter, unsigned long long v) {
return emitter.WriteIntegralType(v);
}
inline Emitter& operator<<(Emitter& emitter, float v) {
return emitter.WriteStreamable(v);
}
inline Emitter& operator<<(Emitter& emitter, double v) {
return emitter.WriteStreamable(v);
}
inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) {
return emitter.SetLocalValue(value);
}
inline Emitter& operator<<(Emitter& emitter, _Indent indent) {
return emitter.SetLocalIndent(indent);
}
inline Emitter& operator<<(Emitter& emitter, _Precision precision) {
return emitter.SetLocalPrecision(precision);
}
} // namespace YAML
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-16
View File
@@ -1,16 +0,0 @@
#ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERDEF_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
#endif
namespace YAML {
struct EmitterNodeType {
enum value { NoType, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap };
};
}
#endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+131 -126
View File
@@ -1,144 +1,149 @@
#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
namespace YAML { namespace YAML
enum EMITTER_MANIP { {
// general manipulators enum EMITTER_MANIP {
Auto, // general manipulators
TagByKind, Auto,
Newline, TagByKind,
Newline,
// output character set // output character set
EmitNonAscii, EmitNonAscii,
EscapeNonAscii, EscapeNonAscii,
EscapeAsJson,
// string manipulators
// Auto, // duplicate
SingleQuoted,
DoubleQuoted,
Literal,
// bool manipulators
YesNoBool, // yes, no
TrueFalseBool, // true, false
OnOffBool, // on, off
UpperCase, // TRUE, N
LowerCase, // f, yes
CamelCase, // No, Off
LongBool, // yes, On
ShortBool, // y, t
// int manipulators
Dec,
Hex,
Oct,
// document manipulators
BeginDoc,
EndDoc,
// sequence manipulators
BeginSeq,
EndSeq,
Flow,
Block,
// map manipulators
BeginMap,
EndMap,
Key,
Value,
// Flow, // duplicate
// Block, // duplicate
// Auto, // duplicate
LongKey
};
struct _Indent {
_Indent(int value_): value(value_) {}
int value;
};
inline _Indent Indent(int value) {
return _Indent(value);
}
struct _Alias {
_Alias(const std::string& content_): content(content_) {}
std::string content;
};
inline _Alias Alias(const std::string content) {
return _Alias(content);
}
struct _Anchor {
_Anchor(const std::string& content_): content(content_) {}
std::string content;
};
// string manipulators inline _Anchor Anchor(const std::string content) {
// Auto, // duplicate return _Anchor(content);
SingleQuoted, }
DoubleQuoted,
Literal, struct _Tag {
struct Type { enum value { Verbatim, PrimaryHandle, NamedHandle }; };
explicit _Tag(const std::string& prefix_, const std::string& content_, Type::value type_)
: prefix(prefix_), content(content_), type(type_)
{
}
std::string prefix;
std::string content;
Type::value type;
};
inline _Tag VerbatimTag(const std::string content) {
return _Tag("", content, _Tag::Type::Verbatim);
}
// null manipulators inline _Tag LocalTag(const std::string content) {
LowerNull, return _Tag("", content, _Tag::Type::PrimaryHandle);
UpperNull, }
CamelNull,
TildeNull,
// bool manipulators inline _Tag LocalTag(const std::string& prefix, const std::string content) {
YesNoBool, // yes, no return _Tag(prefix, content, _Tag::Type::NamedHandle);
TrueFalseBool, // true, false }
OnOffBool, // on, off
UpperCase, // TRUE, N
LowerCase, // f, yes
CamelCase, // No, Off
LongBool, // yes, On
ShortBool, // y, t
// int manipulators inline _Tag SecondaryTag(const std::string content) {
Dec, return _Tag("", content, _Tag::Type::NamedHandle);
Hex, }
Oct,
// document manipulators struct _Comment {
BeginDoc, _Comment(const std::string& content_): content(content_) {}
EndDoc, std::string content;
};
inline _Comment Comment(const std::string content) {
return _Comment(content);
}
struct _Precision {
_Precision(int floatPrecision_, int doublePrecision_): floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {}
int floatPrecision;
int doublePrecision;
};
inline _Precision FloatPrecision(int n) {
return _Precision(n, -1);
}
// sequence manipulators inline _Precision DoublePrecision(int n) {
BeginSeq, return _Precision(-1, n);
EndSeq, }
Flow,
Block,
// map manipulators inline _Precision Precision(int n) {
BeginMap, return _Precision(n, n);
EndMap, }
Key,
Value,
// Flow, // duplicate
// Block, // duplicate
// Auto, // duplicate
LongKey
};
struct _Indent {
_Indent(int value_) : value(value_) {}
int value;
};
inline _Indent Indent(int value) { return _Indent(value); }
struct _Alias {
_Alias(const std::string& content_) : content(content_) {}
std::string content;
};
inline _Alias Alias(const std::string& content) { return _Alias(content); }
struct _Anchor {
_Anchor(const std::string& content_) : content(content_) {}
std::string content;
};
inline _Anchor Anchor(const std::string& content) { return _Anchor(content); }
struct _Tag {
struct Type {
enum value { Verbatim, PrimaryHandle, NamedHandle };
};
explicit _Tag(const std::string& prefix_, const std::string& content_,
Type::value type_)
: prefix(prefix_), content(content_), type(type_) {}
std::string prefix;
std::string content;
Type::value type;
};
inline _Tag VerbatimTag(const std::string& content) {
return _Tag("", content, _Tag::Type::Verbatim);
} }
inline _Tag LocalTag(const std::string& content) { #endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
return _Tag("", content, _Tag::Type::PrimaryHandle);
}
inline _Tag LocalTag(const std::string& prefix, const std::string content) {
return _Tag(prefix, content, _Tag::Type::NamedHandle);
}
inline _Tag SecondaryTag(const std::string& content) {
return _Tag("", content, _Tag::Type::NamedHandle);
}
struct _Comment {
_Comment(const std::string& content_) : content(content_) {}
std::string content;
};
inline _Comment Comment(const std::string& content) { return _Comment(content); }
struct _Precision {
_Precision(int floatPrecision_, int doublePrecision_)
: floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {}
int floatPrecision;
int doublePrecision;
};
inline _Precision FloatPrecision(int n) { return _Precision(n, -1); }
inline _Precision DoublePrecision(int n) { return _Precision(-1, n); }
inline _Precision Precision(int n) { return _Precision(n, n); }
}
#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-17
View File
@@ -1,17 +0,0 @@
#ifndef EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERSTYLE_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
#endif
namespace YAML {
namespace EmitterStyle {
enum value { Default, Block, Flow };
}
}
#endif // EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+23 -32
View File
@@ -1,45 +1,36 @@
#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/anchor.h"
#include <string> #include <string>
#include "yaml-cpp/anchor.h" namespace YAML
#include "yaml-cpp/emitterstyle.h" {
struct Mark;
class EventHandler
{
public:
virtual ~EventHandler() {}
namespace YAML { virtual void OnDocumentStart(const Mark& mark) = 0;
struct Mark; virtual void OnDocumentEnd() = 0;
virtual void OnNull(const Mark& mark, anchor_t anchor) = 0;
virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0;
virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value) = 0;
class EventHandler { virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor) = 0;
public: virtual void OnSequenceEnd() = 0;
virtual ~EventHandler() = default;
virtual void OnDocumentStart(const Mark& mark) = 0; virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor) = 0;
virtual void OnDocumentEnd() = 0; virtual void OnMapEnd() = 0;
};
}
virtual void OnNull(const Mark& mark, anchor_t anchor) = 0; #endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0;
virtual void OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value) = 0;
virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) = 0;
virtual void OnSequenceEnd() = 0;
virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) = 0;
virtual void OnMapEnd() = 0;
virtual void OnAnchor(const Mark& /*mark*/,
const std::string& /*anchor_name*/) {
// empty default implementation for compatibility
}
};
} // namespace YAML
#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+176 -289
View File
@@ -1,305 +1,192 @@
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include "yaml-cpp/noexcept.h"
#include "yaml-cpp/traits.h" #include "yaml-cpp/traits.h"
#include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <sstream>
namespace YAML { namespace YAML
// error messages {
namespace ErrorMsg { // error messages
const char* const YAML_DIRECTIVE_ARGS = namespace ErrorMsg
"YAML directives must have exactly one argument"; {
const char* const YAML_VERSION = "bad YAML version: "; const char * const YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument";
const char* const YAML_MAJOR_VERSION = "YAML major version too large"; const char * const YAML_VERSION = "bad YAML version: ";
const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive"; const char * const YAML_MAJOR_VERSION = "YAML major version too large";
const char* const TAG_DIRECTIVE_ARGS = const char * const REPEATED_YAML_DIRECTIVE= "repeated YAML directive";
"TAG directives must have exactly two arguments"; const char * const TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments";
const char* const REPEATED_TAG_DIRECTIVE = "repeated TAG directive"; const char * const REPEATED_TAG_DIRECTIVE = "repeated TAG directive";
const char* const CHAR_IN_TAG_HANDLE = const char * const CHAR_IN_TAG_HANDLE = "illegal character found while scanning tag handle";
"illegal character found while scanning tag handle"; const char * const TAG_WITH_NO_SUFFIX = "tag handle with no suffix";
const char* const TAG_WITH_NO_SUFFIX = "tag handle with no suffix"; const char * const END_OF_VERBATIM_TAG = "end of verbatim tag not found";
const char* const END_OF_VERBATIM_TAG = "end of verbatim tag not found"; const char * const END_OF_MAP = "end of map not found";
const char* const END_OF_MAP = "end of map not found"; const char * const END_OF_MAP_FLOW = "end of map flow not found";
const char* const END_OF_MAP_FLOW = "end of map flow not found"; const char * const END_OF_SEQ = "end of sequence not found";
const char* const END_OF_SEQ = "end of sequence not found"; const char * const END_OF_SEQ_FLOW = "end of sequence flow not found";
const char* const END_OF_SEQ_FLOW = "end of sequence flow not found"; const char * const MULTIPLE_TAGS = "cannot assign multiple tags to the same node";
const char* const MULTIPLE_TAGS = const char * const MULTIPLE_ANCHORS = "cannot assign multiple anchors to the same node";
"cannot assign multiple tags to the same node"; const char * const MULTIPLE_ALIASES = "cannot assign multiple aliases to the same node";
const char* const MULTIPLE_ANCHORS = const char * const ALIAS_CONTENT = "aliases can't have any content, *including* tags";
"cannot assign multiple anchors to the same node"; const char * const INVALID_HEX = "bad character found while scanning hex number";
const char* const MULTIPLE_ALIASES = const char * const INVALID_UNICODE = "invalid unicode: ";
"cannot assign multiple aliases to the same node"; const char * const INVALID_ESCAPE = "unknown escape character: ";
const char* const ALIAS_CONTENT = const char * const UNKNOWN_TOKEN = "unknown token";
"aliases can't have any content, *including* tags"; const char * const DOC_IN_SCALAR = "illegal document indicator in scalar";
const char* const INVALID_HEX = "bad character found while scanning hex number"; const char * const EOF_IN_SCALAR = "illegal EOF in scalar";
const char* const INVALID_UNICODE = "invalid unicode: "; const char * const CHAR_IN_SCALAR = "illegal character in scalar";
const char* const INVALID_ESCAPE = "unknown escape character: "; const char * const TAB_IN_INDENTATION = "illegal tab when looking for indentation";
const char* const UNKNOWN_TOKEN = "unknown token"; const char * const FLOW_END = "illegal flow end";
const char* const DOC_IN_SCALAR = "illegal document indicator in scalar"; const char * const BLOCK_ENTRY = "illegal block entry";
const char* const EOF_IN_SCALAR = "illegal EOF in scalar"; const char * const MAP_KEY = "illegal map key";
const char* const CHAR_IN_SCALAR = "illegal character in scalar"; const char * const MAP_VALUE = "illegal map value";
const char* const UNEXPECTED_SCALAR = "unexpected scalar"; const char * const ALIAS_NOT_FOUND = "alias not found after *";
const char* const UNEXPECTED_FLOW = "plain value cannot start with flow indicator character"; const char * const ANCHOR_NOT_FOUND = "anchor not found after &";
const char* const TAB_IN_INDENTATION = const char * const CHAR_IN_ALIAS = "illegal character found while scanning alias";
"illegal tab when looking for indentation"; const char * const CHAR_IN_ANCHOR = "illegal character found while scanning anchor";
const char* const FLOW_END = "illegal flow end"; const char * const ZERO_INDENT_IN_BLOCK = "cannot set zero indentation for a block scalar";
const char* const BLOCK_ENTRY = "illegal block entry"; const char * const CHAR_IN_BLOCK = "unexpected character in block scalar";
const char* const MAP_KEY = "illegal map key"; const char * const AMBIGUOUS_ANCHOR = "cannot assign the same alias to multiple nodes";
const char* const MAP_VALUE = "illegal map value"; const char * const UNKNOWN_ANCHOR = "the referenced anchor is not defined";
const char* const ALIAS_NOT_FOUND = "alias not found after *";
const char* const ANCHOR_NOT_FOUND = "anchor not found after &";
const char* const CHAR_IN_ALIAS =
"illegal character found while scanning alias";
const char* const CHAR_IN_ANCHOR =
"illegal character found while scanning anchor";
const char* const ZERO_INDENT_IN_BLOCK =
"cannot set zero indentation for a block scalar";
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 INVALID_NODE = const char * const INVALID_SCALAR = "invalid scalar";
"invalid node; this may result from using a map iterator as a sequence " const char * const KEY_NOT_FOUND = "key not found";
"iterator, or vice-versa"; const char * const BAD_CONVERSION = "bad conversion";
const char* const INVALID_SCALAR = "invalid scalar"; const char * const BAD_DEREFERENCE = "bad dereference";
const char* const KEY_NOT_FOUND = "key not found"; const char * const BAD_SUBSCRIPT = "operator[] call on a scalar";
const char* const BAD_CONVERSION = "bad conversion"; const char * const BAD_PUSHBACK = "appending to a non-sequence";
const char* const BAD_DEREFERENCE = "bad dereference";
const char* const BAD_SUBSCRIPT = "operator[] call on a scalar"; const char * const UNMATCHED_GROUP_TAG = "unmatched group tag";
const char* const BAD_PUSHBACK = "appending to a non-sequence"; const char * const UNEXPECTED_END_SEQ = "unexpected end sequence token";
const char* const BAD_INSERT = "inserting in a non-convertible-to-map"; const char * const UNEXPECTED_END_MAP = "unexpected end map token";
const char * const SINGLE_QUOTED_CHAR = "invalid character in single-quoted string";
const char * const INVALID_ANCHOR = "invalid anchor";
const char * const INVALID_ALIAS = "invalid alias";
const char * const INVALID_TAG = "invalid tag";
const char * const EXPECTED_KEY_TOKEN = "expected key token";
const char * const EXPECTED_VALUE_TOKEN = "expected value token";
const char * const UNEXPECTED_KEY_TOKEN = "unexpected key token";
const char * const UNEXPECTED_VALUE_TOKEN = "unexpected value token";
const char* const UNMATCHED_GROUP_TAG = "unmatched group tag"; template <typename T>
const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token"; inline const std::string KEY_NOT_FOUND_WITH_KEY(const T&, typename disable_if<is_numeric<T> >::type * = 0) {
const char* const UNEXPECTED_END_MAP = "unexpected end map token"; return KEY_NOT_FOUND;
const char* const SINGLE_QUOTED_CHAR = }
"invalid character in single-quoted string";
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";
template <typename T> inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
inline const std::string KEY_NOT_FOUND_WITH_KEY( std::stringstream stream;
const T&, typename disable_if<is_numeric<T>>::type* = 0) { stream << KEY_NOT_FOUND << ": " << key;
return KEY_NOT_FOUND; return stream.str();
}
template <typename T>
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T& key, typename enable_if<is_numeric<T> >::type * = 0) {
std::stringstream stream;
stream << KEY_NOT_FOUND << ": " << key;
return stream.str();
}
}
class Exception: public std::runtime_error {
public:
Exception(const Mark& mark_, const std::string& msg_)
: std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
virtual ~Exception() throw() {}
Mark mark;
std::string msg;
private:
static const std::string build_what(const Mark& mark, const std::string& msg) {
std::stringstream output;
output << "yaml-cpp: error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg;
return output.str();
}
};
class ParserException: public Exception {
public:
ParserException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {}
};
class RepresentationException: public Exception {
public:
RepresentationException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {}
};
// representation exceptions
class InvalidScalar: public RepresentationException {
public:
InvalidScalar(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
};
class KeyNotFound: public RepresentationException {
public:
template <typename T>
KeyNotFound(const Mark& mark_, const T& key_)
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {}
};
template <typename T>
class TypedKeyNotFound: public KeyNotFound {
public:
TypedKeyNotFound(const Mark& mark_, const T& key_)
: KeyNotFound(mark_, key_), key(key_) {}
virtual ~TypedKeyNotFound() throw() {}
T key;
};
template <typename T>
inline TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
return TypedKeyNotFound <T> (mark, key);
}
class BadConversion: public RepresentationException {
public:
BadConversion()
: RepresentationException(Mark::null(), ErrorMsg::BAD_CONVERSION) {}
};
template<typename T>
class TypedBadConversion: public BadConversion {
public:
TypedBadConversion()
: BadConversion() {}
};
class BadDereference: public RepresentationException {
public:
BadDereference()
: RepresentationException(Mark::null(), ErrorMsg::BAD_DEREFERENCE) {}
};
class BadSubscript: public RepresentationException {
public:
BadSubscript()
: RepresentationException(Mark::null(), ErrorMsg::BAD_SUBSCRIPT) {}
};
class BadPushback: public RepresentationException {
public:
BadPushback()
: RepresentationException(Mark::null(), ErrorMsg::BAD_PUSHBACK) {}
};
class EmitterException: public Exception {
public:
EmitterException(const std::string& msg_)
: Exception(Mark::null(), msg_) {}
};
} }
inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) { #endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
std::stringstream stream;
stream << KEY_NOT_FOUND << ": " << key;
return stream.str();
}
inline const std::string KEY_NOT_FOUND_WITH_KEY(const char* key) {
std::stringstream stream;
stream << KEY_NOT_FOUND << ": " << key;
return stream.str();
}
template <typename T>
inline const std::string KEY_NOT_FOUND_WITH_KEY(
const T& key, typename enable_if<is_numeric<T>>::type* = 0) {
std::stringstream stream;
stream << KEY_NOT_FOUND << ": " << key;
return stream.str();
}
template <typename T>
inline const std::string BAD_SUBSCRIPT_WITH_KEY(
const T&, typename disable_if<is_numeric<T>>::type* = nullptr) {
return BAD_SUBSCRIPT;
}
inline const std::string BAD_SUBSCRIPT_WITH_KEY(const std::string& key) {
std::stringstream stream;
stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
return stream.str();
}
inline const std::string BAD_SUBSCRIPT_WITH_KEY(const char* key) {
std::stringstream stream;
stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
return stream.str();
}
template <typename T>
inline const std::string BAD_SUBSCRIPT_WITH_KEY(
const T& key, typename enable_if<is_numeric<T>>::type* = nullptr) {
std::stringstream stream;
stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
return stream.str();
}
inline const std::string INVALID_NODE_WITH_KEY(const std::string& key) {
std::stringstream stream;
if (key.empty()) {
return INVALID_NODE;
}
stream << "invalid node; first invalid key: \"" << key << "\"";
return stream.str();
}
} // namespace ErrorMsg
class YAML_CPP_API Exception : public std::runtime_error {
public:
Exception(const Mark& mark_, const std::string& msg_)
: std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
~Exception() YAML_CPP_NOEXCEPT override;
Exception(const Exception&) = default;
Mark mark;
std::string msg;
private:
static const std::string build_what(const Mark& mark,
const std::string& msg) {
if (mark.is_null()) {
return msg;
}
std::stringstream output;
output << "yaml-cpp: error at line " << mark.line + 1 << ", column "
<< mark.column + 1 << ": " << msg;
return output.str();
}
};
class YAML_CPP_API ParserException : public Exception {
public:
ParserException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {}
ParserException(const ParserException&) = default;
~ParserException() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API RepresentationException : public Exception {
public:
RepresentationException(const Mark& mark_, const std::string& msg_)
: Exception(mark_, msg_) {}
RepresentationException(const RepresentationException&) = default;
~RepresentationException() YAML_CPP_NOEXCEPT override;
};
// representation exceptions
class YAML_CPP_API InvalidScalar : public RepresentationException {
public:
InvalidScalar(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
InvalidScalar(const InvalidScalar&) = default;
~InvalidScalar() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API KeyNotFound : public RepresentationException {
public:
template <typename T>
KeyNotFound(const Mark& mark_, const T& key_)
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {
}
KeyNotFound(const KeyNotFound&) = default;
~KeyNotFound() YAML_CPP_NOEXCEPT override;
};
template <typename T>
class YAML_CPP_API TypedKeyNotFound : public KeyNotFound {
public:
TypedKeyNotFound(const Mark& mark_, const T& key_)
: KeyNotFound(mark_, key_), key(key_) {}
~TypedKeyNotFound() YAML_CPP_NOEXCEPT override = default;
T key;
};
template <typename T>
inline TypedKeyNotFound<T> MakeTypedKeyNotFound(const Mark& mark,
const T& key) {
return TypedKeyNotFound<T>(mark, key);
}
class YAML_CPP_API InvalidNode : public RepresentationException {
public:
InvalidNode(const std::string& key)
: RepresentationException(Mark::null_mark(),
ErrorMsg::INVALID_NODE_WITH_KEY(key)) {}
InvalidNode(const InvalidNode&) = default;
~InvalidNode() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API BadConversion : public RepresentationException {
public:
explicit BadConversion(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {}
BadConversion(const BadConversion&) = default;
~BadConversion() YAML_CPP_NOEXCEPT override;
};
template <typename T>
class TypedBadConversion : public BadConversion {
public:
explicit TypedBadConversion(const Mark& mark_) : BadConversion(mark_) {}
};
class YAML_CPP_API BadDereference : public RepresentationException {
public:
BadDereference()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {}
BadDereference(const BadDereference&) = default;
~BadDereference() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API BadSubscript : public RepresentationException {
public:
template <typename Key>
BadSubscript(const Mark& mark_, const Key& key)
: RepresentationException(mark_, ErrorMsg::BAD_SUBSCRIPT_WITH_KEY(key)) {}
BadSubscript(const BadSubscript&) = default;
~BadSubscript() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API BadPushback : public RepresentationException {
public:
BadPushback()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {}
BadPushback(const BadPushback&) = default;
~BadPushback() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API BadInsert : public RepresentationException {
public:
BadInsert()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {}
BadInsert(const BadInsert&) = default;
~BadInsert() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API EmitterException : public Exception {
public:
EmitterException(const std::string& msg_)
: Exception(Mark::null_mark(), msg_) {}
EmitterException(const EmitterException&) = default;
~EmitterException() YAML_CPP_NOEXCEPT override;
};
class YAML_CPP_API BadFile : public Exception {
public:
explicit BadFile(const std::string& filename)
: Exception(Mark::null_mark(),
std::string(ErrorMsg::BAD_FILE) + ": " + filename) {}
BadFile(const BadFile&) = default;
~BadFile() YAML_CPP_NOEXCEPT override;
};
} // namespace YAML
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-15
View File
@@ -1,15 +0,0 @@
#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
+16 -19
View File
@@ -1,29 +1,26 @@
#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
namespace YAML { namespace YAML
struct YAML_CPP_API Mark { {
Mark() : pos(0), line(0), column(0) {} struct YAML_CPP_API Mark {
Mark(): pos(0), line(0), column(0) {}
static const Mark null_mark() { return Mark(-1, -1, -1); }
static const Mark null() { return Mark(-1, -1, -1); }
bool is_null() const { return pos == -1 && line == -1 && column == -1; }
int pos;
int pos; int line, column;
int line, column;
private:
private: Mark(int pos_, int line_, int column_): pos(pos_), line(line_), column(column_) {}
Mark(int pos_, int line_, int column_) };
: pos(pos_), line(line_), column(column_) {}
};
} }
#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+191 -454
View File
@@ -1,472 +1,209 @@
#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <array>
#include <cmath> #include "yaml-cpp/binary.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/null.h"
#include <limits> #include <limits>
#include <list> #include <list>
#include <map> #include <map>
#include <unordered_map>
#include <sstream> #include <sstream>
#include <type_traits>
#include <valarray>
#include <vector> #include <vector>
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) namespace YAML
#include <string_view> {
#endif namespace conversion {
inline bool IsInfinity(const std::string& input) {
#include "yaml-cpp/binary.h" return input == ".inf" || input == ".Inf" || input == ".INF" || input == "+.inf" || input == "+.Inf" || input == "+.INF";
#include "yaml-cpp/node/impl.h" }
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/node.h" inline bool IsNegativeInfinity(const std::string& input) {
#include "yaml-cpp/node/type.h" return input == "-.inf" || input == "-.Inf" || input == "-.INF";
#include "yaml-cpp/null.h" }
#include "yaml-cpp/fptostring.h"
inline bool IsNaN(const std::string& input) {
return input == ".nan" || input == ".NaN" || input == ".NAN";
namespace YAML { }
class Binary;
struct _Null;
template <typename T>
struct convert;
} // namespace YAML
namespace YAML {
namespace conversion {
inline bool IsInfinity(const std::string& input) {
return input == ".inf" || input == ".Inf" || input == ".INF" ||
input == "+.inf" || input == "+.Inf" || input == "+.INF";
}
inline bool IsNegativeInfinity(const std::string& input) {
return input == "-.inf" || input == "-.Inf" || input == "-.INF";
}
inline bool IsNaN(const std::string& input) {
return input == ".nan" || input == ".NaN" || input == ".NAN";
}
}
// Node
template <>
struct convert<Node> {
static Node encode(const Node& rhs) { return rhs; }
static bool decode(const Node& node, Node& rhs) {
rhs.reset(node);
return true;
}
};
// std::string
template <>
struct convert<std::string> {
static Node encode(const std::string& rhs) { return Node(rhs); }
static bool decode(const Node& node, std::string& rhs) {
if (!node.IsScalar())
return false;
rhs = node.Scalar();
return true;
}
};
// C-strings can only be encoded
template <>
struct convert<const char*> {
static Node encode(const char* rhs) { return Node(rhs); }
};
template <>
struct convert<char*> {
static Node encode(const char* rhs) { return Node(rhs); }
};
template <std::size_t N>
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(); }
static bool decode(const Node& node, _Null& /* rhs */) {
return node.IsNull();
}
};
namespace conversion {
template <typename T>
typename std::enable_if< std::is_floating_point<T>::value, void>::type
inner_encode(const T& rhs, std::stringstream& stream){
if (std::isnan(rhs)) {
stream << ".nan";
} else if (std::isinf(rhs)) {
if (std::signbit(rhs)) {
stream << "-.inf";
} else {
stream << ".inf";
} }
} else {
stream << FpToString(rhs, stream.precision()); // std::string
} template<>
} struct convert<std::string> {
static Node encode(const std::string& rhs) {
template <typename T> return Node(rhs);
typename std::enable_if<!std::is_floating_point<T>::value, void>::type }
inner_encode(const T& rhs, std::stringstream& stream){
stream << rhs; static bool decode(const Node& node, std::string& rhs) {
} if(!node.IsScalar())
return false;
template <typename T> rhs = node.Scalar();
typename std::enable_if<(std::is_same<T, unsigned char>::value || return true;
std::is_same<T, signed char>::value), bool>::type }
ConvertStreamTo(std::stringstream& stream, T& rhs) { };
int num;
if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) { template<>
if (num >= (std::numeric_limits<T>::min)() && struct convert<_Null> {
num <= (std::numeric_limits<T>::max)()) { static Node encode(const _Null& /* rhs */) {
rhs = static_cast<T>(num); return Node();
return true; }
}
} static bool decode(const Node& node, _Null& /* rhs */) {
return false; return node.IsNull();
} }
};
template <typename T>
typename std::enable_if<!(std::is_same<T, unsigned char>::value || #define YAML_DEFINE_CONVERT_STREAMABLE(type)\
std::is_same<T, signed char>::value), bool>::type template<>\
ConvertStreamTo(std::stringstream& stream, T& rhs) { struct convert<type> {\
if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) { static Node encode(const type& rhs) {\
return true; std::stringstream stream;\
} stream << rhs;\
return false; return Node(stream.str());\
} }\
} \
static bool decode(const Node& node, type& rhs) {\
#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \ if(node.Type() != NodeType::Scalar)\
template <> \ return false;\
struct convert<type> { \ const std::string& input = node.Scalar();\
\ std::stringstream stream(input);\
static Node encode(const type& rhs) { \ stream.unsetf(std::ios::dec);\
std::stringstream stream; \ if((stream >> rhs) && (stream >> std::ws).eof())\
stream.imbue(std::locale::classic()); \ return true;\
stream.precision(std::numeric_limits<type>::max_digits10); \ if(std::numeric_limits<type>::has_infinity) {\
conversion::inner_encode(rhs, stream); \ if(conversion::IsInfinity(input)) {\
return Node(stream.str()); \ rhs = std::numeric_limits<type>::infinity();\
} \ return true;\
\ } else if(conversion::IsNegativeInfinity(input)) {\
static bool decode(const Node& node, type& rhs) { \ rhs = -std::numeric_limits<type>::infinity();\
if (node.Type() != NodeType::Scalar) { \ return true;\
return false; \ }\
} \ }\
const std::string& input = node.Scalar(); \ \
std::stringstream stream(input); \ if(std::numeric_limits<type>::has_quiet_NaN && conversion::IsNaN(input)) {\
stream.imbue(std::locale::classic()); \ rhs = std::numeric_limits<type>::quiet_NaN();\
stream.unsetf(std::ios::dec); \ return true;\
if ((stream.peek() == '-') && std::is_unsigned<type>::value) { \ }\
return false; \ \
} \ return false;\
if (conversion::ConvertStreamTo(stream, rhs)) { \ }\
return true; \ }
} \
if (std::numeric_limits<type>::has_infinity) { \ YAML_DEFINE_CONVERT_STREAMABLE(int);
if (conversion::IsInfinity(input)) { \ YAML_DEFINE_CONVERT_STREAMABLE(unsigned);
rhs = std::numeric_limits<type>::infinity(); \ YAML_DEFINE_CONVERT_STREAMABLE(short);
return true; \ YAML_DEFINE_CONVERT_STREAMABLE(unsigned short);
} else if (conversion::IsNegativeInfinity(input)) { \ YAML_DEFINE_CONVERT_STREAMABLE(long);
rhs = negative_op std::numeric_limits<type>::infinity(); \ YAML_DEFINE_CONVERT_STREAMABLE(unsigned long);
return true; \ YAML_DEFINE_CONVERT_STREAMABLE(long long);
} \ YAML_DEFINE_CONVERT_STREAMABLE(unsigned long long);
} \
\ YAML_DEFINE_CONVERT_STREAMABLE(char);
if (std::numeric_limits<type>::has_quiet_NaN) { \ YAML_DEFINE_CONVERT_STREAMABLE(unsigned char);
if (conversion::IsNaN(input)) { \
rhs = std::numeric_limits<type>::quiet_NaN(); \ YAML_DEFINE_CONVERT_STREAMABLE(float);
return true; \ YAML_DEFINE_CONVERT_STREAMABLE(double);
} \ YAML_DEFINE_CONVERT_STREAMABLE(long double);
} \
\
return false; \
} \
}
#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \
YAML_DEFINE_CONVERT_STREAMABLE(type, -)
#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \
YAML_DEFINE_CONVERT_STREAMABLE(type, +)
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(signed char);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double);
#undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED
#undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED
#undef YAML_DEFINE_CONVERT_STREAMABLE #undef YAML_DEFINE_CONVERT_STREAMABLE
// bool
template<>
struct convert<bool> {
static Node encode(bool rhs) {
return rhs ? Node("true") : Node("false");
}
static bool decode(const Node& node, bool& rhs);
};
// bool // std::map
template <> template<typename K, typename V>
struct convert<bool> { struct convert<std::map<K, V> > {
static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); } static Node encode(const std::map<K, V>& rhs) {
Node node(NodeType::Map);
for(typename std::map<K, V>::const_iterator it=rhs.begin();it!=rhs.end();++it)
node[it->first] = it->second;
return node;
}
static bool decode(const Node& node, std::map<K, V>& rhs) {
if(!node.IsMap())
return false;
YAML_CPP_API static bool decode(const Node& node, bool& rhs); rhs.clear();
}; for(const_iterator it=node.begin();it!=node.end();++it)
rhs[it->first.as<K>()] = it->second.as<V>();
// std::map return true;
template <typename K, typename V, typename C, typename A> }
struct convert<std::map<K, V, C, A>> { };
static Node encode(const std::map<K, V, C, A>& rhs) {
Node node(NodeType::Map); // std::vector
for (const auto& element : rhs) template<typename T>
node.force_insert(element.first, element.second); struct convert<std::vector<T> > {
return node; static Node encode(const std::vector<T>& rhs) {
} Node node(NodeType::Sequence);
for(typename std::vector<T>::const_iterator it=rhs.begin();it!=rhs.end();++it)
static bool decode(const Node& node, std::map<K, V, C, A>& rhs) { node.push_back(*it);
if (!node.IsMap()) return node;
return false; }
rhs.clear(); static bool decode(const Node& node, std::vector<T>& rhs) {
for (const auto& element : node) if(!node.IsSequence())
#if defined(__GNUC__) && __GNUC__ < 4 return false;
// workaround for GCC 3:
rhs[element.first.template as<K>()] = element.second.template as<V>(); rhs.clear();
#else for(const_iterator it=node.begin();it!=node.end();++it)
rhs[element.first.as<K>()] = element.second.as<V>(); rhs.push_back(it->as<T>());
#endif return true;
return true; }
} };
};
// std::list
// std::unordered_map template<typename T>
template <typename K, typename V, typename H, typename P, typename A> struct convert<std::list<T> > {
struct convert<std::unordered_map<K, V, H, P, A>> { static Node encode(const std::list<T>& rhs) {
static Node encode(const std::unordered_map<K, V, H, P, A>& rhs) { Node node(NodeType::Sequence);
Node node(NodeType::Map); for(typename std::list<T>::const_iterator it=rhs.begin();it!=rhs.end();++it)
for (const auto& element : rhs) node.push_back(*it);
node.force_insert(element.first, element.second); return node;
return node; }
}
static bool decode(const Node& node, std::list<T>& rhs) {
static bool decode(const Node& node, std::unordered_map<K, V, H, P, A>& rhs) { if(!node.IsSequence())
if (!node.IsMap()) return false;
return false;
rhs.clear();
rhs.clear(); for(const_iterator it=node.begin();it!=node.end();++it)
for (const auto& element : node) rhs.push_back(it->as<T>());
#if defined(__GNUC__) && __GNUC__ < 4 return true;
// 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>(); // binary
#endif template<>
return true; struct convert<Binary> {
} static Node encode(const Binary& rhs) {
}; return Node(EncodeBase64(rhs.data(), rhs.size()));
}
// std::vector
template <typename T, typename A> static bool decode(const Node& node, Binary& rhs) {
struct convert<std::vector<T, A>> { if(!node.IsScalar())
static Node encode(const std::vector<T, A>& rhs) { return false;
Node node(NodeType::Sequence);
for (const auto& element : rhs) std::vector<unsigned char> data = DecodeBase64(node.Scalar());
node.push_back(element); if(data.empty() && !node.Scalar().empty())
return node; return false;
}
rhs.swap(data);
static bool decode(const Node& node, std::vector<T, A>& rhs) { return true;
if (!node.IsSequence()) }
return false; };
rhs.clear();
for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs.push_back(element.template as<T>());
#else
rhs.push_back(element.as<T>());
#endif
return true;
}
};
// std::list
template <typename T, typename A>
struct convert<std::list<T,A>> {
static Node encode(const std::list<T,A>& rhs) {
Node node(NodeType::Sequence);
for (const auto& element : rhs)
node.push_back(element);
return node;
}
static bool decode(const Node& node, std::list<T,A>& rhs) {
if (!node.IsSequence())
return false;
rhs.clear();
for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs.push_back(element.template as<T>());
#else
rhs.push_back(element.as<T>());
#endif
return true;
}
};
// std::array
template <typename T, std::size_t N>
struct convert<std::array<T, N>> {
static Node encode(const std::array<T, N>& rhs) {
Node node(NodeType::Sequence);
for (const auto& element : rhs) {
node.push_back(element);
}
return node;
}
static bool decode(const Node& node, std::array<T, N>& rhs) {
if (!isNodeValid(node)) {
return false;
}
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;
}
private:
static bool isNodeValid(const Node& node) {
return node.IsSequence() && node.size() == 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>> {
static Node encode(const std::pair<T, U>& rhs) {
Node node(NodeType::Sequence);
node.push_back(rhs.first);
node.push_back(rhs.second);
return node;
}
static bool decode(const Node& node, std::pair<T, U>& rhs) {
if (!node.IsSequence())
return false;
if (node.size() != 2)
return false;
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs.first = node[0].template as<T>();
#else
rhs.first = node[0].as<T>();
#endif
#if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3:
rhs.second = node[1].template as<U>();
#else
rhs.second = node[1].as<U>();
#endif
return true;
}
};
// binary
template <>
struct convert<Binary> {
static Node encode(const Binary& rhs) {
return Node(EncodeBase64(rhs.data(), rhs.size()));
}
static bool decode(const Node& node, Binary& rhs) {
if (!node.IsScalar())
return false;
std::vector<unsigned char> data = DecodeBase64(node.Scalar());
if (data.empty() && !node.Scalar().empty())
return false;
rhs.swap(data);
return true;
}
};
} }
#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+26
View File
@@ -0,0 +1,26 @@
#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_BOOL_TYPE_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
#endif
namespace YAML
{
namespace detail
{
struct unspecified_bool {
struct NOT_ALLOWED;
static void true_value(NOT_ALLOWED*) {}
};
typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*);
}
}
#define YAML_CPP_OPERATOR_BOOL()\
operator YAML::detail::unspecified_bool_type() const\
{\
return this->operator!() ? 0 : &YAML::detail::unspecified_bool::true_value;\
}
#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+126 -222
View File
@@ -1,238 +1,142 @@
#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/node/detail/node.h" #include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/detail/node_data.h" #include "yaml-cpp/node/detail/node_data.h"
#include <boost/type_traits.hpp>
#include <algorithm> namespace YAML
#include <type_traits> {
namespace detail
{
template<typename Key, typename Enable = void>
struct get_idx {
static node *get(const std::vector<node *>& /* sequence */, const Key& /* key */, shared_memory_holder /* pMemory */) {
return 0;
}
};
namespace YAML { template<typename Key>
[[noreturn]] extern void throw_bad_subscript(const YAML::Mark& mark); struct get_idx<Key, typename boost::enable_if<boost::is_unsigned<Key> >::type> {
[[noreturn]] extern void throw_bad_insert(); static node *get(const std::vector<node *>& sequence, const Key& key, shared_memory_holder /* pMemory */) {
return key < sequence.size() ? sequence[key] : 0;
}
namespace detail { static node *get(std::vector<node *>& sequence, const Key& key, shared_memory_holder pMemory) {
template <typename Key, typename Enable = void> if(key > sequence.size())
struct get_idx { return 0;
static node* get(const std::vector<node*>& /* sequence */, if(key == sequence.size())
const Key& /* key */, shared_memory_holder /* pMemory */) { sequence.push_back(&pMemory->create_node());
return nullptr; return sequence[key];
} }
}; };
template<typename Key>
struct get_idx<Key, typename boost::enable_if<boost::is_signed<Key> >::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(sequence, static_cast<std::size_t>(key), pMemory) : 0;
}
static node *get(std::vector<node *>& sequence, const Key& key, shared_memory_holder pMemory) {
return key >= 0 ? get_idx<std::size_t>::get(sequence, static_cast<std::size_t>(key), pMemory) : 0;
}
};
template <typename Key> // indexing
struct get_idx<Key, template<typename Key>
typename std::enable_if<std::is_unsigned<Key>::value && inline node& node_data::get(const Key& key, shared_memory_holder pMemory) const
!std::is_same<Key, bool>::value>::type> { {
static node* get(const std::vector<node*>& sequence, const Key& key, switch(m_type) {
shared_memory_holder /* pMemory */) { case NodeType::Map:
return key < sequence.size() ? sequence[key] : nullptr; break;
} case NodeType::Undefined:
case NodeType::Null:
return pMemory->create_node();
case NodeType::Sequence:
if(node *pNode = get_idx<Key>::get(m_sequence, key, pMemory))
return *pNode;
return pMemory->create_node();
case NodeType::Scalar:
throw BadSubscript();
}
static node* get(std::vector<node*>& sequence, const Key& key, for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
shared_memory_holder pMemory) { if(equals(*it->first, key, pMemory))
if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined())) return *it->second;
return nullptr; }
if (key == sequence.size())
sequence.push_back(&pMemory->create_node()); return pMemory->create_node();
return sequence[key]; }
}
}; template<typename Key>
inline node& node_data::get(const Key& key, shared_memory_holder pMemory)
{
switch(m_type) {
case NodeType::Map:
break;
case NodeType::Undefined:
case NodeType::Null:
case NodeType::Sequence:
if(node *pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
m_type = NodeType::Sequence;
return *pNode;
}
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadSubscript();
}
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
if(equals(*it->first, key, pMemory))
return *it->second;
}
node& k = convert_to_node(key, pMemory);
node& v = pMemory->create_node();
insert_map_pair(k, v);
return v;
}
template<typename Key>
inline bool node_data::remove(const Key& key, shared_memory_holder pMemory)
{
if(m_type != NodeType::Map)
return false;
for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
if(equals(*it->first, key, pMemory)) {
m_map.erase(it);
return true;
}
}
return false;
}
template <typename Key> template<typename T>
struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> { inline bool node_data::equals(node& node, const T& rhs, shared_memory_holder pMemory)
static node* get(const std::vector<node*>& sequence, const Key& key, {
shared_memory_holder pMemory) { T lhs;
return key >= 0 ? get_idx<std::size_t>::get( if(convert<T>::decode(Node(node, pMemory), lhs))
sequence, static_cast<std::size_t>(key), pMemory) return lhs == rhs;
: nullptr; return false;
} }
static node* get(std::vector<node*>& sequence, const Key& key,
shared_memory_holder pMemory) { template<typename T>
return key >= 0 ? get_idx<std::size_t>::get( inline node& node_data::convert_to_node(const T& rhs, shared_memory_holder pMemory)
sequence, static_cast<std::size_t>(key), pMemory) {
: nullptr; Node value = convert<T>::encode(rhs);
} value.EnsureNodeExists();
}; pMemory->merge(*value.m_pMemory);
return *value.m_pNode;
template <typename Key, typename Enable = void> }
struct remove_idx { }
static bool remove(std::vector<node*>&, const Key&, std::size_t&) {
return false;
}
};
template <typename Key>
struct remove_idx<
Key, typename std::enable_if<std::is_unsigned<Key>::value &&
!std::is_same<Key, bool>::value>::type> {
static bool remove(std::vector<node*>& sequence, const Key& key,
std::size_t& seqSize) {
if (key >= sequence.size()) {
return false;
} else {
sequence.erase(sequence.begin() + key);
if (seqSize > key) {
--seqSize;
}
return true;
}
}
};
template <typename Key>
struct remove_idx<Key,
typename std::enable_if<std::is_signed<Key>::value>::type> {
static bool remove(std::vector<node*>& sequence, const Key& key,
std::size_t& seqSize) {
return key >= 0 ? remove_idx<std::size_t>::remove(
sequence, static_cast<std::size_t>(key), seqSize)
: false;
}
};
template <typename T>
inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
T lhs;
if (convert<T>::decode(Node(*this, pMemory), lhs)) {
return lhs == rhs;
}
return false;
} }
inline bool node::equals(const char* rhs, shared_memory_holder pMemory) { #endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
std::string lhs;
if (convert<std::string>::decode(Node(*this, std::move(pMemory)), lhs)) {
return lhs == rhs;
}
return false;
}
// indexing
template <typename Key>
inline node* node_data::get(const Key& key,
shared_memory_holder pMemory) const {
switch (m_type) {
case NodeType::Map:
break;
case NodeType::Undefined:
case NodeType::Null:
return nullptr;
case NodeType::Sequence:
if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
return pNode;
return nullptr;
case NodeType::Scalar:
throw_bad_subscript(m_mark);
}
auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
return m.first->equals(key, pMemory);
});
return it != m_map.end() ? it->second : nullptr;
}
template <typename Key>
inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
switch (m_type) {
case NodeType::Map:
break;
case NodeType::Undefined:
case NodeType::Null:
case NodeType::Sequence:
if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
m_type = NodeType::Sequence;
return *pNode;
}
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw_bad_subscript(m_mark);
}
auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
return m.first->equals(key, pMemory);
});
if (it != m_map.end()) {
return *it->second;
}
node& k = convert_to_node(key, pMemory);
node& v = pMemory->create_node();
insert_map_pair(k, v);
return v;
}
template <typename Key>
inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
if (m_type == NodeType::Sequence) {
return remove_idx<Key>::remove(m_sequence, key, m_seqSize);
}
if (m_type == NodeType::Map) {
kv_pairs::iterator it = m_undefinedPairs.begin();
while (it != m_undefinedPairs.end()) {
kv_pairs::iterator jt = std::next(it);
if (it->first->equals(key, pMemory)) {
m_undefinedPairs.erase(it);
}
it = jt;
}
auto iter = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
return m.first->equals(key, pMemory);
});
if (iter != m_map.end()) {
m_map.erase(iter);
return true;
}
}
return false;
}
// map
template <typename Key, typename Value>
inline void node_data::force_insert(const Key& key, const Value& value,
shared_memory_holder pMemory) {
switch (m_type) {
case NodeType::Map:
break;
case NodeType::Undefined:
case NodeType::Null:
case NodeType::Sequence:
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw_bad_insert();
}
node& k = convert_to_node(key, pMemory);
node& v = convert_to_node(value, pMemory);
insert_map_pair(k, v);
}
template <typename T>
inline node& node_data::convert_to_node(const T& rhs,
shared_memory_holder pMemory) {
Node value = convert<T>::encode(rhs);
value.EnsureNodeExists();
pMemory->merge(*value.m_pMemory);
return *value.m_pNode;
}
}
}
#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+52 -84
View File
@@ -1,96 +1,64 @@
#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/detail/node_iterator.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include <cstddef> #include "yaml-cpp/node/detail/node_iterator.h"
#include <iterator> #include <boost/iterator/iterator_adaptor.hpp>
#include <boost/utility.hpp>
namespace YAML
{
namespace detail
{
struct iterator_value;
namespace YAML { template<typename V>
namespace detail { class iterator_base: public boost::iterator_adaptor<
struct iterator_value; iterator_base<V>,
node_iterator,
V,
std::forward_iterator_tag,
V>
{
private:
template<typename> friend class iterator_base;
struct enabler {};
typedef typename iterator_base::base_type base_type;
public:
typedef typename iterator_base::value_type value_type;
public:
iterator_base() {}
explicit iterator_base(base_type rhs, shared_memory_holder pMemory): iterator_base::iterator_adaptor_(rhs), m_pMemory(pMemory) {}
template<class W>
iterator_base(const iterator_base<W>& rhs, typename boost::enable_if<boost::is_convertible<W*, V*>, enabler>::type = enabler()): iterator_base::iterator_adaptor_(rhs.base()), m_pMemory(rhs.m_pMemory) {}
private:
friend class boost::iterator_core_access;
template <typename V> void increment() { this->base_reference() = boost::next(this->base()); }
class iterator_base {
value_type dereference() const {
const typename base_type::value_type& v = *this->base();
if(v.pNode)
return value_type(Node(*v, m_pMemory));
if(v.first && v.second)
return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory));
return value_type();
}
private:
shared_memory_holder m_pMemory;
};
}
}
private: #endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
template <typename>
friend class iterator_base;
struct enabler {};
using base_type = node_iterator;
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 m_ref;
};
public:
using iterator_category = std::forward_iterator_tag;
using value_type = V;
using difference_type = std::ptrdiff_t;
using pointer = V*;
using reference = V&;
public:
iterator_base() : m_iterator(), m_pMemory() {}
explicit iterator_base(base_type rhs, shared_memory_holder pMemory)
: m_iterator(rhs), m_pMemory(pMemory) {}
template <class W>
iterator_base(const iterator_base<W>& rhs,
typename std::enable_if<std::is_convertible<W*, V*>::value,
enabler>::type = enabler())
: m_iterator(rhs.m_iterator), m_pMemory(rhs.m_pMemory) {}
iterator_base<V>& operator++() {
++m_iterator;
return *this;
}
iterator_base<V> operator++(int) {
iterator_base<V> iterator_pre(*this);
++(*this);
return iterator_pre;
}
template <typename W>
bool operator==(const iterator_base<W>& rhs) const {
return m_iterator == rhs.m_iterator;
}
template <typename W>
bool operator!=(const iterator_base<W>& rhs) const {
return m_iterator != rhs.m_iterator;
}
value_type operator*() const {
const typename base_type::value_type& v = *m_iterator;
if (v.pNode)
return value_type(Node(*v, m_pMemory));
if (v.first && v.second)
return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory));
return value_type();
}
proxy operator->() const { return proxy(**this); }
private:
base_type m_iterator;
shared_memory_holder m_pMemory;
};
} // namespace detail
} // namespace YAML
#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+13 -13
View File
@@ -1,27 +1,27 @@
#ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include <list> #include <list>
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML { namespace YAML
{
class node;
namespace detail {
struct iterator_value;
template<typename V> class iterator_base;
}
namespace detail { typedef detail::iterator_base<detail::iterator_value> iterator;
struct iterator_value; typedef detail::iterator_base<const detail::iterator_value> const_iterator;
template <typename V>
class iterator_base;
} }
using iterator = detail::iterator_base<detail::iterator_value>; #endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
using const_iterator = detail::iterator_base<const detail::iterator_value>;
}
#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+29 -38
View File
@@ -1,48 +1,39 @@
#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <set>
#include "yaml-cpp/dll.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include <set>
#include <boost/shared_ptr.hpp>
namespace YAML { namespace YAML
namespace detail { {
class node; namespace detail
} // namespace detail {
} // namespace YAML class memory {
public:
node& create_node();
void merge(const memory& rhs);
private:
typedef std::set<shared_node> Nodes;
Nodes m_nodes;
};
namespace YAML { class memory_holder {
namespace detail { public:
class YAML_CPP_API memory { memory_holder(): m_pMemory(new memory) {}
public:
memory() : m_nodes{} {} node& create_node() { return m_pMemory->create_node(); }
node& create_node(); void merge(memory_holder& rhs);
void merge(const memory& rhs);
size_t size() const; private:
boost::shared_ptr<memory> m_pMemory;
};
}
}
private: #endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
using Nodes = std::set<shared_node>;
Nodes m_nodes;
};
class YAML_CPP_API memory_holder {
public:
memory_holder() : m_pMemory(new memory) {}
node& create_node() { return m_pMemory->create_node(); }
void merge(memory_holder& rhs);
private:
shared_memory m_pMemory;
};
} // namespace detail
} // namespace YAML
#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+110 -161
View File
@@ -1,177 +1,126 @@
#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/node/detail/node_ref.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_ref.h"
#include <set> #include <set>
#include <atomic> #include <boost/utility.hpp>
namespace YAML { namespace YAML
namespace detail { {
class node { namespace detail
private: {
struct less { class node: private boost::noncopyable
bool operator ()(const node* l, const node* r) const {return l->m_index < r->m_index;} {
}; public:
node(): m_pRef(new node_ref) {}
public: bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
node() : m_pRef(new node_ref), m_dependencies{}, m_index{} {} const node_ref *ref() const { return m_pRef.get(); }
node(const node&) = delete;
node& operator=(const node&) = delete; bool is_defined() const { return m_pRef->is_defined(); }
NodeType::value type() const { return m_pRef->type(); }
const std::string& scalar() const { return m_pRef->scalar(); }
const std::string& tag() const { return m_pRef->tag(); }
void mark_defined() {
if(is_defined())
return;
m_pRef->mark_defined();
for(nodes::iterator it=m_dependencies.begin();it!=m_dependencies.end();++it)
(*it)->mark_defined();
m_dependencies.clear();
}
void add_dependency(node& rhs) {
if(is_defined())
rhs.mark_defined();
else
m_dependencies.insert(&rhs);
}
void set_ref(const node& rhs) {
if(rhs.is_defined())
mark_defined();
m_pRef = rhs.m_pRef;
}
void set_data(const node& rhs) {
if(rhs.is_defined())
mark_defined();
m_pRef->set_data(*rhs.m_pRef);
}
void set_type(NodeType::value type) {
if(type != NodeType::Undefined)
mark_defined();
m_pRef->set_type(type);
}
void set_null() {
mark_defined();
m_pRef->set_null();
}
void set_scalar(const std::string& scalar) {
mark_defined();
m_pRef->set_scalar(scalar);
}
void set_tag(const std::string& tag) {
mark_defined();
m_pRef->set_tag(tag);
}
bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; } // size/iterator
const node_ref* ref() const { return m_pRef.get(); } std::size_t size() const { return m_pRef->size(); }
const_node_iterator begin() const { return static_cast<const node_ref&>(*m_pRef).begin(); }
node_iterator begin() { return m_pRef->begin(); }
const_node_iterator end() const { return static_cast<const node_ref&>(*m_pRef).end(); }
node_iterator end() { return m_pRef->end(); }
bool is_defined() const { return m_pRef->is_defined(); } // sequence
const Mark& mark() const { return m_pRef->mark(); } void push_back(node& node, shared_memory_holder pMemory) {
NodeType::value type() const { return m_pRef->type(); } m_pRef->push_back(node, pMemory);
node.add_dependency(*this);
}
void insert(node& key, node& value, shared_memory_holder pMemory) {
m_pRef->insert(key, value, pMemory);
key.add_dependency(*this);
value.add_dependency(*this);
}
const std::string& scalar() const { return m_pRef->scalar(); } // indexing
const std::string& tag() const { return m_pRef->tag(); } template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); }
EmitterStyle::value style() const { return m_pRef->style(); } template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) {
node& value = m_pRef->get(key, pMemory);
value.add_dependency(*this);
return value;
}
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); }
node& get(node& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); }
node& get(node& key, shared_memory_holder pMemory) {
node& value = m_pRef->get(key, pMemory);
key.add_dependency(*this);
value.add_dependency(*this);
return value;
}
bool remove(node& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); }
template <typename T> private:
bool equals(const T& rhs, shared_memory_holder pMemory); shared_node_ref m_pRef;
bool equals(const char* rhs, shared_memory_holder pMemory); typedef std::set<node *> nodes;
nodes m_dependencies;
};
}
}
void mark_defined() { #endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
if (is_defined())
return;
m_pRef->mark_defined();
for (node* dependency : m_dependencies)
dependency->mark_defined();
m_dependencies.clear();
}
void add_dependency(node& rhs) {
if (is_defined())
rhs.mark_defined();
else
m_dependencies.insert(&rhs);
}
void set_ref(const node& rhs) {
if (rhs.is_defined())
mark_defined();
m_pRef = rhs.m_pRef;
}
void set_data(const node& rhs) {
if (rhs.is_defined())
mark_defined();
m_pRef->set_data(*rhs.m_pRef);
}
void set_mark(const Mark& mark) { m_pRef->set_mark(mark); }
void set_type(NodeType::value type) {
if (type != NodeType::Undefined)
mark_defined();
m_pRef->set_type(type);
}
void set_null() {
mark_defined();
m_pRef->set_null();
}
void set_scalar(const std::string& scalar) {
mark_defined();
m_pRef->set_scalar(scalar);
}
void set_tag(const std::string& tag) {
mark_defined();
m_pRef->set_tag(tag);
}
// style
void set_style(EmitterStyle::value style) {
mark_defined();
m_pRef->set_style(style);
}
// size/iterator
std::size_t size() const { return m_pRef->size(); }
const_node_iterator begin() const {
return static_cast<const node_ref&>(*m_pRef).begin();
}
node_iterator begin() { return m_pRef->begin(); }
const_node_iterator end() const {
return static_cast<const node_ref&>(*m_pRef).end();
}
node_iterator end() { return m_pRef->end(); }
// sequence
void push_back(node& input, shared_memory_holder pMemory) {
m_pRef->push_back(input, pMemory);
input.add_dependency(*this);
m_index = m_amount.fetch_add(1);
}
void insert(node& key, node& value, shared_memory_holder pMemory) {
m_pRef->insert(key, value, pMemory);
key.add_dependency(*this);
value.add_dependency(*this);
}
// indexing
template <typename Key>
node* get(const Key& key, shared_memory_holder pMemory) const {
// NOTE: this returns a non-const node so that the top-level Node can wrap
// it, and returns a pointer so that it can be nullptr (if there is no such
// key).
return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
}
template <typename Key>
node& get(const Key& key, shared_memory_holder pMemory) {
node& value = m_pRef->get(key, pMemory);
value.add_dependency(*this);
return value;
}
template <typename Key>
bool remove(const Key& key, shared_memory_holder pMemory) {
return m_pRef->remove(key, pMemory);
}
node* get(node& key, shared_memory_holder pMemory) const {
// NOTE: this returns a non-const node so that the top-level Node can wrap
// it, and returns a pointer so that it can be nullptr (if there is no such
// key).
return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
}
node& get(node& key, shared_memory_holder pMemory) {
node& value = m_pRef->get(key, pMemory);
key.add_dependency(*this);
value.add_dependency(*this);
return value;
}
bool remove(node& key, shared_memory_holder pMemory) {
return m_pRef->remove(key, pMemory);
}
// map
template <typename Key, typename Value>
void force_insert(const Key& key, const Value& value,
shared_memory_holder pMemory) {
m_pRef->force_insert(key, value, pMemory);
}
private:
shared_node_ref m_pRef;
using nodes = std::set<node*, less>;
nodes m_dependencies;
size_t m_index;
static YAML_CPP_API std::atomic<size_t> m_amount;
};
} // namespace detail
} // namespace YAML
#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+87 -109
View File
@@ -1,127 +1,105 @@
#ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <list>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/detail/node_iterator.h"
#include "yaml-cpp/node/iterator.h" #include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
#include <boost/utility.hpp>
#include <list>
#include <utility>
#include <vector>
namespace YAML { namespace YAML
namespace detail { {
class node; namespace detail
} // namespace detail {
} // namespace YAML class node_data: private boost::noncopyable
{
public:
node_data();
void mark_defined();
void set_type(NodeType::value type);
void set_tag(const std::string& tag);
void set_null();
void set_scalar(const std::string& scalar);
bool is_defined() const { return m_isDefined; }
NodeType::value type() const { return m_isDefined ? m_type : NodeType::Undefined; }
const std::string& scalar() const { return m_scalar; }
const std::string& tag() const { return m_tag; }
// size/iterator
std::size_t size() const;
const_node_iterator begin() const;
node_iterator begin();
const_node_iterator end() const;
node_iterator end();
namespace YAML { // sequence
namespace detail { void push_back(node& node, shared_memory_holder pMemory);
class YAML_CPP_API node_data { void insert(node& key, node& value, shared_memory_holder pMemory);
public:
node_data();
node_data(const node_data&) = delete;
node_data& operator=(const node_data&) = delete;
void mark_defined(); // indexing
void set_mark(const Mark& mark); template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const;
void set_type(NodeType::value type); template<typename Key> node& get(const Key& key, shared_memory_holder pMemory);
void set_tag(const std::string& tag); template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory);
void set_null();
void set_scalar(const std::string& scalar); node& get(node& key, shared_memory_holder pMemory) const;
void set_style(EmitterStyle::value style); node& get(node& key, shared_memory_holder pMemory);
bool remove(node& key, shared_memory_holder pMemory);
public:
static std::string empty_scalar;
private:
void compute_seq_size() const;
void compute_map_size() const;
bool is_defined() const { return m_isDefined; } void reset_sequence();
const Mark& mark() const { return m_mark; } void reset_map();
NodeType::value type() const {
return m_isDefined ? m_type : NodeType::Undefined; void insert_map_pair(node& key, node& value);
} void convert_to_map(shared_memory_holder pMemory);
const std::string& scalar() const { return m_scalar; } void convert_sequence_to_map(shared_memory_holder pMemory);
const std::string& tag() const { return m_tag; }
EmitterStyle::value style() const { return m_style; } template<typename T>
static bool equals(node& node, const T& rhs, shared_memory_holder pMemory);
template<typename T>
static node& convert_to_node(const T& rhs, shared_memory_holder pMemory);
// size/iterator private:
std::size_t size() const; bool m_isDefined;
NodeType::value m_type;
const_node_iterator begin() const; std::string m_tag;
node_iterator begin();
// scalar
const_node_iterator end() const; std::string m_scalar;
node_iterator end();
// sequence
// sequence typedef std::vector<node *> node_seq;
void push_back(node& node, const shared_memory_holder& pMemory); node_seq m_sequence;
void insert(node& key, node& value, const shared_memory_holder& pMemory);
mutable std::size_t m_seqSize;
// indexing
template <typename Key> // map
node* get(const Key& key, shared_memory_holder pMemory) const; typedef std::map<node *, node *> node_map;
template <typename Key> node_map m_map;
node& get(const Key& key, shared_memory_holder pMemory);
template <typename Key> typedef std::pair<node *, node *> kv_pair;
bool remove(const Key& key, shared_memory_holder pMemory); typedef std::list<kv_pair> kv_pairs;
mutable kv_pairs m_undefinedPairs;
node* get(node& key, const shared_memory_holder& pMemory) const; };
node& get(node& key, const shared_memory_holder& pMemory); }
bool remove(node& key, const shared_memory_holder& pMemory);
// map
template <typename Key, typename Value>
void force_insert(const Key& key, const Value& value,
shared_memory_holder pMemory);
public:
static const std::string& empty_scalar();
private:
void compute_seq_size() const;
void compute_map_size() const;
void reset_sequence();
void reset_map();
void insert_map_pair(node& key, node& value);
void convert_to_map(const shared_memory_holder& pMemory);
void convert_sequence_to_map(const shared_memory_holder& pMemory);
template <typename T>
static node& convert_to_node(const T& rhs, shared_memory_holder pMemory);
private:
bool m_isDefined;
Mark m_mark;
NodeType::value m_type;
std::string m_tag;
EmitterStyle::value m_style;
// scalar
std::string m_scalar;
// sequence
using node_seq = std::vector<node *>;
node_seq m_sequence;
mutable std::size_t m_seqSize;
// map
using node_map = std::vector<std::pair<node*, node*>>;
node_map m_map;
using kv_pair = std::pair<node*, node*>;
using kv_pairs = std::list<kv_pair>;
mutable kv_pairs m_undefinedPairs;
};
}
} }
#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+120 -162
View File
@@ -1,181 +1,139 @@
#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include <cstddef> #include <boost/iterator/iterator_facade.hpp>
#include <iterator> #include <boost/utility/enable_if.hpp>
#include <memory>
#include <map> #include <map>
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML { namespace YAML
namespace detail { {
struct iterator_type { namespace detail
enum value { NoneType, Sequence, Map }; {
}; struct iterator_type { enum value { None, Sequence, Map }; };
template<typename V>
struct node_iterator_value: public std::pair<V*, V*> {
typedef std::pair<V*, V*> kv;
node_iterator_value(): kv(), pNode(0) {}
explicit node_iterator_value(V& rhs): kv(), pNode(&rhs) {}
explicit node_iterator_value(V& key, V& value): kv(&key, &value), pNode(0) {}
V& operator *() const { return *pNode; }
V& operator ->() const { return *pNode; }
V *pNode;
};
typedef std::vector<node *> node_seq;
typedef std::map<node *, node *> node_map;
template<typename V>
struct node_iterator_type {
typedef node_seq::iterator seq;
typedef node_map::iterator map;
};
template<typename V>
struct node_iterator_type<const V> {
typedef node_seq::const_iterator seq;
typedef node_map::const_iterator map;
};
template <typename V> template<typename V>
struct node_iterator_value : public std::pair<V*, V*> { class node_iterator_base: public boost::iterator_facade<
using kv = std::pair<V*, V*>; node_iterator_base<V>,
node_iterator_value<V>,
std::forward_iterator_tag,
node_iterator_value<V> >
{
private:
struct enabler {};
public:
typedef typename node_iterator_type<V>::seq SeqIter;
typedef typename node_iterator_type<V>::map MapIter;
typedef node_iterator_value<V> value_type;
node_iterator_base(): m_type(iterator_type::None) {}
explicit node_iterator_base(SeqIter seqIt): m_type(iterator_type::Sequence), m_seqIt(seqIt) {}
explicit node_iterator_base(MapIter mapIt, MapIter mapEnd): m_type(iterator_type::Map), m_mapIt(mapIt), m_mapEnd(mapEnd) {
m_mapIt = increment_until_defined(m_mapIt);
}
template<typename W>
node_iterator_base(const node_iterator_base<W>& rhs, typename boost::enable_if<boost::is_convertible<W*, V*>, enabler>::type = enabler())
: m_type(rhs.m_type), m_seqIt(rhs.m_seqIt), m_mapIt(rhs.m_mapIt), m_mapEnd(rhs.m_mapEnd) {}
private:
friend class boost::iterator_core_access;
template<typename> friend class node_iterator_base;
template<typename W>
bool equal(const node_iterator_base<W>& rhs) const {
if(m_type != rhs.m_type)
return false;
switch(m_type) {
case iterator_type::None: return true;
case iterator_type::Sequence: return m_seqIt == rhs.m_seqIt;
case iterator_type::Map: return m_mapIt == rhs.m_mapIt;
}
return true;
}
void increment() {
switch(m_type) {
case iterator_type::None: break;
case iterator_type::Sequence:
++m_seqIt;
break;
case iterator_type::Map:
++m_mapIt;
m_mapIt = increment_until_defined(m_mapIt);
break;
}
}
node_iterator_value() : kv(), pNode(nullptr) {} value_type dereference() const {
explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {} switch(m_type) {
explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {} case iterator_type::None: return value_type();
case iterator_type::Sequence: return value_type(**m_seqIt);
case iterator_type::Map: return value_type(*m_mapIt->first, *m_mapIt->second);
}
return value_type();
}
MapIter increment_until_defined(MapIter it) {
while(it != m_mapEnd && !is_defined(it))
++it;
return it;
}
bool is_defined(MapIter it) const {
return it->first->is_defined() && it->second->is_defined();
}
V& operator*() const { return *pNode; } private:
V& operator->() const { return *pNode; } typename iterator_type::value m_type;
V* pNode; SeqIter m_seqIt;
}; MapIter m_mapIt, m_mapEnd;
};
using node_seq = std::vector<node *>; typedef node_iterator_base<node> node_iterator;
using node_map = std::vector<std::pair<node*, node*>>; typedef node_iterator_base<const node> const_node_iterator;
}
template <typename V>
struct node_iterator_type {
using seq = node_seq::iterator;
using map = node_map::iterator;
};
template <typename V>
struct node_iterator_type<const V> {
using seq = node_seq::const_iterator;
using map = node_map::const_iterator;
};
template <typename V>
class node_iterator_base {
private:
struct enabler {};
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> m_ref;
};
public:
using iterator_category = std::forward_iterator_tag;
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 SeqIter = typename node_iterator_type<V>::seq;
using MapIter = typename node_iterator_type<V>::map;
node_iterator_base()
: m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}
explicit node_iterator_base(SeqIter seqIt)
: m_type(iterator_type::Sequence),
m_seqIt(seqIt),
m_mapIt(),
m_mapEnd() {}
explicit node_iterator_base(MapIter mapIt, MapIter mapEnd)
: m_type(iterator_type::Map),
m_seqIt(),
m_mapIt(mapIt),
m_mapEnd(mapEnd) {
m_mapIt = increment_until_defined(m_mapIt);
}
template <typename W>
node_iterator_base(const node_iterator_base<W>& rhs,
typename std::enable_if<std::is_convertible<W*, V*>::value,
enabler>::type = enabler())
: m_type(rhs.m_type),
m_seqIt(rhs.m_seqIt),
m_mapIt(rhs.m_mapIt),
m_mapEnd(rhs.m_mapEnd) {}
template <typename>
friend class node_iterator_base;
template <typename W>
bool operator==(const node_iterator_base<W>& rhs) const {
if (m_type != rhs.m_type)
return false;
switch (m_type) {
case iterator_type::NoneType:
return true;
case iterator_type::Sequence:
return m_seqIt == rhs.m_seqIt;
case iterator_type::Map:
return m_mapIt == rhs.m_mapIt;
}
return true;
}
template <typename W>
bool operator!=(const node_iterator_base<W>& rhs) const {
return !(*this == rhs);
}
node_iterator_base<V>& operator++() {
switch (m_type) {
case iterator_type::NoneType:
break;
case iterator_type::Sequence:
++m_seqIt;
break;
case iterator_type::Map:
++m_mapIt;
m_mapIt = increment_until_defined(m_mapIt);
break;
}
return *this;
}
node_iterator_base<V> operator++(int) {
node_iterator_base<V> iterator_pre(*this);
++(*this);
return iterator_pre;
}
value_type operator*() const {
switch (m_type) {
case iterator_type::NoneType:
return value_type();
case iterator_type::Sequence:
return value_type(**m_seqIt);
case iterator_type::Map:
return value_type(*m_mapIt->first, *m_mapIt->second);
}
return value_type();
}
proxy operator->() const { return proxy(**this); }
MapIter increment_until_defined(MapIter it) {
while (it != m_mapEnd && !is_defined(it))
++it;
return it;
}
bool is_defined(MapIter it) const {
return it->first->is_defined() && it->second->is_defined();
}
private:
typename iterator_type::value m_type;
SeqIter m_seqIt;
MapIter m_mapIt, m_mapEnd;
};
using node_iterator = node_iterator_base<node>;
using const_node_iterator = node_iterator_base<const node>;
}
} }
#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+50 -83
View File
@@ -1,98 +1,65 @@
#ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_data.h" #include "yaml-cpp/node/detail/node_data.h"
#include <boost/utility.hpp>
namespace YAML { namespace YAML
namespace detail { {
class node_ref { namespace detail
public: {
node_ref() : m_pData(new node_data) {} class node_ref: private boost::noncopyable
node_ref(const node_ref&) = delete; {
node_ref& operator=(const node_ref&) = delete; public:
node_ref(): m_pData(new node_data) {}
bool is_defined() const { return m_pData->is_defined(); }
NodeType::value type() const { return m_pData->type(); }
const std::string& scalar() const { return m_pData->scalar(); }
const std::string& tag() const { return m_pData->tag(); }
void mark_defined() { m_pData->mark_defined(); }
void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; }
void set_type(NodeType::value type) { m_pData->set_type(type); }
void set_tag(const std::string& tag) { m_pData->set_tag(tag); }
void set_null() { m_pData->set_null(); }
void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); }
// size/iterator
std::size_t size() const { return m_pData->size(); }
const_node_iterator begin() const { return static_cast<const node_data&>(*m_pData).begin(); }
node_iterator begin() {return m_pData->begin(); }
const_node_iterator end() const { return static_cast<const node_data&>(*m_pData).end(); }
node_iterator end() {return m_pData->end(); }
bool is_defined() const { return m_pData->is_defined(); } // sequence
const Mark& mark() const { return m_pData->mark(); } void push_back(node& node, shared_memory_holder pMemory) { m_pData->push_back(node, pMemory); }
NodeType::value type() const { return m_pData->type(); } void insert(node& key, node& value, shared_memory_holder pMemory) { m_pData->insert(key, value, pMemory); }
const std::string& scalar() const { return m_pData->scalar(); }
const std::string& tag() const { return m_pData->tag(); } // indexing
EmitterStyle::value style() const { return m_pData->style(); } template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_data&>(*m_pData).get(key, pMemory); }
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); }
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); }
node& get(node& key, shared_memory_holder pMemory) const { return static_cast<const node_data&>(*m_pData).get(key, pMemory); }
node& get(node& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); }
bool remove(node& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); }
void mark_defined() { m_pData->mark_defined(); } private:
void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } shared_node_data m_pData;
};
void set_mark(const Mark& mark) { m_pData->set_mark(mark); } }
void set_type(NodeType::value type) { m_pData->set_type(type); }
void set_tag(const std::string& tag) { m_pData->set_tag(tag); }
void set_null() { m_pData->set_null(); }
void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); }
void set_style(EmitterStyle::value style) { m_pData->set_style(style); }
// size/iterator
std::size_t size() const { return m_pData->size(); }
const_node_iterator begin() const {
return static_cast<const node_data&>(*m_pData).begin();
}
node_iterator begin() { return m_pData->begin(); }
const_node_iterator end() const {
return static_cast<const node_data&>(*m_pData).end();
}
node_iterator end() { return m_pData->end(); }
// sequence
void push_back(node& node, shared_memory_holder pMemory) {
m_pData->push_back(node, pMemory);
}
void insert(node& key, node& value, shared_memory_holder pMemory) {
m_pData->insert(key, value, pMemory);
}
// indexing
template <typename Key>
node* get(const Key& key, shared_memory_holder pMemory) const {
return static_cast<const node_data&>(*m_pData).get(key, pMemory);
}
template <typename Key>
node& get(const Key& key, shared_memory_holder pMemory) {
return m_pData->get(key, pMemory);
}
template <typename Key>
bool remove(const Key& key, shared_memory_holder pMemory) {
return m_pData->remove(key, pMemory);
}
node* get(node& key, shared_memory_holder pMemory) const {
return static_cast<const node_data&>(*m_pData).get(key, pMemory);
}
node& get(node& key, shared_memory_holder pMemory) {
return m_pData->get(key, pMemory);
}
bool remove(node& key, shared_memory_holder pMemory) {
return m_pData->remove(key, pMemory);
}
// map
template <typename Key, typename Value>
void force_insert(const Key& key, const Value& value,
shared_memory_holder pMemory) {
m_pData->force_insert(key, value, pMemory);
}
private:
shared_node_data m_pData;
};
}
} }
#endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+12 -21
View File
@@ -1,32 +1,23 @@
#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <iosfwd> #include <iosfwd>
#include "yaml-cpp/dll.h" namespace YAML
{
class Emitter;
class Node;
Emitter& operator << (Emitter& out, const Node& node);
std::ostream& operator << (std::ostream& out, const Node& node);
std::string Dump(const Node& node);
}
namespace YAML { #endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
class Emitter;
class Node;
/**
* Emits the node to the given {@link Emitter}. If there is an error in writing,
* {@link Emitter#good} will return false.
*/
YAML_CPP_API Emitter& operator<<(Emitter& out, const Node& node);
/** Emits the node to the given output stream. */
YAML_CPP_API std::ostream& operator<<(std::ostream& out, const Node& node);
/** Converts the node to a YAML string. */
YAML_CPP_API std::string Dump(const Node& node);
} // namespace YAML
#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+342 -376
View File
@@ -1,389 +1,355 @@
#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/exceptions.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/detail/memory.h" #include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h" #include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/iterator.h" #include "yaml-cpp/exceptions.h"
#include "yaml-cpp/node/node.h"
#include <sstream>
#include <string> #include <string>
namespace YAML { namespace YAML
[[noreturn]] extern void throw_invalid_node(const std::string& key); {
[[noreturn]] extern void throw_bad_conversion(const YAML::Mark& mark); inline Node::Node(): m_pNode(0)
inline Node::Node() {
: m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {} }
inline Node::Node(NodeType::value type): m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node())
{
m_pNode->set_type(type);
}
template<typename T>
inline Node::Node(const T& rhs): m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node())
{
Assign(rhs);
}
inline Node::Node(const detail::iterator_value& rhs): m_pMemory(rhs.m_pMemory), m_pNode(rhs.m_pNode)
{
}
inline Node::Node(NodeType::value type) inline Node::Node(const Node& rhs): m_pMemory(rhs.m_pMemory), m_pNode(rhs.m_pNode)
: m_isValid(true), {
m_invalidKey{}, }
m_pMemory(new detail::memory_holder),
m_pNode(&m_pMemory->create_node()) { inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory): m_pMemory(pMemory), m_pNode(&node)
m_pNode->set_type(type); {
}
inline Node::~Node()
{
}
inline void Node::EnsureNodeExists() const
{
if(!m_pNode) {
m_pMemory.reset(new detail::memory_holder);
m_pNode = &m_pMemory->create_node();
m_pNode->set_null();
}
}
inline bool Node::IsDefined() const
{
return m_pNode ? m_pNode->is_defined() : true;
}
inline NodeType::value Node::Type() const
{
return m_pNode ? m_pNode->type() : NodeType::Null;
}
// access
// template helpers
template<typename T, typename S>
struct as_if {
explicit as_if(const Node& node_): node(node_) {}
const Node& node;
const T operator()(const S& fallback) const {
if(!node.m_pNode)
return fallback;
T t;
if(convert<T>::decode(node, t))
return t;
return fallback;
}
};
template<typename S>
struct as_if<std::string, S> {
explicit as_if(const Node& node_): node(node_) {}
const Node& node;
const std::string operator()(const S& fallback) const {
if(node.Type() != NodeType::Scalar)
return fallback;
return node.Scalar();
}
};
template<typename T>
struct as_if<T, void> {
explicit as_if(const Node& node_): node(node_) {}
const Node& node;
const T operator()() const {
if(!node.m_pNode)
throw TypedBadConversion<T>();
T t;
if(convert<T>::decode(node, t))
return t;
throw TypedBadConversion<T>();
}
};
template<>
struct as_if<std::string, void> {
explicit as_if(const Node& node_): node(node_) {}
const Node& node;
const std::string operator()() const {
if(node.Type() != NodeType::Scalar)
throw TypedBadConversion<std::string>();
return node.Scalar();
}
};
// access functions
template<typename T>
inline const T Node::as() const
{
return as_if<T, void>(*this)();
}
template<typename T, typename S>
inline const T Node::as(const S& fallback) const
{
return as_if<T, S>(*this)(fallback);
}
inline const std::string& Node::Scalar() const
{
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar;
}
inline const std::string& Node::Tag() const
{
return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar;
}
inline void Node::SetTag(const std::string& tag)
{
EnsureNodeExists();
m_pNode->set_tag(tag);
}
// assignment
inline bool Node::is(const Node& rhs) const
{
if(!m_pNode || !rhs.m_pNode)
return false;
return m_pNode->is(*rhs.m_pNode);
}
template<typename T>
inline Node& Node::operator=(const T& rhs)
{
Assign(rhs);
return *this;
}
template<typename T>
inline void Node::Assign(const T& rhs)
{
AssignData(convert<T>::encode(rhs));
}
template<>
inline void Node::Assign(const std::string& rhs)
{
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline void Node::Assign(const char *rhs)
{
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline void Node::Assign(char *rhs)
{
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline Node& Node::operator=(const Node& rhs)
{
if(is(rhs))
return *this;
AssignNode(rhs);
return *this;
}
inline void Node::AssignData(const Node& rhs)
{
EnsureNodeExists();
rhs.EnsureNodeExists();
m_pNode->set_data(*rhs.m_pNode);
m_pMemory->merge(*rhs.m_pMemory);
}
inline void Node::AssignNode(const Node& rhs)
{
rhs.EnsureNodeExists();
if(!m_pNode) {
m_pNode = rhs.m_pNode;
m_pMemory = rhs.m_pMemory;
return;
}
m_pNode->set_ref(*rhs.m_pNode);
m_pMemory->merge(*rhs.m_pMemory);
m_pNode = rhs.m_pNode;
}
// size/iterator
inline std::size_t Node::size() const
{
return m_pNode ? m_pNode->size() : 0;
}
inline const_iterator Node::begin() const
{
return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory) : const_iterator();
}
inline iterator Node::begin()
{
return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
}
inline const_iterator Node::end() const
{
return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator();
}
inline iterator Node::end()
{
return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator();
}
// sequence
template<typename T>
inline void Node::push_back(const T& rhs)
{
push_back(Node(rhs));
}
inline void Node::push_back(const Node& rhs)
{
EnsureNodeExists();
rhs.EnsureNodeExists();
m_pNode->push_back(*rhs.m_pNode, m_pMemory);
m_pMemory->merge(*rhs.m_pMemory);
}
// indexing
template<typename Key>
inline const Node Node::operator[](const Key& key) const
{
EnsureNodeExists();
detail::node& value = static_cast<const detail::node&>(*m_pNode).get(key, m_pMemory);
return Node(value, m_pMemory);
}
template<typename Key>
inline Node Node::operator[](const Key& key)
{
EnsureNodeExists();
detail::node& value = m_pNode->get(key, m_pMemory);
return Node(value, m_pMemory);
}
template<typename Key>
inline bool Node::remove(const Key& key)
{
EnsureNodeExists();
return m_pNode->remove(key, m_pMemory);
}
inline const Node Node::operator[](const Node& key) const
{
EnsureNodeExists();
key.EnsureNodeExists();
detail::node& value = static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
return Node(value, m_pMemory);
}
inline Node Node::operator[](const Node& key)
{
EnsureNodeExists();
key.EnsureNodeExists();
detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
return Node(value, m_pMemory);
}
inline bool Node::remove(const Node& key)
{
EnsureNodeExists();
key.EnsureNodeExists();
return m_pNode->remove(*key.m_pNode, m_pMemory);
}
inline const Node Node::operator[](const char *key) const
{
return operator[](std::string(key));
}
inline Node Node::operator[](const char *key)
{
return operator[](std::string(key));
}
inline bool Node::remove(const char *key)
{
return remove(std::string(key));
}
inline const Node Node::operator[](char *key) const
{
return operator[](static_cast<const char *>(key));
}
inline Node Node::operator[](char *key)
{
return operator[](static_cast<const char *>(key));
}
inline bool Node::remove(char *key)
{
return remove(static_cast<const char *>(key));
}
// free functions
inline bool operator==(const Node& lhs, const Node& rhs)
{
return lhs.is(rhs);
}
} }
template <typename T> #endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
inline Node::Node(const T& rhs)
: m_isValid(true),
m_invalidKey{},
m_pMemory(new detail::memory_holder),
m_pNode(&m_pMemory->create_node()) {
Assign(rhs);
}
inline Node::Node(const detail::iterator_value& rhs)
: m_isValid(rhs.m_isValid),
m_invalidKey(rhs.m_invalidKey),
m_pMemory(rhs.m_pMemory),
m_pNode(rhs.m_pNode) {}
inline Node::Node(const Node&) = default;
inline Node::Node(Zombie)
: m_isValid(false), m_invalidKey{}, m_pMemory{}, m_pNode(nullptr) {}
inline Node::Node(Zombie, const std::string& key)
: m_isValid(false), m_invalidKey(key), m_pMemory{}, m_pNode(nullptr) {}
inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
: m_isValid(true), m_invalidKey{}, m_pMemory(pMemory), m_pNode(&node) {}
inline Node::~Node() = default;
inline void Node::EnsureNodeExists() const {
if (!m_isValid)
throw_invalid_node(m_invalidKey);
if (!m_pNode) {
m_pMemory.reset(new detail::memory_holder);
m_pNode = &m_pMemory->create_node();
m_pNode->set_null();
}
}
inline bool Node::IsDefined() const {
if (!m_isValid) {
return false;
}
return m_pNode ? m_pNode->is_defined() : true;
}
inline Mark Node::Mark() const {
if (!m_isValid) {
throw_invalid_node(m_invalidKey);
}
return m_pNode ? m_pNode->mark() : Mark::null_mark();
}
inline NodeType::value Node::Type() const {
if (!m_isValid)
throw_invalid_node(m_invalidKey);
return m_pNode ? m_pNode->type() : NodeType::Null;
}
// access
// template helpers
template <typename T, typename S>
struct as_if {
explicit as_if(const Node& node_) : node(node_) {}
const Node& node;
T operator()(const S& fallback) const {
if (!node.m_pNode)
return fallback;
T t = fallback;
if (convert<T>::decode(node, t))
return t;
return fallback;
}
};
template <typename S>
struct as_if<std::string, S> {
explicit as_if(const Node& node_) : node(node_) {}
const Node& node;
std::string operator()(const S& fallback) const {
if (node.Type() == NodeType::Null)
return "null";
if (node.Type() != NodeType::Scalar)
return fallback;
return node.Scalar();
}
};
template <typename T>
struct as_if<T, void> {
explicit as_if(const Node& node_) : node(node_) {}
const Node& node;
T operator()() const {
if (!node.m_pNode) // no fallback
throw_invalid_node(node.m_invalidKey);
T t;
if (convert<T>::decode(node, t))
return t;
throw_bad_conversion(node.Mark()); // <T>
}
};
template <>
struct as_if<std::string, void> {
explicit as_if(const Node& node_) : node(node_) {}
const Node& node;
std::string operator()() const {
if (node.Type() == NodeType::Undefined) // no fallback
throw_invalid_node(node.m_invalidKey);
if (node.Type() == NodeType::Null)
return "null";
if (node.Type() != NodeType::Scalar)
throw_bad_conversion(node.Mark()); // <std::string>
return node.Scalar();
}
};
// access functions
template <typename T>
inline T Node::as() const {
if (!m_isValid)
throw_invalid_node(m_invalidKey);
return as_if<T, void>(*this)();
}
template <typename T, typename S>
inline T Node::as(const S& fallback) const {
if (!m_isValid)
return fallback;
return as_if<T, S>(*this)(fallback);
}
inline const std::string& Node::Scalar() const {
if (!m_isValid)
throw_invalid_node(m_invalidKey);
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar();
}
inline const std::string& Node::Tag() const {
if (!m_isValid)
throw_invalid_node(m_invalidKey);
return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar();
}
inline void Node::SetTag(const std::string& tag) {
EnsureNodeExists();
m_pNode->set_tag(tag);
}
inline EmitterStyle::value Node::Style() const {
if (!m_isValid)
throw_invalid_node(m_invalidKey);
return m_pNode ? m_pNode->style() : EmitterStyle::Default;
}
inline void Node::SetStyle(EmitterStyle::value style) {
EnsureNodeExists();
m_pNode->set_style(style);
}
// assignment
inline bool Node::is(const Node& rhs) const {
if (!m_isValid || !rhs.m_isValid)
throw_invalid_node(m_invalidKey);
if (!m_pNode || !rhs.m_pNode)
return false;
return m_pNode->is(*rhs.m_pNode);
}
template <typename T>
inline Node& Node::operator=(const T& rhs) {
Assign(rhs);
return *this;
}
inline Node& Node::operator=(const Node& rhs) {
if (is(rhs))
return *this;
AssignNode(rhs);
return *this;
}
inline void Node::reset(const YAML::Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw_invalid_node(m_invalidKey);
m_pMemory = rhs.m_pMemory;
m_pNode = rhs.m_pNode;
}
template <typename T>
inline void Node::Assign(const T& rhs) {
if (!m_isValid)
throw_invalid_node(m_invalidKey);
AssignData(convert<T>::encode(rhs));
}
template <>
inline void Node::Assign(const std::string& rhs) {
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline void Node::Assign(const char* rhs) {
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline void Node::Assign(char* rhs) {
EnsureNodeExists();
m_pNode->set_scalar(rhs);
}
inline void Node::AssignData(const Node& rhs) {
EnsureNodeExists();
rhs.EnsureNodeExists();
m_pNode->set_data(*rhs.m_pNode);
m_pMemory->merge(*rhs.m_pMemory);
}
inline void Node::AssignNode(const Node& rhs) {
if (!m_isValid)
throw_invalid_node(m_invalidKey);
rhs.EnsureNodeExists();
if (!m_pNode) {
m_pNode = rhs.m_pNode;
m_pMemory = rhs.m_pMemory;
return;
}
m_pNode->set_ref(*rhs.m_pNode);
m_pMemory->merge(*rhs.m_pMemory);
m_pNode = rhs.m_pNode;
}
// size/iterator
inline std::size_t Node::size() const {
if (!m_isValid)
throw_invalid_node(m_invalidKey);
return m_pNode ? m_pNode->size() : 0;
}
inline const_iterator Node::begin() const {
if (!m_isValid)
return const_iterator();
return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory)
: const_iterator();
}
inline iterator Node::begin() {
if (!m_isValid)
return iterator();
return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
}
inline const_iterator Node::end() const {
if (!m_isValid)
return const_iterator();
return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator();
}
inline iterator Node::end() {
if (!m_isValid)
return iterator();
return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator();
}
// sequence
template <typename T>
inline void Node::push_back(const T& rhs) {
if (!m_isValid)
throw_invalid_node(m_invalidKey);
push_back(Node(rhs));
}
inline void Node::push_back(const Node& rhs) {
EnsureNodeExists();
rhs.EnsureNodeExists();
m_pNode->push_back(*rhs.m_pNode, m_pMemory);
m_pMemory->merge(*rhs.m_pMemory);
}
template<typename Key>
std::string key_to_string(const Key& key) {
return streamable_to_string<Key, is_streamable<std::stringstream, Key>::value>().impl(key);
}
// indexing
template <typename Key>
inline const Node Node::operator[](const Key& key) const {
EnsureNodeExists();
detail::node* value =
static_cast<const detail::node&>(*m_pNode).get(key, m_pMemory);
if (!value) {
return Node(ZombieNode, key_to_string(key));
}
return Node(*value, m_pMemory);
}
template <typename Key>
inline Node Node::operator[](const Key& key) {
EnsureNodeExists();
detail::node& value = m_pNode->get(key, m_pMemory);
return Node(value, m_pMemory);
}
template <typename Key>
inline bool Node::remove(const Key& key) {
EnsureNodeExists();
return m_pNode->remove(key, m_pMemory);
}
inline const Node Node::operator[](const Node& key) const {
EnsureNodeExists();
key.EnsureNodeExists();
m_pMemory->merge(*key.m_pMemory);
detail::node* value =
static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
if (!value) {
return Node(ZombieNode, key_to_string(key));
}
return Node(*value, m_pMemory);
}
inline Node Node::operator[](const Node& key) {
EnsureNodeExists();
key.EnsureNodeExists();
m_pMemory->merge(*key.m_pMemory);
detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
return Node(value, m_pMemory);
}
inline bool Node::remove(const Node& key) {
EnsureNodeExists();
key.EnsureNodeExists();
return m_pNode->remove(*key.m_pNode, m_pMemory);
}
// map
template <typename Key, typename Value>
inline void Node::force_insert(const Key& key, const Value& value) {
EnsureNodeExists();
m_pNode->force_insert(key, value, m_pMemory);
}
// free functions
inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
} // namespace YAML
#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+12 -18
View File
@@ -1,12 +1,11 @@
#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/detail/iterator_fwd.h" #include "yaml-cpp/node/detail/iterator_fwd.h"
@@ -15,20 +14,15 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
// Assert in place so gcc + libc++ combination properly builds namespace YAML
static_assert(std::is_constructible<YAML::Node, const YAML::Node&>::value, "Node must be copy constructable"); {
namespace detail {
namespace YAML { struct iterator_value: public Node, std::pair<Node, Node> {
namespace detail { iterator_value() {}
struct iterator_value : public Node, std::pair<Node, Node> { explicit iterator_value(const Node& rhs): Node(rhs) {}
iterator_value() = default; explicit iterator_value(const Node& key, const Node& value): std::pair<Node, Node>(key, value) {}
explicit iterator_value(const Node& rhs) };
: Node(rhs), }
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) {}
};
}
} }
#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+93 -128
View File
@@ -1,148 +1,113 @@
#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <stdexcept>
#include <string>
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/mark.h"
#include "yaml-cpp/node/detail/iterator_fwd.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/detail/iterator_fwd.h"
#include "yaml-cpp/node/detail/bool_type.h"
#include <stdexcept>
namespace YAML { namespace YAML
namespace detail { {
class node; class Node
class node_data; {
struct iterator_value; public:
} // namespace detail friend class NodeBuilder;
} // namespace YAML friend class NodeEvents;
friend class detail::node_data;
template<typename> friend class detail::iterator_base;
template<typename T, typename S> friend struct as_if;
typedef YAML::iterator iterator;
typedef YAML::const_iterator const_iterator;
Node();
explicit Node(NodeType::value type);
template<typename T> explicit Node(const T& rhs);
explicit Node(const detail::iterator_value& rhs);
Node(const Node& rhs);
~Node();
NodeType::value Type() const;
bool IsDefined() const;
bool IsNull() const { return Type() == NodeType::Null; }
bool IsScalar() const { return Type() == NodeType::Scalar; }
bool IsSequence() const { return Type() == NodeType::Sequence; }
bool IsMap() const { return Type() == NodeType::Map; }
// bool conversions
YAML_CPP_OPERATOR_BOOL();
bool operator!() const { return !IsDefined(); }
// access
template<typename T> const T as() const;
template<typename T, typename S> const T as(const S& fallback) const;
const std::string& Scalar() const;
const std::string& Tag() const;
void SetTag(const std::string& tag);
namespace YAML { // assignment
class YAML_CPP_API Node { bool is(const Node& rhs) const;
public: template<typename T> Node& operator=(const T& rhs);
friend class NodeBuilder; Node& operator=(const Node& rhs);
friend class NodeEvents;
friend struct detail::iterator_value;
friend class detail::node;
friend class detail::node_data;
template <typename>
friend class detail::iterator_base;
template <typename T, typename S>
friend struct as_if;
using iterator = YAML::iterator; // size/iterator
using const_iterator = YAML::const_iterator; std::size_t size() const;
Node(); const_iterator begin() const;
explicit Node(NodeType::value type); iterator begin();
template <typename T>
explicit Node(const T& rhs); const_iterator end() const;
explicit Node(const detail::iterator_value& rhs); iterator end();
Node(const Node& rhs);
~Node(); // sequence
template<typename T> void push_back(const T& rhs);
void push_back(const Node& rhs);
// indexing
template<typename Key> const Node operator[](const Key& key) const;
template<typename Key> Node operator[](const Key& key);
template<typename Key> bool remove(const Key& key);
YAML::Mark Mark() const; const Node operator[](const Node& key) const;
NodeType::value Type() const; Node operator[](const Node& key);
bool IsDefined() const; bool remove(const Node& key);
bool IsNull() const { return Type() == NodeType::Null; }
bool IsScalar() const { return Type() == NodeType::Scalar; } const Node operator[](const char *key) const;
bool IsSequence() const { return Type() == NodeType::Sequence; } Node operator[](const char *key);
bool IsMap() const { return Type() == NodeType::Map; } bool remove(const char *key);
// bool conversions const Node operator[](char *key) const;
explicit operator bool() const { return IsDefined(); } Node operator[](char *key);
bool operator!() const { return !IsDefined(); } bool remove(char *key);
private:
explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
void EnsureNodeExists() const;
template<typename T> void Assign(const T& rhs);
void Assign(const char *rhs);
void Assign(char *rhs);
// access void AssignData(const Node& rhs);
template <typename T> void AssignNode(const Node& rhs);
T as() const;
template <typename T, typename S> private:
T as(const S& fallback) const; mutable detail::shared_memory_holder m_pMemory;
const std::string& Scalar() const; mutable detail::node *m_pNode;
};
const std::string& Tag() const; bool operator==(const Node& lhs, const Node& rhs);
void SetTag(const std::string& tag);
template<typename T>
// style struct convert;
// WARNING: This API might change in future releases.
EmitterStyle::value Style() const;
void SetStyle(EmitterStyle::value style);
// assignment
bool is(const Node& rhs) const;
template <typename T>
Node& operator=(const T& rhs);
Node& operator=(const Node& rhs);
void reset(const Node& rhs = Node());
// size/iterator
std::size_t size() const;
const_iterator begin() const;
iterator begin();
const_iterator end() const;
iterator end();
// sequence
template <typename T>
void push_back(const T& rhs);
void push_back(const Node& rhs);
// indexing
template <typename Key>
const Node operator[](const Key& key) const;
template <typename Key>
Node operator[](const Key& key);
template <typename Key>
bool remove(const Key& key);
const Node operator[](const Node& key) const;
Node operator[](const Node& key);
bool remove(const Node& key);
// map
template <typename Key, typename Value>
void force_insert(const Key& key, const Value& value);
private:
enum Zombie { ZombieNode };
explicit Node(Zombie);
explicit Node(Zombie, const std::string&);
explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
void EnsureNodeExists() const;
template <typename T>
void Assign(const T& rhs);
void Assign(const char* rhs);
void Assign(char* rhs);
void AssignData(const Node& rhs);
void AssignNode(const Node& rhs);
private:
bool m_isValid;
// String representation of invalid key, if the node is invalid.
std::string m_invalidKey;
mutable detail::shared_memory_holder m_pMemory;
mutable detail::node* m_pNode;
};
YAML_CPP_API bool operator==(const Node& lhs, const Node& rhs);
YAML_CPP_API Node Clone(const Node& node);
template <typename T>
struct convert;
} }
#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+15 -65
View File
@@ -1,9 +1,7 @@
#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
@@ -11,68 +9,20 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "yaml-cpp/dll.h" namespace YAML
{
class Node;
Node Load(const std::string& input);
Node Load(const char *input);
Node Load(std::istream& input);
Node LoadFile(const std::string& filename);
namespace YAML { std::vector<Node> LoadAll(const std::string& input);
class Node; std::vector<Node> LoadAll(const char *input);
std::vector<Node> LoadAll(std::istream& input);
std::vector<Node> LoadAllFromFile(const std::string& filename);
}
/** #endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
* Loads the input string as a single YAML document.
*
* @throws {@link ParserException} if it is malformed.
*/
YAML_CPP_API Node Load(const std::string& input);
/**
* Loads the input string as a single YAML document.
*
* @throws {@link ParserException} if it is malformed.
*/
YAML_CPP_API Node Load(const char* input);
/**
* Loads the input stream as a single YAML document.
*
* @throws {@link ParserException} if it is malformed.
*/
YAML_CPP_API Node Load(std::istream& input);
/**
* Loads the input file as a single YAML document.
*
* @throws {@link ParserException} if it is malformed.
* @throws {@link BadFile} if the file cannot be loaded.
*/
YAML_CPP_API Node LoadFile(const std::string& filename);
/**
* Loads the input string as a list of YAML documents.
*
* @throws {@link ParserException} if it is malformed.
*/
YAML_CPP_API std::vector<Node> LoadAll(const std::string& input);
/**
* Loads the input string as a list of YAML documents.
*
* @throws {@link ParserException} if it is malformed.
*/
YAML_CPP_API std::vector<Node> LoadAll(const char* input);
/**
* Loads the input stream as a list of YAML documents.
*
* @throws {@link ParserException} if it is malformed.
*/
YAML_CPP_API std::vector<Node> LoadAll(std::istream& input);
/**
* Loads the input file as a list of YAML documents.
*
* @throws {@link ParserException} if it is malformed.
* @throws {@link BadFile} if the file cannot be loaded.
*/
YAML_CPP_API std::vector<Node> LoadAllFromFile(const std::string& filename);
} // namespace YAML
#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+19 -18
View File
@@ -1,28 +1,29 @@
#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <memory>
namespace YAML { #include "yaml-cpp/dll.h"
namespace detail { #include <boost/shared_ptr.hpp>
class node;
class node_ref;
class node_data;
class memory;
class memory_holder;
using shared_node = std::shared_ptr<node>; namespace YAML
using shared_node_ref = std::shared_ptr<node_ref>; {
using shared_node_data = std::shared_ptr<node_data>; namespace detail {
using shared_memory_holder = std::shared_ptr<memory_holder>; class node;
using shared_memory = std::shared_ptr<memory>; class node_ref;
} class node_data;
class memory;
class memory_holder;
typedef boost::shared_ptr<node> shared_node;
typedef boost::shared_ptr<node_ref> shared_node_ref;
typedef boost::shared_ptr<node_data> shared_node_data;
typedef boost::shared_ptr<memory_holder> shared_memory_holder;
typedef boost::shared_ptr<memory> shared_memory;
}
} }
#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+6 -9
View File
@@ -1,17 +1,14 @@
#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace YAML {
namespace NodeType { namespace YAML
enum value { Undefined, Null, Scalar, Sequence, Map }; {
struct NodeType { enum value { Undefined, Null, Scalar, Sequence, Map }; };
} }
} #endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-18
View File
@@ -1,18 +0,0 @@
#ifndef NOEXCEPT_H_768872DA_476C_11EA_88B8_90B11C0C0FF8
#define NOEXCEPT_H_768872DA_476C_11EA_88B8_90B11C0C0FF8
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
// This is here for compatibility with older versions of Visual Studio
// which don't support noexcept.
#if defined(_MSC_VER) && _MSC_VER < 1900
#define YAML_CPP_NOEXCEPT _NOEXCEPT
#else
#define YAML_CPP_NOEXCEPT noexcept
#endif
#endif
+25
View File
@@ -0,0 +1,25 @@
#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NONCOPYABLE_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
#endif
#include "yaml-cpp/dll.h"
namespace YAML
{
// this is basically boost::noncopyable
class YAML_CPP_API noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private:
noncopyable(const noncopyable&);
const noncopyable& operator = (const noncopyable&);
};
}
#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+15 -16
View File
@@ -1,26 +1,25 @@
#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include <cstddef>
namespace YAML { namespace YAML
class Node; {
class Node;
struct YAML_CPP_API _Null {};
inline bool operator==(const _Null&, const _Null&) { return true; } struct YAML_CPP_API _Null {};
inline bool operator!=(const _Null&, const _Null&) { return false; } 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 char* str, std::size_t size); YAML_CPP_API bool IsNull(const Node& node); // old API only
extern YAML_CPP_API _Null Null; extern YAML_CPP_API _Null Null;
} }
#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+40
View File
@@ -0,0 +1,40 @@
#ifndef OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define OSTREAM_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
#endif
#include <string>
namespace YAML
{
class ostream
{
public:
ostream();
~ostream();
void reserve(unsigned size);
void put(char ch);
const char *str() const { return m_buffer; }
unsigned row() const { return m_row; }
unsigned col() const { return m_col; }
unsigned pos() const { return m_pos; }
private:
char *m_buffer;
unsigned m_pos;
unsigned m_size;
unsigned m_row, m_col;
};
ostream& operator << (ostream& out, const char *str);
ostream& operator << (ostream& out, const std::string& str);
ostream& operator << (ostream& out, char ch);
}
#endif // OSTREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-76
View File
@@ -1,76 +0,0 @@
#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define OSTREAM_WRAPPER_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
#endif
#include <string>
#include <vector>
#include "yaml-cpp/dll.h"
namespace YAML {
class YAML_CPP_API ostream_wrapper {
public:
ostream_wrapper();
explicit ostream_wrapper(std::ostream& stream);
ostream_wrapper(const ostream_wrapper&) = delete;
ostream_wrapper(ostream_wrapper&&) = delete;
ostream_wrapper& operator=(const ostream_wrapper&) = delete;
ostream_wrapper& operator=(ostream_wrapper&&) = delete;
~ostream_wrapper();
void write(const std::string& str);
void write(const char* str, std::size_t size);
void set_comment() { m_comment = true; }
const char* str() const {
if (m_pStream) {
return nullptr;
} else {
m_buffer[m_pos] = '\0';
return &m_buffer[0];
}
}
std::size_t row() const { return m_row; }
std::size_t col() const { return m_col; }
std::size_t pos() const { return m_pos; }
bool comment() const { return m_comment; }
private:
void update_pos(char ch);
private:
mutable std::vector<char> m_buffer;
std::ostream* const m_pStream;
std::size_t m_pos;
std::size_t m_row, m_col;
bool m_comment;
};
template <std::size_t N>
inline ostream_wrapper& operator<<(ostream_wrapper& stream,
const char (&str)[N]) {
stream.write(str, N - 1);
return stream;
}
inline ostream_wrapper& operator<<(ostream_wrapper& stream,
const std::string& str) {
stream.write(str);
return stream;
}
inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) {
stream.write(&ch, 1);
return stream;
}
} // namespace YAML
#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+37 -76
View File
@@ -1,90 +1,51 @@
#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h"
#include "yaml-cpp/noncopyable.h"
#include <ios> #include <ios>
#include <memory> #include <memory>
#include "yaml-cpp/dll.h" namespace YAML
{
struct Directives;
struct Mark;
struct Token;
class EventHandler;
class Node;
class Scanner;
namespace YAML { class YAML_CPP_API Parser: private noncopyable
class EventHandler; {
class Node; public:
class Scanner; Parser();
struct Directives; Parser(std::istream& in);
struct Token; ~Parser();
/** operator bool() const;
* A parser turns a stream of bytes into one stream of "events" per YAML
* document in the input stream.
*/
class YAML_CPP_API Parser {
public:
/** Constructs an empty parser (with no input. */
Parser();
Parser(const Parser&) = delete; void Load(std::istream& in);
Parser(Parser&&) = delete; bool HandleNextDocument(EventHandler& eventHandler);
Parser& operator=(const Parser&) = delete;
Parser& operator=(Parser&&) = delete; bool GetNextDocument(Node& document); // old API only
void PrintTokens(std::ostream& out);
/** private:
* Constructs a parser from the given input stream. The input stream must void ParseDirectives();
* live as long as the parser. void HandleDirective(const Token& token);
*/ void HandleYamlDirective(const Token& token);
explicit Parser(std::istream& in); void HandleTagDirective(const Token& token);
private:
std::auto_ptr<Scanner> m_pScanner;
std::auto_ptr<Directives> m_pDirectives;
};
}
~Parser(); #endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
/** Evaluates to true if the parser has some valid input to be read. */
explicit operator bool() const;
/**
* Resets the parser with the given input stream. Any existing state is
* erased.
*/
void Load(std::istream& in);
/**
* Handles the next document by calling events on the {@code eventHandler}.
*
* @throw a ParserException on error.
* @return false if there are no more documents
*/
bool HandleNextDocument(EventHandler& eventHandler);
void PrintTokens(std::ostream& out);
private:
/**
* Reads any directives that are next in the queue, setting the internal
* {@code m_pDirectives} state.
*/
void ParseDirectives();
void HandleDirective(const Token& token);
/**
* Handles a "YAML" directive, which should be of the form 'major.minor' (like
* a version number).
*/
void HandleYamlDirective(const Token& token);
/**
* Handles a "TAG" directive, which should be of the form 'handle prefix',
* where 'handle' is converted to 'prefix' in the file.
*/
void HandleTagDirective(const Token& token);
private:
std::unique_ptr<Scanner> m_pScanner;
std::unique_ptr<Directives> m_pDirectives;
};
} // namespace YAML
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+38 -37
View File
@@ -1,50 +1,51 @@
#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <vector> #include <vector>
#include <list> #include <list>
#include <set> #include <set>
#include <map> #include <map>
namespace YAML { namespace YAML
template <typename Seq> {
inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) { template<typename Seq>
emitter << BeginSeq; inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) {
for (const auto& v : seq) emitter << BeginSeq;
emitter << v; for(typename Seq::const_iterator it=seq.begin();it!=seq.end();++it)
emitter << EndSeq; emitter << *it;
return emitter; emitter << EndSeq;
return emitter;
}
template<typename T>
inline Emitter& operator << (Emitter& emitter, const std::vector<T>& v) {
return EmitSeq(emitter, v);
}
template<typename T>
inline Emitter& operator << (Emitter& emitter, const std::list<T>& v) {
return EmitSeq(emitter, v);
}
template<typename T>
inline Emitter& operator << (Emitter& emitter, const std::set<T>& v) {
return EmitSeq(emitter, v);
}
template <typename K, typename V>
inline Emitter& operator << (Emitter& emitter, const std::map<K, V>& m) {
typedef typename std::map <K, V> map;
emitter << BeginMap;
for(typename map::const_iterator it=m.begin();it!=m.end();++it)
emitter << Key << it->first << Value << it->second;
emitter << EndMap;
return emitter;
}
} }
template <typename T> #endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
inline Emitter& operator<<(Emitter& emitter, const std::vector<T>& v) {
return EmitSeq(emitter, v);
}
template <typename T>
inline Emitter& operator<<(Emitter& emitter, const std::list<T>& v) {
return EmitSeq(emitter, v);
}
template <typename T>
inline Emitter& operator<<(Emitter& emitter, const std::set<T>& v) {
return EmitSeq(emitter, v);
}
template <typename K, typename V>
inline Emitter& operator<<(Emitter& emitter, const std::map<K, V>& m) {
emitter << BeginMap;
for (const auto& v : m)
emitter << Key << v.first << Value << v.second;
emitter << EndMap;
return emitter;
}
}
#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+37 -116
View File
@@ -1,136 +1,57 @@
#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <type_traits>
#include <utility>
#include <string>
#include <sstream>
namespace YAML { namespace YAML
template <typename> {
struct is_numeric { template <typename>
enum { value = false }; struct is_numeric { enum { value = false }; };
};
template <> template <> struct is_numeric <char> { enum { value = true }; };
struct is_numeric<char> { template <> struct is_numeric <unsigned char> { enum { value = true }; };
enum { value = true }; template <> struct is_numeric <int> { enum { value = true }; };
}; template <> struct is_numeric <unsigned int> { enum { value = true }; };
template <> template <> struct is_numeric <long int> { enum { value = true }; };
struct is_numeric<unsigned char> { template <> struct is_numeric <unsigned long int> { enum { value = true }; };
enum { value = true }; template <> struct is_numeric <short int> { enum { value = true }; };
}; template <> struct is_numeric <unsigned short int> { enum { value = true }; };
template <>
struct is_numeric<int> {
enum { value = true };
};
template <>
struct is_numeric<unsigned int> {
enum { value = true };
};
template <>
struct is_numeric<long int> {
enum { value = true };
};
template <>
struct is_numeric<unsigned long int> {
enum { value = true };
};
template <>
struct is_numeric<short int> {
enum { value = true };
};
template <>
struct is_numeric<unsigned short int> {
enum { value = true };
};
#if defined(_MSC_VER) && (_MSC_VER < 1310) #if defined(_MSC_VER) && (_MSC_VER < 1310)
template <> template <> struct is_numeric <__int64> { enum { value = true }; };
struct is_numeric<__int64> { template <> struct is_numeric <unsigned __int64> { enum { value = true }; };
enum { value = true };
};
template <>
struct is_numeric<unsigned __int64> {
enum { value = true };
};
#else #else
template <> template <> struct is_numeric <long long> { enum { value = true }; };
struct is_numeric<long long> { template <> struct is_numeric <unsigned long long> { enum { value = true }; };
enum { value = true };
};
template <>
struct is_numeric<unsigned long long> {
enum { value = true };
};
#endif #endif
template <> template <> struct is_numeric <float> { enum { value = true }; };
struct is_numeric<float> { template <> struct is_numeric <double> { enum { value = true }; };
enum { value = true }; template <> struct is_numeric <long double> { enum { value = true }; };
};
template <>
struct is_numeric<double> {
enum { value = true };
};
template <>
struct is_numeric<long double> {
enum { value = true };
};
template <bool, class T = void> template <bool, class T = void>
struct enable_if_c { struct enable_if_c {
using type = T; typedef T type;
}; };
template <class T> template <class T>
struct enable_if_c<false, T> {}; struct enable_if_c<false, T> {};
template <class Cond, class T = void> template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {}; struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool, class T = void> template <bool, class T = void>
struct disable_if_c { struct disable_if_c {
using type = T; typedef T type;
}; };
template <class T> template <class T>
struct disable_if_c<true, T> {}; struct disable_if_c<true, T> {};
template <class Cond, class T = void> template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {}; struct disable_if : public disable_if_c<Cond::value, T> {};
} }
template <typename S, typename T> #endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
struct is_streamable {
template <typename StreamT, typename ValueT>
static auto test(int)
-> decltype(std::declval<StreamT&>() << std::declval<ValueT>(), std::true_type());
template <typename, typename>
static auto test(...) -> std::false_type;
static const bool value = decltype(test<S, T>(0))::value;
};
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();
}
};
template<typename Key>
struct streamable_to_string<Key, false> {
static std::string impl(const Key&) {
return "";
}
};
#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+2 -9
View File
@@ -1,17 +1,12 @@
#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
// IWYU pragma: begin_exports
#include "yaml-cpp/parser.h" #include "yaml-cpp/parser.h"
#include "yaml-cpp/emitter.h" #include "yaml-cpp/emitter.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/stlemitter.h" #include "yaml-cpp/stlemitter.h"
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
@@ -23,6 +18,4 @@
#include "yaml-cpp/node/parse.h" #include "yaml-cpp/node/parse.h"
#include "yaml-cpp/node/emit.h" #include "yaml-cpp/node/emit.h"
// IWYU pragma: end_exports #endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2008-2015 Jesse Beder. Copyright (c) 2008 Jesse Beder.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+86 -93
View File
@@ -1,100 +1,93 @@
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
#include <cctype> namespace YAML
{
static const char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
namespace YAML { std::string EncodeBase64(const unsigned char *data, std::size_t size)
static const char encoding[] = {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const char PAD = '=';
std::string EncodeBase64(const unsigned char *data, std::size_t size) { std::string ret;
const char PAD = '='; ret.resize(4 * size / 3 + 3);
char *out = &ret[0];
std::string ret;
ret.resize(4 * size / 3 + 3); std::size_t chunks = size / 3;
char *out = &ret[0]; std::size_t remainder = size % 3;
std::size_t chunks = size / 3; for(std::size_t i=0;i<chunks;i++, data += 3) {
std::size_t remainder = size % 3; *out++ = encoding[data[0] >> 2];
*out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
for (std::size_t i = 0; i < chunks; i++, data += 3) { *out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)];
*out++ = encoding[data[0] >> 2]; *out++ = encoding[data[2] & 0x3f];
*out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; }
*out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)];
*out++ = encoding[data[2] & 0x3f]; switch(remainder) {
} case 0:
break;
switch (remainder) { case 1:
case 0: *out++ = encoding[data[0] >> 2];
break; *out++ = encoding[((data[0] & 0x3) << 4)];
case 1: *out++ = PAD;
*out++ = encoding[data[0] >> 2]; *out++ = PAD;
*out++ = encoding[((data[0] & 0x3) << 4)]; break;
*out++ = PAD; case 2:
*out++ = PAD; *out++ = encoding[data[0] >> 2];
break; *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
case 2: *out++ = encoding[((data[1] & 0xf) << 2)];
*out++ = encoding[data[0] >> 2]; *out++ = PAD;
*out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; break;
*out++ = encoding[((data[1] & 0xf) << 2)]; }
*out++ = PAD;
break; ret.resize(out - &ret[0]);
} return ret;
ret.resize(out - &ret[0]);
return ret;
}
static const unsigned char decoding[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,
};
std::vector<unsigned char> DecodeBase64(const std::string &input) {
using ret_type = std::vector<unsigned char>;
if (input.empty())
return ret_type();
ret_type ret(3 * input.size() / 4 + 1);
unsigned char *out = &ret[0];
unsigned value = 0;
for (std::size_t i = 0, cnt = 0; i < input.size(); i++) {
if (std::isspace(static_cast<unsigned char>(input[i]))) {
// skip newlines
continue;
} }
unsigned char d = decoding[static_cast<unsigned char>(input[i])];
if (d == 255) static const unsigned char decoding[] = {
return ret_type(); 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
};
value = (value << 6) | d; std::vector<unsigned char> DecodeBase64(const std::string& input)
if (cnt % 4 == 3) { {
*out++ = value >> 16; typedef std::vector<unsigned char> ret_type;
if (i > 0 && input[i - 1] != '=') if(input.empty())
*out++ = value >> 8; return ret_type();
if (input[i] != '=')
*out++ = value; ret_type ret(3 * input.size() / 4 + 1);
unsigned char *out = &ret[0];
unsigned value = 0;
for(std::size_t i=0;i<input.size();i++) {
unsigned char d = decoding[static_cast<unsigned>(input[i])];
if(d == 255)
return ret_type();
value = (value << 6) | d;
if(i % 4 == 3) {
*out++ = value >> 16;
if(i > 0 && input[i - 1] != '=')
*out++ = value >> 8;
if(input[i] != '=')
*out++ = value;
}
}
ret.resize(out - &ret[0]);
return ret;
} }
++cnt;
}
ret.resize(out - &ret[0]);
return ret;
} }
} // namespace YAML
+25 -31
View File
@@ -1,41 +1,35 @@
#ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cassert>
#include <stack> #include <stack>
#include <cassert>
namespace YAML { namespace YAML
struct CollectionType { {
enum value { NoCollection, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap }; struct CollectionType {
}; enum value { None, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap };
};
class CollectionStack { class CollectionStack
public: {
CollectionStack() : collectionStack{} {} public:
CollectionType::value GetCurCollectionType() const { CollectionType::value GetCurCollectionType() const {
if (collectionStack.empty()) if(collectionStack.empty())
return CollectionType::NoCollection; return CollectionType::None;
return collectionStack.top(); return collectionStack.top();
} }
void PushCollectionType(CollectionType::value type) { collectionStack.push(type); }
void PopCollectionType(CollectionType::value type) { assert(type == GetCurCollectionType()); collectionStack.pop(); }
private:
std::stack<CollectionType::value> collectionStack;
};
}
void PushCollectionType(CollectionType::value type) { #endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
collectionStack.push(type);
}
void PopCollectionType(CollectionType::value type) {
assert(type == GetCurCollectionType());
(void)type;
collectionStack.pop();
}
private:
std::stack<CollectionType::value> collectionStack;
};
} // namespace YAML
#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
File diff suppressed because it is too large Load Diff
+12 -12
View File
@@ -1,16 +1,16 @@
#include "yaml-cpp/parser.h"
#include "yaml-cpp/contrib/graphbuilder.h"
#include "graphbuilderadapter.h" #include "graphbuilderadapter.h"
#include "yaml-cpp/parser.h" // IWYU pragma: keep namespace YAML
{
namespace YAML { void *BuildGraphOfNextDocument(Parser& parser, GraphBuilderInterface& graphBuilder)
class GraphBuilderInterface; {
GraphBuilderAdapter eventHandler(graphBuilder);
void* BuildGraphOfNextDocument(Parser& parser, if (parser.HandleNextDocument(eventHandler)) {
GraphBuilderInterface& graphBuilder) { return eventHandler.RootNode();
GraphBuilderAdapter eventHandler(graphBuilder); } else {
if (parser.HandleNextDocument(eventHandler)) { return NULL;
return eventHandler.RootNode(); }
} }
return nullptr;
} }
} // namespace YAML
+88 -86
View File
@@ -1,94 +1,96 @@
#include "graphbuilderadapter.h" #include "graphbuilderadapter.h"
#include "yaml-cpp/contrib/graphbuilder.h"
namespace YAML { namespace YAML
struct Mark; {
int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
void GraphBuilderAdapter::OnNull(const Mark& mark, anchor_t anchor)
void GraphBuilderAdapter::OnNull(const Mark &mark, anchor_t anchor) { {
void *pParent = GetCurrentParent(); void *pParent = GetCurrentParent();
void *pNode = m_builder.NewNull(mark, pParent); void *pNode = m_builder.NewNull(mark, pParent);
RegisterAnchor(anchor, pNode); RegisterAnchor(anchor, pNode);
DispositionNode(pNode); DispositionNode(pNode);
}
void GraphBuilderAdapter::OnAlias(const Mark &mark, anchor_t anchor) {
void *pReffedNode = m_anchors.Get(anchor);
DispositionNode(m_builder.AnchorReference(mark, pReffedNode));
}
void GraphBuilderAdapter::OnScalar(const Mark &mark, const std::string &tag,
anchor_t anchor, const std::string &value) {
void *pParent = GetCurrentParent();
void *pNode = m_builder.NewScalar(mark, tag, pParent, value);
RegisterAnchor(anchor, pNode);
DispositionNode(pNode);
}
void GraphBuilderAdapter::OnSequenceStart(const Mark &mark,
const std::string &tag,
anchor_t anchor,
EmitterStyle::value /* style */) {
void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent());
m_containers.push(ContainerFrame(pNode));
RegisterAnchor(anchor, pNode);
}
void GraphBuilderAdapter::OnSequenceEnd() {
void *pSequence = m_containers.top().pContainer;
m_containers.pop();
DispositionNode(pSequence);
}
void GraphBuilderAdapter::OnMapStart(const Mark &mark, const std::string &tag,
anchor_t anchor,
EmitterStyle::value /* style */) {
void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent());
m_containers.push(ContainerFrame(pNode, m_pKeyNode));
m_pKeyNode = nullptr;
RegisterAnchor(anchor, pNode);
}
void GraphBuilderAdapter::OnMapEnd() {
void *pMap = m_containers.top().pContainer;
m_pKeyNode = m_containers.top().pPrevKeyNode;
m_containers.pop();
DispositionNode(pMap);
}
void *GraphBuilderAdapter::GetCurrentParent() const {
if (m_containers.empty()) {
return nullptr;
} }
return m_containers.top().pContainer;
} void GraphBuilderAdapter::OnAlias(const Mark& mark, anchor_t anchor)
{
void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode) { void *pReffedNode = m_anchors.Get(anchor);
if (anchor) { DispositionNode(m_builder.AnchorReference(mark, pReffedNode));
m_anchors.Register(anchor, pNode);
} }
}
void GraphBuilderAdapter::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value)
void GraphBuilderAdapter::DispositionNode(void *pNode) { {
if (m_containers.empty()) { void *pParent = GetCurrentParent();
m_pRootNode = pNode; void *pNode = m_builder.NewScalar(mark, tag, pParent, value);
return; RegisterAnchor(anchor, pNode);
DispositionNode(pNode);
} }
void *pContainer = m_containers.top().pContainer; void GraphBuilderAdapter::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor)
if (m_containers.top().isMap()) { {
if (m_pKeyNode) { void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent());
m_builder.AssignInMap(pContainer, m_pKeyNode, pNode); m_containers.push(ContainerFrame(pNode));
m_pKeyNode = nullptr; RegisterAnchor(anchor, pNode);
} else { }
m_pKeyNode = pNode;
void GraphBuilderAdapter::OnSequenceEnd()
{
void *pSequence = m_containers.top().pContainer;
m_containers.pop();
DispositionNode(pSequence);
}
void GraphBuilderAdapter::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor)
{
void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent());
m_containers.push(ContainerFrame(pNode, m_pKeyNode));
m_pKeyNode = NULL;
RegisterAnchor(anchor, pNode);
}
void GraphBuilderAdapter::OnMapEnd()
{
void *pMap = m_containers.top().pContainer;
m_pKeyNode = m_containers.top().pPrevKeyNode;
m_containers.pop();
DispositionNode(pMap);
}
void *GraphBuilderAdapter::GetCurrentParent() const
{
if (m_containers.empty()) {
return NULL;
}
return m_containers.top().pContainer;
}
void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode)
{
if (anchor) {
m_anchors.Register(anchor, pNode);
}
}
void GraphBuilderAdapter::DispositionNode(void *pNode)
{
if (m_containers.empty()) {
m_pRootNode = pNode;
return;
}
void *pContainer = m_containers.top().pContainer;
if (m_containers.top().isMap()) {
if (m_pKeyNode) {
m_builder.AssignInMap(pContainer, m_pKeyNode, pNode);
m_pKeyNode = NULL;
} else {
m_pKeyNode = pNode;
}
} else {
m_builder.AppendToSequence(pContainer, pNode);
} }
} else {
m_builder.AppendToSequence(pContainer, pNode);
} }
} }
} // namespace YAML
+60 -73
View File
@@ -1,86 +1,73 @@
#ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cstdlib> #include <cstdlib>
#include <map> #include <map>
#include <stack> #include <stack>
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/contrib/anchordict.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h" #include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/contrib/anchordict.h"
#include "yaml-cpp/contrib/graphbuilder.h"
namespace YAML { namespace YAML
class GraphBuilderInterface; {
struct Mark; class GraphBuilderAdapter : public EventHandler
} // namespace YAML {
public:
namespace YAML { GraphBuilderAdapter(GraphBuilderInterface& builder)
class GraphBuilderAdapter : public EventHandler { : m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL)
public: {
GraphBuilderAdapter(GraphBuilderInterface& builder) }
: m_builder(builder),
m_containers{}, virtual void OnDocumentStart(const Mark& mark) {(void)mark;}
m_anchors{}, virtual void OnDocumentEnd() {}
m_pRootNode(nullptr),
m_pKeyNode(nullptr) {} virtual void OnNull(const Mark& mark, anchor_t anchor);
GraphBuilderAdapter(const GraphBuilderAdapter&) = delete; virtual void OnAlias(const Mark& mark, anchor_t anchor);
GraphBuilderAdapter(GraphBuilderAdapter&&) = delete; virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value);
GraphBuilderAdapter& operator=(const GraphBuilderAdapter&) = delete;
GraphBuilderAdapter& operator=(GraphBuilderAdapter&&) = delete; virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor);
virtual void OnSequenceEnd();
virtual void OnDocumentStart(const Mark& mark) { (void)mark; }
virtual void OnDocumentEnd() {} virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor);
virtual void OnMapEnd();
virtual void OnNull(const Mark& mark, anchor_t anchor);
virtual void OnAlias(const Mark& mark, anchor_t anchor); void *RootNode() const {return m_pRootNode;}
virtual void OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value); private:
struct ContainerFrame
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, {
anchor_t anchor, EmitterStyle::value style); ContainerFrame(void *pSequence)
virtual void OnSequenceEnd(); : pContainer(pSequence), pPrevKeyNode(&sequenceMarker)
{}
virtual void OnMapStart(const Mark& mark, const std::string& tag, ContainerFrame(void *pMap, void* pPrevKeyNode)
anchor_t anchor, EmitterStyle::value style); : pContainer(pMap), pPrevKeyNode(pPrevKeyNode)
virtual void OnMapEnd(); {}
void* RootNode() const { return m_pRootNode; } void *pContainer;
void *pPrevKeyNode;
private:
struct ContainerFrame { bool isMap() const {return pPrevKeyNode != &sequenceMarker;}
ContainerFrame(void* pSequence)
: pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {} private:
ContainerFrame(void* pMap, void* pPreviousKeyNode) static int sequenceMarker;
: pContainer(pMap), pPrevKeyNode(pPreviousKeyNode) {} };
typedef std::stack<ContainerFrame> ContainerStack;
void* pContainer; typedef AnchorDict<void*> AnchorMap;
void* pPrevKeyNode;
GraphBuilderInterface& m_builder;
bool isMap() const { return pPrevKeyNode != &sequenceMarker; } ContainerStack m_containers;
AnchorMap m_anchors;
private: void *m_pRootNode;
static int sequenceMarker; void *m_pKeyNode;
void *GetCurrentParent() const;
void RegisterAnchor(anchor_t anchor, void *pNode);
void DispositionNode(void *pNode);
}; };
typedef std::stack<ContainerFrame> ContainerStack; }
typedef AnchorDict<void*> AnchorMap;
GraphBuilderInterface& m_builder; #endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
ContainerStack m_containers;
AnchorMap m_anchors;
void* m_pRootNode;
void* m_pKeyNode;
void* GetCurrentParent() const;
void RegisterAnchor(anchor_t anchor, void* pNode);
void DispositionNode(void* pNode);
};
} // namespace YAML
#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-32
View File
@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- MSVC Debugger visualization hints for YAML::Node and YAML::detail::node -->
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="YAML::Node">
<DisplayString Condition="!m_isValid">{{invalid}}</DisplayString>
<DisplayString Condition="!m_pNode">{{pNode==nullptr}}</DisplayString>
<DisplayString>{{ {*m_pNode} }}</DisplayString>
<Expand>
<Item Condition="m_pNode->m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Scalar" Name="scalar">m_pNode->m_pRef._Ptr->m_pData._Ptr->m_scalar</Item>
<Item Condition="m_pNode->m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Sequence" Name="sequence">m_pNode->m_pRef._Ptr->m_pData._Ptr->m_sequence</Item>
<Item Condition="m_pNode->m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Map" Name="map">m_pNode->m_pRef._Ptr->m_pData._Ptr->m_map</Item>
<Item Name="[details]" >m_pNode->m_pRef._Ptr->m_pData._Ptr</Item>
</Expand>
</Type>
<Type Name="YAML::detail::node">
<DisplayString Condition="!m_pRef._Ptr">{{node:pRef==nullptr}}</DisplayString>
<DisplayString Condition="!m_pRef._Ptr->m_pData._Ptr">{{node:pRef->pData==nullptr}}</DisplayString>
<DisplayString Condition="!m_pRef._Ptr->m_pData._Ptr->m_isDefined">{{undefined}}</DisplayString>
<DisplayString Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Scalar">{{{m_pRef._Ptr->m_pData._Ptr->m_scalar}}}</DisplayString>
<DisplayString Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Map">{{ Map {m_pRef._Ptr->m_pData._Ptr->m_map}}}</DisplayString>
<DisplayString Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Sequence">{{ Seq {m_pRef._Ptr->m_pData._Ptr->m_sequence}}}</DisplayString>
<DisplayString>{{{m_pRef._Ptr->m_pData._Ptr->m_type}}}</DisplayString>
<Expand>
<Item Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Scalar" Name="scalar">m_pRef._Ptr->m_pData._Ptr->m_scalar</Item>
<Item Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Sequence" Name="sequence">m_pRef._Ptr->m_pData._Ptr->m_sequence</Item>
<Item Condition="m_pRef._Ptr->m_pData._Ptr->m_type==YAML::NodeType::Map" Name="map">m_pRef._Ptr->m_pData._Ptr->m_map</Item>
<Item Name="[details]" >m_pRef._Ptr->m_pData._Ptr</Item>
</Expand>
</Type>
</AutoVisualizer>
-9
View File
@@ -1,9 +0,0 @@
# MSVC debugger visualizer for YAML::Node
## How to use
Add yaml-cpp.natvis to your Visual C++ project like any other source file. It will be included in the debug information, and improve debugger display on YAML::Node and contained types.
## Compatibility and Troubleshooting
This has been tested for MSVC 2017. It is expected to be compatible with VS 2015 and VS 2019. If you have any problems, you can open an issue here: https://github.com/peterchen-cp/yaml-cpp-natvis
+78 -69
View File
@@ -1,74 +1,83 @@
#include "yaml-cpp/node/convert.h"
#include "yaml-cpp/node/impl.h"
#include <algorithm> #include <algorithm>
#include "yaml-cpp/node/convert.h" namespace
{
namespace { // we're not gonna mess with the mess that is all the isupper/etc. functions
// we're not gonna mess with the mess that is all the isupper/etc. functions bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; } bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; } char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
std::string tolower(const std::string& str)
std::string tolower(const std::string& str) { {
std::string s(str); std::string s(str);
std::transform(s.begin(), s.end(), s.begin(), ToLower); std::transform(s.begin(), s.end(), s.begin(), ToLower);
return s; return s;
}
template <typename T>
bool IsEntirely(const std::string& str, T func)
{
for(std::size_t i=0;i<str.size();i++)
if(!func(str[i]))
return false;
return true;
}
// IsFlexibleCase
// . Returns true if 'str' is:
// . UPPERCASE
// . lowercase
// . Capitalized
bool IsFlexibleCase(const std::string& str)
{
if(str.empty())
return true;
if(IsEntirely(str, IsLower))
return true;
bool firstcaps = IsUpper(str[0]);
std::string rest = str.substr(1);
return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
}
} }
template <typename T> namespace YAML
bool IsEntirely(const std::string& str, T func) { {
return std::all_of(str.begin(), str.end(), [=](char ch) { return func(ch); }); bool convert<bool>::decode(const Node& node, bool& rhs) {
if(!node.IsScalar())
return false;
// we can't use iostream bool extraction operators as they don't
// recognize all possible values in the table below (taken from
// http://yaml.org/type/bool.html)
static const struct {
std::string truename, falsename;
} names[] = {
{ "y", "n" },
{ "yes", "no" },
{ "true", "false" },
{ "on", "off" },
};
if(!IsFlexibleCase(node.Scalar()))
return false;
for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
if(names[i].truename == tolower(node.Scalar())) {
rhs = true;
return true;
}
if(names[i].falsename == tolower(node.Scalar())) {
rhs = false;
return true;
}
}
return false;
}
} }
// IsFlexibleCase
// . Returns true if 'str' is:
// . UPPERCASE
// . lowercase
// . Capitalized
bool IsFlexibleCase(const std::string& str) {
if (str.empty())
return true;
if (IsEntirely(str, IsLower))
return true;
bool firstcaps = IsUpper(str[0]);
std::string rest = str.substr(1);
return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
}
} // namespace
namespace YAML {
bool convert<bool>::decode(const Node& node, bool& rhs) {
if (!node.IsScalar())
return false;
// we can't use iostream bool extraction operators as they don't
// recognize all possible values in the table below (taken from
// http://yaml.org/type/bool.html)
static const struct {
std::string truename, falsename;
} names[] = {
{"y", "n"},
{"yes", "no"},
{"true", "false"},
{"on", "off"},
};
if (!IsFlexibleCase(node.Scalar()))
return false;
for (const auto& name : names) {
if (name.truename == tolower(node.Scalar())) {
rhs = true;
return true;
}
if (name.falsename == tolower(node.Scalar())) {
rhs = false;
return true;
}
}
return false;
}
} // namespace YAML
-9
View File
@@ -1,9 +0,0 @@
#include "yaml-cpp/depthguard.h"
namespace YAML {
DeepRecursion::DeepRecursion(int depth, const Mark& mark_,
const std::string& msg_)
: ParserException(mark_, msg_), m_depth(depth) {}
} // namespace YAML
+21 -14
View File
@@ -1,17 +1,24 @@
#include "directives.h" #include "directives.h"
namespace YAML { namespace YAML
Directives::Directives() : version{true, 1, 2}, tags{} {} {
Directives::Directives()
std::string Directives::TranslateTagHandle( {
const std::string& handle) const { // version
auto it = tags.find(handle); version.isDefault = true;
if (it == tags.end()) { version.major = 1;
if (handle == "!!") version.minor = 2;
return "tag:yaml.org,2002:"; }
return handle;
} const std::string Directives::TranslateTagHandle(const std::string& handle) const
{
return it->second; std::map <std::string, std::string>::const_iterator it = tags.find(handle);
if(it == tags.end()) {
if(handle == "!!")
return "tag:yaml.org,2002:";
return handle;
}
return it->second;
}
} }
} // namespace YAML
+17 -17
View File
@@ -1,29 +1,29 @@
#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <map> #include <map>
namespace YAML { namespace YAML
struct Version { {
bool isDefault; struct Version {
int major, minor; bool isDefault;
}; int major, minor;
};
struct Directives {
Directives();
const std::string TranslateTagHandle(const std::string& handle) const;
struct Directives { Version version;
Directives(); std::map<std::string, std::string> tags;
};
std::string TranslateTagHandle(const std::string& handle) const;
Version version;
std::map<std::string, std::string> tags;
};
} }
#endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+24 -19
View File
@@ -1,25 +1,30 @@
#include "yaml-cpp/node/emit.h" #include "yaml-cpp/node/emit.h"
#include "nodeevents.h"
#include "yaml-cpp/emitfromevents.h" #include "yaml-cpp/emitfromevents.h"
#include "yaml-cpp/emitter.h" #include "yaml-cpp/emitter.h"
#include "nodeevents.h"
namespace YAML { namespace YAML
Emitter& operator<<(Emitter& out, const Node& node) { {
EmitFromEvents emitFromEvents(out); Emitter& operator << (Emitter& out, const Node& node)
NodeEvents events(node); {
events.Emit(emitFromEvents); EmitFromEvents emitFromEvents(out);
return out; NodeEvents events(node);
} events.Emit(emitFromEvents);
return out;
}
std::ostream& operator << (std::ostream& out, const Node& node)
{
Emitter emitter;
emitter << node;
out << emitter.c_str();
return out;
}
std::ostream& operator<<(std::ostream& out, const Node& node) { std::string Dump(const Node& node)
Emitter emitter(out); {
emitter << node; Emitter emitter;
return out; emitter << node;
return emitter.c_str();
}
} }
std::string Dump(const Node& node) {
Emitter emitter;
emitter << node;
return emitter.c_str();
}
} // namespace YAML
+96 -120
View File
@@ -1,129 +1,105 @@
#include "yaml-cpp/emitfromevents.h"
#include "yaml-cpp/emitter.h"
#include "yaml-cpp/null.h"
#include <cassert> #include <cassert>
#include <sstream> #include <sstream>
#include "yaml-cpp/emitfromevents.h"
#include "yaml-cpp/emitter.h"
#include "yaml-cpp/emittermanip.h"
#include "yaml-cpp/null.h"
namespace YAML {
struct Mark;
} // namespace YAML
namespace { namespace {
std::string ToString(YAML::anchor_t anchor) { std::string ToString(YAML::anchor_t anchor) {
std::stringstream stream; std::stringstream stream;
stream << anchor; stream << anchor;
return stream.str(); return stream.str();
} }
} // namespace
namespace YAML {
EmitFromEvents::EmitFromEvents(Emitter& emitter)
: m_emitter(emitter), m_stateStack{} {}
void EmitFromEvents::OnDocumentStart(const Mark&) {}
void EmitFromEvents::OnDocumentEnd() {}
void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) {
BeginNode();
EmitProps("", anchor);
m_emitter << Null;
} }
void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) { namespace YAML
BeginNode(); {
m_emitter << Alias(ToString(anchor)); EmitFromEvents::EmitFromEvents(Emitter& emitter): m_emitter(emitter)
} {
}
void EmitFromEvents::OnDocumentStart(const Mark&)
{
}
void EmitFromEvents::OnDocumentEnd()
{
}
void EmitFromEvents::OnNull(const Mark&, anchor_t anchor)
{
BeginNode();
EmitProps("", anchor);
m_emitter << Null;
}
void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor)
{
BeginNode();
m_emitter << Alias(ToString(anchor));
}
void EmitFromEvents::OnScalar(const Mark&, const std::string& tag, anchor_t anchor, const std::string& value)
{
BeginNode();
EmitProps(tag, anchor);
m_emitter << value;
}
void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag, anchor_t anchor)
{
BeginNode();
EmitProps(tag, anchor);
m_emitter << BeginSeq;
m_stateStack.push(State::WaitingForSequenceEntry);
}
void EmitFromEvents::OnSequenceEnd()
{
m_emitter << EndSeq;
assert(m_stateStack.top() == State::WaitingForSequenceEntry);
m_stateStack.pop();
}
void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag, anchor_t anchor)
{
BeginNode();
EmitProps(tag, anchor);
m_emitter << BeginMap;
m_stateStack.push(State::WaitingForKey);
}
void EmitFromEvents::OnScalar(const Mark&, const std::string& tag, void EmitFromEvents::OnMapEnd()
anchor_t anchor, const std::string& value) { {
BeginNode(); m_emitter << EndMap;
EmitProps(tag, anchor); assert(m_stateStack.top() == State::WaitingForKey);
m_emitter << value; m_stateStack.pop();
} }
void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag, void EmitFromEvents::BeginNode()
anchor_t anchor, {
EmitterStyle::value style) { if(m_stateStack.empty())
BeginNode(); return;
EmitProps(tag, anchor);
switch (style) { switch(m_stateStack.top()) {
case EmitterStyle::Block: case State::WaitingForKey:
m_emitter << Block; m_emitter << Key;
break; m_stateStack.top() = State::WaitingForValue;
case EmitterStyle::Flow: break;
m_emitter << Flow; case State::WaitingForValue:
break; m_emitter << Value;
default: m_stateStack.top() = State::WaitingForKey;
break; break;
} default:
// Restore the global settings to eliminate the override from node style break;
m_emitter.RestoreGlobalModifiedSettings(); }
m_emitter << BeginSeq; }
m_stateStack.push(State::WaitingForSequenceEntry);
void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor)
{
if(!tag.empty() && tag != "?")
m_emitter << VerbatimTag(tag);
if(anchor)
m_emitter << Anchor(ToString(anchor));
}
} }
void EmitFromEvents::OnSequenceEnd() {
m_emitter << EndSeq;
assert(m_stateStack.top() == State::WaitingForSequenceEntry);
m_stateStack.pop();
}
void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) {
BeginNode();
EmitProps(tag, anchor);
switch (style) {
case EmitterStyle::Block:
m_emitter << Block;
break;
case EmitterStyle::Flow:
m_emitter << Flow;
break;
default:
break;
}
// Restore the global settings to eliminate the override from node style
m_emitter.RestoreGlobalModifiedSettings();
m_emitter << BeginMap;
m_stateStack.push(State::WaitingForKey);
}
void EmitFromEvents::OnMapEnd() {
m_emitter << EndMap;
assert(m_stateStack.top() == State::WaitingForKey);
m_stateStack.pop();
}
void EmitFromEvents::BeginNode() {
if (m_stateStack.empty())
return;
switch (m_stateStack.top()) {
case State::WaitingForKey:
m_emitter << Key;
m_stateStack.top() = State::WaitingForValue;
break;
case State::WaitingForValue:
m_emitter << Value;
m_stateStack.top() = State::WaitingForKey;
break;
default:
break;
}
}
void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) {
if (!tag.empty() && tag != "?" && tag != "!"){
if (tag[0] == '!') {
m_emitter << LocalTag(std::string(tag.begin()+1, tag.end()));
} else {
m_emitter << VerbatimTag(tag);
}
}
if (anchor)
m_emitter << Anchor(ToString(anchor));
}
} // namespace YAML
+853 -948
View File
File diff suppressed because it is too large Load Diff
+266 -382
View File
@@ -1,400 +1,284 @@
#include "emitterstate.h"
#include "yaml-cpp/exceptions.h"
#include <limits> #include <limits>
#include "emitterstate.h" namespace YAML
#include "yaml-cpp/exceptions.h" // IWYU pragma: keep {
EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSoftSeparation(false), m_requiresHardSeparation(false)
{
// start up
m_stateStack.push(ES_WAITING_FOR_DOC);
// set default global manipulators
m_charset.set(EmitNonAscii);
m_strFmt.set(Auto);
m_boolFmt.set(TrueFalseBool);
m_boolLengthFmt.set(LongBool);
m_boolCaseFmt.set(LowerCase);
m_intFmt.set(Dec);
m_indent.set(2);
m_preCommentIndent.set(2);
m_postCommentIndent.set(1);
m_seqFmt.set(Block);
m_mapFmt.set(Block);
m_mapKeyFmt.set(Auto);
m_floatPrecision.set(6);
m_doublePrecision.set(15);
}
EmitterState::~EmitterState()
{
}
namespace YAML { // SetLocalValue
EmitterState::EmitterState() // . We blindly tries to set all possible formatters to this value
: m_isGood(true), // . Only the ones that make sense will be accepted
m_lastError{}, void EmitterState::SetLocalValue(EMITTER_MANIP value)
// default global manipulators {
m_charset(EmitNonAscii), SetOutputCharset(value, LOCAL);
m_strFmt(Auto), SetStringFormat(value, LOCAL);
m_boolFmt(TrueFalseBool), SetBoolFormat(value, LOCAL);
m_boolLengthFmt(LongBool), SetBoolCaseFormat(value, LOCAL);
m_boolCaseFmt(LowerCase), SetBoolLengthFormat(value, LOCAL);
m_nullFmt(TildeNull), SetIntFormat(value, LOCAL);
m_intFmt(Dec), SetFlowType(GT_SEQ, value, LOCAL);
m_indent(2), SetFlowType(GT_MAP, value, LOCAL);
m_preCommentIndent(2), SetMapKeyFormat(value, LOCAL);
m_postCommentIndent(1), }
m_seqFmt(Block),
m_mapFmt(Block), void EmitterState::BeginGroup(GROUP_TYPE type)
m_mapKeyFmt(Auto), {
m_floatPrecision(std::numeric_limits<float>::max_digits10), unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
m_doublePrecision(std::numeric_limits<double>::max_digits10), m_curIndent += lastIndent;
//
m_modifiedSettings{}, std::auto_ptr<Group> pGroup(new Group(type));
m_globalModifiedSettings{},
m_groups{}, // transfer settings (which last until this group is done)
m_curIndent(0), pGroup->modifiedSettings = m_modifiedSettings;
m_hasAnchor(false),
m_hasAlias(false),
m_hasTag(false),
m_hasNonContent(false),
m_docCount(0) {}
EmitterState::~EmitterState() = default; // set up group
pGroup->flow = GetFlowType(type);
pGroup->indent = GetIndent();
pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false);
// SetLocalValue m_groups.push(pGroup);
// . We blindly tries to set all possible formatters to this value }
// . Only the ones that make sense will be accepted
void EmitterState::SetLocalValue(EMITTER_MANIP value) { void EmitterState::EndGroup(GROUP_TYPE type)
SetOutputCharset(value, FmtScope::Local); {
SetStringFormat(value, FmtScope::Local); if(m_groups.empty())
SetBoolFormat(value, FmtScope::Local); return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
SetBoolCaseFormat(value, FmtScope::Local);
SetBoolLengthFormat(value, FmtScope::Local); // get rid of the current group
SetNullFormat(value, FmtScope::Local); {
SetIntFormat(value, FmtScope::Local); std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
SetFlowType(GroupType::Seq, value, FmtScope::Local); if(pFinishedGroup->type != type)
SetFlowType(GroupType::Map, value, FmtScope::Local); return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
SetMapKeyFormat(value, FmtScope::Local); }
}
void EmitterState::SetAnchor() { m_hasAnchor = true; } // reset old settings
unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
assert(m_curIndent >= lastIndent);
m_curIndent -= lastIndent;
// some global settings that we changed may have been overridden
// by a local setting we just popped, so we need to restore them
m_globalModifiedSettings.restore();
}
GROUP_TYPE EmitterState::GetCurGroupType() const
{
if(m_groups.empty())
return GT_NONE;
return m_groups.top().type;
}
FLOW_TYPE EmitterState::GetCurGroupFlowType() const
{
if(m_groups.empty())
return FT_NONE;
return (m_groups.top().flow == Flow ? FT_FLOW : FT_BLOCK);
}
bool EmitterState::CurrentlyInLongKey()
{
if(m_groups.empty())
return false;
return m_groups.top().usingLongKey;
}
void EmitterState::StartLongKey()
{
if(!m_groups.empty())
m_groups.top().usingLongKey = true;
}
void EmitterState::StartSimpleKey()
{
if(!m_groups.empty())
m_groups.top().usingLongKey = false;
}
void EmitterState::SetAlias() { m_hasAlias = true; } void EmitterState::ClearModifiedSettings()
{
m_modifiedSettings.clear();
}
void EmitterState::SetTag() { m_hasTag = true; } bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FMT_SCOPE scope)
{
switch(value) {
case EmitNonAscii:
case EscapeNonAscii:
_Set(m_charset, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope)
{
switch(value) {
case Auto:
case SingleQuoted:
case DoubleQuoted:
case Literal:
_Set(m_strFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope)
{
switch(value) {
case OnOffBool:
case TrueFalseBool:
case YesNoBool:
_Set(m_boolFmt, value, scope);
return true;
default:
return false;
}
}
void EmitterState::SetNonContent() { m_hasNonContent = true; } bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope)
{
switch(value) {
case LongBool:
case ShortBool:
_Set(m_boolLengthFmt, value, scope);
return true;
default:
return false;
}
}
void EmitterState::SetLongKey() { bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope)
assert(!m_groups.empty()); {
if (m_groups.empty()) { switch(value) {
return; case UpperCase:
} case LowerCase:
case CamelCase:
_Set(m_boolCaseFmt, value, scope);
return true;
default:
return false;
}
}
assert(m_groups.back()->type == GroupType::Map); bool EmitterState::SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope)
m_groups.back()->longKey = true; {
} switch(value) {
case Dec:
case Hex:
case Oct:
_Set(m_intFmt, value, scope);
return true;
default:
return false;
}
}
void EmitterState::ForceFlow() { bool EmitterState::SetIndent(unsigned value, FMT_SCOPE scope)
assert(!m_groups.empty()); {
if (m_groups.empty()) { if(value == 0)
return; return false;
}
_Set(m_indent, value, scope);
return true;
}
m_groups.back()->flowType = FlowType::Flow; bool EmitterState::SetPreCommentIndent(unsigned value, FMT_SCOPE scope)
} {
if(value == 0)
return false;
_Set(m_preCommentIndent, value, scope);
return true;
}
bool EmitterState::SetPostCommentIndent(unsigned value, FMT_SCOPE scope)
{
if(value == 0)
return false;
_Set(m_postCommentIndent, value, scope);
return true;
}
void EmitterState::StartedNode() { bool EmitterState::SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope)
if (m_groups.empty()) { {
m_docCount++; switch(value) {
} else { case Block:
m_groups.back()->childCount++; case Flow:
if (m_groups.back()->childCount % 2 == 0) { _Set(groupType == GT_SEQ ? m_seqFmt : m_mapFmt, value, scope);
m_groups.back()->longKey = false; return true;
default:
return false;
}
}
EMITTER_MANIP EmitterState::GetFlowType(GROUP_TYPE groupType) const
{
// force flow style if we're currently in a flow
FLOW_TYPE flowType = GetCurGroupFlowType();
if(flowType == FT_FLOW)
return Flow;
// otherwise, go with what's asked of use
return (groupType == GT_SEQ ? m_seqFmt.get() : m_mapFmt.get());
}
bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope)
{
switch(value) {
case Auto:
case LongKey:
_Set(m_mapKeyFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetFloatPrecision(int value, FMT_SCOPE scope)
{
if(value < 0 || value > std::numeric_limits<float>::digits10)
return false;
_Set(m_floatPrecision, value, scope);
return true;
} }
}
bool EmitterState::SetDoublePrecision(int value, FMT_SCOPE scope)
m_hasAnchor = false; {
m_hasAlias = false; if(value < 0 || value > std::numeric_limits<double>::digits10)
m_hasTag = false; return false;
m_hasNonContent = false; _Set(m_doublePrecision, value, scope);
} return true;
EmitterNodeType::value EmitterState::NextGroupType(
GroupType::value type) const {
if (type == GroupType::Seq) {
if (GetFlowType(type) == Block)
return EmitterNodeType::BlockSeq;
return EmitterNodeType::FlowSeq;
}
if (GetFlowType(type) == Block)
return EmitterNodeType::BlockMap;
return EmitterNodeType::FlowMap;
// can't happen
assert(false);
return EmitterNodeType::NoType;
}
void EmitterState::StartedDoc() {
m_hasAnchor = false;
m_hasTag = false;
m_hasNonContent = false;
}
void EmitterState::EndedDoc() {
m_hasAnchor = false;
m_hasTag = false;
m_hasNonContent = false;
}
void EmitterState::StartedScalar() {
StartedNode();
ClearModifiedSettings();
}
void EmitterState::StartedGroup(GroupType::value type) {
StartedNode();
const std::size_t lastGroupIndent =
(m_groups.empty() ? 0 : m_groups.back()->indent);
m_curIndent += lastGroupIndent;
// TODO: Create move constructors for settings types to simplify transfer
std::unique_ptr<Group> pGroup(new Group(type));
// transfer settings (which last until this group is done)
//
// NB: if pGroup->modifiedSettings == m_modifiedSettings,
// m_modifiedSettings is not changed!
pGroup->modifiedSettings = std::move(m_modifiedSettings);
// set up group
if (GetFlowType(type) == Block) {
pGroup->flowType = FlowType::Block;
} else {
pGroup->flowType = FlowType::Flow;
}
pGroup->indent = GetIndent();
m_groups.push_back(std::move(pGroup));
}
void EmitterState::EndedGroup(GroupType::value type) {
if (m_groups.empty()) {
if (type == GroupType::Seq) {
return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
} }
return SetError(ErrorMsg::UNEXPECTED_END_MAP);
}
if (m_hasTag) {
SetError(ErrorMsg::INVALID_TAG);
}
if (m_hasAnchor) {
SetError(ErrorMsg::INVALID_ANCHOR);
}
// get rid of the current group
{
std::unique_ptr<Group> pFinishedGroup = std::move(m_groups.back());
m_groups.pop_back();
if (pFinishedGroup->type != type) {
return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
}
}
// reset old settings
std::size_t lastIndent = (m_groups.empty() ? 0 : m_groups.back()->indent);
assert(m_curIndent >= lastIndent);
m_curIndent -= lastIndent;
// some global settings that we changed may have been overridden
// by a local setting we just popped, so we need to restore them
m_globalModifiedSettings.restore();
ClearModifiedSettings();
m_hasAnchor = false;
m_hasTag = false;
m_hasNonContent = false;
} }
EmitterNodeType::value EmitterState::CurGroupNodeType() const {
if (m_groups.empty()) {
return EmitterNodeType::NoType;
}
return m_groups.back()->NodeType();
}
GroupType::value EmitterState::CurGroupType() const {
return m_groups.empty() ? GroupType::NoType : m_groups.back()->type;
}
FlowType::value EmitterState::CurGroupFlowType() const {
return m_groups.empty() ? FlowType::NoType : m_groups.back()->flowType;
}
std::size_t EmitterState::CurGroupIndent() const {
return m_groups.empty() ? 0 : m_groups.back()->indent;
}
std::size_t EmitterState::CurGroupChildCount() const {
return m_groups.empty() ? m_docCount : m_groups.back()->childCount;
}
bool EmitterState::CurGroupLongKey() const {
return m_groups.empty() ? false : m_groups.back()->longKey;
}
std::size_t EmitterState::LastIndent() const {
if (m_groups.size() <= 1) {
return 0;
}
return m_curIndent - m_groups[m_groups.size() - 2]->indent;
}
void EmitterState::ClearModifiedSettings() { m_modifiedSettings.clear(); }
void EmitterState::RestoreGlobalModifiedSettings() {
m_globalModifiedSettings.restore();
}
bool EmitterState::SetOutputCharset(EMITTER_MANIP value,
FmtScope::value scope) {
switch (value) {
case EmitNonAscii:
case EscapeNonAscii:
case EscapeAsJson:
_Set(m_charset, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) {
switch (value) {
case Auto:
case SingleQuoted:
case DoubleQuoted:
case Literal:
_Set(m_strFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) {
switch (value) {
case OnOffBool:
case TrueFalseBool:
case YesNoBool:
_Set(m_boolFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value,
FmtScope::value scope) {
switch (value) {
case LongBool:
case ShortBool:
_Set(m_boolLengthFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value,
FmtScope::value scope) {
switch (value) {
case UpperCase:
case LowerCase:
case CamelCase:
_Set(m_boolCaseFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetNullFormat(EMITTER_MANIP value, FmtScope::value scope) {
switch (value) {
case LowerNull:
case UpperNull:
case CamelNull:
case TildeNull:
_Set(m_nullFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) {
switch (value) {
case Dec:
case Hex:
case Oct:
_Set(m_intFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetIndent(std::size_t value, FmtScope::value scope) {
if (value <= 1)
return false;
_Set(m_indent, value, scope);
return true;
}
bool EmitterState::SetPreCommentIndent(std::size_t value,
FmtScope::value scope) {
if (value == 0)
return false;
_Set(m_preCommentIndent, value, scope);
return true;
}
bool EmitterState::SetPostCommentIndent(std::size_t value,
FmtScope::value scope) {
if (value == 0)
return false;
_Set(m_postCommentIndent, value, scope);
return true;
}
bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
FmtScope::value scope) {
switch (value) {
case Block:
case Flow:
_Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
return true;
default:
return false;
}
}
EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const {
// force flow style if we're currently in a flow
if (CurGroupFlowType() == FlowType::Flow)
return Flow;
// otherwise, go with what's asked of us
return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
}
bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) {
switch (value) {
case Auto:
case LongKey:
_Set(m_mapKeyFmt, value, scope);
return true;
default:
return false;
}
}
bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) {
if (value > std::numeric_limits<float>::max_digits10)
return false;
_Set(m_floatPrecision, value, scope);
return true;
}
bool EmitterState::SetDoublePrecision(std::size_t value,
FmtScope::value scope) {
if (value > std::numeric_limits<double>::max_digits10)
return false;
_Set(m_doublePrecision, value, scope);
return true;
}
} // namespace YAML
+194 -193
View File
@@ -1,216 +1,217 @@
#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "ptr_stack.h"
#include "setting.h" #include "setting.h"
#include "yaml-cpp/emitterdef.h"
#include "yaml-cpp/emittermanip.h" #include "yaml-cpp/emittermanip.h"
#include <cassert> #include <cassert>
#include <memory>
#include <stack>
#include <stdexcept>
#include <vector> #include <vector>
#include <stack>
#include <memory>
namespace YAML { namespace YAML
struct FmtScope { {
enum value { Local, Global }; enum FMT_SCOPE {
}; LOCAL,
struct GroupType { GLOBAL
enum value { NoType, Seq, Map }; };
};
struct FlowType { enum GROUP_TYPE {
enum value { NoType, Flow, Block }; GT_NONE,
}; GT_SEQ,
GT_MAP
};
enum FLOW_TYPE {
FT_NONE,
FT_FLOW,
FT_BLOCK
};
enum NODE_STATE {
NS_START,
NS_READY_FOR_ATOM,
NS_END
};
enum EMITTER_STATE {
ES_WAITING_FOR_DOC,
ES_WRITING_DOC,
ES_DONE_WITH_DOC,
// block seq
ES_WAITING_FOR_BLOCK_SEQ_ENTRY,
ES_WRITING_BLOCK_SEQ_ENTRY,
ES_DONE_WITH_BLOCK_SEQ_ENTRY,
// flow seq
ES_WAITING_FOR_FLOW_SEQ_ENTRY,
ES_WRITING_FLOW_SEQ_ENTRY,
ES_DONE_WITH_FLOW_SEQ_ENTRY,
// block map
ES_WAITING_FOR_BLOCK_MAP_ENTRY,
ES_WAITING_FOR_BLOCK_MAP_KEY,
ES_WRITING_BLOCK_MAP_KEY,
ES_DONE_WITH_BLOCK_MAP_KEY,
ES_WAITING_FOR_BLOCK_MAP_VALUE,
ES_WRITING_BLOCK_MAP_VALUE,
ES_DONE_WITH_BLOCK_MAP_VALUE,
// flow map
ES_WAITING_FOR_FLOW_MAP_ENTRY,
ES_WAITING_FOR_FLOW_MAP_KEY,
ES_WRITING_FLOW_MAP_KEY,
ES_DONE_WITH_FLOW_MAP_KEY,
ES_WAITING_FOR_FLOW_MAP_VALUE,
ES_WRITING_FLOW_MAP_VALUE,
ES_DONE_WITH_FLOW_MAP_VALUE
};
class EmitterState
{
public:
EmitterState();
~EmitterState();
// basic state checking
bool good() const { return m_isGood; }
const std::string GetLastError() const { return m_lastError; }
void SetError(const std::string& error) { m_isGood = false; m_lastError = error; }
// main state of the machine
EMITTER_STATE GetCurState() const { return m_stateStack.top(); }
void SwitchState(EMITTER_STATE state) { PopState(); PushState(state); }
void PushState(EMITTER_STATE state) { m_stateStack.push(state); }
void PopState() { m_stateStack.pop(); }
void SetLocalValue(EMITTER_MANIP value);
// group handling
void BeginGroup(GROUP_TYPE type);
void EndGroup(GROUP_TYPE type);
GROUP_TYPE GetCurGroupType() const;
FLOW_TYPE GetCurGroupFlowType() const;
int GetCurIndent() const { return m_curIndent; }
bool CurrentlyInLongKey();
void StartLongKey();
void StartSimpleKey();
class EmitterState { bool RequiresSoftSeparation() const { return m_requiresSoftSeparation; }
public: bool RequiresHardSeparation() const { return m_requiresHardSeparation; }
EmitterState(); void RequireSoftSeparation() { m_requiresSoftSeparation = true; }
~EmitterState(); void RequireHardSeparation() { m_requiresSoftSeparation = true; m_requiresHardSeparation = true; }
void ForceHardSeparation() { m_requiresSoftSeparation = false; }
void UnsetSeparation() { m_requiresSoftSeparation = false; m_requiresHardSeparation = false; }
// basic state checking void ClearModifiedSettings();
bool good() const { return m_isGood; }
const std::string GetLastError() const { return m_lastError; }
void SetError(const std::string& error) {
m_isGood = false;
m_lastError = error;
}
// node handling // formatters
void SetAnchor(); bool SetOutputCharset(EMITTER_MANIP value, FMT_SCOPE scope);
void SetAlias(); EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
void SetTag();
void SetNonContent();
void SetLongKey();
void ForceFlow();
void StartedDoc();
void EndedDoc();
void StartedScalar();
void StartedGroup(GroupType::value type);
void EndedGroup(GroupType::value type);
EmitterNodeType::value NextGroupType(GroupType::value type) const; bool SetStringFormat(EMITTER_MANIP value, FMT_SCOPE scope);
EmitterNodeType::value CurGroupNodeType() const; EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
bool SetBoolFormat(EMITTER_MANIP value, FMT_SCOPE scope);
EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
GroupType::value CurGroupType() const; bool SetBoolLengthFormat(EMITTER_MANIP value, FMT_SCOPE scope);
FlowType::value CurGroupFlowType() const; EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
std::size_t CurGroupIndent() const;
std::size_t CurGroupChildCount() const;
bool CurGroupLongKey() const;
std::size_t LastIndent() const; bool SetBoolCaseFormat(EMITTER_MANIP value, FMT_SCOPE scope);
std::size_t CurIndent() const { return m_curIndent; } EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
bool HasAnchor() const { return m_hasAnchor; }
bool HasAlias() const { return m_hasAlias; }
bool HasTag() const { return m_hasTag; }
bool HasBegunNode() const {
return m_hasAnchor || m_hasTag || m_hasNonContent;
}
bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
void ClearModifiedSettings(); bool SetIntFormat(EMITTER_MANIP value, FMT_SCOPE scope);
void RestoreGlobalModifiedSettings(); EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
// formatters bool SetIndent(unsigned value, FMT_SCOPE scope);
void SetLocalValue(EMITTER_MANIP value); int GetIndent() const { return m_indent.get(); }
bool SetPreCommentIndent(unsigned value, FMT_SCOPE scope);
int GetPreCommentIndent() const { return m_preCommentIndent.get(); }
bool SetPostCommentIndent(unsigned value, FMT_SCOPE scope);
int GetPostCommentIndent() const { return m_postCommentIndent.get(); }
bool SetFlowType(GROUP_TYPE groupType, EMITTER_MANIP value, FMT_SCOPE scope);
EMITTER_MANIP GetFlowType(GROUP_TYPE groupType) const;
bool SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope);
EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
bool SetFloatPrecision(int value, FMT_SCOPE scope);
unsigned GetFloatPrecision() const { return m_floatPrecision.get(); }
bool SetDoublePrecision(int value, FMT_SCOPE scope);
unsigned GetDoublePrecision() const { return m_doublePrecision.get(); }
private:
template <typename T>
void _Set(Setting<T>& fmt, T value, FMT_SCOPE scope);
private:
// basic state ok?
bool m_isGood;
std::string m_lastError;
// other state
std::stack<EMITTER_STATE> m_stateStack;
Setting<EMITTER_MANIP> m_charset;
Setting<EMITTER_MANIP> m_strFmt;
Setting<EMITTER_MANIP> m_boolFmt;
Setting<EMITTER_MANIP> m_boolLengthFmt;
Setting<EMITTER_MANIP> m_boolCaseFmt;
Setting<EMITTER_MANIP> m_intFmt;
Setting<unsigned> m_indent;
Setting<unsigned> m_preCommentIndent, m_postCommentIndent;
Setting<EMITTER_MANIP> m_seqFmt;
Setting<EMITTER_MANIP> m_mapFmt;
Setting<EMITTER_MANIP> m_mapKeyFmt;
Setting<int> m_floatPrecision;
Setting<int> m_doublePrecision;
SettingChanges m_modifiedSettings;
SettingChanges m_globalModifiedSettings;
struct Group {
Group(GROUP_TYPE type_): type(type_), usingLongKey(false), indent(0) {}
GROUP_TYPE type;
EMITTER_MANIP flow;
bool usingLongKey;
int indent;
SettingChanges modifiedSettings;
};
bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope); ptr_stack<Group> m_groups;
EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); } unsigned m_curIndent;
bool m_requiresSoftSeparation;
bool m_requiresHardSeparation;
};
bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope); template <typename T>
EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); } void EmitterState::_Set(Setting<T>& fmt, T value, FMT_SCOPE scope) {
switch(scope) {
bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope); case LOCAL:
EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); } m_modifiedSettings.push(fmt.set(value));
break;
bool SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope); case GLOBAL:
EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); } fmt.set(value);
m_globalModifiedSettings.push(fmt.set(value)); // this pushes an identity set, so when we restore,
bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope); // it restores to the value here, and not the previous one
EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); } break;
default:
bool SetNullFormat(EMITTER_MANIP value, FmtScope::value scope); assert(false);
EMITTER_MANIP GetNullFormat() const { return m_nullFmt.get(); } }
}
bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
bool SetIndent(std::size_t value, FmtScope::value scope);
std::size_t GetIndent() const { return m_indent.get(); }
bool SetPreCommentIndent(std::size_t value, FmtScope::value scope);
std::size_t GetPreCommentIndent() const { return m_preCommentIndent.get(); }
bool SetPostCommentIndent(std::size_t value, FmtScope::value scope);
std::size_t GetPostCommentIndent() const { return m_postCommentIndent.get(); }
bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
FmtScope::value scope);
EMITTER_MANIP GetFlowType(GroupType::value groupType) const;
bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope);
EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
bool SetFloatPrecision(std::size_t value, FmtScope::value scope);
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(); }
private:
template <typename T>
void _Set(Setting<T>& fmt, T value, FmtScope::value scope);
void StartedNode();
private:
// basic state ok?
bool m_isGood;
std::string m_lastError;
// other state
Setting<EMITTER_MANIP> m_charset;
Setting<EMITTER_MANIP> m_strFmt;
Setting<EMITTER_MANIP> m_boolFmt;
Setting<EMITTER_MANIP> m_boolLengthFmt;
Setting<EMITTER_MANIP> m_boolCaseFmt;
Setting<EMITTER_MANIP> m_nullFmt;
Setting<EMITTER_MANIP> m_intFmt;
Setting<std::size_t> m_indent;
Setting<std::size_t> m_preCommentIndent, m_postCommentIndent;
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;
SettingChanges m_modifiedSettings;
SettingChanges m_globalModifiedSettings;
struct Group {
explicit Group(GroupType::value type_)
: type(type_),
flowType{},
indent(0),
childCount(0),
longKey(false),
modifiedSettings{} {}
GroupType::value type;
FlowType::value flowType;
std::size_t indent;
std::size_t childCount;
bool longKey;
SettingChanges modifiedSettings;
EmitterNodeType::value NodeType() const {
if (type == GroupType::Seq) {
if (flowType == FlowType::Flow)
return EmitterNodeType::FlowSeq;
else
return EmitterNodeType::BlockSeq;
} else {
if (flowType == FlowType::Flow)
return EmitterNodeType::FlowMap;
else
return EmitterNodeType::BlockMap;
}
// can't get here
assert(false);
return EmitterNodeType::NoType;
}
};
std::vector<std::unique_ptr<Group>> m_groups;
std::size_t m_curIndent;
bool m_hasAnchor;
bool m_hasAlias;
bool m_hasTag;
bool m_hasNonContent;
std::size_t m_docCount;
};
template <typename T>
void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
switch (scope) {
case FmtScope::Local:
m_modifiedSettings.push(fmt.set(value));
break;
case FmtScope::Global:
fmt.set(value);
m_globalModifiedSettings.push(
fmt.set(value)); // this pushes an identity set, so when we restore,
// it restores to the value here, and not the previous one
break;
default:
assert(false);
}
} }
} // namespace YAML
#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+366 -487
View File
@@ -1,499 +1,378 @@
#include <algorithm>
#include <cstdint>
#include <iomanip>
#include <sstream>
#include "emitterutils.h" #include "emitterutils.h"
#include "exp.h" #include "exp.h"
#include "indentation.h" #include "indentation.h"
#include "regex_yaml.h" #include "yaml-cpp/binary.h"
#include "regeximpl.h" #include "yaml-cpp/exceptions.h"
#include "stringsource.h" #include "stringsource.h"
#include "yaml-cpp/binary.h" // IWYU pragma: keep #include <sstream>
#include "yaml-cpp/null.h" #include <iomanip>
#include "yaml-cpp/ostream_wrapper.h"
namespace YAML { namespace YAML
namespace Utils { {
namespace { namespace Utils
enum { REPLACEMENT_CHARACTER = 0xFFFD }; {
namespace {
enum {REPLACEMENT_CHARACTER = 0xFFFD};
bool IsAnchorChar(int ch) { // test for ns-anchor-char bool IsAnchorChar(int ch) { // test for ns-anchor-char
switch (ch) { switch (ch) {
case ',': case ',': case '[': case ']': case '{': case '}': // c-flow-indicator
case '[': case ' ': case '\t': // s-white
case ']': case 0xFEFF: // c-byte-order-mark
case '{': case 0xA: case 0xD: // b-char
case '}': // c-flow-indicator return false;
case ' ': case 0x85:
case '\t': // s-white return true;
case 0xFEFF: // c-byte-order-mark }
case 0xA:
case 0xD: // b-char
return false;
case 0x85:
return true;
}
if (ch < 0x20) { if (ch < 0x20)
return false; return false;
}
if (ch < 0x7E) { if (ch < 0x7E)
return true; return true;
}
if (ch < 0xA0) { if (ch < 0xA0)
return false; return false;
} if (ch >= 0xD800 && ch <= 0xDFFF)
if (ch >= 0xD800 && ch <= 0xDFFF) { return false;
return false; if ((ch & 0xFFFE) == 0xFFFE)
} return false;
if ((ch & 0xFFFE) == 0xFFFE) { if ((ch >= 0xFDD0) && (ch <= 0xFDEF))
return false; return false;
} if (ch > 0x10FFFF)
if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) { return false;
return false;
}
if (ch > 0x10FFFF) {
return false;
}
return true; return true;
}
int Utf8BytesIndicated(char ch) {
int byteVal = static_cast<unsigned char>(ch);
switch (byteVal >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
return 1;
case 12: case 13:
return 2;
case 14:
return 3;
case 15:
return 4;
default:
return -1;
}
}
bool IsTrailingByte(char ch) {
return (ch & 0xC0) == 0x80;
}
bool GetNextCodePointAndAdvance(int& codePoint, std::string::const_iterator& first, std::string::const_iterator last) {
if (first == last)
return false;
int nBytes = Utf8BytesIndicated(*first);
if (nBytes < 1) {
// Bad lead byte
++first;
codePoint = REPLACEMENT_CHARACTER;
return true;
}
if (nBytes == 1) {
codePoint = *first++;
return true;
}
// Gather bits from trailing bytes
codePoint = static_cast<unsigned char>(*first) & ~(0xFF << (7 - nBytes));
++first;
--nBytes;
for (; nBytes > 0; ++first, --nBytes) {
if ((first == last) || !IsTrailingByte(*first)) {
codePoint = REPLACEMENT_CHARACTER;
break;
}
codePoint <<= 6;
codePoint |= *first & 0x3F;
}
// Check for illegal code points
if (codePoint > 0x10FFFF)
codePoint = REPLACEMENT_CHARACTER;
else if (codePoint >= 0xD800 && codePoint <= 0xDFFF)
codePoint = REPLACEMENT_CHARACTER;
else if ((codePoint & 0xFFFE) == 0xFFFE)
codePoint = REPLACEMENT_CHARACTER;
else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF)
codePoint = REPLACEMENT_CHARACTER;
return true;
}
void WriteCodePoint(ostream& out, int codePoint) {
if (codePoint < 0 || codePoint > 0x10FFFF) {
codePoint = REPLACEMENT_CHARACTER;
}
if (codePoint < 0x7F) {
out << static_cast<char>(codePoint);
} else if (codePoint < 0x7FF) {
out << static_cast<char>(0xC0 | (codePoint >> 6))
<< static_cast<char>(0x80 | (codePoint & 0x3F));
} else if (codePoint < 0xFFFF) {
out << static_cast<char>(0xE0 | (codePoint >> 12))
<< static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
<< static_cast<char>(0x80 | (codePoint & 0x3F));
} else {
out << static_cast<char>(0xF0 | (codePoint >> 18))
<< static_cast<char>(0x80 | ((codePoint >> 12) & 0x3F))
<< static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
<< static_cast<char>(0x80 | (codePoint & 0x3F));
}
}
bool IsValidPlainScalar(const std::string& str, bool inFlow, bool allowOnlyAscii) {
if(str.empty())
return false;
// first check the start
const RegEx& start = (inFlow ? Exp::PlainScalarInFlow() : Exp::PlainScalar());
if(!start.Matches(str))
return false;
// and check the end for plain whitespace (which can't be faithfully kept in a plain scalar)
if(!str.empty() && *str.rbegin() == ' ')
return false;
// then check until something is disallowed
const RegEx& disallowed = (inFlow ? Exp::EndScalarInFlow() : Exp::EndScalar())
|| (Exp::BlankOrBreak() + Exp::Comment())
|| Exp::NotPrintable()
|| Exp::Utf8_ByteOrderMark()
|| Exp::Break()
|| Exp::Tab();
StringCharSource buffer(str.c_str(), str.size());
while(buffer) {
if(disallowed.Matches(buffer))
return false;
if(allowOnlyAscii && (0x7F < static_cast<unsigned char>(buffer[0])))
return false;
++buffer;
}
return true;
}
void WriteDoubleQuoteEscapeSequence(ostream& out, int codePoint) {
static const char hexDigits[] = "0123456789abcdef";
char escSeq[] = "\\U00000000";
int digits = 8;
if (codePoint < 0xFF) {
escSeq[1] = 'x';
digits = 2;
} else if (codePoint < 0xFFFF) {
escSeq[1] = 'u';
digits = 4;
}
// Write digits into the escape sequence
int i = 2;
for (; digits > 0; --digits, ++i) {
escSeq[i] = hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF];
}
escSeq[i] = 0; // terminate with NUL character
out << escSeq;
}
bool WriteAliasName(ostream& out, const std::string& str) {
int codePoint;
for(std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());
)
{
if (!IsAnchorChar(codePoint))
return false;
WriteCodePoint(out, codePoint);
}
return true;
}
}
bool WriteString(ostream& out, const std::string& str, bool inFlow, bool escapeNonAscii)
{
if(IsValidPlainScalar(str, inFlow, escapeNonAscii)) {
out << str;
return true;
} else
return WriteDoubleQuotedString(out, str, escapeNonAscii);
}
bool WriteSingleQuotedString(ostream& out, const std::string& str)
{
out << "'";
int codePoint;
for(std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());
)
{
if (codePoint == '\n')
return false; // We can't handle a new line and the attendant indentation yet
if (codePoint == '\'')
out << "''";
else
WriteCodePoint(out, codePoint);
}
out << "'";
return true;
}
bool WriteDoubleQuotedString(ostream& out, const std::string& str, bool escapeNonAscii)
{
out << "\"";
int codePoint;
for(std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());
)
{
if (codePoint == '\"')
out << "\\\"";
else if (codePoint == '\\')
out << "\\\\";
else if (codePoint < 0x20 || (codePoint >= 0x80 && codePoint <= 0xA0)) // Control characters and non-breaking space
WriteDoubleQuoteEscapeSequence(out, codePoint);
else if (codePoint == 0xFEFF) // Byte order marks (ZWNS) should be escaped (YAML 1.2, sec. 5.2)
WriteDoubleQuoteEscapeSequence(out, codePoint);
else if (escapeNonAscii && codePoint > 0x7E)
WriteDoubleQuoteEscapeSequence(out, codePoint);
else
WriteCodePoint(out, codePoint);
}
out << "\"";
return true;
}
bool WriteLiteralString(ostream& out, const std::string& str, int indent)
{
out << "|\n";
out << IndentTo(indent);
int codePoint;
for(std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());
)
{
if (codePoint == '\n')
out << "\n" << IndentTo(indent);
else
WriteCodePoint(out, codePoint);
}
return true;
}
bool WriteChar(ostream& out, char ch)
{
if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'))
out << ch;
else if((0x20 <= ch && ch <= 0x7e) || ch == ' ')
out << "\"" << ch << "\"";
else if(ch == '\t')
out << "\"\\t\"";
else if(ch == '\n')
out << "\"\\n\"";
else if(ch == '\b')
out << "\"\\b\"";
else {
out << "\"";
WriteDoubleQuoteEscapeSequence(out, ch);
out << "\"";
}
return true;
}
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent)
{
const unsigned curIndent = out.col();
out << "#" << Indentation(postCommentIndent);
int codePoint;
for(std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end());
)
{
if(codePoint == '\n')
out << "\n" << IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
else
WriteCodePoint(out, codePoint);
}
return true;
}
bool WriteAlias(ostream& out, const std::string& str)
{
out << "*";
return WriteAliasName(out, str);
}
bool WriteAnchor(ostream& out, const std::string& str)
{
out << "&";
return WriteAliasName(out, str);
}
bool WriteTag(ostream& out, const std::string& str, bool verbatim)
{
out << (verbatim ? "!<" : "!");
StringCharSource buffer(str.c_str(), str.size());
const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
while(buffer) {
int n = reValid.Match(buffer);
if(n <= 0)
return false;
while(--n >= 0) {
out << buffer[0];
++buffer;
}
}
if (verbatim)
out << ">";
return true;
}
bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag)
{
out << "!";
StringCharSource prefixBuffer(prefix.c_str(), prefix.size());
while(prefixBuffer) {
int n = Exp::URI().Match(prefixBuffer);
if(n <= 0)
return false;
while(--n >= 0) {
out << prefixBuffer[0];
++prefixBuffer;
}
}
out << "!";
StringCharSource tagBuffer(tag.c_str(), tag.size());
while(tagBuffer) {
int n = Exp::Tag().Match(tagBuffer);
if(n <= 0)
return false;
while(--n >= 0) {
out << tagBuffer[0];
++tagBuffer;
}
}
return true;
}
bool WriteBinary(ostream& out, const Binary& binary)
{
WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()), false);
return true;
}
}
} }
int Utf8BytesIndicated(char ch) {
int byteVal = static_cast<unsigned char>(ch);
switch (byteVal >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
return 1;
case 12:
case 13:
return 2;
case 14:
return 3;
case 15:
return 4;
default:
return -1;
}
}
bool IsTrailingByte(char ch) { return (ch & 0xC0) == 0x80; }
bool GetNextCodePointAndAdvance(int& codePoint,
const char*& first,
const char* last) {
if (first == last)
return false;
int nBytes = Utf8BytesIndicated(*first);
if (nBytes < 1) {
// Bad lead byte
++first;
codePoint = REPLACEMENT_CHARACTER;
return true;
}
if (nBytes == 1) {
codePoint = *first++;
return true;
}
// Gather bits from trailing bytes
codePoint = static_cast<unsigned char>(*first) & ~(0xFF << (7 - nBytes));
++first;
--nBytes;
for (; nBytes > 0; ++first, --nBytes) {
if ((first == last) || !IsTrailingByte(*first)) {
codePoint = REPLACEMENT_CHARACTER;
break;
}
codePoint <<= 6;
codePoint |= *first & 0x3F;
}
// Check for illegal code points
if (codePoint > 0x10FFFF)
codePoint = REPLACEMENT_CHARACTER;
else if (codePoint >= 0xD800 && codePoint <= 0xDFFF)
codePoint = REPLACEMENT_CHARACTER;
else if ((codePoint & 0xFFFE) == 0xFFFE)
codePoint = REPLACEMENT_CHARACTER;
else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF)
codePoint = REPLACEMENT_CHARACTER;
return true;
}
void WriteCodePoint(ostream_wrapper& out, int codePoint) {
if (codePoint < 0 || codePoint > 0x10FFFF) {
codePoint = REPLACEMENT_CHARACTER;
}
if (codePoint <= 0x7F) {
out << static_cast<char>(codePoint);
} else if (codePoint <= 0x7FF) {
out << static_cast<char>(0xC0 | (codePoint >> 6))
<< static_cast<char>(0x80 | (codePoint & 0x3F));
} else if (codePoint <= 0xFFFF) {
out << static_cast<char>(0xE0 | (codePoint >> 12))
<< static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
<< static_cast<char>(0x80 | (codePoint & 0x3F));
} else {
out << static_cast<char>(0xF0 | (codePoint >> 18))
<< static_cast<char>(0x80 | ((codePoint >> 12) & 0x3F))
<< static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
<< static_cast<char>(0x80 | (codePoint & 0x3F));
}
}
bool IsValidPlainScalar(const char* str, std::size_t size, FlowType::value flowType,
bool allowOnlyAscii) {
// check against null
if (IsNullString(str, size)) {
return false;
}
// check the start
const RegEx& start = (flowType == FlowType::Flow ? Exp::PlainScalarInFlow()
: Exp::PlainScalar());
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 (size != 0 && str[size - 1] == ' ') {
return false;
}
// then check until something is disallowed
static const RegEx disallowed_flow =
Exp::EndScalarInFlow() | (Exp::BlankOrBreak() + Exp::Comment()) |
Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
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::Ampersand();
const RegEx& disallowed =
flowType == FlowType::Flow ? disallowed_flow : disallowed_block;
StringCharSource buffer(str, size);
while (buffer) {
if (disallowed.Matches(buffer)) {
return false;
}
if (allowOnlyAscii && (0x80 <= static_cast<unsigned char>(buffer[0]))) {
return false;
}
++buffer;
}
return true;
}
bool IsValidSingleQuotedScalar(const char* str, std::size_t size, bool escapeNonAscii) {
// TODO: check for non-printable characters?
return std::none_of(str, str + size, [=](char ch) {
return (escapeNonAscii && (0x80 <= static_cast<unsigned char>(ch))) ||
(ch == '\n');
});
}
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, str + size, [=](char ch) {
return (escapeNonAscii && (0x80 <= static_cast<unsigned char>(ch)));
});
}
std::pair<uint16_t, uint16_t> EncodeUTF16SurrogatePair(int codePoint) {
const uint32_t leadOffset = 0xD800 - (0x10000 >> 10);
return {
leadOffset | (codePoint >> 10),
0xDC00 | (codePoint & 0x3FF),
};
}
void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint, StringEscaping::value stringEscapingStyle) {
static const char hexDigits[] = "0123456789abcdef";
out << "\\";
int digits = 8;
if (codePoint < 0xFF && stringEscapingStyle != StringEscaping::JSON) {
out << "x";
digits = 2;
} else if (codePoint < 0xFFFF) {
out << "u";
digits = 4;
} else if (stringEscapingStyle != StringEscaping::JSON) {
out << "U";
digits = 8;
} else {
auto surrogatePair = EncodeUTF16SurrogatePair(codePoint);
WriteDoubleQuoteEscapeSequence(out, surrogatePair.first, stringEscapingStyle);
WriteDoubleQuoteEscapeSequence(out, surrogatePair.second, stringEscapingStyle);
return;
}
// Write digits into the escape sequence
for (; digits > 0; --digits)
out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF];
}
bool WriteAliasName(ostream_wrapper& out, const char* str, std::size_t size) {
int codePoint;
for (const char* i = str;
GetNextCodePointAndAdvance(codePoint, i, str + size);) {
if (!IsAnchorChar(codePoint)) {
return false;
}
WriteCodePoint(out, codePoint);
}
return true;
}
} // namespace
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, size, flowType, escapeNonAscii)) {
return StringFormat::Plain;
}
return StringFormat::DoubleQuoted;
case SingleQuoted:
if (IsValidSingleQuotedScalar(str, size, escapeNonAscii)) {
return StringFormat::SingleQuoted;
}
return StringFormat::DoubleQuoted;
case DoubleQuoted:
return StringFormat::DoubleQuoted;
case Literal:
if (IsValidLiteralScalar(str, size, flowType, escapeNonAscii)) {
return StringFormat::Literal;
}
return StringFormat::DoubleQuoted;
default:
break;
}
return StringFormat::DoubleQuoted;
}
bool WriteSingleQuotedString(ostream_wrapper& out, const char* str, std::size_t size) {
out << "'";
int codePoint;
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
}
if (codePoint == '\'') {
out << "''";
} else {
WriteCodePoint(out, codePoint);
}
}
out << "'";
return true;
}
bool WriteDoubleQuotedString(ostream_wrapper& out, const char* str, std::size_t size,
StringEscaping::value stringEscaping) {
out << "\"";
int codePoint;
for (const char* i = str;
GetNextCodePointAndAdvance(codePoint, i, str + size);) {
switch (codePoint) {
case '\"':
out << "\\\"";
break;
case '\\':
out << "\\\\";
break;
case '\n':
out << "\\n";
break;
case '\t':
out << "\\t";
break;
case '\r':
out << "\\r";
break;
case '\b':
out << "\\b";
break;
case '\f':
out << "\\f";
break;
default:
if (codePoint < 0x20 ||
(codePoint >= 0x80 &&
codePoint <= 0xA0)) { // Control characters and non-breaking space
WriteDoubleQuoteEscapeSequence(out, codePoint, stringEscaping);
} else if (codePoint == 0xFEFF) { // Byte order marks (ZWNS) should be
// escaped (YAML 1.2, sec. 5.2)
WriteDoubleQuoteEscapeSequence(out, codePoint, stringEscaping);
} else if (stringEscaping == StringEscaping::NonAscii && codePoint > 0x7E) {
WriteDoubleQuoteEscapeSequence(out, codePoint, stringEscaping);
} else {
WriteCodePoint(out, codePoint);
}
}
}
out << "\"";
return true;
}
bool WriteLiteralString(ostream_wrapper& out, const char* str, std::size_t size,
std::size_t indent) {
out << "|\n";
int codePoint;
for (const char* i = str;
GetNextCodePointAndAdvance(codePoint, i, str + size);) {
if (codePoint == '\n') {
out << "\n";
} else {
out<< IndentTo(indent);
WriteCodePoint(out, codePoint);
}
}
return true;
}
bool WriteChar(ostream_wrapper& out, char ch, StringEscaping::value stringEscapingStyle) {
if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) {
out << ch;
} else if (ch == '\"') {
out << R"("\"")";
} else if (ch == '\t') {
out << R"("\t")";
} else if (ch == '\n') {
out << R"("\n")";
} else if (ch == '\b') {
out << R"("\b")";
} else if (ch == '\r') {
out << R"("\r")";
} else if (ch == '\f') {
out << R"("\f")";
} else if (ch == '\\') {
out << R"("\\")";
} else if (0x20 <= ch && ch <= 0x7e) {
out << "\"" << ch << "\"";
} else {
out << "\"";
WriteDoubleQuoteEscapeSequence(out, ch, stringEscapingStyle);
out << "\"";
}
return true;
}
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 (const char* i = str;
GetNextCodePointAndAdvance(codePoint, i, str + size);) {
if (codePoint == '\n') {
out << "\n"
<< IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
out.set_comment();
} else {
WriteCodePoint(out, codePoint);
}
}
return true;
}
bool WriteAlias(ostream_wrapper& out, const char* str, std::size_t size) {
out << "*";
return WriteAliasName(out, str, size);
}
bool WriteAnchor(ostream_wrapper& out, const char* str, std::size_t size) {
out << "&";
return WriteAliasName(out, str, size);
}
bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) {
out << (verbatim ? "!<" : "!");
StringCharSource buffer(str.c_str(), str.size());
const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
while (buffer) {
int n = reValid.Match(buffer);
if (n <= 0) {
return false;
}
while (--n >= 0) {
out << buffer[0];
++buffer;
}
}
if (verbatim) {
out << ">";
}
return true;
}
bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
const std::string& tag) {
out << "!";
StringCharSource prefixBuffer(prefix.c_str(), prefix.size());
while (prefixBuffer) {
int n = Exp::URI().Match(prefixBuffer);
if (n <= 0) {
return false;
}
while (--n >= 0) {
out << prefixBuffer[0];
++prefixBuffer;
}
}
out << "!";
StringCharSource tagBuffer(tag.c_str(), tag.size());
while (tagBuffer) {
int n = Exp::Tag().Match(tagBuffer);
if (n <= 0) {
return false;
}
while (--n >= 0) {
out << tagBuffer[0];
++tagBuffer;
}
}
return true;
}
bool WriteBinary(ostream_wrapper& out, const Binary& binary) {
std::string encoded = EncodeBase64(binary.data(), binary.size());
WriteDoubleQuotedString(out, encoded.data(), encoded.size(),
StringEscaping::None);
return true;
}
} // namespace Utils
} // namespace YAML
+22 -45
View File
@@ -1,55 +1,32 @@
#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/ostream.h"
#include <string> #include <string>
#include "emitterstate.h" namespace YAML
#include "yaml-cpp/emittermanip.h" {
#include "yaml-cpp/ostream_wrapper.h" class Binary;
namespace YAML { namespace Utils
class ostream_wrapper; {
} // namespace YAML bool WriteString(ostream& out, const std::string& str, bool inFlow, bool escapeNonAscii);
bool WriteSingleQuotedString(ostream& out, const std::string& str);
namespace YAML { bool WriteDoubleQuotedString(ostream& out, const std::string& str, bool escapeNonAscii);
class Binary; bool WriteLiteralString(ostream& out, const std::string& str, int indent);
bool WriteChar(ostream& out, char ch);
struct StringFormat { bool WriteComment(ostream& out, const std::string& str, int postCommentIndent);
enum value { Plain, SingleQuoted, DoubleQuoted, Literal }; bool WriteAlias(ostream& out, const std::string& str);
}; bool WriteAnchor(ostream& out, const std::string& str);
bool WriteTag(ostream& out, const std::string& str, bool verbatim);
struct StringEscaping { bool WriteTagWithPrefix(ostream& out, const std::string& prefix, const std::string& tag);
enum value { None, NonAscii, JSON }; bool WriteBinary(ostream& out, const Binary& binary);
}; }
namespace Utils {
StringFormat::value ComputeStringFormat(const char* str, std::size_t size,
EMITTER_MANIP strFormat,
FlowType::value flowType,
bool escapeNonAscii);
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 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 char* str, std::size_t size,
std::size_t postCommentIndent);
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);
}
} }
#endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-40
View File
@@ -1,40 +0,0 @@
#include "yaml-cpp/exceptions.h"
#include "yaml-cpp/noexcept.h"
namespace YAML {
// These destructors are defined out-of-line so the vtable is only emitted once.
Exception::~Exception() YAML_CPP_NOEXCEPT = default;
ParserException::~ParserException() YAML_CPP_NOEXCEPT = default;
RepresentationException::~RepresentationException() YAML_CPP_NOEXCEPT = default;
InvalidScalar::~InvalidScalar() YAML_CPP_NOEXCEPT = default;
KeyNotFound::~KeyNotFound() YAML_CPP_NOEXCEPT = default;
InvalidNode::~InvalidNode() YAML_CPP_NOEXCEPT = default;
BadConversion::~BadConversion() YAML_CPP_NOEXCEPT = default;
BadDereference::~BadDereference() YAML_CPP_NOEXCEPT = default;
BadSubscript::~BadSubscript() YAML_CPP_NOEXCEPT = default;
BadPushback::~BadPushback() YAML_CPP_NOEXCEPT = default;
BadInsert::~BadInsert() YAML_CPP_NOEXCEPT = default;
EmitterException::~EmitterException() YAML_CPP_NOEXCEPT = default;
BadFile::~BadFile() YAML_CPP_NOEXCEPT = default;
[[noreturn]] void throw_bad_subscript(const YAML::Mark& mark)
{
throw BadSubscript(mark, std::string{});
}
[[noreturn]] void throw_invalid_node(const std::string& key)
{
throw InvalidNode(key);
}
[[noreturn]] void throw_bad_conversion(const YAML::Mark& mark)
{
throw BadConversion(mark);
}
[[noreturn]] void throw_bad_insert()
{
throw BadInsert();
}
} // namespace YAML
+106 -130
View File
@@ -1,137 +1,113 @@
#include "exp.h"
#include "yaml-cpp/exceptions.h"
#include <sstream> #include <sstream>
#include "exp.h" namespace YAML
#include "stream.h" {
#include "yaml-cpp/exceptions.h" // IWYU pragma: keep namespace Exp
{
unsigned ParseHex(const std::string& str, const Mark& mark)
{
unsigned value = 0;
for(std::size_t i=0;i<str.size();i++) {
char ch = str[i];
int digit = 0;
if('a' <= ch && ch <= 'f')
digit = ch - 'a' + 10;
else if('A' <= ch && ch <= 'F')
digit = ch - 'A' + 10;
else if('0' <= ch && ch <= '9')
digit = ch - '0';
else
throw ParserException(mark, ErrorMsg::INVALID_HEX);
namespace YAML { value = (value << 4) + digit;
struct Mark; }
} // namespace YAML
namespace YAML { return value;
namespace Exp { }
unsigned ParseHex(const std::string& str, const Mark& mark) {
unsigned value = 0;
for (char ch : str) {
int digit = 0;
if ('a' <= ch && ch <= 'f')
digit = ch - 'a' + 10;
else if ('A' <= ch && ch <= 'F')
digit = ch - 'A' + 10;
else if ('0' <= ch && ch <= '9')
digit = ch - '0';
else
throw ParserException(mark, ErrorMsg::INVALID_HEX);
value = (value << 4) + digit; std::string Str(unsigned ch)
} {
return std::string(1, static_cast<char>(ch));
}
return value; // Escape
// . Translates the next 'codeLength' characters into a hex number and returns the result.
// . Throws if it's not actually hex.
std::string Escape(Stream& in, int codeLength)
{
// grab string
std::string str;
for(int i=0;i<codeLength;i++)
str += in.get();
// get the value
unsigned value = ParseHex(str, in.mark());
// legal unicode?
if((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
std::stringstream msg;
msg << ErrorMsg::INVALID_UNICODE << value;
throw ParserException(in.mark(), msg.str());
}
// now break it up into chars
if(value <= 0x7F)
return Str(value);
else if(value <= 0x7FF)
return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
else if(value <= 0xFFFF)
return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
else
return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
}
// Escape
// . Escapes the sequence starting 'in' (it must begin with a '\' or single quote)
// and returns the result.
// . Throws if it's an unknown escape character.
std::string Escape(Stream& in)
{
// eat slash
char escape = in.get();
// switch on escape character
char ch = in.get();
// first do single quote, since it's easier
if(escape == '\'' && ch == '\'')
return "\'";
// now do the slash (we're not gonna check if it's a slash - you better pass one!)
switch(ch) {
case '0': return std::string(1, '\x00');
case 'a': return "\x07";
case 'b': return "\x08";
case 't':
case '\t': return "\x09";
case 'n': return "\x0A";
case 'v': return "\x0B";
case 'f': return "\x0C";
case 'r': return "\x0D";
case 'e': return "\x1B";
case ' ': return "\x20";
case '\"': return "\"";
case '\'': return "\'";
case '\\': return "\\";
case '/': return "/";
case 'N': return "\x85";
case '_': return "\xA0";
case 'L': return "\xE2\x80\xA8"; // LS (#x2028)
case 'P': return "\xE2\x80\xA9"; // PS (#x2029)
case 'x': return Escape(in, 2);
case 'u': return Escape(in, 4);
case 'U': return Escape(in, 8);
}
std::stringstream msg;
throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
}
}
} }
std::string Str(unsigned ch) { return std::string(1, static_cast<char>(ch)); }
// Escape
// . Translates the next 'codeLength' characters into a hex number and returns
// the result.
// . Throws if it's not actually hex.
std::string Escape(Stream& in, int codeLength) {
// grab string
std::string str;
for (int i = 0; i < codeLength; i++)
str += in.get();
// get the value
unsigned value = ParseHex(str, in.mark());
// legal unicode?
if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
std::stringstream msg;
msg << ErrorMsg::INVALID_UNICODE << value;
throw ParserException(in.mark(), msg.str());
}
// now break it up into chars
if (value <= 0x7F)
return Str(value);
if (value <= 0x7FF)
return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
if (value <= 0xFFFF)
return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) +
Str(0x80 + (value & 0x3F));
return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
}
// Escape
// . Escapes the sequence starting 'in' (it must begin with a '\' or single
// quote)
// and returns the result.
// . Throws if it's an unknown escape character.
std::string Escape(Stream& in) {
// eat slash
char escape = in.get();
// switch on escape character
char ch = in.get();
// first do single quote, since it's easier
if (escape == '\'' && ch == '\'')
return "\'";
// now do the slash (we're not gonna check if it's a slash - you better pass
// one!)
switch (ch) {
case '0':
return std::string(1, '\x00');
case 'a':
return "\x07";
case 'b':
return "\x08";
case 't':
case '\t':
return "\x09";
case 'n':
return "\x0A";
case 'v':
return "\x0B";
case 'f':
return "\x0C";
case 'r':
return "\x0D";
case 'e':
return "\x1B";
case ' ':
return R"( )";
case '\"':
return "\"";
case '\'':
return "\'";
case '\\':
return "\\";
case '/':
return "/";
case 'N':
return "\x85";
case '_':
return "\xA0";
case 'L':
return "\xE2\x80\xA8"; // LS (#x2028)
case 'P':
return "\xE2\x80\xA9"; // PS (#x2029)
case 'x':
return Escape(in, 2);
case 'u':
return Escape(in, 4);
case 'U':
return Escape(in, 8);
}
std::stringstream msg;
throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
}
} // namespace Exp
} // namespace YAML
+184 -214
View File
@@ -1,226 +1,196 @@
#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <ios>
#include <string>
#include "regex_yaml.h" #include "regex.h"
#include <string>
#include <ios>
#include "stream.h" #include "stream.h"
namespace YAML { namespace YAML
//////////////////////////////////////////////////////////////////////////////// {
// Here we store a bunch of expressions for matching different parts of the ////////////////////////////////////////////////////////////////////////////////
// file. // Here we store a bunch of expressions for matching different parts of the file.
namespace Exp { namespace Exp
// misc {
inline const RegEx& Empty() { // misc
static const RegEx e; inline const RegEx& Space() {
return e; static const RegEx e = RegEx(' ');
} return e;
inline const RegEx& Space() { }
static const RegEx e = RegEx(' '); inline const RegEx& Tab() {
return e; static const RegEx e = RegEx('\t');
} return e;
inline const RegEx& Tab() { }
static const RegEx e = RegEx('\t'); inline const RegEx& Blank() {
return e; static const RegEx e = Space() || Tab();
} return e;
inline const RegEx& Blank() { }
static const RegEx e = Space() | Tab(); inline const RegEx& Break() {
return e; static const RegEx e = RegEx('\n') || RegEx("\r\n");
} return e;
inline const RegEx& Break() { }
static const RegEx e = RegEx('\n') | RegEx("\r\n") | RegEx('\r'); inline const RegEx& BlankOrBreak() {
return e; static const RegEx e = Blank() || Break();
} return e;
inline const RegEx& BlankOrBreak() { }
static const RegEx e = Blank() | Break(); inline const RegEx& Digit() {
return e; static const RegEx e = RegEx('0', '9');
} return e;
inline const RegEx& Digit() { }
static const RegEx e = RegEx('0', '9'); inline const RegEx& Alpha() {
return e; static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z');
} return e;
inline const RegEx& Alpha() { }
static const RegEx e = RegEx('a', 'z') | RegEx('A', 'Z'); inline const RegEx& AlphaNumeric() {
return e; static const RegEx e = Alpha() || Digit();
} return e;
inline const RegEx& AlphaNumeric() { }
static const RegEx e = Alpha() | Digit(); inline const RegEx& Word() {
return e; static const RegEx e = AlphaNumeric() || RegEx('-');
} return e;
inline const RegEx& Word() { }
static const RegEx e = AlphaNumeric() | RegEx('-'); inline const RegEx& Hex() {
return e; static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f');
} return e;
inline const RegEx& Hex() { }
static const RegEx e = Digit() | RegEx('A', 'F') | RegEx('a', 'f'); // Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. 5.1)
return e; inline const RegEx& NotPrintable() {
} static const RegEx e = RegEx(0) ||
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
// 5.1) RegEx(0x0E, 0x1F) ||
inline const RegEx& NotPrintable() { (RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
static const RegEx e = return e;
RegEx(0) | }
RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) | inline const RegEx& Utf8_ByteOrderMark() {
RegEx(0x0E, 0x1F) | static const RegEx e = RegEx("\xEF\xBB\xBF");
(RegEx('\xC2') + (RegEx('\x80', '\x84') | RegEx('\x86', '\x9F'))); return e;
return e; }
}
inline const RegEx& Utf8_ByteOrderMark() { // actual tags
static const RegEx e = RegEx("\xEF\xBB\xBF");
return e; inline const RegEx& DocStart() {
static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx());
return e;
}
inline const RegEx& DocEnd() {
static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx());
return e;
}
inline const RegEx& DocIndicator() {
static const RegEx e = DocStart() || DocEnd();
return e;
}
inline const RegEx& BlockEntry() {
static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx());
return e;
}
inline const RegEx& Key() {
static const RegEx e = RegEx('?');
return e;
}
inline const RegEx& KeyInFlow() {
static const RegEx e = RegEx('?') + BlankOrBreak();
return e;
}
inline const RegEx& Value() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
return e;
}
inline const RegEx& ValueInFlow() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR));
return e;
}
inline const RegEx& ValueInJSONFlow() {
static const RegEx e = RegEx(':');
return e;
}
inline const RegEx Comment() {
static const RegEx e = RegEx('#');
return e;
}
inline const RegEx& Anchor() {
static const RegEx e = !(RegEx("[]{},", REGEX_OR) || BlankOrBreak());
return e;
}
inline const RegEx& AnchorEnd() {
static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak();
return e;
}
inline const RegEx& URI() {
static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) || (RegEx('%') + Hex() + Hex());
return e;
}
inline const RegEx& Tag() {
static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'", REGEX_OR) || (RegEx('%') + Hex() + Hex());
return e;
}
// Plain scalar rules:
// . Cannot start with a blank.
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
// . In the block context - ? : must be not be followed with a space.
// . In the flow context ? is illegal and : and - must not be followed with a space.
inline const RegEx& PlainScalar() {
static const RegEx e = !(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + (BlankOrBreak() || RegEx())));
return e;
}
inline const RegEx& PlainScalarInFlow() {
static const RegEx e = !(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank()));
return e;
}
inline const RegEx& EndScalar() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
return e;
}
inline const RegEx& EndScalarInFlow() {
static const RegEx e = (RegEx(':') + (BlankOrBreak() || RegEx() || RegEx(",]}", REGEX_OR))) || RegEx(",?[]{}", REGEX_OR);
return e;
}
inline const RegEx& EscSingleQuote() {
static const RegEx e = RegEx("\'\'");
return e;
}
inline const RegEx& EscBreak() {
static const RegEx e = RegEx('\\') + Break();
return e;
}
inline const RegEx& ChompIndicator() {
static const RegEx e = RegEx("+-", REGEX_OR);
return e;
}
inline const RegEx& Chomp() {
static const RegEx e = (ChompIndicator() + Digit()) || (Digit() + ChompIndicator()) || ChompIndicator() || Digit();
return e;
}
// and some functions
std::string Escape(Stream& in);
}
namespace Keys
{
const char Directive = '%';
const char FlowSeqStart = '[';
const char FlowSeqEnd = ']';
const char FlowMapStart = '{';
const char FlowMapEnd = '}';
const char FlowEntry = ',';
const char Alias = '*';
const char Anchor = '&';
const char Tag = '!';
const char LiteralScalar = '|';
const char FoldedScalar = '>';
const char VerbatimTagStart = '<';
const char VerbatimTagEnd = '>';
}
} }
// actual tags #endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
inline const RegEx& DocStart() {
static const RegEx e = RegEx("---") + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& DocEnd() {
static const RegEx e = RegEx("...") + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& DocIndicator() {
static const RegEx e = DocStart() | DocEnd();
return e;
}
inline const RegEx& BlockEntry() {
static const RegEx e = RegEx('-') + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& Key() {
static const RegEx e = RegEx('?') + BlankOrBreak();
return e;
}
inline const RegEx& KeyInFlow() {
static const RegEx e = RegEx('?') + BlankOrBreak();
return e;
}
inline const RegEx& Value() {
static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& ValueInFlow() {
static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx(",]}", REGEX_OR));
return e;
}
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;
}
inline const RegEx& Anchor() {
static const RegEx e = !(RegEx("[]{},", REGEX_OR) | BlankOrBreak());
return e;
}
inline const RegEx& AnchorEnd() {
static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) | BlankOrBreak();
return e;
}
inline const RegEx& URI() {
static const RegEx e = Word() | RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) |
(RegEx('%') + Hex() + Hex());
return e;
}
inline const RegEx& Tag() {
static const RegEx e = Word() | RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) |
(RegEx('%') + Hex() + Hex());
return e;
}
// Plain scalar rules:
// . Cannot start with a blank.
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
// . In the block context - ? : must be not be followed with a space.
// . In the flow context ? is illegal and : and - must not be followed with a
// space.
inline const RegEx& PlainScalar() {
static const RegEx e =
!(BlankOrBreak() | RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) |
(RegEx("-?:", REGEX_OR) + (BlankOrBreak() | RegEx())));
return e;
}
inline const RegEx& PlainScalarInFlow() {
static const RegEx e =
!(BlankOrBreak() | RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) |
(RegEx("-:", REGEX_OR) + (Blank() | RegEx())));
return e;
}
inline const RegEx& EndScalar() {
static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& EndScalarInFlow() {
static const RegEx e =
(RegEx(':') + (BlankOrBreak() | RegEx() | RegEx(",]}", REGEX_OR))) |
RegEx(",?[]{}", REGEX_OR);
return e;
}
inline const RegEx& ScanScalarEndInFlow() {
static const RegEx e = (EndScalarInFlow() | (BlankOrBreak() + Comment()));
return e;
}
inline const RegEx& ScanScalarEnd() {
static const RegEx e = EndScalar() | (BlankOrBreak() + Comment());
return e;
}
inline const RegEx& EscSingleQuote() {
static const RegEx e = RegEx("\'\'");
return e;
}
inline const RegEx& EscBreak() {
static const RegEx e = RegEx('\\') + Break();
return e;
}
inline const RegEx& ChompIndicator() {
static const RegEx e = RegEx("+-", REGEX_OR);
return e;
}
inline const RegEx& Chomp() {
static const RegEx e = (ChompIndicator() + Digit()) |
(Digit() + ChompIndicator()) | ChompIndicator() |
Digit();
return e;
}
// and some functions
std::string Escape(Stream& in);
} // namespace Exp
namespace Keys {
const char Directive = '%';
const char FlowSeqStart = '[';
const char FlowSeqEnd = ']';
const char FlowMapStart = '{';
const char FlowMapEnd = '}';
const char FlowEntry = ',';
const char Alias = '*';
const char Anchor = '&';
const char Tag = '!';
const char LiteralScalar = '|';
const char FoldedScalar = '>';
const char VerbatimTagStart = '<';
const char VerbatimTagEnd = '>';
} // namespace Keys
} // namespace YAML
#endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
-255
View File
@@ -1,255 +0,0 @@
#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, size_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 = 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, precision);
}
std::string FpToString(double v, size_t precision) {
return detail::fp_formatting::FpToString(v, 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();
}
}
+26 -28
View File
@@ -1,40 +1,38 @@
#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cstddef>
#include "yaml-cpp/ostream_wrapper.h" #include "yaml-cpp/ostream.h"
#include <iostream>
namespace YAML { namespace YAML
struct Indentation { {
Indentation(std::size_t n_) : n(n_) {} struct Indentation {
std::size_t n; Indentation(unsigned n_): n(n_) {}
}; unsigned n;
};
inline ostream& operator << (ostream& out, const Indentation& indent) {
for(unsigned i=0;i<indent.n;i++)
out << ' ';
return out;
}
inline ostream_wrapper& operator<<(ostream_wrapper& out, struct IndentTo {
const Indentation& indent) { IndentTo(unsigned n_): n(n_) {}
for (std::size_t i = 0; i < indent.n; i++) unsigned n;
out << ' '; };
return out;
inline ostream& operator << (ostream& out, const IndentTo& indent) {
while(out.col() < indent.n)
out << ' ';
return out;
}
} }
struct IndentTo {
IndentTo(std::size_t n_) : n(n_) {}
std::size_t n;
};
inline ostream_wrapper& operator<<(ostream_wrapper& out, #endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
const IndentTo& indent) {
while (out.col() < indent.n)
out << ' ';
return out;
}
}
#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+26 -31
View File
@@ -1,34 +1,29 @@
#include "yaml-cpp/node/detail/memory.h" #include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep #include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/ptr.h"
namespace YAML { namespace YAML
namespace detail { {
namespace detail
void memory_holder::merge(memory_holder& rhs) { {
if (m_pMemory == rhs.m_pMemory) void memory_holder::merge(memory_holder& rhs)
return; {
if(m_pMemory == rhs.m_pMemory)
if (m_pMemory->size() < rhs.m_pMemory->size()) { return;
std::swap(m_pMemory, rhs.m_pMemory);
} m_pMemory->merge(*rhs.m_pMemory);
rhs.m_pMemory = m_pMemory;
m_pMemory->merge(*rhs.m_pMemory); }
rhs.m_pMemory = m_pMemory;
node& memory::create_node()
{
shared_node pNode(new node);
m_nodes.insert(pNode);
return *pNode;
}
void memory::merge(const memory& rhs)
{
m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
}
}
} }
node& memory::create_node() {
shared_node pNode(new node);
m_nodes.insert(pNode);
return *pNode;
}
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
-12
View File
@@ -1,12 +0,0 @@
#include "yaml-cpp/node/node.h"
#include "nodebuilder.h"
#include "nodeevents.h"
namespace YAML {
Node Clone(const Node& node) {
NodeEvents events(node);
NodeBuilder builder;
events.Emit(builder);
return builder.Root();
}
} // namespace YAML
+290 -320
View File
@@ -1,325 +1,295 @@
#include <algorithm> #include "yaml-cpp/node/detail/node_data.h"
#include <cassert> #include "yaml-cpp/node/detail/memory.h"
#include <iterator> #include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/exceptions.h"
#include <sstream> #include <sstream>
#include "yaml-cpp/exceptions.h" namespace YAML
#include "yaml-cpp/node/detail/memory.h" {
#include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep namespace detail
#include "yaml-cpp/node/detail/node_data.h" {
#include "yaml-cpp/node/detail/node_iterator.h" std::string node_data::empty_scalar;
#include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h"
namespace YAML { node_data::node_data(): m_isDefined(false), m_type(NodeType::Null), m_seqSize(0)
namespace detail { {
YAML_CPP_API std::atomic<size_t> node::m_amount{0}; }
const std::string& node_data::empty_scalar() { void node_data::mark_defined()
static const std::string svalue; {
return svalue; if(m_type == NodeType::Undefined)
m_type = NodeType::Null;
m_isDefined = true;
}
void node_data::set_type(NodeType::value type)
{
if(type == NodeType::Undefined) {
m_type = type;
m_isDefined = false;
return;
}
m_isDefined = true;
if(type == m_type)
return;
m_type = type;
switch(m_type) {
case NodeType::Null:
break;
case NodeType::Scalar:
m_scalar.clear();
break;
case NodeType::Sequence:
reset_sequence();
break;
case NodeType::Map:
reset_map();
break;
case NodeType::Undefined:
assert(false);
break;
}
}
void node_data::set_tag(const std::string& tag)
{
m_tag = tag;
}
void node_data::set_null()
{
m_isDefined = true;
m_type = NodeType::Null;
}
void node_data::set_scalar(const std::string& scalar)
{
m_isDefined = true;
m_type = NodeType::Scalar;
m_scalar = scalar;
}
// size/iterator
std::size_t node_data::size() const
{
if(!m_isDefined)
return 0;
switch(m_type) {
case NodeType::Sequence: compute_seq_size(); return m_seqSize;
case NodeType::Map: compute_map_size(); return m_map.size() - m_undefinedPairs.size();
default:
return 0;
}
return 0;
}
void node_data::compute_seq_size() const
{
while(m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined())
m_seqSize++;
}
void node_data::compute_map_size() const
{
kv_pairs::iterator it = m_undefinedPairs.begin();
while(it != m_undefinedPairs.end()) {
kv_pairs::iterator jt = boost::next(it);
if(it->first->is_defined() && it->second->is_defined())
m_undefinedPairs.erase(it);
it = jt;
}
}
const_node_iterator node_data::begin() const
{
if(!m_isDefined)
return const_node_iterator();
switch(m_type) {
case NodeType::Sequence: return const_node_iterator(m_sequence.begin());
case NodeType::Map: return const_node_iterator(m_map.begin(), m_map.end());
default: return const_node_iterator();
}
}
node_iterator node_data::begin()
{
if(!m_isDefined)
return node_iterator();
switch(m_type) {
case NodeType::Sequence: return node_iterator(m_sequence.begin());
case NodeType::Map: return node_iterator(m_map.begin(), m_map.end());
default: return node_iterator();
}
}
const_node_iterator node_data::end() const
{
if(!m_isDefined)
return const_node_iterator();
switch(m_type) {
case NodeType::Sequence: return const_node_iterator(m_sequence.end());
case NodeType::Map: return const_node_iterator(m_map.end(), m_map.end());
default: return const_node_iterator();
}
}
node_iterator node_data::end()
{
if(!m_isDefined)
return node_iterator();
switch(m_type) {
case NodeType::Sequence: return node_iterator(m_sequence.end());
case NodeType::Map: return node_iterator(m_map.end(), m_map.end());
default: return node_iterator();
}
}
// sequence
void node_data::push_back(node& node, shared_memory_holder /* pMemory */)
{
if(m_type == NodeType::Undefined || m_type == NodeType::Null) {
m_type = NodeType::Sequence;
reset_sequence();
}
if(m_type != NodeType::Sequence)
throw BadPushback();
m_sequence.push_back(&node);
}
void node_data::insert(node& key, node& value, shared_memory_holder pMemory)
{
switch(m_type) {
case NodeType::Map:
break;
case NodeType::Undefined:
case NodeType::Null:
case NodeType::Sequence:
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadSubscript();
}
insert_map_pair(key, value);
}
// indexing
node& node_data::get(node& key, shared_memory_holder pMemory) const
{
if(m_type != NodeType::Map)
return pMemory->create_node();
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
if(it->first->is(key))
return *it->second;
}
return pMemory->create_node();
}
node& node_data::get(node& key, shared_memory_holder pMemory)
{
switch(m_type) {
case NodeType::Map:
break;
case NodeType::Undefined:
case NodeType::Null:
case NodeType::Sequence:
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadSubscript();
}
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
if(it->first->is(key))
return *it->second;
}
node& value = pMemory->create_node();
insert_map_pair(key, value);
return value;
}
bool node_data::remove(node& key, shared_memory_holder /* pMemory */)
{
if(m_type != NodeType::Map)
return false;
for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
if(it->first->is(key)) {
m_map.erase(it);
return true;
}
}
return false;
}
void node_data::reset_sequence()
{
m_sequence.clear();
m_seqSize = 0;
}
void node_data::reset_map()
{
m_map.clear();
m_undefinedPairs.clear();
}
void node_data::insert_map_pair(node& key, node& value)
{
m_map[&key] = &value;
if(!key.is_defined() || !value.is_defined())
m_undefinedPairs.push_back(kv_pair(&key, &value));
}
void node_data::convert_to_map(shared_memory_holder pMemory)
{
switch(m_type) {
case NodeType::Undefined:
case NodeType::Null:
reset_map();
m_type = NodeType::Map;
break;
case NodeType::Sequence:
convert_sequence_to_map(pMemory);
break;
case NodeType::Map:
break;
case NodeType::Scalar:
assert(false);
break;
}
}
void node_data::convert_sequence_to_map(shared_memory_holder pMemory)
{
assert(m_type == NodeType::Sequence);
reset_map();
for(std::size_t i=0;i<m_sequence.size();i++) {
std::stringstream stream;
stream << i;
node& key = pMemory->create_node();
key.set_scalar(stream.str());
insert_map_pair(key, *m_sequence[i]);
}
reset_sequence();
m_type = NodeType::Map;
}
}
} }
node_data::node_data()
: m_isDefined(false),
m_mark(Mark::null_mark()),
m_type(NodeType::Null),
m_tag{},
m_style(EmitterStyle::Default),
m_scalar{},
m_sequence{},
m_seqSize(0),
m_map{},
m_undefinedPairs{} {}
void node_data::mark_defined() {
if (m_type == NodeType::Undefined)
m_type = NodeType::Null;
m_isDefined = true;
}
void node_data::set_mark(const Mark& mark) { m_mark = mark; }
void node_data::set_type(NodeType::value type) {
if (type == NodeType::Undefined) {
m_type = type;
m_isDefined = false;
return;
}
m_isDefined = true;
if (type == m_type)
return;
m_type = type;
switch (m_type) {
case NodeType::Null:
break;
case NodeType::Scalar:
m_scalar.clear();
break;
case NodeType::Sequence:
reset_sequence();
break;
case NodeType::Map:
reset_map();
break;
case NodeType::Undefined:
assert(false);
break;
}
}
void node_data::set_tag(const std::string& tag) { m_tag = tag; }
void node_data::set_style(EmitterStyle::value style) { m_style = style; }
void node_data::set_null() {
m_isDefined = true;
m_type = NodeType::Null;
}
void node_data::set_scalar(const std::string& scalar) {
m_isDefined = true;
m_type = NodeType::Scalar;
m_scalar = scalar;
}
// size/iterator
std::size_t node_data::size() const {
if (!m_isDefined)
return 0;
switch (m_type) {
case NodeType::Sequence:
compute_seq_size();
return m_seqSize;
case NodeType::Map:
compute_map_size();
return m_map.size() - m_undefinedPairs.size();
default:
return 0;
}
return 0;
}
void node_data::compute_seq_size() const {
while (m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined())
m_seqSize++;
}
void node_data::compute_map_size() const {
auto it = m_undefinedPairs.begin();
while (it != m_undefinedPairs.end()) {
auto jt = std::next(it);
if (it->first->is_defined() && it->second->is_defined())
m_undefinedPairs.erase(it);
it = jt;
}
}
const_node_iterator node_data::begin() const {
if (!m_isDefined)
return {};
switch (m_type) {
case NodeType::Sequence:
return const_node_iterator(m_sequence.begin());
case NodeType::Map:
return const_node_iterator(m_map.begin(), m_map.end());
default:
return {};
}
}
node_iterator node_data::begin() {
if (!m_isDefined)
return {};
switch (m_type) {
case NodeType::Sequence:
return node_iterator(m_sequence.begin());
case NodeType::Map:
return node_iterator(m_map.begin(), m_map.end());
default:
return {};
}
}
const_node_iterator node_data::end() const {
if (!m_isDefined)
return {};
switch (m_type) {
case NodeType::Sequence:
return const_node_iterator(m_sequence.end());
case NodeType::Map:
return const_node_iterator(m_map.end(), m_map.end());
default:
return {};
}
}
node_iterator node_data::end() {
if (!m_isDefined)
return {};
switch (m_type) {
case NodeType::Sequence:
return node_iterator(m_sequence.end());
case NodeType::Map:
return node_iterator(m_map.end(), m_map.end());
default:
return {};
}
}
// sequence
void node_data::push_back(node& node,
const shared_memory_holder& /* pMemory */) {
if (m_type == NodeType::Undefined || m_type == NodeType::Null) {
m_type = NodeType::Sequence;
reset_sequence();
}
if (m_type != NodeType::Sequence)
throw BadPushback();
m_sequence.push_back(&node);
}
void node_data::insert(node& key, node& value,
const shared_memory_holder& pMemory) {
switch (m_type) {
case NodeType::Map:
break;
case NodeType::Undefined:
case NodeType::Null:
case NodeType::Sequence:
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadSubscript(m_mark, key);
}
insert_map_pair(key, value);
}
// indexing
node* node_data::get(node& key,
const shared_memory_holder& /* pMemory */) const {
if (m_type != NodeType::Map) {
return nullptr;
}
for (const auto& it : m_map) {
if (it.first->is(key))
return it.second;
}
return nullptr;
}
node& node_data::get(node& key, const shared_memory_holder& pMemory) {
switch (m_type) {
case NodeType::Map:
break;
case NodeType::Undefined:
case NodeType::Null:
case NodeType::Sequence:
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadSubscript(m_mark, key);
}
for (const auto& it : m_map) {
if (it.first->is(key))
return *it.second;
}
node& value = pMemory->create_node();
insert_map_pair(key, value);
return value;
}
bool node_data::remove(node& key, const shared_memory_holder& /* pMemory */) {
if (m_type != NodeType::Map)
return false;
for (auto it = m_undefinedPairs.begin(); it != m_undefinedPairs.end();) {
auto jt = std::next(it);
if (it->first->is(key))
m_undefinedPairs.erase(it);
it = jt;
}
auto it =
std::find_if(m_map.begin(), m_map.end(),
[&](std::pair<YAML::detail::node*, YAML::detail::node*> j) {
return (j.first->is(key));
});
if (it != m_map.end()) {
m_map.erase(it);
return true;
}
return false;
}
void node_data::reset_sequence() {
m_sequence.clear();
m_seqSize = 0;
}
void node_data::reset_map() {
m_map.clear();
m_undefinedPairs.clear();
}
void node_data::insert_map_pair(node& key, node& value) {
m_map.emplace_back(&key, &value);
if (!key.is_defined() || !value.is_defined())
m_undefinedPairs.emplace_back(&key, &value);
}
void node_data::convert_to_map(const shared_memory_holder& pMemory) {
switch (m_type) {
case NodeType::Undefined:
case NodeType::Null:
reset_map();
m_type = NodeType::Map;
break;
case NodeType::Sequence:
convert_sequence_to_map(pMemory);
break;
case NodeType::Map:
break;
case NodeType::Scalar:
assert(false);
break;
}
}
void node_data::convert_sequence_to_map(const shared_memory_holder& pMemory) {
assert(m_type == NodeType::Sequence);
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();
key.set_scalar(stream.str());
insert_map_pair(key, *m_sequence[i]);
}
reset_sequence();
m_type = NodeType::Map;
}
} // namespace detail
} // namespace YAML
+133 -129
View File
@@ -1,134 +1,138 @@
#include "nodebuilder.h"
#include "yaml-cpp/mark.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h"
#include <cassert> #include <cassert>
#include "nodebuilder.h" namespace YAML
#include "yaml-cpp/node/detail/node.h" {
#include "yaml-cpp/node/impl.h" NodeBuilder::NodeBuilder(): m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0)
#include "yaml-cpp/node/node.h" {
#include "yaml-cpp/node/type.h" m_anchors.push_back(0); // since the anchors start at 1
}
NodeBuilder::~NodeBuilder()
{
}
Node NodeBuilder::Root()
{
if(!m_pRoot)
return Node();
return Node(*m_pRoot, m_pMemory);
}
namespace YAML { void NodeBuilder::OnDocumentStart(const Mark&)
struct Mark; {
}
void NodeBuilder::OnDocumentEnd()
{
}
void NodeBuilder::OnNull(const Mark& /* mark */, anchor_t anchor)
{
detail::node& node = Push(anchor);
node.set_null();
Pop();
}
void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor)
{
detail::node& node = *m_anchors[anchor];
Push(node);
Pop();
}
void NodeBuilder::OnScalar(const Mark& /* mark */, const std::string& tag, anchor_t anchor, const std::string& value)
{
detail::node& node = Push(anchor);
node.set_scalar(value);
node.set_tag(tag);
Pop();
}
void NodeBuilder::OnSequenceStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor)
{
detail::node& node = Push(anchor);
node.set_tag(tag);
node.set_type(NodeType::Sequence);
}
void NodeBuilder::OnSequenceEnd()
{
Pop();
}
void NodeBuilder::OnMapStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor)
{
detail::node& node = Push(anchor);
node.set_type(NodeType::Map);
node.set_tag(tag);
m_mapDepth++;
}
void NodeBuilder::OnMapEnd()
{
assert(m_mapDepth > 0);
m_mapDepth--;
Pop();
}
NodeBuilder::NodeBuilder() detail::node& NodeBuilder::Push(anchor_t anchor)
: m_pMemory(new detail::memory_holder), {
m_pRoot(nullptr), detail::node& node = m_pMemory->create_node();
m_stack{}, RegisterAnchor(anchor, node);
m_anchors{}, Push(node);
m_keys{}, return node;
m_mapDepth(0) { }
m_anchors.push_back(nullptr); // since the anchors start at 1
void NodeBuilder::Push(detail::node& node)
{
const bool needsKey = (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && m_keys.size() < m_mapDepth);
m_stack.push_back(&node);
if(needsKey)
m_keys.push_back(PushedKey(&node, false));
}
void NodeBuilder::Pop()
{
assert(!m_stack.empty());
if(m_stack.size() == 1) {
m_pRoot = m_stack[0];
m_stack.pop_back();
return;
}
detail::node& node = *m_stack.back();
m_stack.pop_back();
detail::node& collection = *m_stack.back();
if(collection.type() == NodeType::Sequence) {
collection.push_back(node, m_pMemory);
} else if(collection.type() == NodeType::Map) {
assert(!m_keys.empty());
PushedKey& key = m_keys.back();
if(key.second) {
collection.insert(*key.first, node, m_pMemory);
m_keys.pop_back();
} else {
key.second = true;
}
} else {
assert(false);
m_stack.clear();
}
}
void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node)
{
if(anchor) {
assert(anchor == m_anchors.size());
m_anchors.push_back(&node);
}
}
} }
NodeBuilder::~NodeBuilder() = default;
Node NodeBuilder::Root() {
if (!m_pRoot)
return Node();
return Node(*m_pRoot, m_pMemory);
}
void NodeBuilder::OnDocumentStart(const Mark&) {}
void NodeBuilder::OnDocumentEnd() {}
void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) {
detail::node& node = Push(mark, anchor);
node.set_null();
Pop();
}
void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) {
detail::node& node = *m_anchors[anchor];
Push(node);
Pop();
}
void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value) {
detail::node& node = Push(mark, anchor);
node.set_scalar(value);
node.set_tag(tag);
Pop();
}
void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) {
detail::node& node = Push(mark, anchor);
node.set_tag(tag);
node.set_type(NodeType::Sequence);
node.set_style(style);
}
void NodeBuilder::OnSequenceEnd() { Pop(); }
void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) {
detail::node& node = Push(mark, anchor);
node.set_type(NodeType::Map);
node.set_tag(tag);
node.set_style(style);
m_mapDepth++;
}
void NodeBuilder::OnMapEnd() {
assert(m_mapDepth > 0);
m_mapDepth--;
Pop();
}
detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) {
detail::node& node = m_pMemory->create_node();
node.set_mark(mark);
RegisterAnchor(anchor, node);
Push(node);
return node;
}
void NodeBuilder::Push(detail::node& node) {
const bool needsKey =
(!m_stack.empty() && m_stack.back()->type() == NodeType::Map &&
m_keys.size() < m_mapDepth);
m_stack.push_back(&node);
if (needsKey)
m_keys.emplace_back(&node, false);
}
void NodeBuilder::Pop() {
assert(!m_stack.empty());
if (m_stack.size() == 1) {
m_pRoot = m_stack[0];
m_stack.pop_back();
return;
}
detail::node& node = *m_stack.back();
m_stack.pop_back();
detail::node& collection = *m_stack.back();
if (collection.type() == NodeType::Sequence) {
collection.push_back(node, m_pMemory);
} else if (collection.type() == NodeType::Map) {
assert(!m_keys.empty());
PushedKey& key = m_keys.back();
if (key.second) {
collection.insert(*key.first, node, m_pMemory);
m_keys.pop_back();
} else {
key.second = true;
}
} else {
assert(false);
m_stack.clear();
}
}
void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) {
if (anchor) {
assert(anchor == m_anchors.size());
m_anchors.push_back(&node);
}
}
} // namespace YAML
+45 -61
View File
@@ -1,74 +1,58 @@
#ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <vector>
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h" #include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include <vector>
namespace YAML { namespace YAML
namespace detail { {
class node; class Node;
} // namespace detail
struct Mark;
} // namespace YAML
namespace YAML { class NodeBuilder: public EventHandler
class Node; {
public:
NodeBuilder();
virtual ~NodeBuilder();
Node Root();
virtual void OnDocumentStart(const Mark& mark);
virtual void OnDocumentEnd();
virtual void OnNull(const Mark& mark, anchor_t anchor);
virtual void OnAlias(const Mark& mark, anchor_t anchor);
virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value);
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor);
virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor);
virtual void OnMapEnd();
private:
detail::node& Push(anchor_t anchor);
void Push(detail::node& node);
void Pop();
void RegisterAnchor(anchor_t anchor, detail::node& node);
private:
detail::shared_memory_holder m_pMemory;
detail::node *m_pRoot;
typedef std::vector<detail::node *> Nodes;
Nodes m_stack;
Nodes m_anchors;
class NodeBuilder : public EventHandler { typedef std::pair<detail::node *, bool> PushedKey;
public: std::vector<PushedKey> m_keys;
NodeBuilder(); std::size_t m_mapDepth;
NodeBuilder(const NodeBuilder&) = delete; };
NodeBuilder(NodeBuilder&&) = delete; }
NodeBuilder& operator=(const NodeBuilder&) = delete;
NodeBuilder& operator=(NodeBuilder&&) = delete;
~NodeBuilder() override;
Node Root(); #endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
void OnDocumentStart(const Mark& mark) override;
void OnDocumentEnd() override;
void OnNull(const Mark& mark, anchor_t anchor) override;
void OnAlias(const Mark& mark, anchor_t anchor) override;
void OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value) override;
void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) override;
void OnSequenceEnd() override;
void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) override;
void OnMapEnd() override;
private:
detail::node& Push(const Mark& mark, anchor_t anchor);
void Push(detail::node& node);
void Pop();
void RegisterAnchor(anchor_t anchor, detail::node& node);
private:
detail::shared_memory_holder m_pMemory;
detail::node* m_pRoot;
using Nodes = std::vector<detail::node *>;
Nodes m_stack;
Nodes m_anchors;
using PushedKey = std::pair<detail::node*, bool>;
std::vector<PushedKey> m_keys;
std::size_t m_mapDepth;
};
} // namespace YAML
#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+94 -93
View File
@@ -1,98 +1,99 @@
#include "nodeevents.h" #include "nodeevents.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/eventhandler.h" #include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/detail/node_iterator.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/type.h"
namespace YAML { namespace YAML
void NodeEvents::AliasManager::RegisterReference(const detail::node& node) { {
m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor())); void NodeEvents::AliasManager::RegisterReference(const detail::node& node)
{
m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor()));
}
anchor_t NodeEvents::AliasManager::LookupAnchor(const detail::node& node) const
{
AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref());
if(it == m_anchorByIdentity.end())
return 0;
return it->second;
}
NodeEvents::NodeEvents(const Node& node): m_pMemory(node.m_pMemory), m_root(*node.m_pNode)
{
Setup(m_root);
}
void NodeEvents::Setup(const detail::node& node)
{
int& refCount = m_refCount[node.ref()];
refCount++;
if(refCount > 1)
return;
if(node.type() == NodeType::Sequence) {
for(detail::const_node_iterator it=node.begin();it!=node.end();++it)
Setup(**it);
} else if(node.type() == NodeType::Map) {
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) {
Setup(*it->first);
Setup(*it->second);
}
}
}
void NodeEvents::Emit(EventHandler& handler)
{
AliasManager am;
handler.OnDocumentStart(Mark());
Emit(m_root, handler, am);
handler.OnDocumentEnd();
}
void NodeEvents::Emit(const detail::node& node, EventHandler& handler, AliasManager& am) const
{
anchor_t anchor = NullAnchor;
if(IsAliased(node)) {
anchor = am.LookupAnchor(node);
if(anchor) {
handler.OnAlias(Mark(), anchor);
return;
}
am.RegisterReference(node);
anchor = am.LookupAnchor(node);
}
switch(node.type()) {
case NodeType::Undefined:
break;
case NodeType::Null:
handler.OnNull(Mark(), anchor);
break;
case NodeType::Scalar:
handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
break;
case NodeType::Sequence:
handler.OnSequenceStart(Mark(), node.tag(), anchor);
for(detail::const_node_iterator it=node.begin();it!=node.end();++it)
Emit(**it, handler, am);
handler.OnSequenceEnd();
break;
case NodeType::Map:
handler.OnMapStart(Mark(), node.tag(), anchor);
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) {
Emit(*it->first, handler, am);
Emit(*it->second, handler, am);
}
handler.OnMapEnd();
break;
}
}
bool NodeEvents::IsAliased(const detail::node& node) const
{
RefCount::const_iterator it = m_refCount.find(node.ref());
return it != m_refCount.end() && it->second > 1;
}
} }
anchor_t NodeEvents::AliasManager::LookupAnchor(
const detail::node& node) const {
auto it = m_anchorByIdentity.find(node.ref());
if (it == m_anchorByIdentity.end())
return 0;
return it->second;
}
NodeEvents::NodeEvents(const Node& node)
: m_pMemory(node.m_pMemory), m_root(node.m_pNode), m_refCount{} {
if (m_root)
Setup(*m_root);
}
void NodeEvents::Setup(const detail::node& node) {
int& refCount = m_refCount[node.ref()];
refCount++;
if (refCount > 1)
return;
if (node.type() == NodeType::Sequence) {
for (auto element : node)
Setup(*element);
} else if (node.type() == NodeType::Map) {
for (auto element : node) {
Setup(*element.first);
Setup(*element.second);
}
}
}
void NodeEvents::Emit(EventHandler& handler) {
AliasManager am;
handler.OnDocumentStart(Mark());
if (m_root)
Emit(*m_root, handler, am);
handler.OnDocumentEnd();
}
void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
AliasManager& am) const {
anchor_t anchor = NullAnchor;
if (IsAliased(node)) {
anchor = am.LookupAnchor(node);
if (anchor) {
handler.OnAlias(Mark(), anchor);
return;
}
am.RegisterReference(node);
anchor = am.LookupAnchor(node);
}
switch (node.type()) {
case NodeType::Undefined:
break;
case NodeType::Null:
handler.OnNull(Mark(), anchor);
break;
case NodeType::Scalar:
handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
break;
case NodeType::Sequence:
handler.OnSequenceStart(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());
for (auto element : node) {
Emit(*element.first, handler, am);
Emit(*element.second, handler, am);
}
handler.OnMapEnd();
break;
}
}
bool NodeEvents::IsAliased(const detail::node& node) const {
auto it = m_refCount.find(node.ref());
return it != m_refCount.end() && it->second > 1;
}
} // namespace YAML
+46 -57
View File
@@ -1,68 +1,57 @@
#ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \ #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/node/ptr.h"
#include <map> #include <map>
#include <vector> #include <vector>
#include "yaml-cpp/anchor.h" namespace YAML
#include "yaml-cpp/node/ptr.h" {
class EventHandler;
class Node;
class NodeEvents
{
public:
explicit NodeEvents(const Node& node);
void Emit(EventHandler& handler);
private:
class AliasManager {
public:
AliasManager(): m_curAnchor(0) {}
void RegisterReference(const detail::node& node);
anchor_t LookupAnchor(const detail::node& node) const;
private:
anchor_t _CreateNewAnchor() { return ++m_curAnchor; }
private:
typedef std::map<const detail::node_ref*, anchor_t> AnchorByIdentity;
AnchorByIdentity m_anchorByIdentity;
anchor_t m_curAnchor;
};
void Setup(const detail::node& node);
void Emit(const detail::node& node, EventHandler& handler, AliasManager& am) const;
bool IsAliased(const detail::node& node) const;
private:
detail::shared_memory_holder m_pMemory;
detail::node& m_root;
typedef std::map<const detail::node_ref *, int> RefCount;
RefCount m_refCount;
};
}
namespace YAML { #endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
namespace detail {
class node;
} // namespace detail
} // namespace YAML
namespace YAML {
class EventHandler;
class Node;
class NodeEvents {
public:
explicit NodeEvents(const Node& node);
NodeEvents(const NodeEvents&) = delete;
NodeEvents(NodeEvents&&) = delete;
NodeEvents& operator=(const NodeEvents&) = delete;
NodeEvents& operator=(NodeEvents&&) = delete;
void Emit(EventHandler& handler);
private:
class AliasManager {
public:
AliasManager() : m_anchorByIdentity{}, m_curAnchor(0) {}
void RegisterReference(const detail::node& node);
anchor_t LookupAnchor(const detail::node& node) const;
private:
anchor_t _CreateNewAnchor() { return ++m_curAnchor; }
private:
using AnchorByIdentity = std::map<const detail::node_ref*, anchor_t>;
AnchorByIdentity m_anchorByIdentity;
anchor_t m_curAnchor;
};
void Setup(const detail::node& node);
void Emit(const detail::node& node, EventHandler& handler,
AliasManager& am) const;
bool IsAliased(const detail::node& node) const;
private:
detail::shared_memory_holder m_pMemory;
detail::node* m_root;
using RefCount = std::map<const detail::node_ref*, int>;
RefCount m_refCount;
};
} // namespace YAML
#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
+3 -14
View File
@@ -1,17 +1,6 @@
#include "yaml-cpp/null.h" #include "yaml-cpp/null.h"
#include <cstring>
namespace YAML { namespace YAML
_Null Null; {
_Null 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
+63
View File
@@ -0,0 +1,63 @@
#include "yaml-cpp/ostream.h"
#include <cstring>
namespace YAML
{
ostream::ostream(): m_buffer(0), m_pos(0), m_size(0), m_row(0), m_col(0)
{
reserve(1024);
}
ostream::~ostream()
{
delete [] m_buffer;
}
void ostream::reserve(unsigned size)
{
if(size <= m_size)
return;
char *newBuffer = new char[size];
std::memset(newBuffer, 0, size * sizeof(char));
std::memcpy(newBuffer, m_buffer, m_size * sizeof(char));
delete [] m_buffer;
m_buffer = newBuffer;
m_size = size;
}
void ostream::put(char ch)
{
if(m_pos >= m_size - 1) // an extra space for the NULL terminator
reserve(m_size * 2);
m_buffer[m_pos] = ch;
m_pos++;
if(ch == '\n') {
m_row++;
m_col = 0;
} else
m_col++;
}
ostream& operator << (ostream& out, const char *str)
{
std::size_t length = std::strlen(str);
for(std::size_t i=0;i<length;i++)
out.put(str[i]);
return out;
}
ostream& operator << (ostream& out, const std::string& str)
{
out << str.c_str();
return out;
}
ostream& operator << (ostream& out, char ch)
{
out.put(ch);
return out;
}
}
-62
View File
@@ -1,62 +0,0 @@
#include "yaml-cpp/ostream_wrapper.h"
#include <algorithm>
#include <cstring>
#include <ostream>
namespace YAML {
ostream_wrapper::ostream_wrapper()
: m_buffer(1, '\0'),
m_pStream(nullptr),
m_pos(0),
m_row(0),
m_col(0),
m_comment(false) {}
ostream_wrapper::ostream_wrapper(std::ostream& stream)
: m_buffer{},
m_pStream(&stream),
m_pos(0),
m_row(0),
m_col(0),
m_comment(false) {}
ostream_wrapper::~ostream_wrapper() = default;
void ostream_wrapper::write(const std::string& str) {
if (m_pStream) {
m_pStream->write(str.c_str(), str.size());
} else {
m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1));
std::copy(str.begin(), str.end(), m_buffer.begin() + m_pos);
}
for (char ch : str) {
update_pos(ch);
}
}
void ostream_wrapper::write(const char* str, std::size_t size) {
if (m_pStream) {
m_pStream->write(str, size);
} else {
m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1));
std::copy(str, str + size, m_buffer.begin() + m_pos);
}
for (std::size_t i = 0; i < size; i++) {
update_pos(str[i]);
}
}
void ostream_wrapper::update_pos(char ch) {
m_pos++;
m_col++;
if (ch == '\n') {
m_row++;
m_col = 0;
m_comment = false;
}
}
} // namespace YAML

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